From 3f9139315349e9eb51ef54d433a8cf8b903f8f28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20=C5=BBarnowski?= Date: Wed, 6 Mar 2019 11:45:10 +0100 Subject: [PATCH 1/5] move plugin to separate directory --- build.sbt | 4 +- project/Build.scala | 42 ++++--------------- .../{ => plugin}/resources/scalac-plugin.xml | 0 .../src/tasty4scalac/Plugin.scala | 0 .../src/tasty4scalac/ScalacTastyPickler.scala | 0 .../src/tasty4scalac/ScalacTreePickler.scala | 0 6 files changed, 11 insertions(+), 35 deletions(-) rename tasty4scalac/{ => plugin}/resources/scalac-plugin.xml (100%) rename tasty4scalac/{ => plugin}/src/tasty4scalac/Plugin.scala (100%) rename tasty4scalac/{ => plugin}/src/tasty4scalac/ScalacTastyPickler.scala (100%) rename tasty4scalac/{ => plugin}/src/tasty4scalac/ScalacTreePickler.scala (100%) diff --git a/build.sbt b/build.sbt index 9a8c3a1bd627..ed9c05cbd47b 100644 --- a/build.sbt +++ b/build.sbt @@ -17,7 +17,9 @@ val `scala-library` = Build.`scala-library` val `scala-compiler` = Build.`scala-compiler` val `scala-reflect` = Build.`scala-reflect` val scalap = Build.scalap -val tasty4scalac = Build.tasty4scalac + +val `tasty4scalac-plugin` = Build.`tasty4scalac-plugin` + val dist = Build.dist val `dist-bootstrapped` = Build.`dist-bootstrapped` val `community-build` = Build.`community-build` diff --git a/project/Build.scala b/project/Build.scala index 8d152f7bfb85..507b1535d3ef 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -808,44 +808,18 @@ object Build { libraryDependencies := Seq("org.scala-lang" % "scalap" % scalacVersion) ) - lazy val tasty4scalac = project. + lazy val scalacPluginSettings = commonSettings ++ Seq( + version := dottyVersion, + scalaVersion := scalacVersion + ) + + lazy val `tasty4scalac-plugin` = project. + in(file("tasty4scalac/plugin")). dependsOn(`dotty-compiler`). - settings(commonSettings). + settings(scalacPluginSettings). settings( libraryDependencies := Seq("org.scala-lang" % "scala-compiler" % scalacVersion), - fork in Test := true, - - // From kind-projector - scalacOptions in Test ++= { - val pluginJar = (packageBin in Compile).value - val interfacesJar = packageBin.in(`dotty-interfaces`, Compile).value - val libraryJar = packageBin.in(`dotty-library`, Compile).value - val compilerJar = packageBin.in(`dotty-compiler`, Compile).value - Seq( - s"-Xplugin:${pluginJar.getAbsolutePath}:${libraryJar.getAbsolutePath}:${compilerJar.getAbsolutePath}:${interfacesJar.getAbsolutePath}", - s"-Jdummy=${pluginJar.lastModified}" // ensures recompile - ) - }, - scalacOptions in Test += "-Yrangepos" ) - // lazy val tasty4scalacTests = project. - // dependsOn(tasty4scalac % "plugin->default(compile)"). - // settings(commonSettings). - // settings( - // autoCompilerPlugins := true, - // scalacOptions ++= { - // val jar = (packageBin in Compile in tasty4scalac).value - - // val libraryJar = packageBin.in(`dotty-library`, Compile).value - // val compilerJar = packageBin.in(`dotty-compiler`, Compile).value - // Seq( - // "-Yrangepos", - // s"-Xplugin:${jar.getAbsolutePath}:${compilerJar}:${libraryJar}", - // s"-Jdummy=${jar.lastModified}" // ensures recompile - // ) - // } - // ) - // sbt plugin to use Dotty in your own build, see // https://github.com/lampepfl/dotty-example-project for usage. diff --git a/tasty4scalac/resources/scalac-plugin.xml b/tasty4scalac/plugin/resources/scalac-plugin.xml similarity index 100% rename from tasty4scalac/resources/scalac-plugin.xml rename to tasty4scalac/plugin/resources/scalac-plugin.xml diff --git a/tasty4scalac/src/tasty4scalac/Plugin.scala b/tasty4scalac/plugin/src/tasty4scalac/Plugin.scala similarity index 100% rename from tasty4scalac/src/tasty4scalac/Plugin.scala rename to tasty4scalac/plugin/src/tasty4scalac/Plugin.scala diff --git a/tasty4scalac/src/tasty4scalac/ScalacTastyPickler.scala b/tasty4scalac/plugin/src/tasty4scalac/ScalacTastyPickler.scala similarity index 100% rename from tasty4scalac/src/tasty4scalac/ScalacTastyPickler.scala rename to tasty4scalac/plugin/src/tasty4scalac/ScalacTastyPickler.scala diff --git a/tasty4scalac/src/tasty4scalac/ScalacTreePickler.scala b/tasty4scalac/plugin/src/tasty4scalac/ScalacTreePickler.scala similarity index 100% rename from tasty4scalac/src/tasty4scalac/ScalacTreePickler.scala rename to tasty4scalac/plugin/src/tasty4scalac/ScalacTreePickler.scala From 3379ce5e6a3a235c92b25ac7f459ee4ee0ca1a43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20=C5=BBarnowski?= Date: Wed, 6 Mar 2019 13:52:53 +0100 Subject: [PATCH 2/5] create integration module --- build.sbt | 1 + project/Build.scala | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/build.sbt b/build.sbt index ed9c05cbd47b..354792e17e5f 100644 --- a/build.sbt +++ b/build.sbt @@ -19,6 +19,7 @@ val `scala-reflect` = Build.`scala-reflect` val scalap = Build.scalap val `tasty4scalac-plugin` = Build.`tasty4scalac-plugin` +val `tasty4scalac-integration` = Build.`tasty4scalac-integration` val dist = Build.dist val `dist-bootstrapped` = Build.`dist-bootstrapped` diff --git a/project/Build.scala b/project/Build.scala index 507b1535d3ef..90de212046e4 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -821,6 +821,14 @@ object Build { libraryDependencies := Seq("org.scala-lang" % "scala-compiler" % scalacVersion), ) + lazy val `tasty4scalac-integration` = project. + in(file("tasty4scalac/integration")). + dependsOn(`tasty4scalac-plugin`). + settings(scalacPluginSettings). + settings( + fork in Test := true, + ) + // sbt plugin to use Dotty in your own build, see // https://github.com/lampepfl/dotty-example-project for usage. lazy val `sbt-dotty` = project.in(file("sbt-dotty")). From cfb98752396b66482909d7d3ac59db7e27138564 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20=C5=BBarnowski?= Date: Wed, 6 Mar 2019 15:46:58 +0100 Subject: [PATCH 3/5] add scalac compiler class --- project/Build.scala | 24 ++++++++++++ .../src/tasty4scalac/Compiler.scala | 16 ++++++++ .../integration/src/tasty4scalac/Scalac.scala | 38 +++++++++++++++++++ .../test/tasty4scalac/CompilerTest.java | 30 +++++++++++++++ 4 files changed, 108 insertions(+) create mode 100644 tasty4scalac/integration/src/tasty4scalac/Compiler.scala create mode 100644 tasty4scalac/integration/src/tasty4scalac/Scalac.scala create mode 100644 tasty4scalac/integration/test/tasty4scalac/CompilerTest.java diff --git a/project/Build.scala b/project/Build.scala index 90de212046e4..a062234c4e5e 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -827,6 +827,30 @@ object Build { settings(scalacPluginSettings). settings( fork in Test := true, + javaOptions ++= { + val attList = (dependencyClasspath in Runtime).value + def lib(name: String): String = findLib(attList, name) + + def toClasspath(strings: String*): String = strings.mkString(File.pathSeparator) + + val scalaLibrary = lib("scala-library") + val scalaCompiler = lib("scala-compiler") + val scalaReflect = lib("scala-reflect") + + val dottyLibrary = packageBin.in(`dotty-library`, Compile).value.absolutePath + val dottyCompiler = packageBin.in(`dotty-compiler`, Compile).value.absolutePath + val dottyInterfaces = packageBin.in(`dotty-interfaces`, Compile).value.absolutePath + + val pluginJar = packageBin.in(`tasty4scalac-plugin`, Compile).value.absolutePath + + val scalacClasspath = toClasspath(scalaLibrary, scalaCompiler, scalaReflect) + val pluginClasspath = toClasspath(pluginJar, dottyLibrary, dottyCompiler, dottyInterfaces) + + Seq( + "-Dscalac.classpath=" + scalacClasspath, + "-Dscalac.plugin.classpath=" + pluginClasspath + ) + } ) // sbt plugin to use Dotty in your own build, see diff --git a/tasty4scalac/integration/src/tasty4scalac/Compiler.scala b/tasty4scalac/integration/src/tasty4scalac/Compiler.scala new file mode 100644 index 000000000000..5d6f2825d609 --- /dev/null +++ b/tasty4scalac/integration/src/tasty4scalac/Compiler.scala @@ -0,0 +1,16 @@ +package tasty4scalac + + +trait Compiler { + def compile(code: String): Unit + + final override def toString: String = getClass.getSimpleName +} + +object Compiler { + def scalac(): Compiler = Scalac() + + trait Factory { + def apply(): Compiler + } +} diff --git a/tasty4scalac/integration/src/tasty4scalac/Scalac.scala b/tasty4scalac/integration/src/tasty4scalac/Scalac.scala new file mode 100644 index 000000000000..c9e7b8a21d7b --- /dev/null +++ b/tasty4scalac/integration/src/tasty4scalac/Scalac.scala @@ -0,0 +1,38 @@ +package tasty4scalac + +import java.io._ +import java.net.URL +import java.nio.file._ + +import scala.reflect.internal.util.{BatchSourceFile, NoFile, SourceFile} +import scala.tools.nsc.{Global, Settings} +import scala.tools.nsc.reporters.NoReporter + +final class Scalac(settings: Settings) extends Global(settings, NoReporter) with Compiler { + override def compile(code: String): Unit = { + val file = new BatchSourceFile(NoFile, code.toCharArray) + compile(file) + } + + private def compile(files: SourceFile*): Unit = { + new Run().compileSources(files.toList) + } +} + +object Scalac extends Compiler.Factory { + private val classpath = System.getProperty("scalac.classpath") + private val pluginPath = System.getProperty("scalac.plugin.classpath") + + def apply(): Scalac = { + val settings = new Settings() + settings.classpath.value = classpath + settings.plugin.value = List(pluginPath) + settings.stopAfter.value = List("tasty") + settings.d.value = { + val path = Files.createTempDirectory("tasty-generation") + Files.createDirectories(path).toString + } + + new Scalac(settings) + } +} \ No newline at end of file diff --git a/tasty4scalac/integration/test/tasty4scalac/CompilerTest.java b/tasty4scalac/integration/test/tasty4scalac/CompilerTest.java new file mode 100644 index 000000000000..57c3bdb98405 --- /dev/null +++ b/tasty4scalac/integration/test/tasty4scalac/CompilerTest.java @@ -0,0 +1,30 @@ +package tasty4scalac; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.util.Arrays; +import java.util.Collection; + +@RunWith(Parameterized.class) +public final class CompilerTest { + private final Compiler compiler; + + public CompilerTest(Compiler factory) { + this.compiler = factory; + } + + @Parameterized.Parameters(name = "{index}: {0}") + public static Collection parameters() { + return Arrays.asList(new Compiler[][]{ + {Scalac$.MODULE$.apply()} + }); + } + + @Test + public void compilesSimpleClass() { + String code = "class A"; + compiler.compile(code); + } +} From ae2eb54b2fbcff0295ec40847e3aeb7a46d60520 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20=C5=BBarnowski?= Date: Wed, 6 Mar 2019 15:49:36 +0100 Subject: [PATCH 4/5] compile test cases with scalac --- project/Build.scala | 3 +- .../src/tasty4scalac/CompileSource.scala | 7 +++ .../src/tasty4scalac/Provider.scala | 47 +++++++++++++++++++ .../integration/test/tasty4scalac/Runner.java | 31 ++++++++++++ 4 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 tasty4scalac/integration/src/tasty4scalac/CompileSource.scala create mode 100644 tasty4scalac/integration/src/tasty4scalac/Provider.scala create mode 100644 tasty4scalac/integration/test/tasty4scalac/Runner.java diff --git a/project/Build.scala b/project/Build.scala index a062234c4e5e..ecd8fe58ecb5 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -848,7 +848,8 @@ object Build { Seq( "-Dscalac.classpath=" + scalacClasspath, - "-Dscalac.plugin.classpath=" + pluginClasspath + "-Dscalac.plugin.classpath=" + pluginClasspath, + "-Dtest.root.directory=" + (baseDirectory.value / "test-resources") ) } ) diff --git a/tasty4scalac/integration/src/tasty4scalac/CompileSource.scala b/tasty4scalac/integration/src/tasty4scalac/CompileSource.scala new file mode 100644 index 000000000000..33a4ad9294a2 --- /dev/null +++ b/tasty4scalac/integration/src/tasty4scalac/CompileSource.scala @@ -0,0 +1,7 @@ +package tasty4scalac + +import java.nio.file.Path + +final class CompileSource(val name: String, val source: Path) { + override def toString: String = name +} diff --git a/tasty4scalac/integration/src/tasty4scalac/Provider.scala b/tasty4scalac/integration/src/tasty4scalac/Provider.scala new file mode 100644 index 000000000000..31abff922f49 --- /dev/null +++ b/tasty4scalac/integration/src/tasty4scalac/Provider.scala @@ -0,0 +1,47 @@ +package tasty4scalac + +import java.nio.file.{Files, Path, Paths} +import java.util +import java.util.regex.Pattern +import scala.collection.JavaConverters._ + +trait Provider { + def testCases(): util.Collection[Array[CompileSource]] +} + +object Providers { + private val root = Paths.get(System.getProperty("test.root.directory")) + + def compiledSourceProvider: Provider = new CompiledSources(root) + + private final class CompiledSources(root: Path) extends Provider { + private val negativeTests = Seq( + Pattern.compile(".*/neg(-.*)?/.*"), + Pattern.compile(".*/run-with-compiler/.*"), + Pattern.compile(".*/vulpix-tests/.*"), + Pattern.compile(".*/disabled/.*"), + ) + + def testCases(): util.Collection[Array[CompileSource]] = { + findTestCases(root) + .map(createTestCase) + .map(Array(_)) + .asJavaCollection + } + + private def findTestCases(path: Path): Seq[Path] = { + Files.walk(path) + .iterator() + .asScala + .filterNot(path => negativeTests.exists(p => p.matcher(path.toString).matches())) + .filter(_.getFileName.toString.endsWith(".scala")) + .toSeq + } + + private def createTestCase(path: Path): CompileSource = { + val name = root.relativize(path).toString.dropRight(6) // drop ".scala" + new CompileSource(name, path) + } + } + +} diff --git a/tasty4scalac/integration/test/tasty4scalac/Runner.java b/tasty4scalac/integration/test/tasty4scalac/Runner.java new file mode 100644 index 000000000000..ee4495f8d50e --- /dev/null +++ b/tasty4scalac/integration/test/tasty4scalac/Runner.java @@ -0,0 +1,31 @@ +package tasty4scalac; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.io.IOException; +import java.nio.file.Files; +import java.util.Collection; + +@RunWith(Parameterized.class) +public final class Runner { + private static final Compiler compiler = Compiler$.MODULE$.scalac(); + private final CompileSource test; + + public Runner(CompileSource test) { + this.test = test; + } + + @Parameterized.Parameters(name = "{index}: {0}") + public static Collection parameters() { + return Providers.compiledSourceProvider().testCases(); + } + + @Test + public void compile() throws IOException { + String code = new String(Files.readAllBytes(test.source())); + compiler.compile(code); + } +} + From df342cd649e966c9ff9b714b52335b17062609af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20=C5=BBarnowski?= Date: Wed, 6 Mar 2019 17:01:25 +0100 Subject: [PATCH 5/5] add dotty compiler class --- project/Build.scala | 2 ++ .../src/tasty4scalac/Compiler.scala | 1 + .../integration/src/tasty4scalac/Dotty.scala | 28 +++++++++++++++++++ .../test/tasty4scalac/CompilerTest.java | 3 +- 4 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 tasty4scalac/integration/src/tasty4scalac/Dotty.scala diff --git a/project/Build.scala b/project/Build.scala index ecd8fe58ecb5..7789e4c78d8d 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -845,10 +845,12 @@ object Build { val scalacClasspath = toClasspath(scalaLibrary, scalaCompiler, scalaReflect) val pluginClasspath = toClasspath(pluginJar, dottyLibrary, dottyCompiler, dottyInterfaces) + val dottyClasspath = toClasspath(scalaLibrary, dottyLibrary, dottyCompiler, dottyInterfaces) Seq( "-Dscalac.classpath=" + scalacClasspath, "-Dscalac.plugin.classpath=" + pluginClasspath, + "-Ddotty.classpath=" + dottyClasspath, "-Dtest.root.directory=" + (baseDirectory.value / "test-resources") ) } diff --git a/tasty4scalac/integration/src/tasty4scalac/Compiler.scala b/tasty4scalac/integration/src/tasty4scalac/Compiler.scala index 5d6f2825d609..1994fbd319d6 100644 --- a/tasty4scalac/integration/src/tasty4scalac/Compiler.scala +++ b/tasty4scalac/integration/src/tasty4scalac/Compiler.scala @@ -8,6 +8,7 @@ trait Compiler { } object Compiler { + def dotty(): Compiler = Dotty() def scalac(): Compiler = Scalac() trait Factory { diff --git a/tasty4scalac/integration/src/tasty4scalac/Dotty.scala b/tasty4scalac/integration/src/tasty4scalac/Dotty.scala new file mode 100644 index 000000000000..9af5096eb7b3 --- /dev/null +++ b/tasty4scalac/integration/src/tasty4scalac/Dotty.scala @@ -0,0 +1,28 @@ +package tasty4scalac + +import dotty.tools.dotc.core.Comments.{ContextDoc, ContextDocstrings} +import dotty.tools.dotc.core.Contexts +import dotty.tools.dotc.core.Contexts.ContextBase +import dotty.tools.dotc.reporting.Reporter.NoReporter +import dotty.tools.io.VirtualDirectory +import tasty4scalac.Compiler.Factory + +final class Dotty(val ctx: Contexts.Context) extends dotty.tools.dotc.Compiler with Compiler { + override def compile(code: String): Unit = newRun(ctx.fresh).compile(code) +} + +object Dotty extends Factory { + private val classpath = System.getProperty("dotty.classpath") + + override def apply(): Compiler = { + implicit val ctx: Contexts.FreshContext = new ContextBase().initialCtx.fresh + ctx.setSetting(ctx.settings.classpath, classpath) + ctx.setSetting(ctx.settings.YtestPickler, true) + ctx.setSetting(ctx.settings.encoding, "UTF8") + ctx.setSetting(ctx.settings.outputDir, new VirtualDirectory("")) + + ctx.setReporter(NoReporter) + ctx.setProperty(ContextDoc, new ContextDocstrings) + new Dotty(ctx) + } +} \ No newline at end of file diff --git a/tasty4scalac/integration/test/tasty4scalac/CompilerTest.java b/tasty4scalac/integration/test/tasty4scalac/CompilerTest.java index 57c3bdb98405..54a3d8eaf457 100644 --- a/tasty4scalac/integration/test/tasty4scalac/CompilerTest.java +++ b/tasty4scalac/integration/test/tasty4scalac/CompilerTest.java @@ -18,7 +18,8 @@ public CompilerTest(Compiler factory) { @Parameterized.Parameters(name = "{index}: {0}") public static Collection parameters() { return Arrays.asList(new Compiler[][]{ - {Scalac$.MODULE$.apply()} + {Scalac$.MODULE$.apply()}, + {Dotty$.MODULE$.apply()} }); }