Skip to content

Commit 251eceb

Browse files
committed
Keep package structure in rootTreeOrProvider
`rootTreeOrProvider` is a property of `ClassSymbol`, and contain the tree that defines this symbol (or a mean to get that tree). When the tree came from unpickled TASTY files, we were able to see the nested packages from which the tree comes, along with the imports. However, when the symbol has been loaded from source, we were filling the `rootTreeOrProvider` only with the `TypeDef` that introduced this symbol. This commit moves the assignment of `rootTreeOrProvider` out of the typer and into its own phase. Before assigning, we recreate the package structure so that the information that we get out of `rootTreeOrProvider` is the same regardless of whether the symbol has been loaded from source or unpickled from TASTY.
1 parent c5ef2d0 commit 251eceb

File tree

5 files changed

+55
-5
lines changed

5 files changed

+55
-5
lines changed

compiler/src/dotty/tools/dotc/Compiler.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class Compiler {
5252
List(new FirstTransform, // Some transformations to put trees into a canonical form
5353
new CheckReentrant, // Internal use only: Check that compiled program has no data races involving global vars
5454
new ElimPackagePrefixes, // Eliminate references to package prefixes in Select nodes
55+
new SetRootTree, // Set the `rootTreeOrProvider` on class symbols
5556
new CookComments) :: // Cook the comments: expand variables, doc, etc.
5657
List(new CheckStatic, // Check restrictions that apply to @static members
5758
new ElimRepeated, // Rewrite vararg parameters and arguments

compiler/src/dotty/tools/dotc/Run.scala

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,8 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
200200

201201
/** Enter top-level definitions of classes and objects contain in Scala source file `file`.
202202
* The newly added symbols replace any previously entered symbols.
203-
* If `typeCheck = true`, also run typer on the compilation unit.
203+
* If `typeCheck = true`, also run typer on the compilation unit, and set
204+
* `rootTreeOrProvider`.
204205
*/
205206
def lateCompile(file: AbstractFile, typeCheck: Boolean)(implicit ctx: Context): Unit =
206207
if (!files.contains(file) && !lateFiles.contains(file)) {
@@ -211,9 +212,13 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
211212
if (unit.isJava) new JavaParser(unit.source).parse()
212213
else new Parser(unit.source).parse()
213214
ctx.typer.lateEnter(unit.untpdTree)
214-
def typeCheckUnit() = unit.tpdTree = ctx.typer.typedExpr(unit.untpdTree)
215+
def processUnit() = {
216+
unit.tpdTree = ctx.typer.typedExpr(unit.untpdTree)
217+
val phase = new transform.SetRootTree()
218+
phase.runOn(unit)
219+
}
215220
if (typeCheck)
216-
if (compiling) finalizeActions += (() => typeCheckUnit()) else typeCheckUnit()
221+
if (compiling) finalizeActions += (() => processUnit()) else processUnit()
217222
}
218223
process()(runContext.fresh.setCompilationUnit(unit))
219224
}

compiler/src/dotty/tools/dotc/interactive/InteractiveCompiler.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class InteractiveCompiler extends Compiler {
1313
// after each phase group instead of waiting for the pipeline to finish.
1414
override def phases: List[List[Phase]] = List(
1515
List(new FrontEnd),
16+
List(new transform.SetRootTree),
1617
List(new transform.CookComments)
1718
)
1819
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package dotty.tools.dotc.transform
2+
3+
import dotty.tools.dotc.CompilationUnit
4+
import dotty.tools.dotc.ast.tpd
5+
import dotty.tools.dotc.core.Contexts.Context
6+
import dotty.tools.dotc.transform.MegaPhase.MiniPhase
7+
8+
/** Set the `rootTreeOrProvider` property of class symbols. */
9+
class SetRootTree extends MiniPhase {
10+
11+
override val phaseName: String = SetRootTree.name
12+
override def isRunnable(implicit ctx: Context) =
13+
super.isRunnable && ctx.settings.YretainTrees.value
14+
15+
def runOn(unit: CompilationUnit)(implicit ctx: Context) = {
16+
val runCtx = ctx.fresh.setCompilationUnit(unit)
17+
traverser.traverse(unit.tpdTree)(runCtx)
18+
}
19+
20+
override def transformTypeDef(tree: tpd.TypeDef)(implicit ctx: Context): tpd.Tree = {
21+
if (tree.symbol.isClass) {
22+
val sym = tree.symbol.asClass
23+
tpd.sliceTopLevel(ctx.compilationUnit.tpdTree, sym) match {
24+
case (pkg: tpd.PackageDef) :: Nil =>
25+
sym.rootTreeOrProvider = pkg
26+
case _ =>
27+
sym.rootTreeOrProvider = tree
28+
}
29+
}
30+
tree
31+
}
32+
33+
private def traverser = new tpd.TreeTraverser {
34+
override def traverse(tree: tpd.Tree)(implicit ctx: Context): Unit = tree match {
35+
case typeDef: tpd.TypeDef => transformTypeDef(typeDef)
36+
case other => traverseChildren(other)
37+
}
38+
}
39+
40+
41+
}
42+
43+
object SetRootTree {
44+
val name: String = "SetRootTree"
45+
}

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1615,8 +1615,6 @@ class Typer extends Namer
16151615
// check value class constraints
16161616
checkDerivedValueClass(cls, body1)
16171617

1618-
if (ctx.settings.YretainTrees.value) cls.rootTreeOrProvider = cdef1
1619-
16201618
cdef1
16211619

16221620
// todo later: check that

0 commit comments

Comments
 (0)