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,12 +103,13 @@ 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 ._
109
+ /** Sequence of matched expressions.
110
+ * These expressions are part of the scrutinee and will be bound to the quote pattern term splices.
111
+ */
112
+ type MatchingExps = Seq [Expr [Any ]]
112
113
113
114
/** A map relating equivalent symbols from the scrutinee and the pattern
114
115
* For example in
@@ -121,19 +122,20 @@ object QuoteMatcher {
121
122
122
123
private def withEnv [T ](env : Env )(body : Env ?=> T ): T = body(using env)
123
124
124
- def treeMatch (scrutineeTree : Tree , patternTree : Tree )(using Context ): Option [Tuple ] =
125
+ def treeMatch (scrutineeTree : Tree , patternTree : Tree )(using Context ): Option [MatchingExps ] =
125
126
given Env = Map .empty
126
- scrutineeTree =?= patternTree
127
+ optional :
128
+ scrutineeTree =?= patternTree
127
129
128
130
/** 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 {
131
+ private def matchLists [T ](l1 : List [T ], l2 : List [T ])(mtch : (T , T ) => MatchingExps ): optional[ MatchingExps ] = (l1, l2) match {
130
132
case (x :: xs, y :: ys) => mtch(x, y) &&& matchLists(xs, ys)(mtch)
131
133
case (Nil , Nil ) => matched
132
134
case _ => notMatched
133
135
}
134
136
135
137
extension (scrutinees : List [Tree ])
136
- private def =?= (patterns : List [Tree ])(using Env , Context ): Matching =
138
+ private def =?= (patterns : List [Tree ])(using Env , Context ): optional[ MatchingExps ] =
137
139
matchLists(scrutinees, patterns)(_ =?= _)
138
140
139
141
extension (scrutinee0 : Tree )
@@ -144,9 +146,9 @@ object QuoteMatcher {
144
146
* @param scrutinee The tree being matched
145
147
* @param pattern The pattern tree that the scrutinee should match. Contains `patternHole` holes.
146
148
* @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.
149
+ * @return `None` if it did not match or `Some(tup: MatchingExps )` if it matched where `tup` contains the contents of the holes.
148
150
*/
149
- private def =?= (pattern0 : Tree )(using Env , Context ): Matching =
151
+ private def =?= (pattern0 : Tree )(using Env , Context ): optional[ MatchingExps ] =
150
152
151
153
/* Match block flattening */ // TODO move to cases
152
154
/** Normalize the tree */
@@ -431,7 +433,6 @@ object QuoteMatcher {
431
433
case _ => scrutinee
432
434
val pattern = patternTree.symbol
433
435
434
-
435
436
devirtualizedScrutinee == pattern
436
437
|| summon[Env ].get(devirtualizedScrutinee).contains(pattern)
437
438
|| devirtualizedScrutinee.allOverriddenSymbols.contains(pattern)
@@ -452,32 +453,16 @@ object QuoteMatcher {
452
453
accumulator.apply(Set .empty, term)
453
454
}
454
455
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
456
+ private inline def notMatched : optional[MatchingExps ] =
457
+ optional.break()
461
458
462
- val matched : Matching = Some (Tuple ())
459
+ private inline def matched : MatchingExps =
460
+ Seq .empty
463
461
464
- def matched (tree : Tree )(using Context ): Matching =
465
- Some ( Tuple1 ( new ExprImpl (tree, SpliceScope .getCurrent) ))
462
+ private inline def matched (tree : Tree )(using Context ): MatchingExps =
463
+ Seq ( new ExprImpl (tree, SpliceScope .getCurrent))
466
464
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
- }
465
+ extension (self : MatchingExps )
466
+ private inline def &&& (that : MatchingExps ): MatchingExps = self ++ that
482
467
483
468
}
0 commit comments