diff --git a/compiler/test/dotty/tools/dotc/CompilationTests.scala b/compiler/test/dotty/tools/dotc/CompilationTests.scala index 8af721ca6cb5..a9d0d7e17718 100644 --- a/compiler/test/dotty/tools/dotc/CompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/CompilationTests.scala @@ -207,7 +207,7 @@ class CompilationTests extends ParallelTesting { // compile with bootstrapped library on cp: defaultOutputDir + "lib/src/:" + // as well as bootstrapped compiler: - defaultOutputDir + "dotty1/dotty1/:" + + defaultOutputDir + "dotty1/dotty/:" + Jars.dottyInterfaces ) @@ -241,15 +241,19 @@ class CompilationTests extends ParallelTesting { def dotty1 = { compileList( - "dotty1", + "dotty", compilerSources ++ backendSources ++ backendJvmSources, opt) } - def dotty2 = - compileShallowFilesInDir("../compiler/src/dotty", opt) + def dotty2 = { + compileList( + "dotty", + compilerSources ++ backendSources ++ backendJvmSources, + opt) + } - { + val tests = { lib.keepOutput :: dotty1.keepOutput :: { dotty2 + compileShallowFilesInDir("../compiler/src/dotty/tools", opt) + @@ -266,8 +270,14 @@ class CompilationTests extends ParallelTesting { compileShallowFilesInDir("../compiler/src/dotty/tools/dotc/util", opt) + compileList("shallow-backend", backendSources, opt) + compileList("shallow-backend-jvm", backendJvmSources, opt) - } :: Nil - }.map(_.checkCompile()).foreach(_.delete()) + }.keepOutput :: Nil + }.map(_.checkCompile()) + + assert(new java.io.File("../out/dotty1/dotty/").exists) + assert(new java.io.File("../out/dotty2/dotty/").exists) + compileList("idempotency", List("../tests/idempotency/BootstrapChecker.scala", "../tests/idempotency/IdempotencyCheck.scala"), defaultOptions).checkRuns() + + tests.foreach(_.delete()) } /** Add a `z` so that they run last. TODO: Only run them selectively? */ @@ -275,12 +285,10 @@ class CompilationTests extends ParallelTesting { val opt = defaultOptions.and("-YemitTasty") def idempotency1() = { - compileList("dotty1", compilerSources ++ backendSources ++ backendJvmSources, opt) + compileDir("../collection-strawman/src/main", opt) + compileFilesInDir("../tests/pos", opt) } def idempotency2() = { - compileList("dotty1", compilerSources ++ backendSources ++ backendJvmSources, opt) + compileDir("../collection-strawman/src/main", opt) + compileFilesInDir("../tests/pos", opt) } @@ -290,7 +298,7 @@ class CompilationTests extends ParallelTesting { assert(new java.io.File("../out/idempotency1/").exists) assert(new java.io.File("../out/idempotency2/").exists) - compileFile("../tests/idempotency/IdempotencyCheck.scala", defaultOptions).checkRuns() + compileList("idempotency", List("../tests/idempotency/Checker.scala", "../tests/idempotency/IdempotencyCheck.scala"), defaultOptions).checkRuns() tests.delete() } diff --git a/tests/idempotency/BootstrapChecker.scala b/tests/idempotency/BootstrapChecker.scala new file mode 100644 index 000000000000..e78cd5293d5c --- /dev/null +++ b/tests/idempotency/BootstrapChecker.scala @@ -0,0 +1,5 @@ + +object Test { + def main(args: Array[String]): Unit = + IdempotencyCheck.checkIdempotency("../out/dotty") +} diff --git a/tests/idempotency/Checker.scala b/tests/idempotency/Checker.scala new file mode 100644 index 000000000000..39a38243feaa --- /dev/null +++ b/tests/idempotency/Checker.scala @@ -0,0 +1,5 @@ + +object Test { + def main(args: Array[String]): Unit = + IdempotencyCheck.checkIdempotency("../out/idempotency") +} diff --git a/tests/idempotency/IdempotencyCheck.scala b/tests/idempotency/IdempotencyCheck.scala index 14c23d46568b..6c9d8db18464 100644 --- a/tests/idempotency/IdempotencyCheck.scala +++ b/tests/idempotency/IdempotencyCheck.scala @@ -1,45 +1,43 @@ -import java.nio.file.{Files, Path, Paths} +import java.nio.file.{ Files => JFiles, Path => JPath, Paths => JPaths } import java.util.stream.{ Stream => JStream } import scala.collection.JavaConverters._ -object Test { - - def main(args: Array[String]): Unit = checkIdempotency() - +object IdempotencyCheck { val blacklisted = Set( - // Bridges on collections in different order. Second one in scala2 order. + // No fix needed. Bridges on collections in different order. Second one in scala2 order. "pos/Map/scala/collection/immutable/Map", "pos/Map/scala/collection/immutable/AbstractMap", "pos/t1203a/NodeSeq", "pos/i2345/Whatever" ) - def checkIdempotency(): Unit = { + def checkIdempotency(dirPrefix: String): Unit = { var failed = 0 var total = 0 - val groupedBytecodeFiles: List[(Path, Path, Path, Path)] = { + val groupedBytecodeFiles: List[(JPath, JPath, JPath, JPath)] = { val bytecodeFiles = { - def bytecodeFiles(paths: JStream[Path]): List[Path] = { + def bytecodeFiles(paths: JStream[JPath]): List[JPath] = { def isBytecode(file: String) = file.endsWith(".class") || file.endsWith(".tasty") paths.iterator.asScala.filter(path => isBytecode(path.toString)).toList } - val compilerDir1 = Paths.get("../out/idempotency1") - val compilerDir2 = Paths.get("../out/idempotency2") - bytecodeFiles(Files.walk(compilerDir1)) ++ bytecodeFiles(Files.walk(compilerDir2)) + val compilerDir1 = JPaths.get(dirPrefix + 1) + val compilerDir2 = JPaths.get(dirPrefix + 2) + bytecodeFiles(JFiles.walk(compilerDir1)) ++ bytecodeFiles(JFiles.walk(compilerDir2)) } - val groups = bytecodeFiles.groupBy(f => f.toString.substring("../out/idempotencyN/".length, f.toString.length - 6)) + val groups = bytecodeFiles.groupBy(f => f.toString.substring(dirPrefix.length + 1, f.toString.length - 6)) + groups.filterNot(x => blacklisted(x._1)).valuesIterator.flatMap { g => - def pred(f: Path, i: Int, isTasty: Boolean) = - f.toString.contains("idempotency" + i) && f.toString.endsWith(if (isTasty) ".tasty" else ".class") + def pred(f: JPath, i: Int, isTasty: Boolean) = + f.toString.contains(dirPrefix + i) && f.toString.endsWith(if (isTasty) ".tasty" else ".class") val class1 = g.find(f => pred(f, 1, isTasty = false)) val class2 = g.find(f => pred(f, 2, isTasty = false)) val tasty1 = g.find(f => pred(f, 1, isTasty = true)) val tasty2 = g.find(f => pred(f, 2, isTasty = true)) - assert(class1.isDefined, "Could not find class in idempotency1 for " + class2) - assert(class2.isDefined, "Could not find class in idempotency2 for " + class1) + assert(class1.isDefined, s"Could not find class in ${dirPrefix + 1} for $class2") + assert(class2.isDefined, s"Could not find class in ${dirPrefix + 2} for $class1") if (tasty1.isEmpty || tasty2.isEmpty) Nil else List(Tuple4(class1.get, tasty1.get, class2.get, tasty2.get)) }.toList @@ -47,18 +45,18 @@ object Test { for ((class1, tasty1, class2, tasty2) <- groupedBytecodeFiles) { total += 1 - val bytes1 = Files.readAllBytes(class1) - val bytes2 = Files.readAllBytes(class2) + val bytes1 = JFiles.readAllBytes(class1) + val bytes2 = JFiles.readAllBytes(class2) if (!java.util.Arrays.equals(bytes1, bytes2)) { failed += 1 - val tastyBytes1 = Files.readAllBytes(tasty1) - val tastyBytes2 = Files.readAllBytes(tasty2) + val tastyBytes1 = JFiles.readAllBytes(tasty1) + val tastyBytes2 = JFiles.readAllBytes(tasty2) if (java.util.Arrays.equals(tastyBytes1, tastyBytes2)) println(s"Idempotency test failed between $class1 and $class1 (same tasty)") else println(s"Idempotency test failed between $tasty1 and $tasty2") /* Dump bytes to console, could be useful if issue only appears in CI. - * Create the .class locally with Files.write(path, Array[Byte](...)) with the printed array + * Create the .class locally with JFiles.write(path, Array[Byte](...)) with the printed array */ // println(bytes1.mkString("Array[Byte](", ",", ")")) // println(bytes2.mkString("Array[Byte](", ",", ")"))