From cd2d79c2c5c643182ff4b4fd695be74729c8bee8 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 25 Oct 2017 15:37:24 +0200 Subject: [PATCH 1/2] Rename -Xlink-optimise to -Xlink --- compiler/src/dotty/tools/dotc/config/ScalaSettings.scala | 2 +- compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala | 2 +- compiler/src/dotty/tools/dotc/core/Symbols.scala | 2 +- compiler/src/dotty/tools/dotc/transform/LinkAll.scala | 4 ++-- compiler/test/dotty/tools/dotc/LinkTests.scala | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala index 092918832a5d..da98fff644bc 100644 --- a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala +++ b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala @@ -116,7 +116,7 @@ class ScalaSettings extends Settings.SettingGroup { val YoptPhases = PhasesSetting("-Yopt-phases", "Restrict the optimisation phases to execute under -optimise.") val YoptFuel = IntSetting("-Yopt-fuel", "Maximum number of optimisations performed under -optimise.", -1) val optimise = BooleanSetting("-optimise", "Generates faster bytecode by applying local optimisations to the .program") withAbbreviation "-optimize" - val XlinkOptimise = BooleanSetting("-Xlink-optimise", "Recompile library code with the application.").withAbbreviation("-Xlink-optimize") + val Xlink = BooleanSetting("-Xlink", "Recompile library code with the application.") /** Dottydoc specific settings */ val siteRoot = StringSetting( diff --git a/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala b/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala index abe7ff5a2ae7..742dd5c30e8b 100644 --- a/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala +++ b/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala @@ -337,7 +337,7 @@ class ClassfileLoader(val classfile: AbstractFile) extends SymbolLoader { } private def mayLoadTreesFromTasty(implicit ctx: Context): Boolean = - ctx.settings.YretainTrees.value || ctx.settings.XlinkOptimise.value || ctx.settings.tasty.value + ctx.settings.YretainTrees.value || ctx.settings.Xlink.value || ctx.settings.tasty.value } class SourcefileLoader(val srcfile: AbstractFile) extends SymbolLoader { diff --git a/compiler/src/dotty/tools/dotc/core/Symbols.scala b/compiler/src/dotty/tools/dotc/core/Symbols.scala index 8cddd2e9d70c..b2601445f58d 100644 --- a/compiler/src/dotty/tools/dotc/core/Symbols.scala +++ b/compiler/src/dotty/tools/dotc/core/Symbols.scala @@ -604,7 +604,7 @@ object Symbols { /** If this is either: * - a top-level class and `-Yretain-trees` is set - * - a top-level class loaded from TASTY and `-Xlink-optimise` is set + * - a top-level class loaded from TASTY and `-Xlink` is set * then return the TypeDef tree (possibly wrapped inside PackageDefs) for this class, otherwise EmptyTree. * This will force the info of the class. */ diff --git a/compiler/src/dotty/tools/dotc/transform/LinkAll.scala b/compiler/src/dotty/tools/dotc/transform/LinkAll.scala index fe3270cebf44..a1e2dc408755 100644 --- a/compiler/src/dotty/tools/dotc/transform/LinkAll.scala +++ b/compiler/src/dotty/tools/dotc/transform/LinkAll.scala @@ -34,7 +34,7 @@ class LinkAll extends Phase { } } - if (ctx.settings.XlinkOptimise.value) allUnits(Set.empty, units.toSet, Set.empty) + if (ctx.settings.Xlink.value) allUnits(Set.empty, units.toSet, Set.empty) else units } @@ -67,7 +67,7 @@ class LinkAll extends Phase { object LinkAll { private[LinkAll] def loadCompilationUnit(clsd: ClassDenotation)(implicit ctx: Context): Option[CompilationUnit] = { - assert(ctx.settings.XlinkOptimise.value) + assert(ctx.settings.Xlink.value) val tree = clsd.symbol.asClass.tree if (tree.isEmpty) None else { diff --git a/compiler/test/dotty/tools/dotc/LinkTests.scala b/compiler/test/dotty/tools/dotc/LinkTests.scala index d2c613341b6a..614b956a0a71 100644 --- a/compiler/test/dotty/tools/dotc/LinkTests.scala +++ b/compiler/test/dotty/tools/dotc/LinkTests.scala @@ -44,7 +44,7 @@ class LinkTests extends ParallelTesting { // Setup class paths def mkLinkClassFlags(libPath: String) = - TestFlags(mkClassPath(libPath :: Jars.dottyTestDeps), mkClassPath(Jars.dottyTestDeps), basicDefaultOptions :+ "-Xlink-optimise") + TestFlags(mkClassPath(libPath :: Jars.dottyTestDeps), mkClassPath(Jars.dottyTestDeps), basicDefaultOptions :+ "-Xlink") val strawmanClassPath = mkLinkClassFlags(defaultOutputDir + strawmanLibGroup + "/main/") val customLibClassFlags = mkLinkClassFlags(defaultOutputDir + linkCustomLibGroup + "/custom-lib") From 6eeb672967017f73d62003774f9d2715ac53dfaa Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 24 Oct 2017 15:17:40 +0200 Subject: [PATCH 2/2] Link directly to a JAR --- .../dotty/tools/dotc/CompilationUnit.scala | 11 ++++----- .../dotty/tools/dotc/transform/LinkAll.scala | 12 +++++++++- .../test/dotty/tools/dotc/LinkTests.scala | 8 ++++--- .../tools/dotc/MissingCoreLibTests.scala | 2 +- .../dotty/tools/vulpix/ParallelTesting.scala | 24 +++++++++++-------- .../test/dotty/tools/vulpix/TestFlags.scala | 2 ++ 6 files changed, 38 insertions(+), 21 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/CompilationUnit.scala b/compiler/src/dotty/tools/dotc/CompilationUnit.scala index c8a4e73706e6..2ff2881f9de1 100644 --- a/compiler/src/dotty/tools/dotc/CompilationUnit.scala +++ b/compiler/src/dotty/tools/dotc/CompilationUnit.scala @@ -3,8 +3,7 @@ package dotc import dotty.tools.dotc.core.Types.Type // Do not remove me #3383 import util.SourceFile -import ast.{tpd, untpd} -import dotty.tools.dotc.ast.tpd.{ Tree, TreeTraverser } +import dotty.tools.dotc.ast.{ tpd, untpd } import dotty.tools.dotc.core.Contexts.Context import dotty.tools.dotc.core.SymDenotations.ClassDenotation import dotty.tools.dotc.core.Symbols._ @@ -26,9 +25,9 @@ class CompilationUnit(val source: SourceFile) { object CompilationUnit { /** Make a compilation unit for top class `clsd` with the contends of the `unpickled` */ - def mkCompilationUnit(clsd: ClassDenotation, unpickled: Tree, forceTrees: Boolean)(implicit ctx: Context): CompilationUnit = { + def mkCompilationUnit(clsd: ClassDenotation, unpickled: tpd.Tree, forceTrees: Boolean)(implicit ctx: Context): CompilationUnit = { assert(!unpickled.isEmpty, unpickled) - val unit1 = new CompilationUnit(new SourceFile(clsd.symbol.sourceFile, Seq())) + val unit1 = new CompilationUnit(new SourceFile(clsd.symbol.associatedFile, Seq())) unit1.tpdTree = unpickled if (forceTrees) force.traverse(unit1.tpdTree) @@ -36,7 +35,7 @@ object CompilationUnit { } /** Force the tree to be loaded */ - private object force extends TreeTraverser { - def traverse(tree: Tree)(implicit ctx: Context): Unit = traverseChildren(tree) + private object force extends tpd.TreeTraverser { + def traverse(tree: tpd.Tree)(implicit ctx: Context): Unit = traverseChildren(tree) } } diff --git a/compiler/src/dotty/tools/dotc/transform/LinkAll.scala b/compiler/src/dotty/tools/dotc/transform/LinkAll.scala index a1e2dc408755..7bad22dd275f 100644 --- a/compiler/src/dotty/tools/dotc/transform/LinkAll.scala +++ b/compiler/src/dotty/tools/dotc/transform/LinkAll.scala @@ -34,7 +34,7 @@ class LinkAll extends Phase { } } - if (ctx.settings.Xlink.value) allUnits(Set.empty, units.toSet, Set.empty) + if (doLink) allUnits(Set.empty, units.toSet, Set.empty) else units } @@ -62,6 +62,16 @@ class LinkAll extends Phase { else acc + topClass } } + + private def doLink(implicit ctx: Context): Boolean = { + val link = ctx.settings.Xlink + if (link.value) { + val out = ctx.settings.outputDir + if (out.value.endsWith(".jar")) + ctx.error("With " + link.name + " the output directory " + out.name + " should be a .jar\n" + out.value) + true + } else false + } } object LinkAll { diff --git a/compiler/test/dotty/tools/dotc/LinkTests.scala b/compiler/test/dotty/tools/dotc/LinkTests.scala index 614b956a0a71..c95dea85eaf2 100644 --- a/compiler/test/dotty/tools/dotc/LinkTests.scala +++ b/compiler/test/dotty/tools/dotc/LinkTests.scala @@ -2,6 +2,8 @@ package dotty package tools package dotc +import dotty.tools.io.Jar + import java.io.{File => JFile} import java.nio.file.{Files, Path, Paths} @@ -61,11 +63,11 @@ class LinkTests extends ParallelTesting { for (check <- new JFile(sourceDir).listFiles().filter(_.toString.endsWith(checkExt))) { val outDir = { def path(str: String) = str.substring(linkDir.length, str.length - checkExt.length) - defaultOutputDir + testName + path(check.toString) + "/" + defaultOutputDir + testName + path(check.toString) + "/linked.jar" } val expectedClasses = scala.io.Source.fromFile(check).getLines().toSet - val actualClasses = Files.walk(Paths.get(outDir)).iterator().asScala.collect { - case f if f.toString.endsWith(".class") => f.toString.substring(outDir.length, f.toString.length - ".class".length) + val actualClasses = new Jar(outDir).iterator.collect { + case f if f.toString.endsWith(".class") => f.toString.substring(0, f.toString.length - ".class".length) }.toSet assertEquals(check.toString, expectedClasses, actualClasses) } diff --git a/compiler/test/dotty/tools/dotc/MissingCoreLibTests.scala b/compiler/test/dotty/tools/dotc/MissingCoreLibTests.scala index 31c7197ad498..021568c411ee 100644 --- a/compiler/test/dotty/tools/dotc/MissingCoreLibTests.scala +++ b/compiler/test/dotty/tools/dotc/MissingCoreLibTests.scala @@ -12,7 +12,7 @@ class MissingCoreLibTests { @Test def missingDottyLib: Unit = { val classPath = mkClassPath(Jars.dottyCompiler :: Jars.dottyInterfaces :: Jars.dottyExtras) // missing Jars.dottyLib val source = "../tests/neg/nolib/Foo.scala" - val options = Array("-classpath", classPath, source) + val options = Array("-classpath", classPath, "-d", "../out/", source) val reporter = Main.process(options) assertEquals(1, reporter.errorCount) val errorMessage = reporter.allErrors.head.message diff --git a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala index ec9fd31ce5d8..d4db21a39b75 100644 --- a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala +++ b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala @@ -1027,18 +1027,22 @@ trait ParallelTesting extends RunnerOrchestration { self => } /** Create out directory for directory `d` */ - private def createOutputDirsForDir(d: JFile, sourceDir: JFile, outDir: String): JFile = { + private def createOutputDirsForDir(d: JFile, sourceDir: JFile, outDir: String, flags: TestFlags): JFile = { val targetDir = new JFile(outDir + s"${sourceDir.getName}/${d.getName}") targetDir.mkdirs() - targetDir + jaredIfNeeded(targetDir, flags) } /** Create out directory for `file` */ - private def createOutputDirsForFile(file: JFile, sourceDir: JFile, outDir: String): JFile = { + private def createOutputDirsForFile(file: JFile, sourceDir: JFile, outDir: String, flags: TestFlags): JFile = { val uniqueSubdir = file.getName.substring(0, file.getName.lastIndexOf('.')) val targetDir = new JFile(outDir + s"${sourceDir.getName}/$uniqueSubdir") targetDir.mkdirs() - targetDir + jaredIfNeeded(targetDir, flags) + } + + private def jaredIfNeeded(targetDir: JFile, flags: TestFlags): JFile = { + new JFile(targetDir + (if (flags.isLinkTest) "/linked.jar" else "")) } /** Make sure that directory string is as expected */ @@ -1073,7 +1077,7 @@ trait ParallelTesting extends RunnerOrchestration { self => testGroup.name, Array(sourceFile), flags, - createOutputDirsForFile(sourceFile, parent, outDir) + createOutputDirsForFile(sourceFile, parent, outDir, flags) ) new CompilationTest(target) } @@ -1095,7 +1099,7 @@ trait ParallelTesting extends RunnerOrchestration { self => (parent ne null) && parent.exists && parent.isDirectory, s"Source file: $f, didn't exist" ) - val tastySource = createOutputDirsForFile(sourceFile, parent, outDir) + val tastySource = createOutputDirsForFile(sourceFile, parent, outDir, flags) val target = JointCompilationSource( testGroup.name, Array(sourceFile), @@ -1180,8 +1184,8 @@ trait ParallelTesting extends RunnerOrchestration { self => val (dirs, files) = compilationTargets(sourceDir) val targets = - files.map(f => JointCompilationSource(testGroup.name, Array(f), flags, createOutputDirsForFile(f, sourceDir, outDir))) ++ - dirs.map(dir => SeparateCompilationSource(testGroup.name, dir, flags, createOutputDirsForDir(dir, sourceDir, outDir))) + files.map(f => JointCompilationSource(testGroup.name, Array(f), flags, createOutputDirsForFile(f, sourceDir, outDir, flags))) ++ + dirs.map(dir => SeparateCompilationSource(testGroup.name, dir, flags, createOutputDirsForDir(dir, sourceDir, outDir, flags))) // Create a CompilationTest and let the user decide whether to execute a pos or a neg test new CompilationTest(targets) @@ -1217,7 +1221,7 @@ trait ParallelTesting extends RunnerOrchestration { self => val targets = files.map { f => - val classpath = createOutputDirsForFile(f, sourceDir, outDir) + val classpath = createOutputDirsForFile(f, sourceDir, outDir, flags) JointCompilationSource(testGroup.name, Array(f), flags.withClasspath(classpath.getPath), classpath, fromTasty = true) } // TODO add SeparateCompilationSource from tasty? @@ -1240,7 +1244,7 @@ trait ParallelTesting extends RunnerOrchestration { self => val (_, files) = compilationTargets(sourceDir) val targets = files.map { file => - JointCompilationSource(testGroup.name, Array(file), flags, createOutputDirsForFile(file, sourceDir, outDir)) + JointCompilationSource(testGroup.name, Array(file), flags, createOutputDirsForFile(file, sourceDir, outDir, flags)) } // Create a CompilationTest and let the user decide whether to execute a pos or a neg test diff --git a/compiler/test/dotty/tools/vulpix/TestFlags.scala b/compiler/test/dotty/tools/vulpix/TestFlags.scala index 221da457f9b4..4839e20c2fc6 100644 --- a/compiler/test/dotty/tools/vulpix/TestFlags.scala +++ b/compiler/test/dotty/tools/vulpix/TestFlags.scala @@ -15,6 +15,8 @@ final case class TestFlags( TestFlags(s"$defaultClassPath:$classPath", runClassPath, options) def all: Array[String] = Array("-classpath", defaultClassPath) ++ options + + def isLinkTest: Boolean = options.contains("-Xlink") } object TestFlags {