Let it be the following hierarchy:
object X extends Y{
...
}
trait Y extends Z {
...
}
trait Z {
def run(): Unit
}
I parse the scala file containing the X
and
I want to know if its parent or grandparent is Z
.
I can check for parent as follows:
Given that x: Defn.Object
is the X
class I parsed,
x
.children.collect { case c: Template => c }
.flatMap(p => p.children.collectFirst { case c: Init => c }
will give Y
.
Question: Any idea how I can get the parent of the parent of X
(which is Z
in the above example) ?
Loading Y
(the same way I loaded X
) and finding it's parent doesn't seem like a good idea, since the above is part of a scan procedure where among all files under src/main/scala
I'm trying to find all classes which extend Z
and implement run
, so I don't see an easy and performant way to create a graph with all intermediate classes so as to load them in the right order and check for their parents.
It seems you want Scalameta to process your sources not syntactically but semantically. Then you need SemanticDB. Probably the most convenient way to work with SemanticDB is Scalafix
rules/src/main/scala/MyRule.scala
in/src/main/scala/App.scala
Output of
sbt out/compile
build.sbt
project/plugins.sbt
Other examples:
https://github.com/olafurpg/scalafix-codegen (semantic)
https://github.com/DmytroMitin/scalafix-codegen (semantic)
https://github.com/DmytroMitin/scalameta-demo (syntactic)
Is it possible to using macro to modify the generated code of structural-typing instance invocation? (semantic)
Scala conditional compilation (syntactic)
Macro annotation to override toString of Scala function (syntactic)
How to merge multiple imports in scala? (syntactic)
You can avoid Scalafix but then you'll have to work with internals of SemanticDB manually
Output:
build.sbt
Semanticdb code seems to be working in Scala 3
https://scastie.scala-lang.org/DmytroMitin/3QQwsDG2Rqm71qa6mMMkTw/36 [copy] (at Scastie
-Dscala.usejavacp=true
didn't help withobject scala.runtime in compiler mirror not found
, so I used Coursier to guarantee thatscala-library
is on path, locally it works without Coursier)