@@ -3,9 +3,12 @@ package test
3
3
import dotty .partest .DPConfig
4
4
import dotty .tools .dotc .{Main , Bench , Driver }
5
5
import dotty .tools .dotc .reporting .Reporter
6
+ import dotty .tools .dotc .util .SourcePosition
7
+ import dotty .tools .dotc .config .CompilerCommand
6
8
import scala .collection .mutable .ListBuffer
7
- import scala .reflect .io .{ Path , Directory , File => SFile }
9
+ import scala .reflect .io .{ Path , Directory , File => SFile , AbstractFile }
8
10
import scala .tools .partest .nest .{ FileManager , NestUI }
11
+ import scala .annotation .tailrec
9
12
import java .io .{ RandomAccessFile , File => JFile }
10
13
11
14
import org .junit .Test
@@ -178,13 +181,83 @@ abstract class CompilerTest {
178
181
179
182
// ========== HELPERS =============
180
183
181
- private def compileArgs (args : Array [String ], xerrors : Int = 0 )(implicit defaultOptions : List [String ]): Unit = {
184
+ private def compileArgs (args : Array [String ], xerrors : Int = 0 )
185
+ (implicit defaultOptions : List [String ]): Unit = {
182
186
val allArgs = args ++ defaultOptions
183
187
val processor = if (allArgs.exists(_.startsWith(" #" ))) Bench else Main
184
- val nerrors = processor.process(allArgs).errorCount
188
+ val reporter = processor.process(allArgs)
189
+
190
+ val nerrors = reporter.errorCount
185
191
assert(nerrors == xerrors, s " Wrong # of errors. Expected: $xerrors, found: $nerrors" )
192
+
193
+ // is neg test, check errors occur on right line
194
+ if (xerrors > 0 ) {
195
+ val errorLines = reporter.allErrors.map(_.pos)
196
+ // reporter didn't record as many errors as its errorCount says
197
+ assert(errorLines.length == nerrors, s " Not enough errors recorded. " )
198
+ val (byFile, noPos) = errorLines.groupBy(_.source.file).partition(_._1.toString != " <no source>" )
199
+
200
+ // check the compiler errors that have a source position
201
+ val noPosErrFiles = byFile.foldLeft(0 )(_ + checkErrorsInFile(_))
202
+
203
+ // check that files without compiler errors don't contain error markers
204
+ val allFiles = (allArgs filter {
205
+ case arg => arg.endsWith(" .scala" ) || arg.endsWith(" .java" )
206
+ }).toList
207
+ val checkedFiles = byFile.keys.toList.map(_.toString)
208
+ val noPosExpected = noPosErrFiles + checkNoErrorMissing(allFiles.filter(! checkedFiles.contains(_)))
209
+
210
+ // check compiler errors without source position, their number should
211
+ // correspond to all "// nopos-error" markers in any files
212
+ val noPosFound = noPos.foldLeft(0 )(_ + _._2.length)
213
+ assert(noPosFound == noPosExpected,
214
+ s " Wrong # of errors without source position. Expected (all files): $noPosExpected, found (compiler): $noPosFound" )
215
+ }
186
216
}
187
217
218
+ /** For neg tests, check that all errors thrown by compiler have a "// error"
219
+ * on the corresponding line in the source file.
220
+ */
221
+ def checkErrorsInFile (errors : (AbstractFile , List [SourcePosition ])): Int = {
222
+ errors match {
223
+ case (fileName, pos@ (first :: rest)) =>
224
+ val content = first.source.content.mkString
225
+ val (line, rest) = content.span(_ != '\n ' )
226
+ val byLine = scala.collection.mutable.Map (errors._2.groupBy(_.line).toSeq: _* )
227
+
228
+ @ tailrec
229
+ def checkLine (line : String , rest : String , index : Int ): Unit = {
230
+ val expected = countErrors(line)
231
+ byLine.remove(index) match {
232
+ case Some (pos) => checkErrors(fileName.toString, Some (index), expected, pos.length)
233
+ case None => checkErrors(fileName.toString, Some (index), expected, 0 )
234
+ }
235
+ val (newLine, newRest) = rest.span(_ != '\n ' )
236
+ if (! newRest.isEmpty)
237
+ checkLine(newLine, newRest.drop(1 ), index + 1 )
238
+ }
239
+
240
+ checkLine(line, rest.drop(1 ), 0 )
241
+ assert(byLine.isEmpty, " Some compiler errors don't correspond to any line in the source file: " + fileName + " : " + byLine)
242
+ countNoPosErrors(content)
243
+ case (fileName, Nil ) => assert(false , " impossible: empty groupBy value in file: " + fileName); 0
244
+ }
245
+ }
246
+
247
+ def countErrors (s : String ) = " // ?error" .r.findAllIn(s).length
248
+ def countNoPosErrors (s : String ) = " // ?nopos-error" .r.findAllIn(s).length
249
+
250
+ def checkErrors (fileName : String , index : Option [Int ], exp : Int , found : Int ) = {
251
+ val i = index.map({ i => " :" + (i + 1 ) }).getOrElse(" " )
252
+ assert(found == exp, s " Wrong # of errors for $fileName$i. Expected (file): $exp, found (compiler): $found" )
253
+ }
254
+
255
+ def checkNoErrorMissing (files : List [String ]) = files.foldLeft(0 )({ case (sum, fileName) =>
256
+ val content = SFile (fileName).slurp
257
+ checkErrors(fileName, None , countErrors(content), 0 )
258
+ sum + countNoPosErrors(content)
259
+ })
260
+
188
261
// In particular, don't copy flags from scalac tests
189
262
private val extensionsToCopy = scala.collection.immutable.HashSet (" scala" , " java" )
190
263
0 commit comments