Skip to content

Commit c059b64

Browse files
authored
Merge pull request #6194 from dotty-staging/prepare-bootstrap
Preliminary fix needed for the full bootstrap
2 parents e4c4e0a + dc0c818 commit c059b64

11 files changed

+78
-143
lines changed

build.sbt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ val `dotty-compiler-bootstrapped` = Build.`dotty-compiler-bootstrapped`
88
val `dotty-library` = Build.`dotty-library`
99
val `dotty-library-bootstrapped` = Build.`dotty-library-bootstrapped`
1010
val `dotty-sbt-bridge` = Build.`dotty-sbt-bridge`
11+
val `dotty-sbt-bridge-tests` = Build.`dotty-sbt-bridge-tests`
1112
val `dotty-language-server` = Build.`dotty-language-server`
1213
val `dotty-bench` = Build.`dotty-bench`
1314
val `dotty-bench-bootstrapped` = Build.`dotty-bench-bootstrapped`

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,13 +1391,6 @@ class Definitions {
13911391
for (m <- ScalaShadowingPackageClass.info.decls)
13921392
ScalaPackageClass.enter(m)
13931393

1394-
// Temporary measure, as long as we do not read these classes from Tasty.
1395-
// Scala-2 classes don't have NoInits set even if they are pure. We override this
1396-
// for Product and Serializable so that case classes can be pure. A full solution
1397-
// requires that we read all Scala code from Tasty.
1398-
ProductClass.setFlag(NoInits)
1399-
SerializableClass.setFlag(NoInits)
1400-
14011394
// force initialization of every symbol that is synthesized or hijacked by the compiler
14021395
val forced = syntheticCoreClasses ++ syntheticCoreMethods ++ ScalaValueClasses()
14031396

compiler/src/dotty/tools/dotc/core/StdNames.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ object StdNames {
197197
final val Nothing: N = "Nothing"
198198
final val Null: N = "Null"
199199
final val Object: N = "Object"
200+
final val Product: N = "Product"
200201
final val PartialFunction: N = "PartialFunction"
201202
final val PrefixType: N = "PrefixType"
202203
final val S: N = "S"

compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -804,7 +804,7 @@ class ClassfileParser(
804804
ctx.error("Could not load TASTY from .tasty for virtual file " + classfile)
805805
Array.empty
806806
case Some(jar: ZipArchive) => // We are in a jar
807-
val cl = new URLClassLoader(Array(jar.jpath.toUri.toURL))
807+
val cl = new URLClassLoader(Array(jar.jpath.toUri.toURL), /*parent =*/ null)
808808
val path = classfile.path.stripSuffix(".class") + ".tasty"
809809
val stream = cl.getResourceAsStream(path)
810810
if (stream != null) {

compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,14 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
467467
def completeRoot(denot: ClassDenotation, completer: LazyType): Symbol = {
468468
denot.setFlag(flags)
469469
denot.resetFlag(Touched) // allow one more completion
470+
471+
// Temporary measure, as long as we do not read these classes from Tasty.
472+
// Scala-2 classes don't have NoInits set even if they are pure. We override this
473+
// for Product and Serializable so that case classes can be pure. A full solution
474+
// requires that we read all Scala code from Tasty.
475+
if (owner == defn.ScalaPackageClass && ((name eq tpnme.Serializable) || (name eq tpnme.Product)))
476+
denot.setFlag(NoInits)
477+
470478
denot.info = completer
471479
denot.symbol
472480
}

compiler/test/dotty/Properties.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package dotty
22

3+
import java.nio.file._
4+
35
/** Runtime properties from defines or environmnent */
46
object Properties {
57

@@ -36,6 +38,9 @@ object Properties {
3638
*/
3739
val testsSafeMode: Boolean = sys.props.isDefinedAt("dotty.tests.safemode")
3840

41+
/** Extra directory containing sources for the compiler */
42+
def dottyCompilerManagedSources: Path = Paths.get(sys.props("dotty.tests.dottyCompilerManagedSources"))
43+
3944
/** dotty-interfaces jar */
4045
def dottyInterfaces: String = sys.props("dotty.tests.classes.dottyInterfaces")
4146

compiler/test/dotty/tools/TestSources.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ object TestSources {
6262
(fileName.endsWith(".scala") || fileName.endsWith(".java")) && !excludedFiles.contains(fileName)
6363
}
6464

65-
assert(Files.isDirectory(path))
65+
assert(Files.isDirectory(path), s"Not a directory: $path")
6666
val files = if (shallow) Files.list(path) else Files.walk(path)
6767
try {
6868
val sources = files

compiler/test/dotty/tools/dotc/BootstrappedOnlyCompilationTests.scala

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import org.junit.experimental.categories.Category
1010
import scala.concurrent.duration._
1111
import vulpix._
1212

13+
import java.nio.file._
14+
1315
@Category(Array(classOf[BootstrappedOnlyTests]))
1416
class BootstrappedOnlyCompilationTests extends ParallelTesting {
1517
import ParallelTesting._
@@ -109,4 +111,27 @@ class BootstrappedOnlyCompilationTests extends ParallelTesting {
109111
compileDir("compiler/src/dotty/tools/dotc/core/tasty", picklingWithCompilerOptions) +
110112
compileDir("compiler/src/dotty/tools/dotc/core/unpickleScala2", picklingWithCompilerOptions)
111113
}.limitThreads(4).checkCompile()
114+
115+
@Test def testPlugins: Unit = {
116+
val pluginFile = "plugin.properties"
117+
118+
// 1. hack with absolute path for -Xplugin
119+
// 2. copy `pluginFile` to destination
120+
def compileFilesInDir(dir: String): CompilationTest = {
121+
val outDir = defaultOutputDir + "testPlugins/"
122+
val sourceDir = new java.io.File(dir)
123+
124+
val dirs = sourceDir.listFiles.toList.filter(_.isDirectory)
125+
val targets = dirs.map { dir =>
126+
val compileDir = createOutputDirsForDir(dir, sourceDir, outDir)
127+
Files.copy(dir.toPath.resolve(pluginFile), compileDir.toPath.resolve(pluginFile), StandardCopyOption.REPLACE_EXISTING)
128+
val flags = TestFlags(withCompilerClasspath, noCheckOptions).and("-Xplugin:" + compileDir.getAbsolutePath)
129+
SeparateCompilationSource("testPlugins", dir, flags, compileDir)
130+
}
131+
132+
new CompilationTest(targets)
133+
}
134+
135+
compileFilesInDir("tests/plugins/neg").checkExpectedErrors()
136+
}
112137
}

compiler/test/dotty/tools/dotc/CompilationTests.scala

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -239,12 +239,10 @@ class CompilationTests extends ParallelTesting {
239239
defaultOptions.and("-Ycheck-reentrant", "-strict", "-priorityclasspath", defaultOutputDir))(libGroup)
240240

241241
val compilerSources = sources(Paths.get("compiler/src"))
242+
val compilerManagedSources = sources(Properties.dottyCompilerManagedSources)
242243

243-
val scalaJSIRDir = Paths.get("compiler/target/scala-2.12/src_managed/main/scalajs-ir-src/org/scalajs/ir")
244-
val scalaJSIRSources = sources(scalaJSIRDir, shallow = true)
245-
246-
val dotty1 = compileList("dotty", compilerSources ++ scalaJSIRSources, opt)(dotty1Group)
247-
val dotty2 = compileList("dotty", compilerSources ++ scalaJSIRSources, opt)(dotty2Group)
244+
val dotty1 = compileList("dotty", compilerSources ++ compilerManagedSources, opt)(dotty1Group)
245+
val dotty2 = compileList("dotty", compilerSources ++ compilerManagedSources, opt)(dotty2Group)
248246

249247
val tests = {
250248
lib.keepOutput :: dotty1.keepOutput :: {
@@ -262,7 +260,7 @@ class CompilationTests extends ParallelTesting {
262260
compileShallowFilesInDir("compiler/src/dotty/tools/dotc/util", opt) +
263261
compileShallowFilesInDir("compiler/src/dotty/tools/backend", opt) +
264262
compileShallowFilesInDir("compiler/src/dotty/tools/backend/jvm", opt) +
265-
compileList("shallow-scalajs-ir", scalaJSIRSources, opt)
263+
compileList("managed-sources", compilerManagedSources, opt)
266264
}.keepOutput :: Nil
267265
}.map(_.checkCompile())
268266

@@ -274,29 +272,6 @@ class CompilationTests extends ParallelTesting {
274272

275273
tests.foreach(_.delete())
276274
}
277-
278-
@Test def testPlugins: Unit = {
279-
val pluginFile = "plugin.properties"
280-
281-
// 1. hack with absolute path for -Xplugin
282-
// 2. copy `pluginFile` to destination
283-
def compileFilesInDir(dir: String): CompilationTest = {
284-
val outDir = defaultOutputDir + "testPlugins/"
285-
val sourceDir = new java.io.File(dir)
286-
287-
val dirs = sourceDir.listFiles.toList.filter(_.isDirectory)
288-
val targets = dirs.map { dir =>
289-
val compileDir = createOutputDirsForDir(dir, sourceDir, outDir)
290-
Files.copy(dir.toPath.resolve(pluginFile), compileDir.toPath.resolve(pluginFile), StandardCopyOption.REPLACE_EXISTING)
291-
val flags = TestFlags(withCompilerClasspath, noCheckOptions).and("-Xplugin:" + compileDir.getAbsolutePath)
292-
SeparateCompilationSource("testPlugins", dir, flags, compileDir)
293-
}
294-
295-
new CompilationTest(targets)
296-
}
297-
298-
compileFilesInDir("tests/plugins/neg").checkExpectedErrors()
299-
}
300275
}
301276

302277
object CompilationTests {

compiler/test/dotty/tools/dotc/InterfaceEntryPointTest.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package tools.dotc
33

44
import org.junit.Test
55
import org.junit.Assert._
6+
import org.junit.experimental.categories.Category
67
import interfaces._
78
import scala.collection.mutable.ListBuffer
89
import java.nio.file._
@@ -18,6 +19,7 @@ import java.nio.file._
1819
*
1920
* @see [[OtherEntryPointsTest]]
2021
*/
22+
@Category(Array(classOf[BootstrappedOnlyTests]))
2123
class InterfaceEntryPointTest {
2224
@Test def runCompilerFromInterface = {
2325
val sources =

project/Build.scala

Lines changed: 30 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ object Build {
461461
else List()
462462

463463
val jarOpts = List(
464+
"-Ddotty.tests.dottyCompilerManagedSources=" + (sourceManaged in Compile).value,
464465
"-Ddotty.tests.classes.dottyInterfaces=" + jars("dotty-interfaces"),
465466
"-Ddotty.tests.classes.dottyLibrary=" + jars("dotty-library"),
466467
"-Ddotty.tests.classes.dottyCompiler=" + jars("dotty-compiler"),
@@ -679,19 +680,39 @@ object Build {
679680
case Bootstrapped => `dotty-library-bootstrapped`
680681
}
681682

682-
lazy val `dotty-sbt-bridge` = project.in(file("sbt-bridge")).
683-
dependsOn(dottyCompiler(NonBootstrapped) % Provided).
683+
lazy val `dotty-sbt-bridge` = project.in(file("sbt-bridge/src")).
684+
// We cannot depend on any bootstrapped project to compile the bridge, since the
685+
// bridge is needed to compile these projects.
684686
dependsOn(dottyDoc(NonBootstrapped) % Provided).
685687
settings(commonJavaSettings).
686688
settings(
687689
description := "sbt compiler bridge for Dotty",
688-
libraryDependencies ++= Seq(
689-
Dependencies.`compiler-interface` % Provided,
690-
(Dependencies.`zinc-api-info` % Test).withDottyCompat(scalaVersion.value)
691-
),
690+
691+
sources in Test := Seq(),
692+
scalaSource in Compile := baseDirectory.value,
693+
javaSource in Compile := baseDirectory.value,
694+
695+
// Referring to the other project using a string avoids an infinite loop
696+
// when sbt reads the settings.
697+
test in Test := (test in (LocalProject("dotty-sbt-bridge-tests"), Test)).value,
698+
699+
libraryDependencies += Dependencies.`compiler-interface` % Provided
700+
)
701+
702+
// We use a separate project for the bridge tests since they can only be run
703+
// with the bootstrapped library on the classpath.
704+
lazy val `dotty-sbt-bridge-tests` = project.in(file("sbt-bridge/test")).
705+
dependsOn(dottyCompiler(Bootstrapped) % Test).
706+
settings(commonBootstrappedSettings).
707+
settings(
708+
sources in Compile := Seq(),
709+
scalaSource in Test := baseDirectory.value,
710+
javaSource in Test := baseDirectory.value,
692711

693712
fork in Test := true,
694-
parallelExecution in Test := false
713+
parallelExecution in Test := false,
714+
715+
libraryDependencies += (Dependencies.`zinc-api-info` % Test).withDottyCompat(scalaVersion.value)
695716
)
696717

697718
lazy val `dotty-language-server` = project.in(file("language-server")).
@@ -765,6 +786,7 @@ object Build {
765786
*/
766787
lazy val sjsSandbox = project.in(file("sandbox/scalajs")).
767788
enablePlugins(ScalaJSPlugin).
789+
dependsOn(dottyLibrary(Bootstrapped)).
768790
settings(commonBootstrappedSettings).
769791
settings(
770792
/* Remove the Scala.js compiler plugin for scalac, and enable the
@@ -787,8 +809,7 @@ object Build {
787809
scalaJSLinkerConfig ~= {
788810
_.withCheckIR(true).withParallel(false)
789811
}
790-
).
791-
settings(compileWithDottySettings)
812+
)
792813

793814
lazy val `dotty-bench` = project.in(file("bench")).asDottyBench(NonBootstrapped)
794815
lazy val `dotty-bench-bootstrapped` = project.in(file("bench")).asDottyBench(Bootstrapped)
@@ -1035,102 +1056,6 @@ object Build {
10351056
)
10361057
)
10371058

1038-
// Compile with dotty
1039-
lazy val compileWithDottySettings = {
1040-
inConfig(Compile)(inTask(compile)(Defaults.runnerTask) ++ Seq(
1041-
// Compile with dotty
1042-
fork in compile := true,
1043-
1044-
compile := {
1045-
val inputs = (compileInputs in compile).value
1046-
val inputOptions = inputs.options()
1047-
import inputOptions._
1048-
1049-
val s = streams.value
1050-
val logger = s.log
1051-
val cacheDir = s.cacheDirectory
1052-
1053-
// Discover classpaths
1054-
1055-
def cpToString(cp: Seq[File]) =
1056-
cp.map(_.getAbsolutePath).mkString(File.pathSeparator)
1057-
1058-
val compilerCp = Attributed.data((fullClasspath in (`dotty-compiler`, Compile)).value)
1059-
val cpStr = cpToString(classpath ++ compilerCp)
1060-
1061-
// List all my dependencies (recompile if any of these changes)
1062-
1063-
val allMyDependencies = classpath filterNot (_ == classesDirectory) flatMap { cpFile =>
1064-
if (cpFile.isDirectory) (cpFile ** "*.class").get
1065-
else Seq(cpFile)
1066-
}
1067-
1068-
// Compile
1069-
1070-
val run = (runner in compile).value
1071-
val cachedCompile = FileFunction.cached(cacheDir / "compile",
1072-
FilesInfo.lastModified, FilesInfo.exists) { dependencies =>
1073-
1074-
logger.info(
1075-
"Compiling %d Scala sources to %s..." format (
1076-
sources.size, classesDirectory))
1077-
1078-
if (classesDirectory.exists)
1079-
IO.delete(classesDirectory)
1080-
IO.createDirectory(classesDirectory)
1081-
1082-
val sourcesArgs = sources.map(_.getAbsolutePath()).toList
1083-
1084-
/* run.run() below in doCompile() will emit a call to its
1085-
* logger.info("Running dotty.tools.dotc.Main [...]")
1086-
* which we do not want to see. We use this patched logger to
1087-
* filter out that particular message.
1088-
*/
1089-
val patchedLogger = new Logger {
1090-
def log(level: Level.Value, message: => String) = {
1091-
val msg = message
1092-
if (level != Level.Info ||
1093-
!msg.startsWith("Running dotty.tools.dotc.Main"))
1094-
logger.log(level, msg)
1095-
}
1096-
def success(message: => String) = logger.success(message)
1097-
def trace(t: => Throwable) = logger.trace(t)
1098-
}
1099-
1100-
def doCompile(sourcesArgs: List[String]): Unit = {
1101-
run.run("dotty.tools.dotc.Main", compilerCp,
1102-
"-classpath" :: cpStr ::
1103-
"-d" :: classesDirectory.getAbsolutePath ::
1104-
scalacOptions ++:
1105-
sourcesArgs,
1106-
patchedLogger)
1107-
}
1108-
1109-
// Work around the Windows limitation on command line length.
1110-
val isWindows =
1111-
System.getProperty("os.name").toLowerCase().indexOf("win") >= 0
1112-
if ((fork in compile).value && isWindows &&
1113-
(sourcesArgs.map(_.length).sum > 1536)) {
1114-
IO.withTemporaryFile("sourcesargs", ".txt") { sourceListFile =>
1115-
IO.writeLines(sourceListFile, sourcesArgs)
1116-
doCompile(List("@"+sourceListFile.getAbsolutePath))
1117-
}
1118-
} else {
1119-
doCompile(sourcesArgs)
1120-
}
1121-
1122-
// Output is all files in classesDirectory
1123-
(classesDirectory ** AllPassFilter).get.toSet
1124-
}
1125-
1126-
cachedCompile((sources ++ allMyDependencies).toSet)
1127-
1128-
// We do not have dependency analysis when compiling externally
1129-
sbt.internal.inc.Analysis.Empty
1130-
}
1131-
))
1132-
}
1133-
11341059
lazy val commonDistSettings = Seq(
11351060
packMain := Map(),
11361061
publishArtifact := false,

0 commit comments

Comments
 (0)