@@ -33,11 +33,11 @@ import scala.annotation.constructorOnly
33
33
* val x1: U1 = ???
34
34
* val x2: U2 = ???
35
35
* ...
36
- * {{{ 3 | x1 | contents0 | T0 }}} // hole
36
+ * {{{ 3 | x1 | holeContents0 | T0 }}} // hole
37
37
* ...
38
- * {{{ 4 | x2 | contents1 | T1 }}} // hole
38
+ * {{{ 4 | x2 | holeContents1 | T1 }}} // hole
39
39
* ...
40
- * {{{ 5 | x1, x2 | contents2 | T2 }}} // hole
40
+ * {{{ 5 | x1, x2 | holeContents2 | T2 }}} // hole
41
41
* ...
42
42
* }
43
43
* ```
@@ -59,9 +59,9 @@ import scala.annotation.constructorOnly
59
59
* ]],
60
60
* typeHole = Seq(a, b),
61
61
* termHole = (idx: Int, args: List[Any], quotes: Quotes) => idx match {
62
- * case 3 => content0 .apply(args(0).asInstanceOf[Expr[U1]]).apply(quotes) // beta reduced
63
- * case 4 => content1 .apply(args(0).asInstanceOf[Expr[U2]]).apply(quotes) // beta reduced
64
- * case 5 => content2 .apply(args(0).asInstanceOf[Expr[U1]], args(1).asInstanceOf[Expr[U2]]).apply(quotes) // beta reduced
62
+ * case 3 => holeContents0 .apply(args(0).asInstanceOf[Expr[U1]]).apply(quotes) // beta reduced
63
+ * case 4 => holeContents1 .apply(args(0).asInstanceOf[Expr[U2]]).apply(quotes) // beta reduced
64
+ * case 5 => holeContents2 .apply(args(0).asInstanceOf[Expr[U1]], args(1).asInstanceOf[Expr[U2]]).apply(quotes) // beta reduced
65
65
* },
66
66
* )
67
67
* ```
@@ -93,26 +93,25 @@ class PickleQuotes extends MacroTransform {
93
93
override def transform (tree : tpd.Tree )(using Context ): tpd.Tree =
94
94
tree match
95
95
case Apply (Select (quote : Quote , nme.apply), List (quotes)) =>
96
- val (contents , quote1) = makeHoles (quote)
96
+ val (holeContents , quote1) = extractHolesContents (quote)
97
97
val quote2 = encodeTypeArgs(quote1)
98
- val contents1 = contents ::: quote.tags
99
- val pickled = PickleQuotes .pickle(quote2, quotes, contents1)
100
- transform(pickled) // pickle quotes that are in the contents
98
+ val holeContents1 = holeContents.map(transform(_))
99
+ PickleQuotes .pickle(quote2, quotes, holeContents1)
101
100
case tree : DefDef if ! tree.rhs.isEmpty && tree.symbol.isInlineMethod =>
102
101
tree
103
102
case _ =>
104
103
super .transform(tree)
105
104
}
106
105
107
- private def makeHoles (quote : tpd.Quote )(using Context ): (List [Tree ], tpd.Quote ) =
106
+ private def extractHolesContents (quote : tpd.Quote )(using Context ): (List [Tree ], tpd.Quote ) =
108
107
class HoleContentExtractor extends Transformer :
109
- private val contents = List .newBuilder[Tree ]
108
+ private val holeContents = List .newBuilder[Tree ]
110
109
override def transform (tree : tpd.Tree )(using Context ): tpd.Tree =
111
110
tree match
112
111
case tree @ Hole (isTerm, _, _, content) =>
113
112
assert(isTerm)
114
113
assert(! content.isEmpty)
115
- contents += content
114
+ holeContents += content
116
115
val holeType = getTermHoleType(tree.tpe)
117
116
val hole = untpd.cpy.Hole (tree)(content = EmptyTree ).withType(holeType)
118
117
cpy.Inlined (tree)(EmptyTree , Nil , hole)
@@ -148,10 +147,10 @@ class PickleQuotes extends MacroTransform {
148
147
mapOver(tp)
149
148
}
150
149
151
- /** Get the contents of the transformed tree */
150
+ /** Get the holeContents of the transformed tree */
152
151
def getContents () =
153
- val res = contents .result
154
- contents .clear()
152
+ val res = holeContents .result
153
+ holeContents .clear()
155
154
res
156
155
end HoleContentExtractor
157
156
@@ -160,7 +159,7 @@ class PickleQuotes extends MacroTransform {
160
159
val quote1 = cpy.Quote (quote)(body1, quote.tags)
161
160
162
161
(holeMaker.getContents(), quote1)
163
- end makeHoles
162
+ end extractHolesContents
164
163
165
164
/** Encode quote tags as holes in the quote body.
166
165
*
@@ -237,7 +236,7 @@ object PickleQuotes {
237
236
val name : String = " pickleQuotes"
238
237
val description : String = " turn quoted trees into explicit run-time data structures"
239
238
240
- def pickle (quote : Quote , quotes : Tree , contents : List [Tree ])(using Context ) = {
239
+ def pickle (quote : Quote , quotes : Tree , holeContents : List [Tree ])(using Context ) = {
241
240
val body = quote.body
242
241
val bodyType = quote.bodyType
243
242
@@ -335,27 +334,22 @@ object PickleQuotes {
335
334
case x :: Nil => Literal (Constant (x))
336
335
case xs => tpd.mkList(xs.map(x => Literal (Constant (x))), TypeTree (defn.StringType ))
337
336
338
- // TODO split holes earlier into types and terms. This all holes in each category can have consecutive indices
339
- val (typeSplices, termSplices) = contents.zipWithIndex.partition {
340
- _._1.tpe.derivesFrom(defn.QuotedTypeClass )
341
- }
342
-
343
337
// This and all closures in typeSplices are removed by the BetaReduce phase
344
338
val types =
345
- if typeSplices. isEmpty then Literal (Constant (null )) // keep pickled quote without contents as small as possible
346
- else SeqLiteral (typeSplices.map(_._1) , TypeTree (defn.QuotedTypeClass .typeRef.appliedTo(WildcardType )))
339
+ if quote.tags. isEmpty then Literal (Constant (null )) // keep pickled quote without holeContents as small as possible
340
+ else SeqLiteral (quote.tags , TypeTree (defn.QuotedTypeClass .typeRef.appliedTo(TypeBounds .emptyPolyKind )))
347
341
348
342
// This and all closures in termSplices are removed by the BetaReduce phase
349
343
val termHoles =
350
- if termSplices .isEmpty then Literal (Constant (null )) // keep pickled quote without contents as small as possible
344
+ if holeContents .isEmpty then Literal (Constant (null )) // keep pickled quote without holeContents as small as possible
351
345
else
352
346
Lambda (
353
347
MethodType (
354
348
List (nme.idx, nme.contents, nme.quotes).map(name => UniqueName .fresh(name).toTermName),
355
349
List (defn.IntType , defn.SeqType .appliedTo(defn.AnyType ), defn.QuotesClass .typeRef),
356
350
defn.QuotedExprClass .typeRef.appliedTo(defn.AnyType )),
357
351
args =>
358
- val cases = termSplices .map { case (splice, idx) =>
352
+ val cases = holeContents.zipWithIndex .map { case (splice, idx) =>
359
353
val defn .FunctionOf (argTypes, defn.FunctionOf (quotesType :: _, _, _), _) = splice.tpe: @ unchecked
360
354
val rhs = {
361
355
val spliceArgs = argTypes.zipWithIndex.map { (argType, i) =>
@@ -414,7 +408,7 @@ object PickleQuotes {
414
408
case _ => None
415
409
416
410
if body.isType then
417
- if contents .isEmpty && body.symbol.isPrimitiveValueClass then taggedType()
411
+ if holeContents .isEmpty && body.symbol.isPrimitiveValueClass then taggedType()
418
412
else pickleAsTasty()
419
413
else
420
414
getLiteral(body) match
0 commit comments