I am calling Scala 3's compiler as a library, which gives you CompilationUnit
per source after compilation. This has tpdTree
, which by the sound of it should contain type information.
I'm trying to walk the tree to get any type symbol as:
atPhase(Phases.typerPhase.next) {
// traverse unit.tpdTree...
}
Where tree walking looks like:
class ValExtractor(tpes: Set[String]) extends tpd.TreeTraverser:
def isAcceptableType(tpe: Types.Type)(using ctx: Context): Boolean =
tpe.baseClasses.exists { sym =>
tpes.contains(sym.fullName.toString)
}
override def traverse(tree: tpd.Tree)(using ctx: Context): Unit =
tree match
case tpd.ValDef(name, tpt, _) if isAcceptableType(tpt.tpe) =>
println("do something")
case t: tpd.Template => this((), t.body)
case t: tpd.PackageDef => this((), t.stats)
case t: tpd.TypeDef => this((), t.rhs)
case _ => ()
end ValExtractor
I get
[info] assertion failed: denotation class Int invalid in run 1. ValidFor: Period(1..55, run = 2)
[info] scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
[info] dotty.tools.dotc.core.Denotations$SingleDenotation.updateValidity(Denotations.scala:719)
[info] dotty.tools.dotc.core.Denotations$SingleDenotation.bringForward(Denotations.scala:744)
[info] dotty.tools.dotc.core.Denotations$SingleDenotation.toNewRun$1(Denotations.scala:803)
[info] dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:877)
[info] dotty.tools.dotc.core.Symbols$Symbol.recomputeDenot(Symbols.scala:122)
[info] dotty.tools.dotc.core.Symbols$Symbol.computeDenot(Symbols.scala:116)
[info] dotty.tools.dotc.core.Symbols$Symbol.denot(Symbols.scala:109)
[info] dotty.tools.dotc.core.Symbols$.toDenot(Symbols.scala:502)
[info] dotty.tools.dotc.core.Denotations$SingleDenotation.updateValidity(Denotations.scala:718)
[info] dotty.tools.dotc.core.Denotations$SingleDenotation.bringForward(Denotations.scala:744)
[info] dotty.tools.dotc.core.Denotations$SingleDenotation.toNewRun$1(Denotations.scala:803)
[info] dotty.tools.dotc.core.Denotations$SingleDenotation.current(Denotations.scala:877)
[info] dotty.tools.dotc.core.Types$NamedType.computeDenot(Types.scala:2253)
[info] dotty.tools.dotc.core.Types$NamedType.denot(Types.scala:2213)
[info] dotty.tools.dotc.core.Types$NamedType.info(Types.scala:2201)
[info] dotty.tools.dotc.core.Types$TypeRef.underlying(Types.scala:2693)
[info] dotty.tools.dotc.core.Types$Type.baseClasses(Types.scala:600)
What am I doing wrong?
Resolution
In my case I had (using ctx: Context)
in my method, but apparently that did not match the run context. Passing it explicitly as follows fixed it:
atPhase(Phases.typerPhase.next) {
(new ValExtractor(valTypes.toSet)).getVals(unit.tpdTree)
}(using run.runContext)
CodePudding user response:
You need to run the query in a context where the run
value is the same as when the definitions were created (or is a later run, but an earlier run is not valid).
The error message you are seeing is that you ask about a denotation of a symbol at run 1, which is conceptually before it was created at run 2.
See https://www.youtube.com/watch?v=WxyyJyB_Ssc for a video where the run/phase concept is explained.