Skip to content

Commit 96747c8

Browse files
committed
Add link tests
1 parent 7b0b245 commit 96747c8

31 files changed

+232
-8
lines changed

compiler/src/dotty/tools/dotc/config/ScalaSettings.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ class ScalaSettings extends Settings.SettingGroup {
102102
val YcheckAllPatmat = BooleanSetting("-Ycheck-all-patmat", "Check exhaustivity and redundancy of all pattern matching (used for testing the algorithm)")
103103
val YretainTrees = BooleanSetting("-Yretain-trees", "Retain trees for top-level classes, accessible from ClassSymbol#tree")
104104
val YshowTreeIds = BooleanSetting("-Yshow-tree-ids", "Uniquely tag all tree nodes in debugging output.")
105+
val YRunClasspath = PathSetting("-YRunClasspath", "Specify where to find user class files while executing run tests.", defaultClasspath)
105106

106107
/** Area-specific debug output */
107108
val Yexplainlowlevel = BooleanSetting("-Yexplain-lowlevel", "When explaining type errors, show types at a lower level.")

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

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package tools
33
package dotc
44

55
import org.junit.{ Test, BeforeClass, AfterClass }
6+
import org.junit.Assert._
67

78
import java.nio.file._
89
import java.util.stream.{ Stream => JStream }
@@ -11,6 +12,7 @@ import scala.util.matching.Regex
1112
import scala.concurrent.duration._
1213

1314
import vulpix.{ ParallelTesting, SummaryReport, SummaryReporting, TestConfiguration }
15+
import dotty.tools.io.JFile
1416

1517

1618
class CompilationTests extends ParallelTesting {
@@ -29,7 +31,6 @@ class CompilationTests extends ParallelTesting {
2931

3032
@Test def compilePos: Unit = {
3133
compileList("compileStdLib", StdLibSources.whitelisted, scala2Mode.and("-migration", "-Yno-inline")) +
32-
compileDir("../collection-strawman/src/main", defaultOptions) +
3334
compileDir("../compiler/src/dotty/tools/dotc/ast", defaultOptions) +
3435
compileDir("../compiler/src/dotty/tools/dotc/config", defaultOptions) +
3536
compileDir("../compiler/src/dotty/tools/dotc/core", allowDeepSubtypes) +
@@ -292,6 +293,79 @@ class CompilationTests extends ParallelTesting {
292293

293294
tests.foreach(_.delete())
294295
}
296+
297+
@Test def linkAll: Unit = {
298+
// Setup and compile libraries
299+
def strawmanLibrary =
300+
compileDir("../collection-strawman/src/main", defaultOptions)
301+
def linkCustomLib =
302+
compileDir("../tests/link/custom-lib", defaultOptions)
303+
304+
val libraries = {
305+
strawmanLibrary +
306+
linkCustomLib
307+
}.keepOutput.checkCompile()
308+
309+
// Setup class paths
310+
def mkLinkClassPath(libPath: String) =
311+
mkClassPath(libPath :: Jars.dottyTestDeps) ++ mkClassPath(Jars.dottyTestDeps, "-YRunClasspath")
312+
val strawmanClassPath = mkLinkClassPath(defaultOutputDir + "strawmanLibrary/main/")
313+
val customLibClassPath = mkLinkClassPath(defaultOutputDir + "linkCustomLib/custom-lib")
314+
315+
// Link tests
316+
val linkDir = "../tests/link"
317+
val linkStramanDir = linkDir + "/strawman"
318+
val linkCustomLibDir = linkDir + "/on-custom-lib"
319+
def linkStrawmanTest = compileFilesInDir(linkStramanDir, basicLinkOptimise ++ strawmanClassPath)
320+
def linkCustomLibTest = compileFilesInDir(linkCustomLibDir, basicLinkOptimise ++ customLibClassPath)
321+
322+
def classFileChecks(sourceDir: String, testName: String) = {
323+
val checkExt = ".classcheck"
324+
for (check <- new JFile(sourceDir).listFiles().filter(_.toString.endsWith(checkExt))) {
325+
val outDir = {
326+
def path(str: String) = str.substring(linkDir.length, str.length - checkExt.length)
327+
defaultOutputDir + testName + path(check.toString) + "/"
328+
}
329+
val expectedClasses = scala.io.Source.fromFile(check).getLines().toSet
330+
val actualClasses = Files.walk(Paths.get(outDir)).iterator().asScala.collect {
331+
case f if f.toString.endsWith(".class") => f.toString.substring(outDir.length, f.toString.length - ".class".length)
332+
}.toSet
333+
assertEquals(check.toString, expectedClasses, actualClasses)
334+
}
335+
}
336+
337+
// Run all tests
338+
val tests = {
339+
linkStrawmanTest +
340+
linkCustomLibTest
341+
}.keepOutput.checkRuns()
342+
343+
classFileChecks(linkStramanDir, "linkStrawmanTest")
344+
classFileChecks(linkCustomLibDir, "linkCustomLibTest")
345+
346+
(libraries + tests).delete()
347+
}
348+
349+
private val (compilerSources, backendSources, backendJvmSources) = {
350+
val compilerDir = Paths.get("../compiler/src")
351+
val compilerSources0 = sources(Files.walk(compilerDir))
352+
353+
val backendDir = Paths.get("../scala-backend/src/compiler/scala/tools/nsc/backend")
354+
val backendJvmDir = Paths.get("../scala-backend/src/compiler/scala/tools/nsc/backend/jvm")
355+
356+
// NOTE: Keep these exclusions synchronized with the ones in the sbt build (Build.scala)
357+
val backendExcluded =
358+
List("JavaPlatform.scala", "Platform.scala", "ScalaPrimitives.scala")
359+
val backendJvmExcluded =
360+
List("BCodeICodeCommon.scala", "GenASM.scala", "GenBCode.scala", "ScalacBackendInterface.scala", "BackendStats.scala")
361+
362+
val backendSources0 =
363+
sources(Files.list(backendDir), excludedFiles = backendExcluded)
364+
val backendJvmSources0 =
365+
sources(Files.list(backendJvmDir), excludedFiles = backendJvmExcluded)
366+
367+
(compilerSources0, backendSources0, backendJvmSources0)
368+
}
295369
}
296370

297371
object CompilationTests {

compiler/test/dotty/tools/vulpix/ParallelTesting.scala

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ trait ParallelTesting extends RunnerOrchestration { self =>
6161
.map(":" + _)
6262
.getOrElse("")
6363

64+
def runClassPath = {
65+
flags
66+
.dropWhile(_ != "-YRunClasspath")
67+
.drop(1)
68+
.headOption
69+
.map(outDir.getAbsolutePath + ":" + _)
70+
.getOrElse(classPath)
71+
}
6472

6573
def title: String = self match {
6674
case self: JointCompilationSource =>
@@ -503,7 +511,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
503511

504512
private def verifyOutput(checkFile: Option[JFile], dir: JFile, testSource: TestSource, warnings: Int) = {
505513
if (Properties.testsNoRun) addNoRunWarning()
506-
else runMain(testSource.classPath) match {
514+
else runMain(testSource.runClassPath) match {
507515
case Success(_) if !checkFile.isDefined || !checkFile.get.exists => // success!
508516
case Success(output) => {
509517
val outputLines = output.lines.toArray
@@ -1124,8 +1132,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
11241132
* `testName` since files can be in separate directories and or be otherwise
11251133
* dissociated
11261134
*/
1127-
def compileList(testName: String, files: List[String], flags: Array[String])(implicit outDirectory: String): CompilationTest = {
1128-
val callingMethod = getCallingMethod()
1135+
def compileList(testName: String, files: List[String], flags: Array[String], callingMethod: String = getCallingMethod())(implicit outDirectory: String): CompilationTest = {
11291136
val outDir = outDirectory + callingMethod + "/" + testName + "/"
11301137

11311138
// Directories in which to compile all containing files with `flags`:

compiler/test/dotty/tools/vulpix/TestConfiguration.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ object TestConfiguration {
2525

2626
val classPath = mkClassPath(Jars.dottyTestDeps)
2727

28-
def mkClassPath(deps: List[String]): Array[String] = {
29-
val paths = deps map { p =>
28+
def mkClassPath(classPaths: List[String], classPathFlag: String = "-classpath"): Array[String] = {
29+
val paths = classPaths map { p =>
3030
val file = new java.io.File(p)
3131
assert(
3232
file.exists,
@@ -49,12 +49,13 @@ object TestConfiguration {
4949
file.getAbsolutePath
5050
} mkString (":")
5151

52-
Array("-classpath", paths)
52+
Array(classPathFlag, paths)
5353
}
5454

5555
val yCheckOptions = Array("-Ycheck:tailrec,resolveSuper,erasure,mixin,getClass,restoreScopes,labelDef")
5656

57-
val defaultUnoptimised = noCheckOptions ++ checkOptions ++ yCheckOptions ++ classPath
57+
val basicDefaultOptions = noCheckOptions ++ checkOptions ++ yCheckOptions
58+
val defaultUnoptimised = basicDefaultOptions ++ classPath
5859
val defaultOptimised = defaultUnoptimised :+ "-optimise"
5960
val defaultOptions = defaultUnoptimised
6061
val allowDeepSubtypes = defaultOptions diff Array("-Yno-deep-subtypes")
@@ -67,4 +68,5 @@ object TestConfiguration {
6768
val scala2Mode = defaultOptions ++ Array("-language:Scala2")
6869
val explicitUTF8 = defaultOptions ++ Array("-encoding", "UTF8")
6970
val explicitUTF16 = defaultOptions ++ Array("-encoding", "UTF16")
71+
val basicLinkOptimise = basicDefaultOptions ++ Array("-Xlink-optimise")
7072
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
class EmptyClass
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
object EmptyObject
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
trait EmptyTrait

tests/link/custom-lib/Map2.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
trait Map2[K] {
2+
def get(k: K): K = k
3+
def foo: K = {
4+
this match {
5+
case that: Map2[b] => that.get(3.asInstanceOf[b])
6+
case _ => get(5.asInstanceOf[K])
7+
}
8+
}
9+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package object foo {
2+
def bar = 42
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
EmptyClass
2+
Test
3+
Test$

0 commit comments

Comments
 (0)