@@ -7,6 +7,7 @@ import scala.annotation.{Annotation, compileTimeOnly}
7
7
import dotty .tools .dotc
8
8
import dotty .tools .dotc .ast .tpd
9
9
import dotty .tools .dotc .core .Contexts ._
10
+ import dotty .tools .dotc .core .Names .*
10
11
import dotty .tools .dotc .core .StdNames .nme
11
12
12
13
/** Matches a quoted tree against a quoted pattern tree.
@@ -193,29 +194,6 @@ object Matcher {
193
194
scrutinee.tpe <:< tpt.tpe =>
194
195
matched(scrutinee.asExpr)
195
196
196
- /* Higher order term hole */
197
- // Matches an open term and wraps it into a lambda that provides the free variables
198
- case (scrutinee, pattern @ Apply (TypeApply (Ident (" higherOrderHole" ), List (Inferred ())), Repeated (args, _) :: Nil ))
199
- if pattern.symbol.eq(dotc.core.Symbols .defn.QuotedRuntimePatterns_higherOrderHole ) =>
200
-
201
- def bodyFn (lambdaArgs : List [Tree ]): Tree = {
202
- val argsMap = args.map(_.symbol).zip(lambdaArgs.asInstanceOf [List [Term ]]).toMap
203
- new TreeMap {
204
- override def transformTerm (tree : Term )(owner : Symbol ): Term =
205
- tree match
206
- case tree : Ident => summon[Env ].get(tree.symbol.asInstanceOf ).asInstanceOf [Option [Symbol ]].flatMap(argsMap.get).getOrElse(tree)
207
- case tree => super .transformTerm(tree)(owner)
208
- }.transformTree(scrutinee)(Symbol .spliceOwner)
209
- }
210
- val names = args.map {
211
- case Block (List (DefDef (" $anonfun" , _, _, Some (Apply (Ident (name), _)))), _) => name
212
- case arg => arg.symbol.name
213
- }
214
- val argTypes = args.map(x => x.tpe.widenTermRefByName)
215
- val resType = pattern.tpe
216
- val res = Lambda (Symbol .spliceOwner, MethodType (names)(_ => argTypes, _ => resType), (meth, x) => bodyFn(x).changeOwner(meth))
217
- matched(res.asExpr)
218
-
219
197
220
198
// No Match
221
199
case _ =>
@@ -228,6 +206,7 @@ object Matcher {
228
206
import tpd .* // TODO remove
229
207
import dotc .core .Flags .* // TODO remove
230
208
import dotc .core .Types .* // TODO remove
209
+ import dotc .core .Symbols .* // TODO remove
231
210
232
211
/** Check that both are `val` or both are `lazy val` or both are `var` **/
233
212
def checkValFlags (): Boolean = {
@@ -244,8 +223,42 @@ object Matcher {
244
223
case _ => None
245
224
end TypeTreeTypeTest
246
225
226
+ object Lambda :
227
+ def apply (owner : Symbol , tpe : MethodType , rhsFn : (Symbol , List [Tree ]) => Tree ): Block =
228
+ val meth = dotc.core.Symbols .newSymbol(owner, nme.ANON_FUN , Synthetic | Method , tpe)
229
+ tpd.Closure (meth, tss => rhsFn(meth, tss.head))
230
+ end Lambda
231
+
247
232
(scrutinee, pattern) match
248
233
234
+ /* Higher order term hole */
235
+ // Matches an open term and wraps it into a lambda that provides the free variables
236
+ case (scrutinee, pattern @ Apply (TypeApply (Ident (_), List (TypeTree ())), SeqLiteral (args, _) :: Nil ))
237
+ if pattern.symbol.eq(dotc.core.Symbols .defn.QuotedRuntimePatterns_higherOrderHole ) =>
238
+
239
+ def bodyFn (lambdaArgs : List [Tree ]): Tree = {
240
+ val argsMap = args.map(_.symbol).zip(lambdaArgs.asInstanceOf [List [Tree ]]).toMap
241
+ new TreeMap {
242
+ override def transform (tree : Tree )(using Context ): Tree =
243
+ tree match
244
+ case tree : Ident => summon[Env ].get(tree.symbol).flatMap(argsMap.get).getOrElse(tree)
245
+ case tree => super .transform(tree)
246
+ }.transform(scrutinee)
247
+ }
248
+ val names : List [TermName ] = args.map {
249
+ case Block (List (DefDef (nme.ANON_FUN , _, _, Apply (Ident (name), _))), _) => name.asTermName
250
+ case arg => arg.symbol.name.asTermName
251
+ }
252
+ val argTypes = args.map(x => x.tpe.widenTermRefExpr)
253
+ val resType = pattern.tpe
254
+ val res =
255
+ Lambda (
256
+ ctx.owner,
257
+ MethodType (names)(
258
+ _ => argTypes, _ => resType),
259
+ (meth, x) => tpd.TreeOps (bodyFn(x)).changeNonLocalOwners(meth.asInstanceOf ))
260
+ matched(qctx.reflect.TreeMethods .asExpr(res.asInstanceOf [qctx.reflect.Tree ]))
261
+
249
262
//
250
263
// Match two equivalent trees
251
264
//
0 commit comments