1
1
package scala .quoted
2
2
package runtime .impl
3
3
4
-
5
4
import dotty .tools .dotc .ast .tpd
6
5
import dotty .tools .dotc .core .Contexts .*
7
6
import dotty .tools .dotc .core .Flags .*
8
7
import dotty .tools .dotc .core .Names .*
9
8
import dotty .tools .dotc .core .Types .*
10
9
import dotty .tools .dotc .core .StdNames .nme
11
10
import dotty .tools .dotc .core .Symbols .*
11
+ import dotty .tools .dotc .util .optional
12
12
13
13
/** Matches a quoted tree against a quoted pattern tree.
14
14
* A quoted pattern tree may have type and term holes in addition to normal terms.
@@ -103,13 +103,9 @@ import dotty.tools.dotc.core.Symbols.*
103
103
object QuoteMatcher {
104
104
import tpd .*
105
105
106
- // TODO improve performance
107
-
108
106
// TODO use flag from Context. Maybe -debug or add -debug-macros
109
107
private inline val debug = false
110
108
111
- import Matching ._
112
-
113
109
/** A map relating equivalent symbols from the scrutinee and the pattern
114
110
* For example in
115
111
* ```
@@ -121,19 +117,20 @@ object QuoteMatcher {
121
117
122
118
private def withEnv [T ](env : Env )(body : Env ?=> T ): T = body(using env)
123
119
124
- def treeMatch (scrutineeTerm : Tree , patternTerm : Tree )(using Context ): Option [Tuple ] =
120
+ def treeMatch (scrutineeTerm : Tree , patternTerm : Tree )(using Context ): Option [Seq [ Expr [ Any ]] ] =
125
121
given Env = Map .empty
126
- scrutineeTerm =?= patternTerm
122
+ optional :
123
+ scrutineeTerm =?= patternTerm
127
124
128
125
/** Check that all trees match with `mtch` and concatenate the results with &&& */
129
- private def matchLists [T ](l1 : List [T ], l2 : List [T ])(mtch : (T , T ) => Matching ): Matching = (l1, l2) match {
126
+ private def matchLists [T ](l1 : List [T ], l2 : List [T ])(mtch : (T , T ) => Seq [ Expr [ Any ]] ): optional[ Seq [ Expr [ Any ]]] = (l1, l2) match {
130
127
case (x :: xs, y :: ys) => mtch(x, y) &&& matchLists(xs, ys)(mtch)
131
128
case (Nil , Nil ) => matched
132
129
case _ => notMatched
133
130
}
134
131
135
132
extension (scrutinees : List [Tree ])
136
- private def =?= (patterns : List [Tree ])(using Env , Context ): Matching =
133
+ private def =?= (patterns : List [Tree ])(using Env , Context ): optional[ Seq [ Expr [ Any ]]] =
137
134
matchLists(scrutinees, patterns)(_ =?= _)
138
135
139
136
extension (scrutinee0 : Tree )
@@ -144,9 +141,9 @@ object QuoteMatcher {
144
141
* @param scrutinee The tree being matched
145
142
* @param pattern The pattern tree that the scrutinee should match. Contains `patternHole` holes.
146
143
* @param `summon[Env]` Set of tuples containing pairs of symbols (s, p) where s defines a symbol in `scrutinee` which corresponds to symbol p in `pattern`.
147
- * @return `None` if it did not match or `Some(tup: Tuple )` if it matched where `tup` contains the contents of the holes.
144
+ * @return `None` if it did not match or `Some(tup: Seq[Expr[Any]] )` if it matched where `tup` contains the contents of the holes.
148
145
*/
149
- private def =?= (pattern0 : Tree )(using Env , Context ): Matching =
146
+ private def =?= (pattern0 : Tree )(using Env , Context ): optional[ Seq [ Expr [ Any ]]] =
150
147
151
148
/* Match block flattening */ // TODO move to cases
152
149
/** Normalize the tree */
@@ -431,7 +428,6 @@ object QuoteMatcher {
431
428
case _ => scrutinee
432
429
val pattern = patternTree.symbol
433
430
434
-
435
431
devirtualizedScrutinee == pattern
436
432
|| summon[Env ].get(devirtualizedScrutinee).contains(pattern)
437
433
|| devirtualizedScrutinee.allOverriddenSymbols.contains(pattern)
@@ -452,32 +448,16 @@ object QuoteMatcher {
452
448
accumulator.apply(Set .empty, term)
453
449
}
454
450
455
- /** Result of matching a part of an expression */
456
- private type Matching = Option [Tuple ]
457
-
458
- private object Matching {
459
-
460
- def notMatched : Matching = None
451
+ private inline def notMatched : optional[Seq [Expr [Any ]]] =
452
+ optional.break()
461
453
462
- val matched : Matching = Some (Tuple ())
454
+ private inline def matched : Seq [Expr [Any ]] =
455
+ Seq .empty
463
456
464
- def matched (tree : Tree )(using Context ): Matching =
465
- Some ( Tuple1 ( new ExprImpl (tree, SpliceScope .getCurrent) ))
457
+ private inline def matched (tree : Tree )(using Context ): Seq [ Expr [ Any ]] =
458
+ Seq ( new ExprImpl (tree, SpliceScope .getCurrent))
466
459
467
- extension (self : Matching )
468
- def asOptionOfTuple : Option [Tuple ] = self
469
-
470
- /** Concatenates the contents of two successful matchings or return a `notMatched` */
471
- def &&& (that : => Matching ): Matching = self match {
472
- case Some (x) =>
473
- that match {
474
- case Some (y) => Some (x ++ y)
475
- case _ => None
476
- }
477
- case _ => None
478
- }
479
- end extension
480
-
481
- }
460
+ extension (self : Seq [Expr [Any ]])
461
+ private inline def &&& (that : Seq [Expr [Any ]]): Seq [Expr [Any ]] = self ++ that
482
462
483
463
}
0 commit comments