@@ -181,26 +181,30 @@ object QuoteMatcher {
181
181
case _ => None
182
182
end TypeTreeTypeTest
183
183
184
- (scrutinee, pattern) match
184
+ val res = pattern match
185
185
186
186
/* Term hole */
187
187
// Match a scala.internal.Quoted.patternHole typed as a repeated argument and return the scrutinee tree
188
- case (scrutinee @ Typed (s, tpt1), Typed ( TypeApply (patternHole, tpt :: Nil ), tpt2) )
188
+ case Typed (TypeApply (patternHole, tpt :: Nil ), tpt2)
189
189
if patternHole.symbol.eq(defn.QuotedRuntimePatterns_patternHole ) &&
190
- s.tpe <:< tpt.tpe &&
191
- tpt2.tpe.derivesFrom(defn.RepeatedParamClass ) =>
192
- matched(scrutinee)
190
+ tpt2.tpe.derivesFrom(defn.RepeatedParamClass ) =>
191
+ scrutinee match
192
+ case Typed (s, tpt1) if s.tpe <:< tpt.tpe => matched(scrutinee)
193
+ case _ => notMatched
193
194
194
195
/* Term hole */
195
196
// Match a scala.internal.Quoted.patternHole and return the scrutinee tree
196
- case ( ClosedPatternTerm (scrutinee), TypeApply (patternHole, tpt :: Nil ) )
197
+ case TypeApply (patternHole, tpt :: Nil )
197
198
if patternHole.symbol.eq(defn.QuotedRuntimePatterns_patternHole ) &&
198
199
scrutinee.tpe <:< tpt.tpe =>
199
- matched(scrutinee)
200
+ scrutinee match
201
+ case ClosedPatternTerm (scrutinee) => matched(scrutinee)
202
+ case _ => notMatched
203
+
200
204
201
205
/* Higher order term hole */
202
206
// Matches an open term and wraps it into a lambda that provides the free variables
203
- case (scrutinee, pattern @ Apply (TypeApply (Ident (_), List (TypeTree ())), SeqLiteral (args, _) :: Nil ) )
207
+ case Apply (TypeApply (Ident (_), List (TypeTree ())), SeqLiteral (args, _) :: Nil )
204
208
if pattern.symbol.eq(defn.QuotedRuntimePatterns_higherOrderHole ) =>
205
209
val names : List [TermName ] = args.map {
206
210
case Block (List (DefDef (nme.ANON_FUN , _, _, Apply (Ident (name), _))), _) => name.asTermName
@@ -221,138 +225,180 @@ object QuoteMatcher {
221
225
}
222
226
matched(Closure (meth, bodyFn))
223
227
224
- //
225
- // Match two equivalent trees
226
- //
227
-
228
- /* Match literal */
229
- case (Literal (constant1), Literal (constant2)) if constant1 == constant2 =>
230
- matched
231
-
232
- /* Match type ascription (a) */
233
- case (Typed (expr1, _), pattern) =>
234
- expr1 =?= pattern
235
-
236
228
/* Match type ascription (b) */
237
- case (scrutinee, Typed (expr2, _) ) =>
229
+ case Typed (expr2, _) =>
238
230
scrutinee =?= expr2
239
231
240
- /* Match selection */
241
- case (ref : RefTree , Select (qual2, _)) if symbolMatch(scrutinee, pattern) =>
242
- ref match
243
- case Select (qual1, _) => qual1 =?= qual2
244
- case ref : Ident =>
245
- ref.tpe match
246
- case TermRef (qual : TermRef , _) => tpd.ref(qual) =?= qual2
247
- case _ => matched
248
-
249
- /* Match reference */
250
- case (_ : RefTree , _ : Ident ) if symbolMatch(scrutinee, pattern) =>
251
- matched
252
-
253
- /* Match application */
254
- case (Apply (fn1, args1), Apply (fn2, args2)) =>
255
- fn1 =?= fn2 &&& args1 =?= args2
256
-
257
- /* Match type application */
258
- case (TypeApply (fn1, args1), TypeApply (fn2, args2)) =>
259
- fn1 =?= fn2 &&& args1 =?= args2
260
-
261
- /* Match block */
262
- case (Block (stat1 :: stats1, expr1), Block (stat2 :: stats2, expr2)) =>
263
- val newEnv = (stat1, stat2) match {
264
- case (stat1 : MemberDef , stat2 : MemberDef ) =>
265
- summon[Env ] + (stat1.symbol -> stat2.symbol)
266
- case _ =>
267
- summon[Env ]
268
- }
269
- withEnv(newEnv) {
270
- stat1 =?= stat2 &&& Block (stats1, expr1) =?= Block (stats2, expr2)
271
- }
272
-
273
- /* Match if */
274
- case (If (cond1, thenp1, elsep1), If (cond2, thenp2, elsep2)) =>
275
- cond1 =?= cond2 &&& thenp1 =?= thenp2 &&& elsep1 =?= elsep2
276
-
277
- /* Match while */
278
- case (WhileDo (cond1, body1), WhileDo (cond2, body2)) =>
279
- cond1 =?= cond2 &&& body1 =?= body2
280
-
281
- /* Match assign */
282
- case (Assign (lhs1, rhs1), Assign (lhs2, rhs2)) =>
283
- lhs1 =?= lhs2 &&& rhs1 =?= rhs2
284
-
285
- /* Match new */
286
- case (New (tpt1), New (tpt2)) if tpt1.tpe.typeSymbol == tpt2.tpe.typeSymbol =>
287
- matched
288
-
289
- /* Match this */
290
- case (This (_), This (_)) if scrutinee.symbol == pattern.symbol =>
291
- matched
292
-
293
- /* Match super */
294
- case (Super (qual1, mix1), Super (qual2, mix2)) if mix1 == mix2 =>
295
- qual1 =?= qual2
296
-
297
- /* Match varargs */
298
- case (SeqLiteral (elems1, _), SeqLiteral (elems2, _)) if elems1.size == elems2.size =>
299
- elems1 =?= elems2
300
-
301
- /* Match type */
302
- // TODO remove this?
303
- case (TypeTreeTypeTest (scrutinee), TypeTreeTypeTest (pattern)) if scrutinee.tpe <:< pattern.tpe =>
304
- matched
305
-
306
- /* Match val */
307
- case (scrutinee @ ValDef (_, tpt1, _), pattern @ ValDef (_, tpt2, _)) if checkValFlags() =>
308
- def rhsEnv = summon[Env ] + (scrutinee.symbol -> pattern.symbol)
309
- tpt1 =?= tpt2 &&& withEnv(rhsEnv)(scrutinee.rhs =?= pattern.rhs)
310
-
311
- /* Match def */
312
- case (scrutinee @ DefDef (_, paramss1, tpt1, _), pattern @ DefDef (_, paramss2, tpt2, _)) =>
313
- def rhsEnv : Env =
314
- val paramSyms : List [(Symbol , Symbol )] =
315
- for
316
- (clause1, clause2) <- paramss1.zip(paramss2)
317
- (param1, param2) <- clause1.zip(clause2)
318
- yield
319
- param1.symbol -> param2.symbol
320
- val oldEnv : Env = summon[Env ]
321
- val newEnv : List [(Symbol , Symbol )] = (scrutinee.symbol -> pattern.symbol) :: paramSyms
322
- oldEnv ++ newEnv
323
-
324
- matchLists(paramss1, paramss2)(_ =?= _)
325
- &&& tpt1 =?= tpt2
326
- &&& withEnv(rhsEnv)(scrutinee.rhs =?= pattern.rhs)
327
-
328
- case (Closure (_, _, tpt1), Closure (_, _, tpt2)) =>
329
- // TODO match tpt1 with tpt2?
330
- matched
331
-
332
- case (NamedArg (name1, arg1), NamedArg (name2, arg2)) if name1 == name2 =>
333
- arg1 =?= arg2
334
-
335
- case (EmptyTree , EmptyTree ) =>
336
- matched
337
-
338
- // No Match
339
232
case _ =>
340
- if (debug)
341
- val quotes = QuotesImpl ()
342
- println(
343
- s """ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
344
- |Scrutinee
345
- | ${scrutinee.show}
346
- |did not match pattern
347
- | ${pattern.show}
348
- |
349
- |with environment: ${summon[Env ]}
350
- |
351
- |Scrutinee: ${quotes.reflect.Printer .TreeStructure .show(scrutinee.asInstanceOf )}
352
- |Pattern: ${quotes.reflect.Printer .TreeStructure .show(pattern.asInstanceOf )}
353
- |
354
- | """ .stripMargin)
355
- notMatched
233
+ scrutinee match
234
+ /* Match type ascription (a) */
235
+ case Typed (expr1, _) =>
236
+ expr1 =?= pattern
237
+
238
+ /* Match literal */
239
+ case Literal (constant1) =>
240
+ pattern match
241
+ case Literal (constant2) if constant1 == constant2 => matched
242
+ case _ => notMatched
243
+
244
+ case ref : RefTree =>
245
+ pattern match
246
+ /* Match selection */
247
+ case Select (qual2, _) if symbolMatch(scrutinee, pattern) =>
248
+ ref match
249
+ case Select (qual1, _) => qual1 =?= qual2
250
+ case ref : Ident =>
251
+ ref.tpe match
252
+ case TermRef (qual : TermRef , _) => tpd.ref(qual) =?= qual2
253
+ case _ => matched
254
+ /* Match reference */
255
+ case _ : Ident if symbolMatch(scrutinee, pattern) => matched
256
+ /* Match type */
257
+ case TypeTreeTypeTest (pattern) if scrutinee.tpe <:< pattern.tpe => matched
258
+ case _ => notMatched
259
+
260
+ /* Match application */
261
+ case Apply (fn1, args1) =>
262
+ pattern match
263
+ case Apply (fn2, args2) =>
264
+ fn1 =?= fn2 &&& args1 =?= args2
265
+ case _ => notMatched
266
+
267
+ /* Match type application */
268
+ case TypeApply (fn1, args1) =>
269
+ pattern match
270
+ case TypeApply (fn2, args2) =>
271
+ fn1 =?= fn2 &&& args1 =?= args2
272
+ case _ => notMatched
273
+
274
+ /* Match block */
275
+ case Block (stat1 :: stats1, expr1) =>
276
+ pattern match
277
+ case Block (stat2 :: stats2, expr2) =>
278
+ val newEnv = (stat1, stat2) match {
279
+ case (stat1 : MemberDef , stat2 : MemberDef ) =>
280
+ summon[Env ] + (stat1.symbol -> stat2.symbol)
281
+ case _ =>
282
+ summon[Env ]
283
+ }
284
+ withEnv(newEnv) {
285
+ stat1 =?= stat2 &&& Block (stats1, expr1) =?= Block (stats2, expr2)
286
+ }
287
+ case _ => notMatched
288
+
289
+ /* Match if */
290
+ case If (cond1, thenp1, elsep1) =>
291
+ pattern match
292
+ case If (cond2, thenp2, elsep2) =>
293
+ cond1 =?= cond2 &&& thenp1 =?= thenp2 &&& elsep1 =?= elsep2
294
+ case _ => notMatched
295
+
296
+ /* Match while */
297
+ case WhileDo (cond1, body1) =>
298
+ pattern match
299
+ case WhileDo (cond2, body2) => cond1 =?= cond2 &&& body1 =?= body2
300
+ case _ => notMatched
301
+
302
+ /* Match assign */
303
+ case Assign (lhs1, rhs1) =>
304
+ pattern match
305
+ case Assign (lhs2, rhs2) => lhs1 =?= lhs2 &&& rhs1 =?= rhs2
306
+ case _ => notMatched
307
+
308
+ /* Match new */
309
+ case New (tpt1) =>
310
+ pattern match
311
+ case New (tpt2) if tpt1.tpe.typeSymbol == tpt2.tpe.typeSymbol => matched
312
+ case _ => notMatched
313
+
314
+ /* Match this */
315
+ case This (_) =>
316
+ pattern match
317
+ case This (_) if scrutinee.symbol == pattern.symbol => matched
318
+ case _ => notMatched
319
+
320
+ /* Match super */
321
+ case Super (qual1, mix1) =>
322
+ pattern match
323
+ case Super (qual2, mix2) if mix1 == mix2 => qual1 =?= qual2
324
+ case _ => notMatched
325
+
326
+ /* Match varargs */
327
+ case SeqLiteral (elems1, _) =>
328
+ pattern match
329
+ case SeqLiteral (elems2, _) if elems1.size == elems2.size => elems1 =?= elems2
330
+ case _ => notMatched
331
+
332
+ /* Match type */
333
+ // TODO remove this?
334
+ case TypeTreeTypeTest (scrutinee) =>
335
+ pattern match
336
+ case TypeTreeTypeTest (pattern) if scrutinee.tpe <:< pattern.tpe => matched
337
+ case _ => notMatched
338
+
339
+ /* Match val */
340
+ case scrutinee @ ValDef (_, tpt1, _) =>
341
+ pattern match
342
+ case pattern @ ValDef (_, tpt2, _) if checkValFlags() =>
343
+ def rhsEnv = summon[Env ] + (scrutinee.symbol -> pattern.symbol)
344
+ tpt1 =?= tpt2 &&& withEnv(rhsEnv)(scrutinee.rhs =?= pattern.rhs)
345
+ case _ => notMatched
346
+
347
+ /* Match def */
348
+ case scrutinee @ DefDef (_, paramss1, tpt1, _) =>
349
+ pattern match
350
+ case pattern @ DefDef (_, paramss2, tpt2, _) =>
351
+ def rhsEnv : Env =
352
+ val paramSyms : List [(Symbol , Symbol )] =
353
+ for
354
+ (clause1, clause2) <- paramss1.zip(paramss2)
355
+ (param1, param2) <- clause1.zip(clause2)
356
+ yield
357
+ param1.symbol -> param2.symbol
358
+ val oldEnv : Env = summon[Env ]
359
+ val newEnv : List [(Symbol , Symbol )] = (scrutinee.symbol -> pattern.symbol) :: paramSyms
360
+ oldEnv ++ newEnv
361
+ matchLists(paramss1, paramss2)(_ =?= _)
362
+ &&& tpt1 =?= tpt2
363
+ &&& withEnv(rhsEnv)(scrutinee.rhs =?= pattern.rhs)
364
+ case _ => notMatched
365
+
366
+ case Closure (_, _, tpt1) =>
367
+ pattern match
368
+ case Closure (_, _, tpt2) => matched // TODO match tpt1 with tpt2?
369
+ case _ => notMatched
370
+
371
+ case NamedArg (name1, arg1) =>
372
+ pattern match
373
+ case NamedArg (name2, arg2) if name1 == name2 => arg1 =?= arg2
374
+ case _ => notMatched
375
+
376
+ case EmptyTree =>
377
+ if pattern.isEmpty then matched
378
+ else notMatched
379
+
380
+ // No Match
381
+ case _ =>
382
+ notMatched
383
+
384
+ if (debug && res == notMatched)
385
+ val quotes = QuotesImpl ()
386
+ println(
387
+ s """ >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
388
+ |Scrutinee
389
+ | ${scrutinee.show}
390
+ |did not match pattern
391
+ | ${pattern.show}
392
+ |
393
+ |with environment: ${summon[Env ]}
394
+ |
395
+ |Scrutinee: ${quotes.reflect.Printer .TreeStructure .show(scrutinee.asInstanceOf )}
396
+ |Pattern: ${quotes.reflect.Printer .TreeStructure .show(pattern.asInstanceOf )}
397
+ |
398
+ | """ .stripMargin)
399
+
400
+ res
401
+ end =?=
356
402
357
403
end extension
358
404
0 commit comments