@@ -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,19 +229,23 @@ 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
- foldMatchings(patternMatch, guardMatch, rhsMatch)
242
+
243
+ {
244
+ implied for Env = caseEnv
245
+ val guardMatch = treeOptMatches(scrutinee.guard, pattern.guard)
246
+ val rhsMatch = treeMatches(scrutinee.rhs, pattern.rhs)
247
+ foldMatchings(patternMatch, guardMatch, rhsMatch)
248
+ }
243
249
}
244
250
245
251
/** Check that the pattern trees match and return the contents from the pattern holes.
@@ -248,21 +254,21 @@ object Matcher {
248
254
*
249
255
* @param scrutinee The pattern tree beeing matched
250
256
* @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`.
257
+ * @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
258
* @return The new environment containing the bindings defined in this pattern tuppled with
253
259
* `None` if it did not match or `Some(tup: Tuple)` if it matched where `tup` contains the contents of the holes.
254
260
*/
255
- def patternMatches (scrutinee : Pattern , pattern : Pattern )( implicit env : Set [( Symbol , Symbol )]) : (Set [( Symbol , Symbol )] , Option [Tuple ]) = (scrutinee, pattern) match {
261
+ def patternMatches (scrutinee : Pattern , pattern : Pattern ) given Env : (Env , Option [Tuple ]) = (scrutinee, pattern) match {
256
262
case (Pattern .Value (v1), Pattern .Unapply (TypeApply (Select (patternHole @ Ident (" patternHole" ), " unapply" ), List (tpt)), Nil , Nil ))
257
263
if patternHole.symbol.owner.fullName == " scala.runtime.quoted.Matcher$" =>
258
- (env , Some (Tuple1 (v1.seal)))
264
+ (the[ Env ] , Some (Tuple1 (v1.seal)))
259
265
260
266
case (Pattern .Value (v1), Pattern .Value (v2)) =>
261
- (env , treeMatches(v1, v2))
267
+ (the[ Env ] , treeMatches(v1, v2))
262
268
263
269
case (Pattern .Bind (name1, body1), Pattern .Bind (name2, body2)) =>
264
- val bindEnv = env + (scrutinee.symbol -> pattern.symbol)
265
- patternMatches(body1, body2)( bindEnv)
270
+ val bindEnv = the[ Env ] + (scrutinee.symbol -> pattern.symbol)
271
+ patternMatches(body1, body2) given bindEnv
266
272
267
273
case (Pattern .Unapply (fun1, implicits1, patterns1), Pattern .Unapply (fun2, implicits2, patterns2)) =>
268
274
val funMatch = treeMatches(fun1, fun2)
@@ -276,10 +282,10 @@ object Matcher {
276
282
foldPatterns(patterns1, patterns2)
277
283
278
284
case (Pattern .TypeTest (tpt1), Pattern .TypeTest (tpt2)) =>
279
- (env , treeMatches(tpt1, tpt2))
285
+ (the[ Env ] , treeMatches(tpt1, tpt2))
280
286
281
287
case (Pattern .WildcardPattern (), Pattern .WildcardPattern ()) =>
282
- (env , Some (()))
288
+ (the[ Env ] , Some (()))
283
289
284
290
case _ =>
285
291
if (debug)
@@ -299,18 +305,19 @@ object Matcher {
299
305
|
300
306
|
301
307
| """ .stripMargin)
302
- (env , None )
308
+ (the[ Env ] , None )
303
309
}
304
310
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)
311
+ def foldPatterns (patterns1 : List [Pattern ], patterns2 : List [Pattern ]) given Env : (Env , Option [Tuple ]) = {
312
+ if (patterns1.size != patterns2.size) (the[ Env ] , None )
313
+ else patterns1.zip(patterns2).foldLeft((the[ Env ] , Option [Tuple ](()))) { (acc, x) =>
314
+ val (env, res) = patternMatches(x._1, x._2) given acc ._1
309
315
(env, foldMatchings(acc._2, res))
310
316
}
311
317
}
312
318
313
- treeMatches(scrutineeExpr.unseal, patternExpr.unseal)(Set .empty).asInstanceOf [Option [Tup ]]
319
+ implied for Env = Set .empty
320
+ treeMatches(scrutineeExpr.unseal, patternExpr.unseal).asInstanceOf [Option [Tup ]]
314
321
}
315
322
316
323
/** Joins the mattchings into a single matching. If any matching is `None` the result is `None`.
0 commit comments