1
- package scala . internal .quoted
1
+ package dotty . tools . dotc .quoted
2
2
3
3
import scala .annotation .internal .sharable
4
4
import scala .annotation .{Annotation , compileTimeOnly }
@@ -98,33 +98,8 @@ import scala.internal.tasty.CompilerInterface.quoteContextWithCompilerInterface
98
98
*/
99
99
object Matcher {
100
100
101
- /** A splice in a quoted pattern is desugared by the compiler into a call to this method */
102
- @ compileTimeOnly(" Illegal reference to `scala.internal.quoted.CompileTime.patternHole`" )
103
- def patternHole [T ]: T = ???
104
-
105
- @ compileTimeOnly(" Illegal reference to `scala.internal.quoted.CompileTime.patternHigherOrderHole`" )
106
- /** A higher order splice in a quoted pattern is desugared by the compiler into a call to this method */
107
- def patternHigherOrderHole [U ](pat : Any , args : Any * ): U = ???
108
-
109
- @ compileTimeOnly(" Illegal reference to `scala.internal.quoted.CompileTime.higherOrderHole`" )
110
- /** A higher order splice in a quoted pattern is desugared by the compiler into a call to this method */
111
- def higherOrderHole [U ](args : Any * ): U = ???
112
-
113
- // TODO remove
114
- /** A splice of a name in a quoted pattern is desugared by wrapping getting this annotation */
115
- @ compileTimeOnly(" Illegal reference to `scala.internal.quoted.CompileTime.patternBindHole`" )
116
- class patternBindHole extends Annotation
117
-
118
- /** A splice of a name in a quoted pattern is that marks the definition of a type splice */
119
- @ compileTimeOnly(" Illegal reference to `scala.internal.quoted.CompileTime.patternType`" )
120
- class patternType extends Annotation
121
-
122
- /** A type pattern that must be aproximated from above */
123
- @ compileTimeOnly(" Illegal reference to `scala.internal.quoted.CompileTime.fromAbove`" )
124
- class fromAbove extends Annotation
125
-
126
101
class QuoteMatcher [QCtx <: QuoteContext & Singleton ](val qctx0 : QCtx ) {
127
- val qctx = quoteContextWithCompilerInterface( qctx0)
102
+ val qctx = qctx0. asInstanceOf [qctx0. type { val tasty : qctx0.tasty. type & scala.internal.tasty. CompilerInterface }]
128
103
129
104
// TODO improve performance
130
105
@@ -145,54 +120,13 @@ object Matcher {
145
120
146
121
inline private def withEnv [T ](env : Env )(inline body : Env ?=> T ): T = body(using env)
147
122
148
- class SymBinding (val sym : Symbol , val fromAbove : Boolean )
149
-
150
- def termMatch (scrutineeTerm : Term , patternTerm : Term , hasTypeSplices : Boolean ): Option [Tuple ] = {
123
+ def termMatch (scrutineeTerm : Term , patternTerm : Term ): Option [Tuple ] =
151
124
given Env = Map .empty
152
- val matchings = scrutineeTerm =?= patternTerm
153
- if ! hasTypeSplices then matchings
154
- else {
155
- // After matching and doing all subtype checks, we have to approximate all the type bindings
156
- // that we have found and seal them in a quoted.Type
157
- matchings.asOptionOfTuple.map { tup =>
158
- Tuple .fromArray(tup.toArray.map { // TODO improve performance
159
- case x : SymBinding => qctx.tasty.Constraints_approximation (x.sym, ! x.fromAbove).seal
160
- case x => x
161
- })
162
- }
163
- }
164
- }
125
+ scrutineeTerm =?= patternTerm
165
126
166
- // TODO factor out common logic with `termMatch`
167
- def typeTreeMatch (scrutineeTypeTree : TypeTree , patternTypeTree : TypeTree , hasTypeSplices : Boolean ): Option [Tuple ] = {
127
+ def typeTreeMatch (scrutineeTypeTree : TypeTree , patternTypeTree : TypeTree ): Option [Tuple ] =
168
128
given Env = Map .empty
169
- val matchings = scrutineeTypeTree =?= patternTypeTree
170
- if ! hasTypeSplices then matchings
171
- else {
172
- // After matching and doing all subtype checks, we have to approximate all the type bindings
173
- // that we have found and seal them in a quoted.Type
174
- matchings.asOptionOfTuple.map { tup =>
175
- Tuple .fromArray(tup.toArray.map { // TODO improve performance
176
- case x : SymBinding => qctx.tasty.Constraints_approximation (x.sym, ! x.fromAbove).seal
177
- case x => x
178
- })
179
- }
180
- }
181
- }
182
-
183
- private def hasPatternTypeAnnotation (sym : Symbol ) = sym.annots.exists(isPatternTypeAnnotation)
184
-
185
- private def hasFromAboveAnnotation (sym : Symbol ) = sym.annots.exists(isFromAboveAnnotation)
186
-
187
- private def isPatternTypeAnnotation (tree : Tree ): Boolean = tree match {
188
- case New (tpt) => tpt.symbol == qctx.tasty.Definitions_InternalQuotedMatcher_patternTypeAnnot
189
- case annot => annot.symbol.owner == qctx.tasty.Definitions_InternalQuotedMatcher_patternTypeAnnot
190
- }
191
-
192
- private def isFromAboveAnnotation (tree : Tree ): Boolean = tree match {
193
- case New (tpt) => tpt.symbol == qctx.tasty.Definitions_InternalQuotedMatcher_fromAboveAnnot
194
- case annot => annot.symbol.owner == qctx.tasty.Definitions_InternalQuotedMatcher_fromAboveAnnot
195
- }
129
+ scrutineeTypeTree =?= patternTypeTree
196
130
197
131
/** Check that all trees match with `mtch` and concatenate the results with &&& */
198
132
private def matchLists [T ](l1 : List [T ], l2 : List [T ])(mtch : (T , T ) => Matching ): Matching = (l1, l2) match {
@@ -244,23 +178,23 @@ object Matcher {
244
178
245
179
/* Term hole */
246
180
// Match a scala.internal.Quoted.patternHole typed as a repeated argument and return the scrutinee tree
247
- case (scrutinee as Typed (s, tpt1), Typed (TypeApply (patternHole, tpt :: Nil ), tpt2))
248
- if patternHole.symbol == qctx.tasty.Definitions_InternalQuotedMatcher_patternHole &&
181
+ case (scrutinee @ Typed (s, tpt1), Typed (TypeApply (patternHole, tpt :: Nil ), tpt2))
182
+ if patternHole.symbol == qctx.tasty.Definitions_InternalQuotedPatterns_patternHole &&
249
183
s.tpe <:< tpt.tpe &&
250
184
tpt2.tpe.derivesFrom(defn.RepeatedParamClass ) =>
251
185
matched(scrutinee.seal)
252
186
253
187
/* Term hole */
254
188
// Match a scala.internal.Quoted.patternHole and return the scrutinee tree
255
189
case (ClosedPatternTerm (scrutinee), TypeApply (patternHole, tpt :: Nil ))
256
- if patternHole.symbol == qctx.tasty.Definitions_InternalQuotedMatcher_patternHole &&
190
+ if patternHole.symbol == qctx.tasty.Definitions_InternalQuotedPatterns_patternHole &&
257
191
scrutinee.tpe <:< tpt.tpe =>
258
192
matched(scrutinee.seal)
259
193
260
194
/* Higher order term hole */
261
195
// Matches an open term and wraps it into a lambda that provides the free variables
262
- case (scrutinee, pattern as Apply (TypeApply (Ident (" higherOrderHole" ), List (Inferred ())), Repeated (args, _) :: Nil ))
263
- if pattern.symbol == qctx.tasty.Definitions_InternalQuotedMatcher_higherOrderHole =>
196
+ case (scrutinee, pattern @ Apply (TypeApply (Ident (" higherOrderHole" ), List (Inferred ())), Repeated (args, _) :: Nil ))
197
+ if pattern.symbol == qctx.tasty.Definitions_InternalQuotedPatterns_higherOrderHole =>
264
198
265
199
def bodyFn (lambdaArgs : List [Tree ]): Tree = {
266
200
val argsMap = args.map(_.symbol).zip(lambdaArgs.asInstanceOf [List [Term ]]).toMap
@@ -317,10 +251,6 @@ object Matcher {
317
251
case (TypeApply (fn1, args1), TypeApply (fn2, args2)) =>
318
252
fn1 =?= fn2 &&& args1 =?= args2
319
253
320
- case (Block (stats1, expr1), Block (binding :: stats2, expr2)) if isTypeBinding(binding) =>
321
- qctx.tasty.Constraints_add (binding.symbol :: Nil )
322
- matched(new SymBinding (binding.symbol, hasFromAboveAnnotation(binding.symbol))) &&& Block (stats1, expr1) =?= Block (stats2, expr2)
323
-
324
254
/* Match block */
325
255
case (Block (stat1 :: stats1, expr1), Block (stat2 :: stats2, expr2)) =>
326
256
val newEnv = (stat1, stat2) match {
@@ -333,11 +263,6 @@ object Matcher {
333
263
stat1 =?= stat2 &&& Block (stats1, expr1) =?= Block (stats2, expr2)
334
264
}
335
265
336
- case (scrutinee, Block (typeBindings, expr2)) if typeBindings.forall(isTypeBinding) =>
337
- val bindingSymbols = typeBindings.map(_.symbol)
338
- qctx.tasty.Constraints_add (bindingSymbols)
339
- bindingSymbols.foldRight(scrutinee =?= expr2)((x, acc) => matched(new SymBinding (x, hasFromAboveAnnotation(x))) &&& acc)
340
-
341
266
/* Match if */
342
267
case (If (cond1, thenp1, elsep1), If (cond2, thenp2, elsep2)) =>
343
268
cond1 =?= cond2 &&& thenp1 =?= thenp2 &&& elsep1 =?= elsep2
@@ -456,10 +381,6 @@ object Matcher {
456
381
}
457
382
}
458
383
459
- private def isTypeBinding (tree : Tree ): Boolean = tree match {
460
- case tree : TypeDef => hasPatternTypeAnnotation(tree.symbol)
461
- case _ => false
462
- }
463
384
}
464
385
465
386
/** Result of matching a part of an expression */
0 commit comments