Skip to content

Commit b3a94b1

Browse files
committed
Create infrastructure for semantic db
tests/run-with-compiler/tasty-consumer/Test.scala shows an example of how to consume tasty files.
1 parent fd93b46 commit b3a94b1

File tree

9 files changed

+128
-1
lines changed

9 files changed

+128
-1
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package dotty.tools.dotc.consumetasty
2+
3+
import dotty.tools.dotc
4+
import dotty.tools.dotc.core.Contexts._
5+
6+
import scala.tasty.file.TastyConsumer
7+
8+
object ConsumeTasty {
9+
def apply(classpath: String, classes: List[String], tastyConsumer: TastyConsumer): Unit = {
10+
if (classes.isEmpty)
11+
throw new IllegalArgumentException("Parameter classes should no be empty")
12+
13+
class Consume extends dotc.Driver {
14+
override protected def newCompiler(implicit ctx: Context): dotc.Compiler =
15+
new TastyFromClass(tastyConsumer)
16+
}
17+
18+
val currentClasspath = System.getProperty("java.class.path")
19+
val args = "-from-tasty" +: "-classpath" +: s"$classpath:$currentClasspath" +: classes
20+
(new Consume).process(args.toArray)
21+
}
22+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package dotty.tools.dotc.consumetasty
2+
3+
import dotty.tools.dotc.core.Contexts._
4+
import dotty.tools.dotc.core.Phases.Phase
5+
import dotty.tools.dotc.tastyreflect.TastyImpl
6+
7+
import scala.tasty.file.TastyConsumer
8+
9+
class TastyConsumerPhase(consumer: TastyConsumer) extends Phase {
10+
11+
override def phaseName: String = "tastyConsumer"
12+
13+
override def run(implicit ctx: Context): Unit = {
14+
val tasty = new TastyImpl(ctx)
15+
consumer(tasty)(ctx.compilationUnit.tpdTree)
16+
}
17+
18+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package dotty.tools.dotc.consumetasty
2+
3+
import dotty.tools.dotc.core.Phases.Phase
4+
import dotty.tools.dotc.fromtasty._
5+
6+
import scala.tasty.file.TastyConsumer
7+
8+
class TastyFromClass(consumer: TastyConsumer) extends TASTYCompiler {
9+
10+
override protected def frontendPhases: List[List[Phase]] =
11+
List(new ReadTastyTreesFromClasses) :: // Load classes from tasty
12+
Nil
13+
14+
override protected def picklerPhases: List[List[Phase]] = Nil
15+
override protected def transformPhases: List[List[Phase]] = Nil
16+
17+
override protected def backendPhases: List[List[Phase]] =
18+
List(new TastyConsumerPhase(consumer)) :: // Print all loaded classes
19+
Nil
20+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package scala.tasty.file
2+
3+
object ConsumeTasty {
4+
def apply(classpath: String, classes: List[String], tastyConsumer: TastyConsumer): Unit = {
5+
val cl = getClass.getClassLoader
6+
try {
7+
val dottyConsumeTastyCls = cl.loadClass("dotty.tools.dotc.consumetasty.ConsumeTasty")
8+
val makeMeth = dottyConsumeTastyCls.getMethod("apply", classOf[String], classOf[List[_]], classOf[TastyConsumer])
9+
makeMeth.invoke(null, classpath, classes, tastyConsumer)
10+
}
11+
catch {
12+
case ex: ClassNotFoundException =>
13+
throw new Exception(
14+
s"""Could not load the dotty.tools.dotc.consumetasty.ConsumeTasty class `${ex.getMessage}` from the JVM classpath. Make sure that the compiler is on the JVM classpath.""",
15+
ex
16+
)
17+
}
18+
}
19+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package scala.tasty.file
2+
3+
import scala.tasty.Tasty
4+
5+
trait TastyConsumer {
6+
def apply(tasty: Tasty)(root: tasty.Tree): Unit
7+
}

project/Build.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,7 @@ object Build {
677677
val dottyCompiler = jars("dotty-compiler")
678678
val args0: List[String] = spaceDelimited("<arg>").parsed.toList
679679
val decompile = args0.contains("-decompile")
680+
val consumeTasty = args0.contains("-gen-semantic-db")
680681
val printTasty = args0.contains("-print-tasty")
681682
val debugFromTasty = args0.contains("-Ythrough-tasty")
682683
val args = args0.filter(arg => arg != "-repl" && arg != "-decompile" &&
@@ -685,11 +686,12 @@ object Build {
685686
val main =
686687
if (repl) "dotty.tools.repl.Main"
687688
else if (decompile || printTasty) "dotty.tools.dotc.decompiler.Main"
689+
else if (consumeTasty) "dotty.tools.dotc.semanticdb.Main"
688690
else if (debugFromTasty) "dotty.tools.dotc.fromtasty.Debug"
689691
else "dotty.tools.dotc.Main"
690692

691693
var extraClasspath = s"$scalaLib${File.pathSeparator}$dottyLib"
692-
if ((decompile || printTasty) && !args.contains("-classpath")) extraClasspath += s"${File.pathSeparator}."
694+
if ((decompile || printTasty || consumeTasty) && !args.contains("-classpath")) extraClasspath += s"${File.pathSeparator}."
693695
if (args0.contains("-with-compiler")) {
694696
if (!isDotty.value) {
695697
throw new MessageOnlyException("-with-compiler can only be used with a bootstrapped compiler")
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
ClassDef("Foo", DefDef("<init>", Nil, List(Nil), TypeTree.Synthetic(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Synthetic()), "<init>", Some(Signature(Nil, java.lang.Object))), Nil)), None, List(ValDef("foo", TypeTree.TypeIdent("Int"), Some(Term.Literal(Constant.Int(2)))), DefDef("bar", Nil, List(List(ValDef("i", TypeTree.TypeIdent("Int"), None))), TypeTree.TypeIdent("Int"), Some(Term.Literal(Constant.Int(3))))))
2+
DefDef("<init>", Nil, List(Nil), TypeTree.Synthetic(), None)
3+
ValDef("foo", TypeTree.TypeIdent("Int"), Some(Term.Literal(Constant.Int(2))))
4+
DefDef("bar", Nil, List(List(ValDef("i", TypeTree.TypeIdent("Int"), None))), TypeTree.TypeIdent("Int"), Some(Term.Literal(Constant.Int(3))))
5+
ValDef("i", TypeTree.TypeIdent("Int"), None)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
class Foo {
3+
val foo: Int = 2
4+
def bar(i: Int): Int = 3
5+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import scala.tasty.Tasty
2+
import scala.tasty.util.TreeTraverser
3+
import scala.tasty.file._
4+
5+
object Test {
6+
def main(args: Array[String]): Unit = {
7+
ConsumeTasty("", List("Foo"), new DBConsumer)
8+
}
9+
}
10+
11+
class DBConsumer extends TastyConsumer {
12+
13+
final def apply(tasty: Tasty)(root: tasty.Tree): Unit = {
14+
import tasty._
15+
object Traverser extends TreeTraverser[tasty.type](tasty) {
16+
17+
override def traverseTree(tree: Tree)(implicit ctx: Context): Unit = tree match {
18+
case IsDefinition(tree) =>
19+
println(tree.show)
20+
super.traverseTree(tree)
21+
case tree =>
22+
super.traverseTree(tree)
23+
}
24+
25+
}
26+
Traverser.traverseTree(root)(tasty.rootContext)
27+
}
28+
29+
}

0 commit comments

Comments
 (0)