@@ -33,17 +33,19 @@ object Matcher {
33
33
def unapply [Tup <: Tuple ](scrutineeExpr : Expr [_])(implicit patternExpr : Expr [_], reflection : Reflection ): Option [Tup ] = {
34
34
import reflection .{Bind => BindPattern , _ }
35
35
36
+ type Env = Set [(Symbol , Symbol )]
37
+
36
38
// TODO improve performance
37
39
38
40
/** Check that the trees match and return the contents from the pattern holes.
39
41
* Return None if the trees do not match otherwise return Some of a tuple containing all the contents in the holes.
40
42
*
41
43
* @param scrutinee The tree beeing matched
42
44
* @param pattern The pattern tree that the scrutinee should match. Contains `patternHole` holes.
43
- * @param env Set of tuples containing pairs of symbols (s, p) where s defines a symbol in `scrutinee` which corresponds to symbol p in `pattern`.
45
+ * @param `the[Env]` Set of tuples containing pairs of symbols (s, p) where s defines a symbol in `scrutinee` which corresponds to symbol p in `pattern`.
44
46
* @return `None` if it did not match or `Some(tup: Tuple)` if it matched where `tup` contains the contents of the holes.
45
47
*/
46
- def treeMatches (scrutinee : Tree , pattern : Tree )( implicit env : Set [( Symbol , Symbol )]) : Option [Tuple ] = {
48
+ def treeMatches (scrutinee : Tree , pattern : Tree ) given Env : Option [Tuple ] = {
47
49
48
50
/** Check that both are `val` or both are `lazy val` or both are `var` **/
49
51
def checkValFlags (): Boolean = {
@@ -101,7 +103,7 @@ object Matcher {
101
103
case (Typed (expr1, tpt1), Typed (expr2, tpt2)) =>
102
104
foldMatchings(treeMatches(expr1, expr2), treeMatches(tpt1, tpt2))
103
105
104
- case (Ident (_), Ident (_)) if scrutinee.symbol == pattern.symbol || env ((scrutinee.symbol, pattern.symbol)) =>
106
+ case (Ident (_), Ident (_)) if scrutinee.symbol == pattern.symbol || the[ Env ].apply ((scrutinee.symbol, pattern.symbol)) =>
105
107
Some (())
106
108
107
109
case (Select (qual1, _), Select (qual2, _)) if scrutinee.symbol == pattern.symbol =>
@@ -160,8 +162,8 @@ object Matcher {
160
162
if (hasBindAnnotation(pattern.symbol) || hasBindTypeAnnotation(tpt2)) bindingMatch(scrutinee.symbol)
161
163
else Some (())
162
164
val returnTptMatch = treeMatches(tpt1, tpt2)
163
- val rhsEnv = env + (scrutinee.symbol -> pattern.symbol)
164
- val rhsMatchings = treeOptMatches(rhs1, rhs2)( rhsEnv)
165
+ val rhsEnv = the[ Env ] + (scrutinee.symbol -> pattern.symbol)
166
+ val rhsMatchings = treeOptMatches(rhs1, rhs2) given rhsEnv
165
167
foldMatchings(bindMatch, returnTptMatch, rhsMatchings)
166
168
167
169
case (DefDef (_, typeParams1, paramss1, tpt1, Some (rhs1)), DefDef (_, typeParams2, paramss2, tpt2, Some (rhs2))) =>
@@ -174,10 +176,10 @@ object Matcher {
174
176
else Some (())
175
177
val tptMatch = treeMatches(tpt1, tpt2)
176
178
val rhsEnv =
177
- env + (scrutinee.symbol -> pattern.symbol) ++
179
+ the[ Env ] + (scrutinee.symbol -> pattern.symbol) ++
178
180
typeParams1.zip(typeParams2).map((tparam1, tparam2) => tparam1.symbol -> tparam2.symbol) ++
179
181
paramss1.flatten.zip(paramss2.flatten).map((param1, param2) => param1.symbol -> param2.symbol)
180
- val rhsMatch = treeMatches(rhs1, rhs2)( rhsEnv)
182
+ val rhsMatch = treeMatches(rhs1, rhs2) given rhsEnv
181
183
182
184
foldMatchings(bindMatch, typeParmasMatch, paramssMatch, tptMatch, rhsMatch)
183
185
@@ -227,18 +229,18 @@ object Matcher {
227
229
}
228
230
}
229
231
230
- def treeOptMatches (scrutinee : Option [Tree ], pattern : Option [Tree ])( implicit env : Set [( Symbol , Symbol )]) : Option [Tuple ] = {
232
+ def treeOptMatches (scrutinee : Option [Tree ], pattern : Option [Tree ]) given Env : Option [Tuple ] = {
231
233
(scrutinee, pattern) match {
232
234
case (Some (x), Some (y)) => treeMatches(x, y)
233
235
case (None , None ) => Some (())
234
236
case _ => None
235
237
}
236
238
}
237
239
238
- def caseMatches (scrutinee : CaseDef , pattern : CaseDef )( implicit env : Set [( Symbol , Symbol )]) : Option [Tuple ] = {
240
+ def caseMatches (scrutinee : CaseDef , pattern : CaseDef ) given Env : Option [Tuple ] = {
239
241
val (caseEnv, patternMatch) = patternMatches(scrutinee.pattern, pattern.pattern)
240
- val guardMatch = treeOptMatches(scrutinee.guard, pattern.guard)( caseEnv)
241
- val rhsMatch = treeMatches(scrutinee.rhs, pattern.rhs)( caseEnv)
242
+ val guardMatch = treeOptMatches(scrutinee.guard, pattern.guard) given caseEnv
243
+ val rhsMatch = treeMatches(scrutinee.rhs, pattern.rhs) given caseEnv
242
244
foldMatchings(patternMatch, guardMatch, rhsMatch)
243
245
}
244
246
@@ -248,21 +250,21 @@ object Matcher {
248
250
*
249
251
* @param scrutinee The pattern tree beeing matched
250
252
* @param pattern The pattern tree that the scrutinee should match. Contains `patternHole` holes.
251
- * @param env Set of tuples containing pairs of symbols (s, p) where s defines a symbol in `scrutinee` which corresponds to symbol p in `pattern`.
253
+ * @param `the[Env]` Set of tuples containing pairs of symbols (s, p) where s defines a symbol in `scrutinee` which corresponds to symbol p in `pattern`.
252
254
* @return The new environment containing the bindings defined in this pattern tuppled with
253
255
* `None` if it did not match or `Some(tup: Tuple)` if it matched where `tup` contains the contents of the holes.
254
256
*/
255
- def patternMatches (scrutinee : Pattern , pattern : Pattern )( implicit env : Set [( Symbol , Symbol )]) : (Set [( Symbol , Symbol )] , Option [Tuple ]) = (scrutinee, pattern) match {
257
+ def patternMatches (scrutinee : Pattern , pattern : Pattern ) given Env : (Env , Option [Tuple ]) = (scrutinee, pattern) match {
256
258
case (Pattern .Value (v1), Pattern .Unapply (TypeApply (Select (patternHole @ Ident (" patternHole" ), " unapply" ), List (tpt)), Nil , Nil ))
257
259
if patternHole.symbol.owner.fullName == " scala.runtime.quoted.Matcher$" =>
258
- (env , Some (Tuple1 (v1.seal)))
260
+ (the[ Env ] , Some (Tuple1 (v1.seal)))
259
261
260
262
case (Pattern .Value (v1), Pattern .Value (v2)) =>
261
- (env , treeMatches(v1, v2))
263
+ (the[ Env ] , treeMatches(v1, v2))
262
264
263
265
case (Pattern .Bind (name1, body1), Pattern .Bind (name2, body2)) =>
264
- val bindEnv = env + (scrutinee.symbol -> pattern.symbol)
265
- patternMatches(body1, body2)( bindEnv)
266
+ val bindEnv = the[ Env ] + (scrutinee.symbol -> pattern.symbol)
267
+ patternMatches(body1, body2) given bindEnv
266
268
267
269
case (Pattern .Unapply (fun1, implicits1, patterns1), Pattern .Unapply (fun2, implicits2, patterns2)) =>
268
270
val funMatch = treeMatches(fun1, fun2)
@@ -276,10 +278,10 @@ object Matcher {
276
278
foldPatterns(patterns1, patterns2)
277
279
278
280
case (Pattern .TypeTest (tpt1), Pattern .TypeTest (tpt2)) =>
279
- (env , treeMatches(tpt1, tpt2))
281
+ (the[ Env ] , treeMatches(tpt1, tpt2))
280
282
281
283
case (Pattern .WildcardPattern (), Pattern .WildcardPattern ()) =>
282
- (env , Some (()))
284
+ (the[ Env ] , Some (()))
283
285
284
286
case _ =>
285
287
if (debug)
@@ -299,18 +301,18 @@ object Matcher {
299
301
|
300
302
|
301
303
| """ .stripMargin)
302
- (env , None )
304
+ (the[ Env ] , None )
303
305
}
304
306
305
- def foldPatterns (patterns1 : List [Pattern ], patterns2 : List [Pattern ])( implicit env : Set [( Symbol , Symbol )]) : (Set [( Symbol , Symbol )] , Option [Tuple ]) = {
306
- if (patterns1.size != patterns2.size) (env , None )
307
- else patterns1.zip(patterns2).foldLeft((env , Option [Tuple ](()))) { (acc, x) =>
308
- val (env, res) = patternMatches(x._1, x._2)( acc._1)
307
+ def foldPatterns (patterns1 : List [Pattern ], patterns2 : List [Pattern ]) given Env : (Env , Option [Tuple ]) = {
308
+ if (patterns1.size != patterns2.size) (the[ Env ] , None )
309
+ else patterns1.zip(patterns2).foldLeft((the[ Env ] , Option [Tuple ](()))) { (acc, x) =>
310
+ val (env, res) = patternMatches(x._1, x._2) given acc ._1
309
311
(env, foldMatchings(acc._2, res))
310
312
}
311
313
}
312
314
313
- treeMatches(scrutineeExpr.unseal, patternExpr.unseal)( Set .empty).asInstanceOf [Option [Tup ]]
315
+ ( treeMatches(scrutineeExpr.unseal, patternExpr.unseal) given Set .empty).asInstanceOf [Option [Tup ]]
314
316
}
315
317
316
318
/** Joins the mattchings into a single matching. If any matching is `None` the result is `None`.
0 commit comments