Skip to content

Commit 3e782e9

Browse files
committed
Add quote ASTs to TASTy
1 parent dfff8f6 commit 3e782e9

File tree

3 files changed

+54
-22
lines changed

3 files changed

+54
-22
lines changed

compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -701,28 +701,32 @@ class TreePickler(pickler: TastyPickler, attributes: Attributes) {
701701
pickleTree(alias)
702702
}
703703
case tree @ Quote(body, Nil) =>
704-
// TODO: Add QUOTE tag to TASTy
705704
assert(body.isTerm,
706705
"""Quote with type should not be pickled.
707706
|Quote with type should only exists after staging phase at staging level 0.""".stripMargin)
708-
pickleTree(
709-
// scala.quoted.runtime.Expr.quoted[<tree.bodyType>](<body>)
710-
ref(defn.QuotedRuntime_exprQuote)
711-
.appliedToType(tree.bodyType)
712-
.appliedTo(body)
713-
.withSpan(tree.span)
714-
)
707+
writeByte(QUOTE)
708+
pickleTree(body) // TODO Do not add length
715709
case Splice(expr) =>
716-
pickleTree( // TODO: Add SPLICE tag to TASTy
717-
// scala.quoted.runtime.Expr.splice[<tree.tpe>](<expr>)
718-
ref(defn.QuotedRuntime_exprSplice)
719-
.appliedToType(tree.tpe)
720-
.appliedTo(expr)
721-
.withSpan(tree.span)
722-
)
723-
case tree: QuotePattern =>
724-
// TODO: Add QUOTEPATTERN tag to TASTy
725-
pickleTree(QuotePatterns.encode(tree))
710+
writeByte(SPLICE)
711+
withLength {
712+
pickleTree(expr)
713+
pickleType(tree.tpe) // TODO is is possible to recompute this type from `expr`?
714+
}
715+
case QuotePattern(bindings, body, quotes) =>
716+
writeByte(QUOTEPATTERN)
717+
withLength {
718+
if body.isType then writeByte(EXPLICITtpt)
719+
pickleTree(body)
720+
pickleTree(quotes)
721+
pickleType(tree.tpe)
722+
bindings.foreach(pickleTree)
723+
}
724+
case SplicePattern(pat, args) =>
725+
writeByte(SPLICEPATTERN)
726+
withLength {
727+
pickleTree(pat)
728+
args.foreach(pickleTree)
729+
}
726730
case Hole(_, idx, args, _) =>
727731
writeByte(HOLE)
728732
withLength {

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1314,6 +1314,9 @@ class TreeUnpickler(reader: TastyReader,
13141314
NamedArg(readName(), readTree())
13151315
case EXPLICITtpt =>
13161316
readTpt()
1317+
case QUOTE =>
1318+
val body = readTree()
1319+
Quote(body, Nil)
13171320
case _ =>
13181321
readPathTree()
13191322
}
@@ -1503,7 +1506,7 @@ class TreeUnpickler(reader: TastyReader,
15031506
val unapply = UnApply(fn, implicitArgs, argPats, patType)
15041507
if fn.symbol == defn.QuoteMatching_ExprMatch_unapply
15051508
|| fn.symbol == defn.QuoteMatching_TypeMatch_unapply
1506-
then QuotePatterns.decode(unapply)
1509+
then QuotePatterns.decode(unapply) // decode pre 3.5.0 encoding
15071510
else unapply
15081511
case REFINEDtpt =>
15091512
val refineCls = symAtAddr.getOrElse(start,
@@ -1551,6 +1554,22 @@ class TreeUnpickler(reader: TastyReader,
15511554
val hi = if currentAddr == end then lo else readTpt()
15521555
val alias = if currentAddr == end then EmptyTree else readTpt()
15531556
createNullableTypeBoundsTree(lo, hi, alias)
1557+
case SPLICE =>
1558+
val expr = readTree()
1559+
val tpe = readType() // TODO is is possible to recompute this type from `expr`?
1560+
Splice(expr, tpe)
1561+
case QUOTEPATTERN =>
1562+
val bodyReader = fork
1563+
skipTree()
1564+
val quotes = readTree()
1565+
val patType = readType()
1566+
val bindings = readStats(ctx.owner, end)
1567+
val body = bodyReader.readTree() // need bindings in scope, so needs to be read before
1568+
QuotePattern(bindings, body, quotes, patType)
1569+
case SPLICEPATTERN =>
1570+
val pat = readTree()
1571+
val args = until(end)(readTree())
1572+
untpd.SplicePattern(pat, args) // TODO set type?
15541573
case HOLE =>
15551574
readHole(end, isTerm = true)
15561575
case _ =>

tasty/src/dotty/tools/tasty/TastyFormat.scala

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,14 @@ Standard-Section: "ASTs" TopLevelStat*
110110
WHILE Length cond_Term body_Term -- while cond do body
111111
REPEATED Length elem_Type elem_Term* -- Varargs argument of type `elem`
112112
SELECTouter Length levels_Nat qual_Term underlying_Type -- Follow `levels` outer links, starting from `qual`, with given `underlying` type
113+
QUOTE body_Term -- Quoted expression `'{ body }`
114+
SPLICE Length expr_Term tpe_Type -- Spliced expression `${ expr }` with type `tpe`
115+
SPLICEPATTEN Length pat_Term args_Term* -- Pattern splice `${pat}` or `$pat(args*)` in a quoted pattern
113116
-- patterns:
114117
BIND Length boundName_NameRef patType_Type pat_Term -- name @ pat, wherev `patType` is the type of the bound symbol
115118
ALTERNATIVE Length alt_Term* -- alt1 | ... | altn as a pattern
116119
UNAPPLY Length fun_Term ImplicitArg* pat_Type pat_Term* -- Unapply node `fun(_: pat_Type)(implicitArgs)` flowing into patterns `pat`.
120+
QUOTEPATTERN Length body_Term quotes_Term pat_Type bindings_Term* -- Quote pattern node `'{ bindings*; body }(using quotes)'`
117121
-- type trees:
118122
IDENTtpt NameRef Type -- Used for all type idents
119123
SELECTtpt NameRef qual_Term -- qual.name
@@ -543,6 +547,7 @@ object TastyFormat {
543547
final val BOUNDED = 102
544548
final val EXPLICITtpt = 103
545549
final val ELIDED = 104
550+
final val QUOTE = 105
546551

547552

548553
// Tree Cat. 4: tag Nat AST
@@ -600,7 +605,7 @@ object TastyFormat {
600605
final val ANDtype = 165
601606
// final val ??? = 166
602607
final val ORtype = 167
603-
// final val ??? = 168
608+
final val SPLICE = 168
604609
final val POLYtype = 169
605610
final val TYPELAMBDAtype = 170
606611
final val LAMBDAtpt = 171
@@ -610,8 +615,8 @@ object TastyFormat {
610615
final val TYPEREFin = 175
611616
final val SELECTin = 176
612617
final val EXPORT = 177
613-
// final val ??? = 178
614-
// final val ??? = 179
618+
final val QUOTEPATTERN = 178
619+
final val SPLICEPATTERN = 179
615620
final val METHODtype = 180
616621
final val APPLYsigpoly = 181
617622

@@ -858,6 +863,10 @@ object TastyFormat {
858863
case PROTECTEDqualified => "PROTECTEDqualified"
859864
case EXPLICITtpt => "EXPLICITtpt"
860865
case ELIDED => "ELIDED"
866+
case QUOTE => "QUOTE"
867+
case SPLICE => "SPLICE"
868+
case QUOTEPATTERN => "QUOTEPATTERN"
869+
case SPLICEPATTERN => "SPLICEPATTERN"
861870
case HOLE => "HOLE"
862871
}
863872

0 commit comments

Comments
 (0)