Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #8020: Create dotty-tasty-inspector library #8021

Merged
merged 2 commits into from
Jan 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ steps:
depends_on: [ clone ]
commands:
- cp -R . /tmp/2/ && cd /tmp/2/
- ./project/scripts/sbt ";dotty-bootstrapped/compile ;dotty-bootstrapped/test ;dotty-staging/test ;sjsSandbox/run;sjsSandbox/test;sjsJUnitTests/test ;configureIDE"
- ./project/scripts/sbt ";dotty-bootstrapped/compile ;dotty-bootstrapped/test;sjsSandbox/run;sjsSandbox/test;sjsJUnitTests/test ;configureIDE"
- ./project/scripts/bootstrapCmdTests

- name: community_build
Expand Down
1 change: 1 addition & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +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-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
55 changes: 0 additions & 55 deletions compiler/src/dotty/tools/dotc/consumetasty/ConsumeTasty.scala

This file was deleted.

This file was deleted.

28 changes: 0 additions & 28 deletions compiler/src/dotty/tools/dotc/consumetasty/TastyFromClass.scala

This file was deleted.

47 changes: 47 additions & 0 deletions compiler/src/dotty/tools/dotc/util/ClasspathFromClassloader.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package dotty.tools.dotc.util

import java.net.URLClassLoader
import java.nio.file.Paths

import dotty.tools.repl.AbstractFileClassLoader

object ClasspathFromClassloader {

/** Attempt to recreate a classpath from a classloader.
*
* BEWARE: with exotic enough classloaders, this may not work at all or do
* the wrong thing.
*/
def apply(cl: ClassLoader): String = {
val classpathBuff = List.newBuilder[String]
def collectClassLoaderPaths(cl: ClassLoader): Unit = {
if (cl != null) {
cl match {
case cl: URLClassLoader =>
// This is wrong if we're in a subclass of URLClassLoader
// that filters loading classes from its parent ¯\_(ツ)_/¯
collectClassLoaderPaths(cl.getParent)
// Parent classloaders are searched before their child, so the part of
// the classpath coming from the child is added at the _end_ of the
// classpath.
classpathBuff ++=
cl.getURLs.iterator.map(url => Paths.get(url.toURI).toAbsolutePath.toString)
case _ =>
// HACK: We can't just collect the classpath from arbitrary parent
// classloaders since the current classloader might intentionally
// filter loading classes from its parent (for example
// BootFilteredLoader in the sbt launcher does this and we really
// don't want to include the scala-library that sbt depends on
// here), but we do need to look at the parent of the REPL
// classloader, so we special case it. We can't do this using a type
// test since the REPL classloader class itself is normally loaded
// with a different classloader.
if (cl.getClass.getName == classOf[AbstractFileClassLoader].getName)
collectClassLoaderPaths(cl.getParent)
}
}
}
collectClassLoaderPaths(cl)
classpathBuff.result().mkString(java.io.File.pathSeparator)
}
}
3 changes: 3 additions & 0 deletions compiler/test/dotty/Properties.scala
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ object Properties {
/** dotty-staging jar */
def dottyStaging: String = sys.props("dotty.tests.classes.dottyStaging")

/** 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,7 +127,8 @@ class BootstrappedOnlyCompilationTests extends ParallelTesting {
aggregateTests(
compileFilesInDir("tests/run-with-compiler", withCompilerOptions),
compileFilesInDir("tests/run-staging", withStagingOptions),
compileDir("tests/run-with-compiler-custom-args/tasty-interpreter", withCompilerOptions)
compileFilesInDir("tests/run-custom-args/tasty-inspector", withTastyInspectorOptions),
compileDir("tests/run-custom-args/tasty-interpreter", withTastyInspectorOptions),
).checkRuns()
}

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

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

def mkClasspath(classpaths: List[String]): String =
classpaths.map({ p =>
val file = new java.io.File(p)
Expand All @@ -54,6 +57,8 @@ object TestConfiguration {
defaultOptions.withClasspath(withCompilerClasspath).withRunClasspath(withCompilerClasspath)
lazy val withStagingOptions =
defaultOptions.withClasspath(withStagingClasspath).withRunClasspath(withStagingClasspath)
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
1 change: 1 addition & 0 deletions dist/bin/common
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ DOTTY_COMP=$(find_lib "*dotty-compiler*")
DOTTY_INTF=$(find_lib "*dotty-interfaces*")
DOTTY_LIB=$(find_lib "*dotty-library*")
DOTTY_STAGING=$(find_lib "*dotty-staging*")
DOTTY_CONSUME_TASTY=$(find_lib "*dotty-consume-tasty*")
TASTY_CORE=$(find_lib "*tasty-core*")
SCALA_ASM=$(find_lib "*scala-asm*")
SCALA_LIB=$(find_lib "*scala-library*")
Expand Down
2 changes: 1 addition & 1 deletion dist/bin/dotr
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ elif [ $execute_repl == true ] || [ ${#residual_args[@]} -ne 0 ]; then
echo "warning: multiple classpaths are found, dotr only use the last one."
fi
if [ $with_compiler == true ]; then
cp_arg+="$PSEP$DOTTY_COMP$PSEP$TASTY_CORE$PSEP$DOTTY_INTF$PSEP$SCALA_ASM$PSEP$DOTTY_STAGING"
cp_arg+="$PSEP$DOTTY_COMP$PSEP$TASTY_CORE$PSEP$DOTTY_INTF$PSEP$SCALA_ASM$PSEP$DOTTY_STAGING$PSEP$DOTTY_CONSUME_TASTY"
fi
eval exec "\"$JAVACMD\"" "$DEBUG" "-classpath \"$cp_arg\"" "${jvm_options[@]}" "${residual_args[@]}"
else
Expand Down
23 changes: 19 additions & 4 deletions docs/docs/reference/metaprogramming/tasty-inspect.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ layout: doc-page
title: "TASTy Inspection"
---

```scala
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 @@ -16,7 +20,10 @@ To inspect the TASTy Reflect trees of a TASTy file a consumer can be defined in
the following way.

```scala
class Consumer extends TastyConsumer {
import scala.tasty.Reflection
import scala.tasty.file._

class Consumer extends TastyInspector {
final def apply(reflect: Reflection)(root: reflect.Tree): Unit = {
import reflect._
// Do something with the tree
Expand All @@ -30,7 +37,15 @@ 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)
}
}
```
```

Note that if we need to run the main (in an object called `Test`) after
compilation we need make available the compiler to the runtime:

```shell
dotc -with-compiler -d out Test.scala
dotr -with-compiler -classpath out Test
```
26 changes: 0 additions & 26 deletions library/src/scala/tasty/file/ConsumeTasty.scala

This file was deleted.

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

This file was deleted.

Loading