Skip to content

Commit 67a6475

Browse files
committed
Extract StagingLevel from TreeMapWithStages
1 parent 8362d14 commit 67a6475

File tree

9 files changed

+58
-44
lines changed

9 files changed

+58
-44
lines changed

compiler/src/dotty/tools/dotc/inlines/PrepareInlineable.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import transform.{AccessProxies, PCPCheckAndHeal, Splicer}
2121
import transform.SymUtils.*
2222
import config.Printers.inlining
2323
import util.Property
24-
import dotty.tools.dotc.transform.TreeMapWithStages._
24+
import dotty.tools.dotc.staging.StagingLevel.freshStagingLevelContext
2525

2626
object PrepareInlineable {
2727
import tpd._
@@ -293,7 +293,7 @@ object PrepareInlineable {
293293
if (code.symbol.flags.is(Inline))
294294
report.error("Macro cannot be implemented with an `inline` method", code.srcPos)
295295
Splicer.checkValidMacroBody(code)
296-
new PCPCheckAndHeal(freshStagingContext).transform(body) // Ignore output, only check PCP
296+
(new PCPCheckAndHeal).transform(body)(using freshStagingLevelContext) // Ignore output, only check PCP
297297
case Block(List(stat), Literal(Constants.Constant(()))) => checkMacro(stat)
298298
case Block(Nil, expr) => checkMacro(expr)
299299
case Typed(expr, _) => checkMacro(expr)

compiler/src/dotty/tools/dotc/quoted/Interpreter.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import dotty.tools.dotc.core.Symbols._
2525
import dotty.tools.dotc.core.TypeErasure
2626
import dotty.tools.dotc.core.Types._
2727
import dotty.tools.dotc.quoted._
28-
import dotty.tools.dotc.transform.TreeMapWithStages._
2928
import dotty.tools.dotc.typer.ImportInfo.withRootImports
3029
import dotty.tools.dotc.util.SrcPos
3130
import dotty.tools.dotc.reporting.Message
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package dotty.tools.dotc.staging
2+
3+
import dotty.tools.dotc.ast.{TreeMapWithImplicits, tpd}
4+
import dotty.tools.dotc.config.Printers.staging
5+
import dotty.tools.dotc.core.Decorators._
6+
import dotty.tools.dotc.core.Contexts._
7+
import dotty.tools.dotc.core.StagingContext._
8+
import dotty.tools.dotc.core.Symbols._
9+
import dotty.tools.dotc.util.Property
10+
11+
import scala.collection.mutable
12+
13+
object StagingLevel {
14+
15+
/** A key to be used in a context property that caches the `levelOf` mapping */
16+
private val LevelOfKey = new Property.Key[mutable.HashMap[Symbol, Int]]
17+
18+
/** Initial context for a StagingTransformer transformation. */
19+
def freshStagingLevelContext(using Context): Context =
20+
ctx.fresh.setProperty(LevelOfKey, new mutable.HashMap[Symbol, Int])
21+
22+
/** The quotation level of the definition of the locally defined symbol */
23+
def levelOf(sym: Symbol)(using Context): Int =
24+
ctx.property(LevelOfKey).get.getOrElse(sym, 0)
25+
26+
def removeLevelOf(sym: Symbol)(using Context): Unit =
27+
val levelOfMap = ctx.property(LevelOfKey).get
28+
levelOfMap -= sym
29+
30+
/** Enter staging level of symbol defined by `tree` */
31+
def markSymbol(sym: Symbol)(using Context): Boolean =
32+
val levelOfMap = ctx.property(LevelOfKey).get
33+
if level != 0 && !levelOfMap.contains(sym) then
34+
levelOfMap(sym) = level
35+
true
36+
else
37+
false
38+
}

compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,10 @@ import dotty.tools.dotc.transform.SymUtils._
1717
import dotty.tools.dotc.typer.Checking
1818
import dotty.tools.dotc.typer.Implicits.SearchFailureType
1919
import dotty.tools.dotc.core.Annotations._
20+
import dotty.tools.dotc.staging.StagingLevel.*
2021

2122
import dotty.tools.dotc.util.Property
2223

23-
import scala.annotation.constructorOnly
24-
2524
/** Checks that the Phase Consistency Principle (PCP) holds and heals types.
2625
*
2726
* Local term references are phase consistent if and only if they are used at the same level as their definition.
@@ -48,7 +47,7 @@ import scala.annotation.constructorOnly
4847
* }
4948
*
5049
*/
51-
class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(ictx) with Checking {
50+
class PCPCheckAndHeal extends TreeMapWithStages with Checking {
5251
import tpd._
5352

5453
private val InAnnotation = Property.Key[Unit]()

compiler/src/dotty/tools/dotc/transform/PickleQuotes.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import scala.collection.mutable
1919
import dotty.tools.dotc.core.Annotations._
2020
import dotty.tools.dotc.core.StdNames._
2121
import dotty.tools.dotc.quoted._
22-
import dotty.tools.dotc.transform.TreeMapWithStages._
22+
import dotty.tools.dotc.staging.StagingLevel.freshStagingLevelContext
2323
import dotty.tools.dotc.inlines.Inlines
2424

2525
import scala.annotation.constructorOnly
@@ -93,7 +93,7 @@ class PickleQuotes extends MacroTransform {
9393
case _ =>
9494

9595
override def run(using Context): Unit =
96-
if (ctx.compilationUnit.needsStaging) super.run(using freshStagingContext)
96+
if (ctx.compilationUnit.needsStaging) super.run(using freshStagingLevelContext)
9797

9898
protected def newTransformer(using Context): Transformer = new Transformer {
9999
override def transform(tree: tpd.Tree)(using Context): tpd.Tree =

compiler/src/dotty/tools/dotc/transform/ReifiedReflect.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import dotty.tools.dotc.core.Annotations._
1717
import dotty.tools.dotc.core.Names._
1818
import dotty.tools.dotc.core.StdNames._
1919
import dotty.tools.dotc.quoted._
20-
import dotty.tools.dotc.transform.TreeMapWithStages._
2120

2221
import scala.annotation.constructorOnly
2322

compiler/src/dotty/tools/dotc/transform/Splicing.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import dotty.tools.dotc.core.Annotations._
2121
import dotty.tools.dotc.core.Names._
2222
import dotty.tools.dotc.core.StdNames._
2323
import dotty.tools.dotc.quoted._
24-
import dotty.tools.dotc.transform.TreeMapWithStages._
24+
import dotty.tools.dotc.staging.StagingLevel.freshStagingLevelContext
2525
import dotty.tools.dotc.config.ScalaRelease.*
2626

2727
import scala.annotation.constructorOnly
@@ -77,7 +77,7 @@ class Splicing extends MacroTransform:
7777

7878
override def run(using Context): Unit =
7979
if ctx.compilationUnit.needsStaging then
80-
super.run(using freshStagingContext)
80+
super.run(using freshStagingLevelContext)
8181

8282
protected def newTransformer(using Context): Transformer = Level0QuoteTransformer
8383

@@ -246,7 +246,7 @@ class Splicing extends MacroTransform:
246246
if tree.symbol == defn.QuotedTypeModule_of && containsCapturedType(tpt.tpe) =>
247247
val newContent = capturedPartTypes(tpt)
248248
newContent match
249-
case block: Block =>
249+
case block: Block =>
250250
inContext(ctx.withSource(tree.source)) {
251251
Apply(TypeApply(typeof, List(newContent)), List(quotes)).withSpan(tree.span)
252252
}
@@ -342,7 +342,7 @@ class Splicing extends MacroTransform:
342342
val bindingSym = refBindingMap.getOrElseUpdate(tree.symbol, (tree, newBinding))._2
343343
ref(bindingSym)
344344

345-
private def newQuotedTypeClassBinding(tpe: Type)(using Context) =
345+
private def newQuotedTypeClassBinding(tpe: Type)(using Context) =
346346
newSymbol(
347347
spliceOwner,
348348
UniqueName.fresh(nme.Type).toTermName,
@@ -376,7 +376,7 @@ class Splicing extends MacroTransform:
376376
tpt match
377377
case block: Block =>
378378
cpy.Block(block)(newHealedTypes ::: block.stats, TypeTree(captured))
379-
case _ =>
379+
case _ =>
380380
if newHealedTypes.nonEmpty then
381381
cpy.Block(tpt)(newHealedTypes, TypeTree(captured))
382382
else

compiler/src/dotty/tools/dotc/transform/Staging.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import dotty.tools.dotc.core.Symbols._
1111
import dotty.tools.dotc.core.Types._
1212
import dotty.tools.dotc.util.SrcPos
1313
import dotty.tools.dotc.transform.SymUtils._
14-
import dotty.tools.dotc.transform.TreeMapWithStages._
14+
import dotty.tools.dotc.staging.StagingLevel.*
1515

1616

1717

@@ -35,7 +35,7 @@ class Staging extends MacroTransform {
3535
// Recheck that PCP holds but do not heal any inconsistent types as they should already have been heald
3636
tree match {
3737
case PackageDef(pid, _) if tree.symbol.owner == defn.RootClass =>
38-
val checker = new PCPCheckAndHeal(freshStagingContext) {
38+
val checker = new PCPCheckAndHeal {
3939
override protected def tryHeal(sym: Symbol, tp: TypeRef, pos: SrcPos)(using Context): TypeRef = {
4040
def symStr =
4141
if (sym.is(ModuleClass)) sym.sourceModule.show
@@ -51,7 +51,7 @@ class Staging extends MacroTransform {
5151
tp
5252
}
5353
}
54-
checker.transform(tree)
54+
checker.transform(tree)(using freshStagingLevelContext)
5555
case _ =>
5656
}
5757

@@ -66,11 +66,11 @@ class Staging extends MacroTransform {
6666
}
6767

6868
override def run(using Context): Unit =
69-
if (ctx.compilationUnit.needsStaging) super.run(using freshStagingContext)
69+
if (ctx.compilationUnit.needsStaging) super.run(using freshStagingLevelContext)
7070

7171
protected def newTransformer(using Context): Transformer = new Transformer {
7272
override def transform(tree: tpd.Tree)(using Context): tpd.Tree =
73-
new PCPCheckAndHeal(ctx).transform(tree)
73+
(new PCPCheckAndHeal).transform(tree)
7474
}
7575
}
7676

compiler/src/dotty/tools/dotc/transform/TreeMapWithStages.scala

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,25 @@ import dotty.tools.dotc.core.Contexts._
88
import dotty.tools.dotc.core.StagingContext._
99
import dotty.tools.dotc.core.Symbols._
1010
import dotty.tools.dotc.util.Property
11+
import dotty.tools.dotc.staging.StagingLevel
1112

1213
import scala.collection.mutable
13-
import scala.annotation.constructorOnly
1414

1515
/** The main transformer class
1616
* @param level the current level, where quotes add one and splices subtract one level.
1717
* The initial level is 0, a level `l` where `l > 0` implies code has been quoted `l` times
1818
* and `l == -1` is code inside a top level splice (in an inline method).
1919
* @param levels a stacked map from symbols to the levels in which they were defined
2020
*/
21-
abstract class TreeMapWithStages(@constructorOnly ictx: Context) extends TreeMapWithImplicits {
22-
21+
abstract class TreeMapWithStages extends TreeMapWithImplicits {
2322
import tpd._
24-
import TreeMapWithStages._
25-
26-
/** A map from locally defined symbols to their definition quotation level */
27-
private[this] val levelOfMap: mutable.HashMap[Symbol, Int] = ictx.property(LevelOfKey).get
2823

2924
/** A stack of entered symbols, to be unwound after scope exit */
3025
private[this] var enteredSyms: List[Symbol] = Nil
3126

3227
/** If we are inside a quote or a splice */
3328
private[this] var inQuoteOrSplice = false
3429

35-
/** The quotation level of the definition of the locally defined symbol */
36-
protected def levelOf(sym: Symbol): Int = levelOfMap.getOrElse(sym, 0)
37-
3830
/** Locally defined symbols seen so far by `StagingTransformer.transform` */
3931
protected def localSymbols: List[Symbol] = enteredSyms
4032

@@ -43,8 +35,7 @@ abstract class TreeMapWithStages(@constructorOnly ictx: Context) extends TreeMap
4335

4436
/** Enter staging level of symbol defined by `tree` */
4537
private def markSymbol(sym: Symbol)(using Context): Unit =
46-
if level != 0 && !levelOfMap.contains(sym) then
47-
levelOfMap(sym) = level
38+
if StagingLevel.markSymbol(sym) then
4839
enteredSyms = sym :: enteredSyms
4940

5041
/** Enter staging level of symbol defined by `tree`, if applicable. */
@@ -79,7 +70,7 @@ abstract class TreeMapWithStages(@constructorOnly ictx: Context) extends TreeMap
7970
try super.transform(tree)
8071
finally
8172
while (enteredSyms ne lastEntered) {
82-
levelOfMap -= enteredSyms.head
73+
StagingLevel.removeLevelOf(enteredSyms.head)
8374
enteredSyms = enteredSyms.tail
8475
}
8576

@@ -150,15 +141,3 @@ abstract class TreeMapWithStages(@constructorOnly ictx: Context) extends TreeMap
150141
}
151142
}
152143
}
153-
154-
155-
object TreeMapWithStages {
156-
157-
/** A key to be used in a context property that caches the `levelOf` mapping */
158-
private val LevelOfKey = new Property.Key[mutable.HashMap[Symbol, Int]]
159-
160-
/** Initial context for a StagingTransformer transformation. */
161-
def freshStagingContext(using Context): Context =
162-
ctx.fresh.setProperty(LevelOfKey, new mutable.HashMap[Symbol, Int])
163-
164-
}

0 commit comments

Comments
 (0)