@@ -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,34 @@ trait ParallelTesting extends RunnerOrchestration { self =>
400
392
reporter
401
393
}
402
394
395
+ protected def compileFromTasty (files0 : Array [JFile ], 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
+ val driver = dotc.FromTasty
409
+
410
+ val allArgs = flags.withClasspath(files0.map(_.getAbsolutePath).mkString(" :" )).all
411
+
412
+ // Compile with a try to catch any StackTrace generated by the compiler:
413
+ try {
414
+ driver.process(allArgs ++ classes, reporter = reporter)
415
+ }
416
+ catch {
417
+ case NonFatal (ex) => reporter.logStackTrace(ex)
418
+ }
419
+
420
+ reporter
421
+ }
422
+
403
423
private [ParallelTesting ] def executeTestSuite (): this .type = {
404
424
assert(_testSourcesCompleted == 0 , " not allowed to re-use a `CompileRun`" )
405
425
@@ -440,24 +460,30 @@ trait ParallelTesting extends RunnerOrchestration { self =>
440
460
441
461
this
442
462
}
463
+
464
+ /** Returns all files in directory or the file if not a directory */
465
+ private def flattenFiles (f : JFile ): Array [JFile ] =
466
+ if (f.isDirectory) f.listFiles.flatMap(flattenFiles)
467
+ else Array (f)
443
468
}
444
469
445
470
private final class PosTest (testSources : List [TestSource ], times : Int , threadLimit : Option [Int ], suppressAllOutput : Boolean )(implicit summaryReport : SummaryReporting )
446
471
extends Test (testSources, times, threadLimit, suppressAllOutput) {
447
472
protected def encapsulatedCompilation (testSource : TestSource ) = new LoggedRunnable {
448
473
def checkTestSource (): Unit = tryCompile(testSource) {
449
474
testSource match {
450
- case testSource @ JointCompilationSource (_, files, flags, outDir) => {
451
- val reporter = compile(testSource.sourceFiles, flags, false , outDir)
475
+ case testSource @ JointCompilationSource (_, files, flags, outDir, fromTasty) =>
476
+ val reporter =
477
+ if (fromTasty) compileFromTasty(testSource.sourceFiles, flags, false , outDir)
478
+ else compile(testSource.sourceFiles, flags, false , outDir)
452
479
registerCompletion(reporter.errorCount)
453
480
454
481
if (reporter.compilerCrashed || reporter.errorCount > 0 ) {
455
482
logReporterContents(reporter)
456
483
logBuildInstructions(reporter, testSource, reporter.errorCount, reporter.warningCount)
457
484
}
458
- }
459
485
460
- case testSource @ SeparateCompilationSource (_, dir, flags, outDir) => {
486
+ case testSource @ SeparateCompilationSource (_, dir, flags, outDir) =>
461
487
val reporters = testSource.compilationGroups.map(files => compile(files, flags, false , outDir))
462
488
val compilerCrashed = reporters.exists(_.compilerCrashed)
463
489
val errorCount = reporters.foldLeft(0 ) { (acc, reporter) =>
@@ -475,7 +501,6 @@ trait ParallelTesting extends RunnerOrchestration { self =>
475
501
reporters.foreach(logReporterContents)
476
502
logBuildInstructions(reporters.head, testSource, errorCount, warningCount)
477
503
}
478
- }
479
504
}
480
505
}
481
506
}
@@ -546,7 +571,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
546
571
protected def encapsulatedCompilation (testSource : TestSource ) = new LoggedRunnable {
547
572
def checkTestSource (): Unit = tryCompile(testSource) {
548
573
val (compilerCrashed, errorCount, warningCount, verifier : Function0 [Unit ]) = testSource match {
549
- case testSource @ JointCompilationSource (_, files, flags, outDir) => {
574
+ case testSource @ JointCompilationSource (_, files, flags, outDir, fromTasty ) =>
550
575
val checkFile = files.flatMap { file =>
551
576
if (file.isDirectory) Nil
552
577
else {
@@ -556,17 +581,18 @@ trait ParallelTesting extends RunnerOrchestration { self =>
556
581
else Nil
557
582
}
558
583
}.headOption
559
- val reporter = compile(testSource.sourceFiles, flags, false , outDir)
584
+ val reporter =
585
+ if (fromTasty) compileFromTasty(testSource.sourceFiles, flags, false , outDir)
586
+ else compile(testSource.sourceFiles, flags, false , outDir)
560
587
561
588
if (reporter.compilerCrashed || reporter.errorCount > 0 ) {
562
589
logReporterContents(reporter)
563
590
logBuildInstructions(reporter, testSource, reporter.errorCount, reporter.warningCount)
564
591
}
565
592
566
593
(reporter.compilerCrashed, reporter.errorCount, reporter.warningCount, () => verifyOutput(checkFile, outDir, testSource, reporter.warningCount))
567
- }
568
594
569
- case testSource @ SeparateCompilationSource (_, dir, flags, outDir) => {
595
+ case testSource @ SeparateCompilationSource (_, dir, flags, outDir) =>
570
596
val checkFile = new JFile (dir.getAbsolutePath.reverse.dropWhile(_ == '/' ).reverse + " .check" )
571
597
val reporters = testSource.compilationGroups.map(compile(_, flags, false , outDir))
572
598
val compilerCrashed = reporters.exists(_.compilerCrashed)
@@ -584,7 +610,6 @@ trait ParallelTesting extends RunnerOrchestration { self =>
584
610
}
585
611
586
612
(compilerCrashed, errorCount, warningCount, () => verifyOutput(Some (checkFile), outDir, testSource, warningCount))
587
- }
588
613
}
589
614
590
615
if (! compilerCrashed && errorCount == 0 ) verifier()
@@ -655,7 +680,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
655
680
}
656
681
657
682
val (compilerCrashed, expectedErrors, actualErrors, hasMissingAnnotations, errorMap) = testSource match {
658
- case testSource @ JointCompilationSource (_, files, flags, outDir) => {
683
+ case testSource @ JointCompilationSource (_, files, flags, outDir, fromTasty ) =>
659
684
val sourceFiles = testSource.sourceFiles
660
685
val (errorMap, expectedErrors) = getErrorMapAndExpectedCount(sourceFiles)
661
686
val reporter = compile(sourceFiles, flags, true , outDir)
@@ -665,7 +690,6 @@ trait ParallelTesting extends RunnerOrchestration { self =>
665
690
logReporterContents(reporter)
666
691
667
692
(reporter.compilerCrashed, expectedErrors, actualErrors, () => getMissingExpectedErrors(errorMap, reporter.errors), errorMap)
668
- }
669
693
670
694
case testSource @ SeparateCompilationSource (_, dir, flags, outDir) => {
671
695
val compilationGroups = testSource.compilationGroups
@@ -941,7 +965,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
941
965
*/
942
966
def copyToTarget (): CompilationTest = new CompilationTest (
943
967
targets.map {
944
- case target @ JointCompilationSource (_, files, _, outDir) =>
968
+ case target @ JointCompilationSource (_, files, _, outDir, _ ) =>
945
969
target.copy(files = files.map(copyToDir(outDir,_)))
946
970
case target @ SeparateCompilationSource (_, dir, _, outDir) =>
947
971
target.copy(dir = copyToDir(outDir, dir))
@@ -1137,6 +1161,44 @@ trait ParallelTesting extends RunnerOrchestration { self =>
1137
1161
new CompilationTest (targets)
1138
1162
}
1139
1163
1164
+ /** This function compiles the files and folders contained within directory
1165
+ * `f` in a specific way. Once compiled, they are recompiled/run from tasty as sources.
1166
+ *
1167
+ * - Each file is compiled separately as a single compilation run
1168
+ * - Each directory is compiled as a `SeparateCompilationTaret`, in this
1169
+ * target all files are grouped according to the file suffix `_X` where `X`
1170
+ * is a number. These groups are then ordered in ascending order based on
1171
+ * the value of `X` and each group is compiled one after the other.
1172
+ *
1173
+ * For this function to work as expected, we use the same convention for
1174
+ * directory layout as the old partest. That is:
1175
+ *
1176
+ * - Single files can have an associated check-file with the same name (but
1177
+ * with file extension `.check`)
1178
+ * - Directories can have an associated check-file, where the check file has
1179
+ * the same name as the directory (with the file extension `.check`)
1180
+ */
1181
+ def compileTastyInDir (f : String , flags0 : TestFlags )(implicit testGroup : TestGroup ): (CompilationTest , CompilationTest ) = {
1182
+ val outDir = defaultOutputDir + testGroup + " /"
1183
+ val flags = flags0 and " -Yretain-trees"
1184
+ val sourceDir = new JFile (f)
1185
+ checkRequirements(f, sourceDir, outDir)
1186
+
1187
+ val (dirs, files) = compilationTargets(sourceDir)
1188
+
1189
+ val targets =
1190
+ files.map { f =>
1191
+ val classpath = createOutputDirsForFile(f, sourceDir, outDir)
1192
+ JointCompilationSource (testGroup.name, Array (f), flags.withClasspath(classpath.getPath), classpath, fromTasty = true )
1193
+ }
1194
+ // TODO add SeparateCompilationSource from tasty?
1195
+
1196
+ // Create a CompilationTest and let the user decide whether to execute a pos or a neg test
1197
+ val generateClassFiles = compileFilesInDir(f, flags0)
1198
+ (generateClassFiles, new CompilationTest (targets))
1199
+ }
1200
+
1201
+
1140
1202
/** This function behaves similar to `compileFilesInDir` but it ignores
1141
1203
* sub-directories and as such, does **not** perform separate compilation
1142
1204
* tests.
@@ -1165,4 +1227,7 @@ object ParallelTesting {
1165
1227
val name = f.getName
1166
1228
name.endsWith(" .scala" ) || name.endsWith(" .java" )
1167
1229
}
1230
+
1231
+ def isHasTastyFile (f : JFile ): Boolean =
1232
+ f.getName.endsWith(" .hasTasty" )
1168
1233
}
0 commit comments