@@ -181,26 +181,30 @@ object QuoteMatcher {
181181 case _ => None
182182 end TypeTreeTypeTest
183183
184- (scrutinee, pattern) match
184+ val res = pattern match
185185
186186 /* Term hole */
187187 // 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)
189189 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
193194
194195 /* Term hole */
195196 // 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 )
197198 if patternHole.symbol.eq(defn.QuotedRuntimePatterns_patternHole ) &&
198199 scrutinee.tpe <:< tpt.tpe =>
199- matched(scrutinee)
200+ scrutinee match
201+ case ClosedPatternTerm (scrutinee) => matched(scrutinee)
202+ case _ => notMatched
203+
200204
201205 /* Higher order term hole */
202206 // 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 )
204208 if pattern.symbol.eq(defn.QuotedRuntimePatterns_higherOrderHole ) =>
205209 val names : List [TermName ] = args.map {
206210 case Block (List (DefDef (nme.ANON_FUN , _, _, Apply (Ident (name), _))), _) => name.asTermName
@@ -221,138 +225,180 @@ object QuoteMatcher {
221225 }
222226 matched(Closure (meth, bodyFn))
223227
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-
236228 /* Match type ascription (b) */
237- case (scrutinee, Typed (expr2, _) ) =>
229+ case Typed (expr2, _) =>
238230 scrutinee =?= expr2
239231
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
339232 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 =?=
356402
357403 end extension
358404
0 commit comments