Skip to content

Commit a72d85c

Browse files
committed
Add QuotePattern AST node
1 parent 0af8809 commit a72d85c

File tree

5 files changed

+30
-1
lines changed

5 files changed

+30
-1
lines changed

compiler/src/dotty/tools/dotc/ast/Trees.scala

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -737,13 +737,18 @@ object Trees {
737737
type ThisTree[+T <: Untyped] = Splice[T]
738738
}
739739

740+
case class QuotePattern[+T <: Untyped] private[ast] (bindings: List[Tree[T]], body: Tree[T], quotes: Tree[T])(implicit @constructorOnly src: SourceFile)
741+
extends PatternTree[T] {
742+
type ThisTree[+T <: Untyped] = QuotePattern[T]
743+
}
744+
740745
/** A tree representing a pattern splice `${ pattern }`, `$ident` or `$ident(args*)` in a quote pattern.
741746
*
742747
* Parser will only create `${ pattern }` and `$ident`, hence they will not have args.
743748
* While typing, the `$ident(args*)` the args are identified and desugared into a `SplicePattern`
744749
* containing them.
745750
*
746-
* SplicePattern are removed after typing the pattern and are not present in TASTy.
751+
* SplicePattern are removed after typing the pattern and are not present in TASTy. (TODO update)
747752
*
748753
* @param body The tree that was spliced
749754
* @param args The arguments of the splice (the HOAS arguments)
@@ -1163,6 +1168,7 @@ object Trees {
11631168
type Inlined = Trees.Inlined[T]
11641169
type Quote = Trees.Quote[T]
11651170
type Splice = Trees.Splice[T]
1171+
type QuotePattern = Trees.QuotePattern[T]
11661172
type SplicePattern = Trees.SplicePattern[T]
11671173
type TypeTree = Trees.TypeTree[T]
11681174
type InferredTypeTree = Trees.InferredTypeTree[T]
@@ -1342,6 +1348,10 @@ object Trees {
13421348
case tree: Splice if (expr eq tree.expr) => tree
13431349
case _ => finalize(tree, untpd.Splice(expr)(sourceFile(tree)))
13441350
}
1351+
def QuotePattern(tree: Tree)(bindings: List[Tree], body: Tree, quotes: Tree)(using Context): QuotePattern = tree match {
1352+
case tree: QuotePattern if (bindings eq tree.bindings) && (body eq tree.body) && (quotes eq tree.quotes) => tree
1353+
case _ => finalize(tree, untpd.QuotePattern(bindings, body, quotes)(sourceFile(tree)))
1354+
}
13451355
def SplicePattern(tree: Tree)(body: Tree, args: List[Tree])(using Context): SplicePattern = tree match {
13461356
case tree: SplicePattern if (body eq tree.body) && (args eq tree.args) => tree
13471357
case _ => finalize(tree, untpd.SplicePattern(body, args)(sourceFile(tree)))
@@ -1587,6 +1597,8 @@ object Trees {
15871597
cpy.Quote(tree)(transform(body)(using quoteContext), transform(tags))
15881598
case tree @ Splice(expr) =>
15891599
cpy.Splice(tree)(transform(expr)(using spliceContext))
1600+
case tree @ QuotePattern(bindings, body, quotes) =>
1601+
cpy.QuotePattern(tree)(transform(bindings), transform(body)(using quoteContext), transform(quotes))
15901602
case tree @ SplicePattern(body, args) =>
15911603
cpy.SplicePattern(tree)(transform(body)(using spliceContext), transform(args))
15921604
case tree @ Hole(isTerm, idx, args, content) =>
@@ -1734,6 +1746,8 @@ object Trees {
17341746
this(this(x, body)(using quoteContext), tags)
17351747
case Splice(expr) =>
17361748
this(x, expr)(using spliceContext)
1749+
case QuotePattern(bindings, body, quotes) =>
1750+
this(this(this(x, bindings), body)(using quoteContext), quotes)
17371751
case SplicePattern(body, args) =>
17381752
this(this(x, body)(using spliceContext), args)
17391753
case Hole(_, _, args, content) =>

compiler/src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
173173
def Quote(body: Tree, tags: List[Tree])(using Context): Quote =
174174
untpd.Quote(body, tags).withBodyType(body.tpe)
175175

176+
def QuotePattern(bindings: List[Tree], body: Tree, quotes: Tree, proto: Type)(using Context): QuotePattern =
177+
ta.assignType(untpd.QuotePattern(bindings, body, quotes), proto)
178+
176179
def Splice(expr: Tree, tpe: Type)(using Context): Splice =
177180
untpd.Splice(expr).withType(tpe)
178181

compiler/src/dotty/tools/dotc/ast/untpd.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
399399
def Inlined(call: tpd.Tree, bindings: List[MemberDef], expansion: Tree)(implicit src: SourceFile): Inlined = new Inlined(call, bindings, expansion)
400400
def Quote(body: Tree, tags: List[Tree])(implicit src: SourceFile): Quote = new Quote(body, tags)
401401
def Splice(expr: Tree)(implicit src: SourceFile): Splice = new Splice(expr)
402+
def QuotePattern(bindings: List[Tree], body: Tree, quotes: Tree)(implicit src: SourceFile): QuotePattern = new QuotePattern(bindings, body, quotes)
402403
def SplicePattern(body: Tree, args: List[Tree])(implicit src: SourceFile): SplicePattern = new SplicePattern(body, args)
403404
def TypeTree()(implicit src: SourceFile): TypeTree = new TypeTree()
404405
def InferredTypeTree()(implicit src: SourceFile): TypeTree = new InferredTypeTree()

compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,14 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
741741
case Splice(expr) =>
742742
val spliceTypeText = (keywordStr("[") ~ toTextGlobal(tree.typeOpt) ~ keywordStr("]")).provided(printDebug && tree.typeOpt.exists)
743743
keywordStr("$") ~ spliceTypeText ~ keywordStr("{") ~ toTextGlobal(expr) ~ keywordStr("}")
744+
case tree @ QuotePattern(bindings, body, quotes) =>
745+
// TODO print quotes for debugging
746+
val bindingsText = bindings.map(binding => {
747+
keywordStr("type ") ~ toText(binding.symbol.name) ~ toText(binding.symbol.info) ~ "; "
748+
}).reduceLeft(_ ~~ _).provided(bindings.nonEmpty)
749+
val open = if (body.isTerm) keywordStr("{") else keywordStr("[")
750+
val close = if (body.isTerm) keywordStr("}") else keywordStr("]")
751+
keywordStr("'") ~ open ~ bindingsText ~ toTextGlobal(body) ~ close
744752
case SplicePattern(pattern, args) =>
745753
val spliceTypeText = (keywordStr("[") ~ toTextGlobal(tree.typeOpt) ~ keywordStr("]")).provided(printDebug && tree.typeOpt.exists)
746754
keywordStr("$") ~ spliceTypeText ~ {

compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,9 @@ trait TypeAssigner {
508508
def assignType(tree: untpd.UnApply, proto: Type)(using Context): UnApply =
509509
tree.withType(proto)
510510

511+
def assignType(tree: untpd.QuotePattern, proto: Type)(using Context): QuotePattern =
512+
tree.withType(proto)
513+
511514
def assignType(tree: untpd.ValDef, sym: Symbol)(using Context): ValDef =
512515
tree.withType(if (sym.exists) assertExists(sym.termRef) else NoType)
513516

0 commit comments

Comments
 (0)