@@ -14,13 +14,14 @@ import java.util.concurrent.{TimeUnit, TimeoutException, Executors => JExecutors
1414
1515import scala .collection .mutable
1616import scala .io .{Codec , Source }
17+ import scala .jdk .CollectionConverters .*
1718import scala .util .{Random , Try , Failure => TryFailure , Success => TrySuccess , Using }
1819import scala .util .control .NonFatal
1920import scala .util .matching .Regex
2021import scala .collection .mutable .ListBuffer
2122
2223import dotc .{Compiler , Driver }
23- import dotc .core .Contexts ._
24+ import dotc .core .Contexts .*
2425import dotc .decompiler
2526import dotc .report
2627import dotc .interfaces .Diagnostic .ERROR
@@ -750,17 +751,26 @@ trait ParallelTesting extends RunnerOrchestration { self =>
750751 def compilerCrashed = reporters.exists(_.compilerCrashed)
751752 lazy val (errorMap, expectedErrors) = getErrorMapAndExpectedCount(testSource.sourceFiles.toIndexedSeq)
752753 lazy val actualErrors = reporters.foldLeft(0 )(_ + _.errorCount)
753- def hasMissingAnnotations = getMissingExpectedErrors(errorMap, reporters.iterator.flatMap(_.errors))
754+ lazy val (expected, unexpected) = getMissingExpectedErrors(errorMap, reporters.iterator.flatMap(_.errors))
755+ def hasMissingAnnotations = expected.nonEmpty || unexpected.nonEmpty
754756 def showErrors = " -> following the errors:\n " +
755- reporters.flatMap(_.allErrors.map(e => (e.pos.line + 1 ).toString + " : " + e.message)).mkString(start = " at " , sep = " \n at " , end = " " )
756-
757- if (compilerCrashed) Some (s " Compiler crashed when compiling: ${testSource.title}" )
758- else if (actualErrors == 0 ) Some (s " \n No errors found when compiling neg test $testSource" )
759- else if (expectedErrors == 0 ) Some (s " \n No errors expected/defined in $testSource -- use // error or // nopos-error " )
760- else if (expectedErrors != actualErrors) Some (s " \n Wrong number of errors encountered when compiling $testSource\n expected: $expectedErrors, actual: $actualErrors " + showErrors)
761- else if (hasMissingAnnotations) Some (s " \n Errors found on incorrect row numbers when compiling $testSource\n $showErrors" )
762- else if (! errorMap.isEmpty) Some (s " \n Expected error(s) have {<error position>=<unreported error>}: $errorMap" )
763- else None
757+ reporters.flatMap(_.allErrors.sortBy(_.pos.line).map(e => s " ${e.pos.line + 1 }: ${e.message}" )).mkString(" at " , " \n at " , " " )
758+
759+ Option {
760+ if compilerCrashed then s " Compiler crashed when compiling: ${testSource.title}"
761+ else if actualErrors == 0 then s " \n No errors found when compiling neg test $testSource"
762+ else if expectedErrors == 0 then s " \n No errors expected/defined in $testSource -- use // error or // nopos-error "
763+ else if expectedErrors != actualErrors then
764+ s """ |Wrong number of errors encountered when compiling $testSource
765+ |expected: $expectedErrors, actual: $actualErrors
766+ | ${expected.mkString(" Unfulfilled expectations:\n " , " \n " , " " )}
767+ | ${unexpected.mkString(" Unexpected errors:\n " , " \n " , " " )}
768+ | $showErrors
769+ | """ .stripMargin.trim.linesIterator.mkString(" \n " , " \n " , " " )
770+ else if hasMissingAnnotations then s " \n Errors found on incorrect row numbers when compiling $testSource\n $showErrors"
771+ else if ! errorMap.isEmpty then s " \n Expected error(s) have {<error position>=<unreported error>}: $errorMap"
772+ else null
773+ }
764774 }
765775
766776 override def onSuccess (testSource : TestSource , reporters : Seq [TestReporter ], logger : LoggedRunnable ): Unit =
@@ -783,7 +793,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
783793 source.getLines.zipWithIndex.foreach { case (line, lineNbr) =>
784794 val errors = line.toSeq.sliding(" // error" .length).count(_.unwrap == " // error" )
785795 if (errors > 0 )
786- errorMap.put(s " ${file.getPath}: $lineNbr" , errors)
796+ errorMap.put(s " ${file.getPath}: ${ lineNbr+ 1 } " , errors)
787797
788798 val noposErrors = line.toSeq.sliding(" // nopos-error" .length).count(_.unwrap == " // nopos-error" )
789799 if (noposErrors > 0 ) {
@@ -813,34 +823,32 @@ trait ParallelTesting extends RunnerOrchestration { self =>
813823 (errorMap, expectedErrors)
814824 }
815825
816- def getMissingExpectedErrors (errorMap : HashMap [String , Integer ], reporterErrors : Iterator [Diagnostic ]) = ! reporterErrors.forall { error =>
817- val pos1 = error.pos.nonInlined
818- val key = if (pos1.exists) {
819- def toRelative (path : String ): String = // For some reason, absolute paths leak from the compiler itself...
820- path.split(JFile .separatorChar).dropWhile(_ != " tests" ).mkString(JFile .separator)
821- val fileName = toRelative(pos1.source.file.toString)
822- s " $fileName: ${pos1.line}"
823-
824- } else " nopos"
825-
826- val errors = errorMap.get(key)
827-
828- def missing = { echo(s " Error reported in ${pos1.source}, but no annotation found " ) ; false }
829-
830- if (errors ne null ) {
831- if (errors == 1 ) errorMap.remove(key)
832- else errorMap.put(key, errors - 1 )
833- true
834- }
835- else if key == " nopos" then
836- missing
837- else
838- errorMap.get(" anypos" ) match
839- case null => missing
840- case 1 => errorMap.remove(" anypos" ) ; true
841- case slack => if slack < 1 then missing
842- else errorMap.put(" anypos" , slack - 1 ) ; true
843- }
826+ // return unfulfilled expected errors and unexpected diagnostics
827+ def getMissingExpectedErrors (errorMap : HashMap [String , Integer ], reporterErrors : Iterator [Diagnostic ]): (List [String ], List [String ]) =
828+ val unexpected, unpositioned = ListBuffer .empty[String ]
829+ // For some reason, absolute paths leak from the compiler itself...
830+ def relativize (path : String ): String = path.split(JFile .separatorChar).dropWhile(_ != " tests" ).mkString(JFile .separator)
831+ def seenAt (key : String ): Boolean =
832+ errorMap.get(key) match
833+ case null => false
834+ case 1 => errorMap.remove(key) ; true
835+ case n => errorMap.put(key, n - 1 ) ; true
836+ def sawDiagnostic (d : Diagnostic ): Unit =
837+ d.pos.nonInlined match
838+ case srcpos if srcpos.exists =>
839+ val key = s " ${relativize(srcpos.source.file.toString)}: ${srcpos.line + 1 }"
840+ if ! seenAt(key) then unexpected += key
841+ case srcpos =>
842+ if ! seenAt(" nopos" ) then unpositioned += relativize(srcpos.source.file.toString)
843+
844+ reporterErrors.foreach(sawDiagnostic)
845+
846+ errorMap.get(" anypos" ) match
847+ case n if n == unexpected.size => errorMap.remove(" anypos" ) ; unexpected.clear()
848+ case _ =>
849+
850+ (errorMap.asScala.keys.toList, (unexpected ++ unpositioned).toList)
851+ end getMissingExpectedErrors
844852 }
845853
846854 private final class NoCrashTest (testSources : List [TestSource ], times : Int , threadLimit : Option [Int ], suppressAllOutput : Boolean )(implicit summaryReport : SummaryReporting )
0 commit comments