@@ -93,7 +93,7 @@ class Staging extends MacroTransformWithImplicits {
93
93
if (ctx.compilationUnit.needsStaging) super .run
94
94
95
95
protected def newTransformer (implicit ctx : Context ): Transformer =
96
- new Reifier (0 , new LevelInfo )
96
+ new Reifier (new LevelInfo )
97
97
98
98
private class LevelInfo {
99
99
/** A map from locally defined symbols to the staging levels of their definitions */
@@ -106,14 +106,13 @@ class Staging extends MacroTransformWithImplicits {
106
106
* and `l == -1` is code inside a top level splice (in an inline method).
107
107
* @param levels a stacked map from symbols to the levels in which they were defined
108
108
*/
109
- private class Reifier (val level : Int , levels : LevelInfo )
109
+ private class Reifier (levels : LevelInfo )
110
110
extends ImplicitsTransformer {
111
111
import levels ._
112
- assert(level >= - 1 )
113
112
114
113
/** A nested reifier for a quote (if `isQuote = true`) or a splice (if not) */
115
114
def nested (isQuote : Boolean )(implicit ctx : Context ): Reifier = {
116
- new Reifier (if (isQuote) level + 1 else level - 1 , levels)
115
+ new Reifier (levels)
117
116
}
118
117
119
118
/** A stack of entered symbols, to be unwound after scope exit */
@@ -124,7 +123,7 @@ class Staging extends MacroTransformWithImplicits {
124
123
case tree : DefTree =>
125
124
val sym = tree.symbol
126
125
if ((sym.isClass || ! sym.maybeOwner.isType) && ! levelOf.contains(sym)) {
127
- levelOf(sym) = level
126
+ levelOf(sym) = quotationLevel
128
127
enteredSyms = sym :: enteredSyms
129
128
}
130
129
case _ =>
@@ -137,8 +136,8 @@ class Staging extends MacroTransformWithImplicits {
137
136
*/
138
137
def levelOK (sym : Symbol )(implicit ctx : Context ): Boolean = levelOf.get(sym) match {
139
138
case Some (l) =>
140
- l == level ||
141
- level == - 1 && (
139
+ l == quotationLevel ||
140
+ quotationLevel == - 1 && (
142
141
sym == defn.TastyReflection_macroContext ||
143
142
// here we assume that Splicer.canBeSpliced was true before going to level -1,
144
143
// this implies that all non-inline arguments are quoted and that the following two cases are checked
@@ -164,12 +163,12 @@ class Staging extends MacroTransformWithImplicits {
164
163
ctx.error(
165
164
em """ access to $symStr from wrong staging level:
166
165
| - the definition is at level ${levelOf.getOrElse(sym, 0 )},
167
- | - but the access is at level $level . $errMsg""" , pos)
166
+ | - but the access is at level $quotationLevel . $errMsg""" , pos)
168
167
None
169
168
}
170
169
tp match {
171
170
case tp : TypeRef =>
172
- if (level == - 1 ) {
171
+ if (quotationLevel == - 1 ) {
173
172
assert(ctx.inInlineMethod)
174
173
None
175
174
} else {
@@ -205,7 +204,7 @@ class Staging extends MacroTransformWithImplicits {
205
204
206
205
/** Check all named types and this-types in a given type for phase consistency. */
207
206
def checkType (pos : SourcePosition )(implicit ctx : Context ): TypeMap = new TypeMap {
208
- def apply (tp : Type ): Type = reporting.trace(i " check type level $tp at $level " ) {
207
+ def apply (tp : Type ): Type = reporting.trace(i " check type level $tp at $quotationLevel " ) {
209
208
tp match {
210
209
case tp : TypeRef if tp.symbol.isSplice =>
211
210
if (tp.isTerm)
@@ -278,14 +277,14 @@ class Staging extends MacroTransformWithImplicits {
278
277
*/
279
278
private def quotation (body : Tree , quote : Tree )(implicit ctx : Context ): Tree = {
280
279
val isType = quote.symbol eq defn.QuotedType_apply
281
- if (level > 0 ) {
282
- val body1 = nested(isQuote = true ).transform(body)
280
+ if (quotationLevel > 0 ) {
281
+ val body1 = nested(isQuote = true ).transform(body)(quoteContext)
283
282
// Keep quotes as trees to reduce pickled size and have a Expr.show without pickled quotes
284
283
if (isType) ref(defn.QuotedType_apply ).appliedToType(body1.tpe.widen)
285
284
else ref(defn.QuotedExpr_apply ).appliedToType(body1.tpe.widen).appliedTo(body1)
286
285
} else {
287
- val body1 = nested(isQuote = true ).transform(body)
288
- if (level == 0 && ! ctx.inInlineMethod) {
286
+ val body1 = nested(isQuote = true ).transform(body)(quoteContext)
287
+ if (quotationLevel == 0 && ! ctx.inInlineMethod) {
289
288
quote match {
290
289
case quote : Apply => cpy.Apply (quote)(quote.fun, body1 :: Nil )
291
290
case quote : TypeApply => cpy.TypeApply (quote)(quote.fun, body1 :: Nil )
@@ -303,24 +302,24 @@ class Staging extends MacroTransformWithImplicits {
303
302
* are in the body of an inline method.
304
303
*/
305
304
private def splice (splice : Select )(implicit ctx : Context ): Tree = {
306
- if (level >= 1 ) {
307
- val body1 = nested(isQuote = false ).transform(splice.qualifier)
305
+ if (quotationLevel >= 1 ) {
306
+ val body1 = nested(isQuote = false ).transform(splice.qualifier)(spliceContext)
308
307
body1.select(splice.name)
309
308
}
310
- else if (enclosingInlineds.nonEmpty) { // level 0 in an inlined call
309
+ else if (enclosingInlineds.nonEmpty) { // quotationLevel 0 in an inlined call
311
310
val spliceCtx = ctx.outer // drop the last `inlineContext`
312
311
val pos : SourcePosition = spliceCtx.source.atSpan(enclosingInlineds.head.span)
313
312
val evaluatedSplice = Splicer .splice(splice.qualifier, pos, macroClassLoader)(spliceCtx).withSpan(splice.span)
314
313
if (ctx.reporter.hasErrors) splice else transform(evaluatedSplice)
315
314
}
316
- else if (! ctx.owner.isInlineMethod) { // level 0 outside an inline method
315
+ else if (! ctx.owner.isInlineMethod) { // quotationLevel 0 outside an inline method
317
316
ctx.error(i " splice outside quotes or inline method " , splice.sourcePos)
318
317
splice
319
318
}
320
- else if (Splicer .canBeSpliced(splice.qualifier)) { // level 0 inside an inline definition
321
- nested(isQuote = false ).transform(splice.qualifier) // Just check PCP
319
+ else if (Splicer .canBeSpliced(splice.qualifier)) { // quotationLevel 0 inside an inline definition
320
+ nested(isQuote = false ).transform(splice.qualifier)(spliceContext) // Just check PCP
322
321
}
323
- else { // level 0 inside an inline definition
322
+ else { // quotationLevel 0 inside an inline definition
324
323
ctx.error(
325
324
" Malformed macro call. The contents of the ~ must call a static method and arguments must be quoted or inline." .stripMargin,
326
325
splice.sourcePos)
@@ -329,7 +328,7 @@ class Staging extends MacroTransformWithImplicits {
329
328
}
330
329
331
330
override def transform (tree : Tree )(implicit ctx : Context ): Tree =
332
- reporting.trace(i " reify $tree at $level " , show = true ) {
331
+ reporting.trace(i " reify $tree at $quotationLevel " , show = true ) {
333
332
def mapOverTree (lastEntered : List [Symbol ]) =
334
333
try super .transform(tree)
335
334
finally
@@ -347,7 +346,7 @@ class Staging extends MacroTransformWithImplicits {
347
346
tree.qualifier match {
348
347
case Quoted (quotedTree) => transform(quotedTree) // ~('x) --> x
349
348
case _ =>
350
- if (tree.isType || level == 0 ) splice(tree)
349
+ if (tree.isType || quotationLevel == 0 ) splice(tree)
351
350
else {
352
351
// TODO add comment '{ ~(...: T) } --> '{ ~(...: T).asInstanceOf[T] } --> '{ ~(...: T).asInstanceOf[~t] }
353
352
val tp = checkType(tree.sourcePos).apply(tree.tpe.widenTermRefExpr)
@@ -373,7 +372,7 @@ class Staging extends MacroTransformWithImplicits {
373
372
mapOverTree(last)
374
373
case _ : Import =>
375
374
tree
376
- case tree : DefDef if tree.symbol.is(Macro ) && level == 0 =>
375
+ case tree : DefDef if tree.symbol.is(Macro ) && quotationLevel == 0 =>
377
376
if (enclosingInlineds.nonEmpty)
378
377
return EmptyTree // Already checked at definition site and already inlined
379
378
markDef(tree)
@@ -393,7 +392,7 @@ class Staging extends MacroTransformWithImplicits {
393
392
""" .stripMargin, tree.rhs.sourcePos)
394
393
tree
395
394
}
396
- case tree : DefDef if tree.symbol.is(Macro ) && level > 0 =>
395
+ case tree : DefDef if tree.symbol.is(Macro ) && quotationLevel > 0 =>
397
396
mapOverTree(enteredSyms)
398
397
EmptyTree
399
398
case tree : ValDef =>
0 commit comments