Skip to content

Commit

Permalink
Rename tasty-consumer to tasty-inspector
Browse files Browse the repository at this point in the history
Also rework TastyInspector API to simplify use.
  • Loading branch information
nicolasstucki committed Jan 24, 2020
1 parent b4c1d50 commit 83fc85a
Show file tree
Hide file tree
Showing 23 changed files with 128 additions and 154 deletions.
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ val `dotty-library-bootstrappedJS` = Build.`dotty-library-bootstrappedJS`
val `dotty-sbt-bridge` = Build.`dotty-sbt-bridge`
val `dotty-sbt-bridge-tests` = Build.`dotty-sbt-bridge-tests`
val `dotty-staging` = Build.`dotty-staging`
val `dotty-tasty-consumer` = Build.`dotty-tasty-consumer`
val `dotty-tasty-inspector` = Build.`dotty-tasty-inspector`
val `dotty-language-server` = Build.`dotty-language-server`
val `dotty-bench` = Build.`dotty-bench`
val `dotty-bench-bootstrapped` = Build.`dotty-bench-bootstrapped`
Expand Down
4 changes: 2 additions & 2 deletions compiler/test/dotty/Properties.scala
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ object Properties {
/** dotty-staging jar */
def dottyStaging: String = sys.props("dotty.tests.classes.dottyStaging")

/** dotty-tasty-consumer jar */
def dottyTastyConsumer: String = sys.props("dotty.tests.classes.dottyTastyConsumer")
/** dotty-tasty-inspector jar */
def dottyTastyInspector: String = sys.props("dotty.tests.classes.dottyTastyInspector")

/** tasty-core jar */
def tastyCore: String = sys.props("dotty.tests.classes.tastyCore")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ class BootstrappedOnlyCompilationTests extends ParallelTesting {
aggregateTests(
compileFilesInDir("tests/run-with-compiler", withCompilerOptions),
compileFilesInDir("tests/run-staging", withStagingOptions),
compileFilesInDir("tests/run-custom-args/tasty-consumer", withTastyConsumerOptions),
compileDir("tests/run-custom-args/tasty-interpreter", withTastyConsumerOptions),
compileFilesInDir("tests/run-custom-args/tasty-inspector", withTastyInspectorOptions),
compileDir("tests/run-custom-args/tasty-interpreter", withTastyInspectorOptions),
).checkRuns()
}

Expand Down
8 changes: 4 additions & 4 deletions compiler/test/dotty/tools/vulpix/TestConfiguration.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ object TestConfiguration {
lazy val withStagingClasspath =
withCompilerClasspath + File.pathSeparator + mkClasspath(List(Properties.dottyStaging))

lazy val withTastyConsumerClasspath =
withCompilerClasspath + File.pathSeparator + mkClasspath(List(Properties.dottyTastyConsumer))
lazy val withTastyInspectorClasspath =
withCompilerClasspath + File.pathSeparator + mkClasspath(List(Properties.dottyTastyInspector))

def mkClasspath(classpaths: List[String]): String =
classpaths.map({ p =>
Expand All @@ -57,8 +57,8 @@ object TestConfiguration {
defaultOptions.withClasspath(withCompilerClasspath).withRunClasspath(withCompilerClasspath)
lazy val withStagingOptions =
defaultOptions.withClasspath(withStagingClasspath).withRunClasspath(withStagingClasspath)
lazy val withTastyConsumerOptions =
defaultOptions.withClasspath(withTastyConsumerClasspath).withRunClasspath(withTastyConsumerClasspath)
lazy val withTastyInspectorOptions =
defaultOptions.withClasspath(withTastyInspectorClasspath).withRunClasspath(withTastyInspectorClasspath)
val allowDeepSubtypes = defaultOptions without "-Yno-deep-subtypes"
val allowDoubleBindings = defaultOptions without "-Yno-double-bindings"
val picklingOptions = defaultOptions and (
Expand Down
8 changes: 4 additions & 4 deletions docs/docs/reference/metaprogramming/tasty-inspect.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ title: "TASTy Inspection"
---

```scala
libraryDependencies += "ch.epfl.lamp" %% "dotty-tasty-consumer" % scalaVersion.value
libraryDependencies += "ch.epfl.lamp" %% "dotty-tasty-inspector" % scalaVersion.value
```

TASTy files contain the full typed tree of a class including source positions
and documentation. This is ideal for tools that analyze or extract semantic
information of the code. To avoid the hassle of working directly with the TASTy
file we provide the `TastyConsumer` which loads the contents and exposes it
file we provide the `TastyInspector` which loads the contents and exposes it
through the TASTy reflect API.


Expand All @@ -23,7 +23,7 @@ the following way.
import scala.tasty.Reflection
import scala.tasty.file._

class Consumer extends TastyConsumer {
class Consumer extends TastyInspector {
final def apply(reflect: Reflection)(root: reflect.Tree): Unit = {
import reflect._
// Do something with the tree
Expand All @@ -37,7 +37,7 @@ the class `foo.Bar` for a foo in the classpath.
```scala
object Test {
def main(args: Array[String]): Unit = {
ConsumeTasty("", List("foo.Bar"), new Consumer)
InspectTasty("", List("foo.Bar"), new Consumer)
}
}
```
Expand Down
22 changes: 11 additions & 11 deletions project/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -595,10 +595,10 @@ object Build {
val asm = findArtifactPath(externalDeps, "scala-asm")
val dottyCompiler = jars("dotty-compiler")
val dottyStaging = jars("dotty-staging")
val dottyTastyConsumer = jars("dotty-tasty-consumer")
val dottyTastyInspector = jars("dotty-tasty-inspector")
val dottyInterfaces = jars("dotty-interfaces")
val tastyCore = jars("tasty-core")
run(insertClasspathInArgs(args1, List(dottyCompiler, dottyInterfaces, asm, dottyStaging, dottyTastyConsumer, tastyCore).mkString(File.pathSeparator)))
run(insertClasspathInArgs(args1, List(dottyCompiler, dottyInterfaces, asm, dottyStaging, dottyTastyInspector, tastyCore).mkString(File.pathSeparator)))
} else run(args)
},

Expand Down Expand Up @@ -672,10 +672,10 @@ object Build {
}
val dottyInterfaces = jars("dotty-interfaces")
val dottyStaging = jars("dotty-staging")
val dottyTastyConsumer = jars("dotty-tasty-consumer")
val dottyTastyInspector = jars("dotty-tasty-inspector")
val tastyCore = jars("tasty-core")
val asm = findArtifactPath(externalDeps, "scala-asm")
extraClasspath ++= Seq(dottyCompiler, dottyInterfaces, asm, dottyStaging, dottyTastyConsumer, tastyCore)
extraClasspath ++= Seq(dottyCompiler, dottyInterfaces, asm, dottyStaging, dottyTastyInspector, tastyCore)
}

val fullArgs = main :: insertClasspathInArgs(args, extraClasspath.mkString(File.pathSeparator))
Expand Down Expand Up @@ -721,14 +721,14 @@ object Build {
val jars = packageAll.value
Seq(
"-Ddotty.tests.classes.dottyStaging=" + jars("dotty-staging"),
"-Ddotty.tests.classes.dottyTastyConsumer=" + jars("dotty-tasty-consumer"),
"-Ddotty.tests.classes.dottyTastyInspector=" + jars("dotty-tasty-inspector"),
)
},
packageAll := {
packageAll.in(`dotty-compiler`).value ++ Seq(
"dotty-compiler" -> packageBin.in(Compile).value.getAbsolutePath,
"dotty-staging" -> packageBin.in(LocalProject("dotty-staging"), Compile).value.getAbsolutePath,
"dotty-tasty-consumer" -> packageBin.in(LocalProject("dotty-tasty-consumer"), Compile).value.getAbsolutePath,
"dotty-tasty-inspector" -> packageBin.in(LocalProject("dotty-tasty-inspector"), Compile).value.getAbsolutePath,
"tasty-core" -> packageBin.in(LocalProject("tasty-core-bootstrapped"), Compile).value.getAbsolutePath,
)
}
Expand Down Expand Up @@ -807,10 +807,10 @@ object Build {
javaOptions := (javaOptions in `dotty-compiler-bootstrapped`).value
)

lazy val `dotty-tasty-consumer` = project.in(file("tasty-consumer")).
lazy val `dotty-tasty-inspector` = project.in(file("tasty-inspector")).
withCommonSettings(Bootstrapped).
// We want the compiler to be present in the compiler classpath when compiling this project but not
// when compiling a project that depends on dotty-tasty-consumer (see sbt-dotty/sbt-test/sbt-dotty/tasty-consumer-example-project),
// when compiling a project that depends on dotty-tasty-inspector (see sbt-dotty/sbt-test/sbt-dotty/tasty-inspector-example-project),
// but we always need it to be present on the JVM classpath at runtime.
dependsOn(dottyCompiler(Bootstrapped) % "provided; compile->runtime; test->test").
settings(commonBootstrappedSettings).
Expand Down Expand Up @@ -1121,7 +1121,7 @@ object Build {
publishLocal in `dotty-library-bootstrapped`,
publishLocal in `tasty-core-bootstrapped`,
publishLocal in `dotty-staging`,
publishLocal in `dotty-tasty-consumer`,
publishLocal in `dotty-tasty-inspector`,
publishLocal in `scala-library`,
publishLocal in `scala-reflect`,
publishLocal in `dotty-doc-bootstrapped`,
Expand Down Expand Up @@ -1332,7 +1332,7 @@ object Build {
def asDottyRoot(implicit mode: Mode): Project = project.withCommonSettings.
aggregate(`dotty-interfaces`, dottyLibrary, dottyCompiler, tastyCore, dottyDoc, `dotty-sbt-bridge`).
bootstrappedAggregate(`scala-library`, `scala-compiler`, `scala-reflect`, scalap,
`dotty-language-server`, `dotty-staging`, `dotty-tasty-consumer`, `dotty-tastydoc`).
`dotty-language-server`, `dotty-staging`, `dotty-tasty-inspector`, `dotty-tastydoc`).
dependsOn(tastyCore).
dependsOn(dottyCompiler).
dependsOn(dottyLibrary).
Expand Down Expand Up @@ -1371,7 +1371,7 @@ object Build {
def asDottyTastydoc(implicit mode: Mode): Project = project.withCommonSettings.
aggregate(`dotty-tastydoc-input`).
dependsOn(dottyCompiler).
dependsOn(`dotty-tasty-consumer`).
dependsOn(`dotty-tasty-inspector`).
settings(commonDocSettings)

def asDottyTastydocInput(implicit mode: Mode): Project = project.withCommonSettings.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import scala.tasty.file._
object Main extends App {


class Consumer extends TastyConsumer {
class Consumer extends TastyInspector {
final def apply(reflect: Reflection)(root: reflect.Tree): Unit = {
import reflect._
val tastyStr = root.show
println(tastyStr)
}
}

ConsumeTasty("", List("lib.Foo"), new Consumer)
InspectTasty("", List("lib.Foo"), new Consumer)

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ lazy val app = project
.in(file("app"))
.settings(
scalaVersion := dottyVersion,
libraryDependencies += "ch.epfl.lamp" %% "dotty-tasty-consumer" % scalaVersion.value,
libraryDependencies += "ch.epfl.lamp" %% "dotty-tasty-inspector" % scalaVersion.value,
)
.dependsOn(lib)
39 changes: 0 additions & 39 deletions tasty-consumer/src/scala/tasty/file/ConsumeTasty.scala

This file was deleted.

7 changes: 0 additions & 7 deletions tasty-consumer/src/scala/tasty/file/TastyConsumer.scala

This file was deleted.

18 changes: 0 additions & 18 deletions tasty-consumer/src/scala/tasty/file/TastyConsumerPhase.scala

This file was deleted.

26 changes: 0 additions & 26 deletions tasty-consumer/src/scala/tasty/file/TastyFromClass.scala

This file was deleted.

67 changes: 67 additions & 0 deletions tasty-inspector/src/scala/tasty/inspector/TastyInspector.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package scala.tasty.inspector

import scala.tasty.Reflection

import dotty.tools.dotc.Compiler
import dotty.tools.dotc.Driver
import dotty.tools.dotc.Run
import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.core.Mode
import dotty.tools.dotc.core.Phases.Phase
import dotty.tools.dotc.fromtasty._
import dotty.tools.dotc.tastyreflect.ReflectionImpl
import dotty.tools.dotc.util.ClasspathFromClassloader

import java.io.File.pathSeparator

trait TastyInspector { self =>

/** Process a TASTy file using TASTy reflect */
protected def processCompilationUnit(reflect: Reflection)(root: reflect.Tree): Unit

/** Load and process TASTy files using TASTy reflect
*
* @param classpath Classpath where the classes are located
* @param classes classes to be inspected
*/
def inspect(classpath: String, classes: List[String]): Unit = {
if (classes.isEmpty)
throw new IllegalArgumentException("Parameter classes should no be empty")

class InspectorDriver extends Driver {
override protected def newCompiler(implicit ctx: Context): Compiler = new TastyFromClass
}

class TastyFromClass extends TASTYCompiler {
override protected def frontendPhases: List[List[Phase]] =
List(new ReadTasty) :: // Load classes from tasty
Nil

override protected def picklerPhases: List[List[Phase]] = Nil
override protected def transformPhases: List[List[Phase]] = Nil

override protected def backendPhases: List[List[Phase]] =
List(new TastyInspectorPhase) :: // Print all loaded classes
Nil

override def newRun(implicit ctx: Context): Run = {
reset()
new TASTYRun(this, ctx.fresh.addMode(Mode.ReadPositions).addMode(Mode.ReadComments))
}
}

class TastyInspectorPhase extends Phase {
override def phaseName: String = "tastyInspector"

override def run(implicit ctx: Context): Unit = {
val reflect = ReflectionImpl(ctx)
self.processCompilationUnit(reflect)(ctx.compilationUnit.tpdTree.asInstanceOf[reflect.Tree])
}
}

val currentClasspath = ClasspathFromClassloader(getClass.getClassLoader)
val args = "-from-tasty" :: "-Yretain-trees" :: "-classpath" :: s"$classpath$pathSeparator$currentClasspath" :: classes
(new InspectorDriver).process(args.toArray)
}

}
6 changes: 3 additions & 3 deletions tastydoc/src/dotty/tastydoc/Main.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package dotty.tastydoc

import scala.tasty.file._
import scala.tasty.inspector._

import dotty.tastydoc.representations._

Expand Down Expand Up @@ -92,8 +92,8 @@ object Main {
} else {
println("Running Dotty Tastydoc on: " + classes.mkString(" "))
val mutablePackagesMap: scala.collection.mutable.HashMap[String, EmulatedPackageRepresentation] = new scala.collection.mutable.HashMap[String, EmulatedPackageRepresentation]()
val tc = new TastydocConsumer(mutablePackagesMap)
ConsumeTasty(extraClasspath, classes, tc)
val tc = new TastydocInspector(mutablePackagesMap)
tc.inspect(extraClasspath, classes)

representations.setSubClasses(mutablePackagesMap)

Expand Down
19 changes: 0 additions & 19 deletions tastydoc/src/dotty/tastydoc/TastydocConsumer.scala

This file was deleted.

Loading

0 comments on commit 83fc85a

Please sign in to comment.