@@ -40,8 +40,8 @@ import dotty.tools.vulpix.TestConfiguration.defaultOptions
4040 * using this, you should be running your JUnit tests **sequentially**, as the
4141 * test suite itself runs with a high level of concurrency.
4242 */
43- trait ParallelTesting extends RunnerOrchestration { self =>
44- import ParallelTesting ._
43+ trait ParallelTesting extends RunnerOrchestration :
44+ import ParallelTesting .*
4545
4646 /** If the running environment supports an interactive terminal, each `Test`
4747 * will be run with a progress bar and real time feedback
@@ -935,29 +935,33 @@ trait ParallelTesting extends RunnerOrchestration { self =>
935935 (errorMap, expectedErrors)
936936 end getErrorMapAndExpectedCount
937937
938- // return unfulfilled expected errors and unexpected diagnostics
938+ // return unfulfilled expected errors and unexpected diagnostics.
939+ // the errorMap of expected errors is drained and returned as unfulfilled.
940+ // a diagnostic at EOF after NL is recorded at the preceding line,
941+ // to obviate `anypos-error` in that case.
939942 def getMissingExpectedErrors (errorMap : HashMap [String , Integer ], reporterErrors : Iterator [Diagnostic ]): (List [String ], List [String ]) =
940943 val unexpected, unpositioned = ListBuffer .empty[String ]
941944 // For some reason, absolute paths leak from the compiler itself...
942945 def relativize (path : String ): String = path.split(JFile .separatorChar).dropWhile(_ != " tests" ).mkString(JFile .separator)
943946 def seenAt (key : String ): Boolean =
944947 errorMap.get(key) match
945- case null => false
946- case 1 => errorMap.remove(key); true
947- case n => errorMap.put(key, n - 1 ); true
948+ case null => false
949+ case 1 => errorMap.remove(key); true
950+ case n => errorMap.put(key, n - 1 ); true
948951 def sawDiagnostic (d : Diagnostic ): Unit =
949- d.pos.nonInlined match
950- case srcpos if srcpos.exists =>
951- val key = s " ${relativize(srcpos.source.file.toString)}: ${srcpos.line + 1 }"
952- if ! seenAt(key) then unexpected += key
953- case srcpos =>
954- if ! seenAt(" nopos" ) then unpositioned += relativize(srcpos.source.file.toString)
952+ val srcpos = d.pos.nonInlined.adjustedAtEOF
953+ val relatively = relativize(srcpos.source.file.toString)
954+ if srcpos.exists then
955+ val key = s " ${relatively}: ${srcpos.line + 1 }"
956+ if ! seenAt(key) then unexpected += key
957+ else
958+ if ! seenAt(" nopos" ) then unpositioned += relatively
955959
956960 reporterErrors.foreach(sawDiagnostic)
957961
958- errorMap.get(" anypos" ) match
959- case n if n == unexpected.size => errorMap.remove(" anypos" ) ; unexpected.clear( )
960- case _ =>
962+ if errorMap.get(" anypos" ) == unexpected.size then
963+ errorMap.remove(" anypos" )
964+ unexpected.clear()
961965
962966 (errorMap.asScala.keys.toList, (unexpected ++ unpositioned).toList)
963967 end getMissingExpectedErrors
@@ -1570,9 +1574,9 @@ trait ParallelTesting extends RunnerOrchestration { self =>
15701574 flags.options.sliding(2 ).collectFirst {
15711575 case Array (" -encoding" , encoding) => Charset .forName(encoding)
15721576 }.getOrElse(StandardCharsets .UTF_8 )
1573- }
15741577
1575- object ParallelTesting {
1578+
1579+ object ParallelTesting :
15761580
15771581 def defaultOutputDir : String = " out" + JFile .separator
15781582
@@ -1584,4 +1588,14 @@ object ParallelTesting {
15841588 def isTastyFile (f : JFile ): Boolean =
15851589 f.getName.endsWith(" .tasty" )
15861590
1587- }
1591+ extension (pos : SourcePosition )
1592+ private def adjustedAtEOF : SourcePosition =
1593+ if pos.span.isSynthetic
1594+ && pos.span.isZeroExtent
1595+ && pos.span.exists
1596+ && pos.span.start == pos.source.length
1597+ && pos.source(pos.span.start - 1 ) == '\n '
1598+ then
1599+ pos.withSpan(pos.span.shift(- 1 ))
1600+ else
1601+ pos
0 commit comments