@@ -132,7 +132,8 @@ trait ParallelTesting extends RunnerOrchestration { self =>
132
132
name : String ,
133
133
files : Array [JFile ],
134
134
flags : TestFlags ,
135
- outDir : JFile
135
+ outDir : JFile ,
136
+ fromTasty : Boolean = false
136
137
) extends TestSource {
137
138
def sourceFiles : Array [JFile ] = files.filter(isSourceFile)
138
139
@@ -213,7 +214,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
213
214
private val filteredSources =
214
215
if (! testFilter.isDefined) testSources
215
216
else testSources.filter {
216
- case JointCompilationSource (_, files, _, _) =>
217
+ case JointCompilationSource (_, files, _, _, _ ) =>
217
218
files.exists(file => file.getAbsolutePath.contains(testFilter.get))
218
219
case SeparateCompilationSource (_, dir, _, _) =>
219
220
dir.getAbsolutePath.contains(testFilter.get)
@@ -336,15 +337,6 @@ trait ParallelTesting extends RunnerOrchestration { self =>
336
337
337
338
val files : Array [JFile ] = files0.flatMap(flattenFiles)
338
339
339
- def addOutDir (xs : Array [String ]): Array [String ] = {
340
- val (beforeCp, cpAndAfter) = xs.toList.span(_ != " -classpath" )
341
- if (cpAndAfter.nonEmpty) {
342
- val (cp :: cpArg :: rest) = cpAndAfter
343
- (beforeCp ++ (cp :: (cpArg + s " : ${targetDir.getAbsolutePath}" ) :: rest)).toArray
344
- }
345
- else (beforeCp ++ (" -classpath" :: targetDir.getAbsolutePath :: Nil )).toArray
346
- }
347
-
348
340
def compileWithJavac (fs : Array [String ]) = if (fs.nonEmpty) {
349
341
val fullArgs = Array (
350
342
" javac" ,
@@ -379,7 +371,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
379
371
}
380
372
}
381
373
382
- val allArgs = addOutDir( flags.all)
374
+ val allArgs = flags.withClasspath(targetDir.getAbsolutePath).all
383
375
384
376
// Compile with a try to catch any StackTrace generated by the compiler:
385
377
try {
@@ -400,6 +392,30 @@ trait ParallelTesting extends RunnerOrchestration { self =>
400
392
reporter
401
393
}
402
394
395
+ protected def compileFromTasty (flags0 : TestFlags , suppressErrors : Boolean , targetDir : JFile ): TestReporter = {
396
+ val tastyOutput = new JFile (targetDir.getPath + " _from-tasty" )
397
+ tastyOutput.mkdir()
398
+ val flags = flags0 and (" -d" , tastyOutput.getAbsolutePath)
399
+
400
+ def hasTastyFileToClassName (f : JFile ): String =
401
+ targetDir.toPath.relativize(f.toPath).toString.dropRight(" .hasTasty" .length).replace('/' , '.' )
402
+ val classes = flattenFiles(targetDir).filter(isHasTastyFile).map(hasTastyFileToClassName)
403
+
404
+ val reporter =
405
+ TestReporter .reporter(realStdout, logLevel =
406
+ if (suppressErrors || suppressAllOutput) ERROR + 1 else ERROR )
407
+
408
+ // Compile with a try to catch any StackTrace generated by the compiler:
409
+ try {
410
+ dotc.FromTasty .process(flags.all ++ classes, reporter = reporter)
411
+ }
412
+ catch {
413
+ case NonFatal (ex) => reporter.logStackTrace(ex)
414
+ }
415
+
416
+ reporter
417
+ }
418
+
403
419
private [ParallelTesting ] def executeTestSuite (): this .type = {
404
420
assert(_testSourcesCompleted == 0 , " not allowed to re-use a `CompileRun`" )
405
421
@@ -440,24 +456,30 @@ trait ParallelTesting extends RunnerOrchestration { self =>
440
456
441
457
this
442
458
}
459
+
460
+ /** Returns all files in directory or the file if not a directory */
461
+ private def flattenFiles (f : JFile ): Array [JFile ] =
462
+ if (f.isDirectory) f.listFiles.flatMap(flattenFiles)
463
+ else Array (f)
443
464
}
444
465
445
466
private final class PosTest (testSources : List [TestSource ], times : Int , threadLimit : Option [Int ], suppressAllOutput : Boolean )(implicit summaryReport : SummaryReporting )
446
467
extends Test (testSources, times, threadLimit, suppressAllOutput) {
447
468
protected def encapsulatedCompilation (testSource : TestSource ) = new LoggedRunnable {
448
469
def checkTestSource (): Unit = tryCompile(testSource) {
449
470
testSource match {
450
- case testSource @ JointCompilationSource (_, files, flags, outDir) => {
451
- val reporter = compile(testSource.sourceFiles, flags, false , outDir)
471
+ case testSource @ JointCompilationSource (_, files, flags, outDir, fromTasty) =>
472
+ val reporter =
473
+ if (fromTasty) compileFromTasty(flags, false , outDir)
474
+ else compile(testSource.sourceFiles, flags, false , outDir)
452
475
registerCompletion(reporter.errorCount)
453
476
454
477
if (reporter.compilerCrashed || reporter.errorCount > 0 ) {
455
478
logReporterContents(reporter)
456
479
logBuildInstructions(reporter, testSource, reporter.errorCount, reporter.warningCount)
457
480
}
458
- }
459
481
460
- case testSource @ SeparateCompilationSource (_, dir, flags, outDir) => {
482
+ case testSource @ SeparateCompilationSource (_, dir, flags, outDir) =>
461
483
val reporters = testSource.compilationGroups.map(files => compile(files, flags, false , outDir))
462
484
val compilerCrashed = reporters.exists(_.compilerCrashed)
463
485
val errorCount = reporters.foldLeft(0 ) { (acc, reporter) =>
@@ -475,7 +497,6 @@ trait ParallelTesting extends RunnerOrchestration { self =>
475
497
reporters.foreach(logReporterContents)
476
498
logBuildInstructions(reporters.head, testSource, errorCount, warningCount)
477
499
}
478
- }
479
500
}
480
501
}
481
502
}
@@ -546,7 +567,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
546
567
protected def encapsulatedCompilation (testSource : TestSource ) = new LoggedRunnable {
547
568
def checkTestSource (): Unit = tryCompile(testSource) {
548
569
val (compilerCrashed, errorCount, warningCount, verifier : Function0 [Unit ]) = testSource match {
549
- case testSource @ JointCompilationSource (_, files, flags, outDir) => {
570
+ case testSource @ JointCompilationSource (_, files, flags, outDir, fromTasty ) =>
550
571
val checkFile = files.flatMap { file =>
551
572
if (file.isDirectory) Nil
552
573
else {
@@ -556,17 +577,18 @@ trait ParallelTesting extends RunnerOrchestration { self =>
556
577
else Nil
557
578
}
558
579
}.headOption
559
- val reporter = compile(testSource.sourceFiles, flags, false , outDir)
580
+ val reporter =
581
+ if (fromTasty) compileFromTasty(flags, false , outDir)
582
+ else compile(testSource.sourceFiles, flags, false , outDir)
560
583
561
584
if (reporter.compilerCrashed || reporter.errorCount > 0 ) {
562
585
logReporterContents(reporter)
563
586
logBuildInstructions(reporter, testSource, reporter.errorCount, reporter.warningCount)
564
587
}
565
588
566
589
(reporter.compilerCrashed, reporter.errorCount, reporter.warningCount, () => verifyOutput(checkFile, outDir, testSource, reporter.warningCount))
567
- }
568
590
569
- case testSource @ SeparateCompilationSource (_, dir, flags, outDir) => {
591
+ case testSource @ SeparateCompilationSource (_, dir, flags, outDir) =>
570
592
val checkFile = new JFile (dir.getAbsolutePath.reverse.dropWhile(_ == '/' ).reverse + " .check" )
571
593
val reporters = testSource.compilationGroups.map(compile(_, flags, false , outDir))
572
594
val compilerCrashed = reporters.exists(_.compilerCrashed)
@@ -584,7 +606,6 @@ trait ParallelTesting extends RunnerOrchestration { self =>
584
606
}
585
607
586
608
(compilerCrashed, errorCount, warningCount, () => verifyOutput(Some (checkFile), outDir, testSource, warningCount))
587
- }
588
609
}
589
610
590
611
if (! compilerCrashed && errorCount == 0 ) verifier()
@@ -655,7 +676,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
655
676
}
656
677
657
678
val (compilerCrashed, expectedErrors, actualErrors, hasMissingAnnotations, errorMap) = testSource match {
658
- case testSource @ JointCompilationSource (_, files, flags, outDir) => {
679
+ case testSource @ JointCompilationSource (_, files, flags, outDir, fromTasty ) =>
659
680
val sourceFiles = testSource.sourceFiles
660
681
val (errorMap, expectedErrors) = getErrorMapAndExpectedCount(sourceFiles)
661
682
val reporter = compile(sourceFiles, flags, true , outDir)
@@ -665,7 +686,6 @@ trait ParallelTesting extends RunnerOrchestration { self =>
665
686
logReporterContents(reporter)
666
687
667
688
(reporter.compilerCrashed, expectedErrors, actualErrors, () => getMissingExpectedErrors(errorMap, reporter.errors), errorMap)
668
- }
669
689
670
690
case testSource @ SeparateCompilationSource (_, dir, flags, outDir) => {
671
691
val compilationGroups = testSource.compilationGroups
@@ -941,7 +961,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
941
961
*/
942
962
def copyToTarget (): CompilationTest = new CompilationTest (
943
963
targets.map {
944
- case target @ JointCompilationSource (_, files, _, outDir) =>
964
+ case target @ JointCompilationSource (_, files, _, outDir, _ ) =>
945
965
target.copy(files = files.map(copyToDir(outDir,_)))
946
966
case target @ SeparateCompilationSource (_, dir, _, outDir) =>
947
967
target.copy(dir = copyToDir(outDir, dir))
@@ -1056,6 +1076,30 @@ trait ParallelTesting extends RunnerOrchestration { self =>
1056
1076
new CompilationTest (target)
1057
1077
}
1058
1078
1079
+ /** Compiles a single file from the string path `f` using the supplied flags */
1080
+ def compileTasty (f : String , flags : TestFlags )(implicit testGroup : TestGroup ): (CompilationTest , CompilationTest ) = {
1081
+ val sourceFile = new JFile (f)
1082
+ val parent = sourceFile.getParentFile
1083
+ val outDir =
1084
+ defaultOutputDir + testGroup + " /" +
1085
+ sourceFile.getName.substring(0 , sourceFile.getName.lastIndexOf('.' )) + " /"
1086
+
1087
+ require(
1088
+ sourceFile.exists && ! sourceFile.isDirectory &&
1089
+ (parent ne null ) && parent.exists && parent.isDirectory,
1090
+ s " Source file: $f, didn't exist "
1091
+ )
1092
+ val tastySource = createOutputDirsForFile(sourceFile, parent, outDir)
1093
+ val target = JointCompilationSource (
1094
+ testGroup.name,
1095
+ Array (sourceFile),
1096
+ flags.withClasspath(tastySource.getPath) and " -Yretain-trees" ,
1097
+ tastySource,
1098
+ fromTasty = true
1099
+ )
1100
+ (compileFile(f, flags), new CompilationTest (target))
1101
+ }
1102
+
1059
1103
/** Compiles a directory `f` using the supplied `flags`. This method does
1060
1104
* deep compilation, that is - it compiles all files and subdirectories
1061
1105
* contained within the directory `f`.
@@ -1137,6 +1181,44 @@ trait ParallelTesting extends RunnerOrchestration { self =>
1137
1181
new CompilationTest (targets)
1138
1182
}
1139
1183
1184
+ /** This function compiles the files and folders contained within directory
1185
+ * `f` in a specific way. Once compiled, they are recompiled/run from tasty as sources.
1186
+ *
1187
+ * - Each file is compiled separately as a single compilation run
1188
+ * - Each directory is compiled as a `SeparateCompilationTaret`, in this
1189
+ * target all files are grouped according to the file suffix `_X` where `X`
1190
+ * is a number. These groups are then ordered in ascending order based on
1191
+ * the value of `X` and each group is compiled one after the other.
1192
+ *
1193
+ * For this function to work as expected, we use the same convention for
1194
+ * directory layout as the old partest. That is:
1195
+ *
1196
+ * - Single files can have an associated check-file with the same name (but
1197
+ * with file extension `.check`)
1198
+ * - Directories can have an associated check-file, where the check file has
1199
+ * the same name as the directory (with the file extension `.check`)
1200
+ */
1201
+ def compileTastyInDir (f : String , flags0 : TestFlags )(implicit testGroup : TestGroup ): (CompilationTest , CompilationTest ) = {
1202
+ val outDir = defaultOutputDir + testGroup + " /"
1203
+ val flags = flags0 and " -Yretain-trees"
1204
+ val sourceDir = new JFile (f)
1205
+ checkRequirements(f, sourceDir, outDir)
1206
+
1207
+ val (dirs, files) = compilationTargets(sourceDir)
1208
+
1209
+ val targets =
1210
+ files.map { f =>
1211
+ val classpath = createOutputDirsForFile(f, sourceDir, outDir)
1212
+ JointCompilationSource (testGroup.name, Array (f), flags.withClasspath(classpath.getPath), classpath, fromTasty = true )
1213
+ }
1214
+ // TODO add SeparateCompilationSource from tasty?
1215
+
1216
+ // Create a CompilationTest and let the user decide whether to execute a pos or a neg test
1217
+ val generateClassFiles = compileFilesInDir(f, flags0)
1218
+ (generateClassFiles, new CompilationTest (targets))
1219
+ }
1220
+
1221
+
1140
1222
/** This function behaves similar to `compileFilesInDir` but it ignores
1141
1223
* sub-directories and as such, does **not** perform separate compilation
1142
1224
* tests.
@@ -1165,4 +1247,7 @@ object ParallelTesting {
1165
1247
val name = f.getName
1166
1248
name.endsWith(" .scala" ) || name.endsWith(" .java" )
1167
1249
}
1250
+
1251
+ def isHasTastyFile (f : JFile ): Boolean =
1252
+ f.getName.endsWith(" .hasTasty" )
1168
1253
}
0 commit comments