Skip to content

Commit 5ca3224

Browse files
Merge pull request #3019 from dotty-staging/add-compilation-order-idempotency-tests
Add compilation order idempotency tests
2 parents 2c44615 + ab6e7dc commit 5ca3224

12 files changed

+106
-46
lines changed

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

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -236,13 +236,6 @@ class CompilationTests extends ParallelTesting {
236236
compileDir("../library/src",
237237
allowDeepSubtypes.and("-Ycheck-reentrant", "-strict", "-priorityclasspath", defaultOutputDir))
238238

239-
def sources(paths: JStream[Path], excludedFiles: List[String] = Nil): List[String] =
240-
paths.iterator().asScala
241-
.filter(path =>
242-
(path.toString.endsWith(".scala") || path.toString.endsWith(".java"))
243-
&& !excludedFiles.contains(path.getFileName.toString))
244-
.map(_.toString).toList
245-
246239
val compilerDir = Paths.get("../compiler/src")
247240
val compilerSources = sources(Files.walk(compilerDir))
248241

@@ -301,13 +294,6 @@ class CompilationTests extends ParallelTesting {
301294
}
302295

303296
private val (compilerSources, backendSources, backendJvmSources) = {
304-
def sources(paths: JStream[Path], excludedFiles: List[String] = Nil): List[String] =
305-
paths.iterator().asScala
306-
.filter(path =>
307-
(path.toString.endsWith(".scala") || path.toString.endsWith(".java"))
308-
&& !excludedFiles.contains(path.getFileName.toString))
309-
.map(_.toString).toList
310-
311297
val compilerDir = Paths.get("../compiler/src")
312298
val compilerSources0 = sources(Files.walk(compilerDir))
313299

@@ -332,4 +318,11 @@ class CompilationTests extends ParallelTesting {
332318
object CompilationTests {
333319
implicit val summaryReport: SummaryReporting = new SummaryReport
334320
@AfterClass def cleanup(): Unit = summaryReport.echoSummary()
321+
322+
def sources(paths: JStream[Path], excludedFiles: List[String] = Nil): List[String] =
323+
paths.iterator().asScala
324+
.filter(path =>
325+
(path.toString.endsWith(".scala") || path.toString.endsWith(".java"))
326+
&& !excludedFiles.contains(path.getFileName.toString))
327+
.map(_.toString).toList
335328
}

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

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ package dotty
22
package tools
33
package dotc
44

5+
import java.io.{ File => JFile }
6+
import java.nio.file.{ Files, Paths, Path }
7+
58
import org.junit.{ Test, AfterClass }
69

710
import scala.concurrent.duration._
@@ -22,25 +25,57 @@ class IdempotencyTests extends ParallelTesting {
2225
def testFilter = Properties.testsFilter
2326

2427
/* TODO: Only run them selectively? */
25-
@Test def bytecodeIdempotency: Unit = {
28+
@Test def idempotency: Unit = {
2629
val opt = defaultOptions.and("-YemitTasty")
2730

28-
def idempotency1() = {
29-
compileDir("../collection-strawman/src/main", opt) +
30-
compileFilesInDir("../tests/pos", opt)
31+
def sourcesFrom(dir: Path) = CompilationTests.sources(Files.walk(dir))
32+
33+
val strawmanSources = sourcesFrom(Paths.get("../collection-strawman/src/main"))
34+
val strawmanSourcesSorted = strawmanSources.sorted
35+
val strawmanSourcesRevSorted = strawmanSourcesSorted.reverse
36+
37+
val posIdempotency = {
38+
def posIdempotency1 = compileFilesInDir("../tests/pos", opt)
39+
def posIdempotency2 = compileFilesInDir("../tests/pos", opt)
40+
posIdempotency1 + posIdempotency2
3141
}
32-
def idempotency2() = {
33-
compileDir("../collection-strawman/src/main", opt) +
34-
compileFilesInDir("../tests/pos", opt)
42+
43+
val orderIdempotency = {
44+
(for {
45+
testDir <- new JFile("../tests/order-idempotency").listFiles() if testDir.isDirectory
46+
} yield {
47+
val sources = sourcesFrom(testDir.toPath)
48+
def orderIdempotency1 = compileList(testDir.getName, sources, opt)
49+
def orderIdempotency2 = compileList(testDir.getName, sources.reverse, opt)
50+
orderIdempotency1 + orderIdempotency2
51+
}).reduce(_ + _)
3552
}
3653

37-
val tests = (idempotency1() + idempotency2()).keepOutput.checkCompile()
54+
val strawmanIdempotency = {
55+
compileList("strawman0", strawmanSources, opt) +
56+
compileList("strawman1", strawmanSources, opt) +
57+
compileList("strawman2", strawmanSourcesSorted, opt) +
58+
compileList("strawman3", strawmanSourcesRevSorted, opt)
59+
}
3860

39-
assert(new java.io.File("../out/idempotency1/").exists)
40-
assert(new java.io.File("../out/idempotency2/").exists)
61+
def check(name: String) = {
62+
val files = List(s"../tests/idempotency/$name.scala", "../tests/idempotency/IdempotencyCheck.scala")
63+
compileList(name, files, defaultOptions)
64+
}
65+
val allChecks = {
66+
check("CheckOrderIdempotency") +
67+
check("CheckStrawmanIdempotency") +
68+
check("CheckPosIdempotency")
69+
}
4170

42-
compileList("idempotency", List("../tests/idempotency/Checker.scala", "../tests/idempotency/IdempotencyCheck.scala"), defaultOptions).checkRuns()
71+
val allTests = {
72+
strawmanIdempotency +
73+
orderIdempotency +
74+
posIdempotency
75+
}
4376

77+
val tests = allTests.keepOutput.checkCompile()
78+
allChecks.checkRuns()
4479
tests.delete()
4580
}
4681

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

22
object Test {
33
def main(args: Array[String]): Unit =
4-
IdempotencyCheck.checkIdempotency("../out/dotty")
4+
IdempotencyCheck.checkIdempotency("../out/dotty1", "../out/dotty2")
55
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
object Test {
3+
def main(args: Array[String]): Unit =
4+
IdempotencyCheck.checkIdempotency("../out/orderIdempotency1", "../out/orderIdempotency2")
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
object Test {
3+
def main(args: Array[String]): Unit =
4+
IdempotencyCheck.checkIdempotency("../out/posIdempotency1", "../out/posIdempotency2")
5+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
object Test {
3+
def main(args: Array[String]): Unit = {
4+
IdempotencyCheck.checkIdempotency("../out/idempotency/strawman0", "../out/idempotency/strawman1")
5+
// FIXME: #2964 and maybe more
6+
/*
7+
IdempotencyCheck.checkIdempotency("../out/idempotency/strawman1", "../out/idempotency/strawman2")
8+
IdempotencyCheck.checkIdempotency("../out/idempotency/strawman1", "../out/idempotency/strawman3")
9+
*/
10+
}
11+
}

tests/idempotency/Checker.scala

Lines changed: 0 additions & 5 deletions
This file was deleted.

tests/idempotency/IdempotencyCheck.scala

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,32 @@ object IdempotencyCheck {
1313
"pos/i2345/Whatever"
1414
)
1515

16-
def checkIdempotency(dirPrefix: String): Unit = {
16+
def checkIdempotency(dir1: String, dir2: String): Unit = {
1717
var failed = 0
1818
var total = 0
1919

2020
val groupedBytecodeFiles: List[(JPath, JPath, JPath, JPath)] = {
2121
val bytecodeFiles = {
22-
def bytecodeFiles(paths: JStream[JPath]): List[JPath] = {
22+
def bytecodeFiles(paths: JStream[JPath], dir: String): List[(String, JPath)] = {
2323
def isBytecode(file: String) = file.endsWith(".class") || file.endsWith(".tasty")
24-
paths.iterator.asScala.filter(path => isBytecode(path.toString)).toList
24+
def tupleWithName(f: JPath) = (f.toString.substring(dir.length + 1, f.toString.length - 6), f)
25+
paths.iterator.asScala.filter(path => isBytecode(path.toString)).map(tupleWithName).toList
2526
}
26-
val compilerDir1 = JPaths.get(dirPrefix + 1)
27-
val compilerDir2 = JPaths.get(dirPrefix + 2)
28-
bytecodeFiles(JFiles.walk(compilerDir1)) ++ bytecodeFiles(JFiles.walk(compilerDir2))
27+
val compilerDir1 = JPaths.get(dir1)
28+
val compilerDir2 = JPaths.get(dir2)
29+
bytecodeFiles(JFiles.walk(compilerDir1), dir1) ++ bytecodeFiles(JFiles.walk(compilerDir2), dir2)
2930
}
30-
val groups = bytecodeFiles.groupBy(f => f.toString.substring(dirPrefix.length + 1, f.toString.length - 6))
31+
val groups = bytecodeFiles.groupBy(_._1).mapValues(_.map(_._2))
3132

3233
groups.filterNot(x => blacklisted(x._1)).valuesIterator.flatMap { g =>
33-
def pred(f: JPath, i: Int, isTasty: Boolean) =
34-
f.toString.contains(dirPrefix + i) && f.toString.endsWith(if (isTasty) ".tasty" else ".class")
35-
val class1 = g.find(f => pred(f, 1, isTasty = false))
36-
val class2 = g.find(f => pred(f, 2, isTasty = false))
37-
val tasty1 = g.find(f => pred(f, 1, isTasty = true))
38-
val tasty2 = g.find(f => pred(f, 2, isTasty = true))
39-
assert(class1.isDefined, s"Could not find class in ${dirPrefix + 1} for $class2")
40-
assert(class2.isDefined, s"Could not find class in ${dirPrefix + 2} for $class1")
34+
def pred(f: JPath, dir: String, isTasty: Boolean) =
35+
f.toString.contains(dir) && f.toString.endsWith(if (isTasty) ".tasty" else ".class")
36+
val class1 = g.find(f => pred(f, dir1, isTasty = false))
37+
val class2 = g.find(f => pred(f, dir2, isTasty = false))
38+
val tasty1 = g.find(f => pred(f, dir1, isTasty = true))
39+
val tasty2 = g.find(f => pred(f, dir2, isTasty = true))
40+
assert(class1.isDefined, s"Could not find class in ${dir1} for $class2")
41+
assert(class2.isDefined, s"Could not find class in ${dir2} for $class1")
4142
if (tasty1.isEmpty || tasty2.isEmpty) Nil
4243
else List(Tuple4(class1.get, tasty1.get, class2.get, tasty2.get))
4344
}.toList
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
object App {
2+
val list1 = new C(2, N)
3+
val list2 = new C(2, list1)
4+
list2.head
5+
list2.tail
6+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
class C[+T](val head: T, val tail: L[T]) extends L[T]
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
trait L[+T] {
2+
def head: T
3+
def tail: L[T]
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
object N extends L[Nothing] {
2+
def head = ???
3+
def tail = ???
4+
}

0 commit comments

Comments
 (0)