@@ -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,81 @@ abstract class CompilerTest extends DottyTest {
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, ctx).errorCount
188
+ val reporter = processor.process(allArgs, ctx)
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 = CompilerCommand .distill(allArgs)(ctx).arguments
205
+ val checkedFiles = byFile.keys.toList.map(_.toString)
206
+ val noPosExpected = noPosErrFiles + checkNoErrorMissing(allFiles.filter(! checkedFiles.contains(_)))
207
+
208
+ // check compiler errors without source position, their number should
209
+ // correspond to all "// nopos-error" markers in any files
210
+ val noPosFound = noPos.foldLeft(0 )(_ + _._2.length)
211
+ assert(noPosFound == noPosExpected,
212
+ s " Wrong # of errors without source position. Expected (all files): $noPosExpected, found (compiler): $noPosFound" )
213
+ }
186
214
}
187
215
216
+ /** For neg tests, check that all errors thrown by compiler have a "// error"
217
+ * on the corresponding line in the source file.
218
+ */
219
+ def checkErrorsInFile (errors : (AbstractFile , List [SourcePosition ])): Int = {
220
+ errors match {
221
+ case (fileName, pos@ (first :: rest)) =>
222
+ val content = first.source.content.mkString
223
+ val (line, rest) = content.span(_ != '\n ' )
224
+ val byLine = scala.collection.mutable.Map (errors._2.groupBy(_.line).toSeq: _* )
225
+
226
+ @ tailrec
227
+ def checkLine (line : String , rest : String , index : Int ): Unit = {
228
+ val expected = countErrors(line)
229
+ byLine.remove(index) match {
230
+ case Some (pos) => checkErrors(fileName.toString, Some (index), expected, pos.length)
231
+ case None => checkErrors(fileName.toString, Some (index), expected, 0 )
232
+ }
233
+ val (newLine, newRest) = rest.span(_ != '\n ' )
234
+ if (! newRest.isEmpty)
235
+ checkLine(newLine, newRest.drop(1 ), index + 1 )
236
+ }
237
+
238
+ checkLine(line, rest.drop(1 ), 0 )
239
+ assert(byLine.isEmpty, " Some compiler errors don't correspond to any line in the source file: " + fileName + " : " + byLine)
240
+ countNoPosErrors(content)
241
+ case (fileName, Nil ) => assert(false , " impossible: empty groupBy value in file: " + fileName); 0
242
+ }
243
+ }
244
+
245
+ def countErrors (s : String ) = " // ?error" .r.findAllIn(s).length
246
+ def countNoPosErrors (s : String ) = " // ?nopos-error" .r.findAllIn(s).length
247
+
248
+ def checkErrors (fileName : String , index : Option [Int ], exp : Int , found : Int ) = {
249
+ val i = index.map({ i => " :" + (i + 1 ) }).getOrElse(" " )
250
+ assert(found == exp, s " Wrong # of errors for $fileName$i. Expected (file): $exp, found (compiler): $found" )
251
+ }
252
+
253
+ def checkNoErrorMissing (files : List [String ]) = files.foldLeft(0 )({ case (sum, fileName) =>
254
+ val content = SFile (fileName).slurp
255
+ checkErrors(fileName, None , countErrors(content), 0 )
256
+ sum + countNoPosErrors(content)
257
+ })
258
+
188
259
// In particular, don't copy flags from scalac tests
189
260
private val extensionsToCopy = scala.collection.immutable.HashSet (" scala" , " java" )
190
261
0 commit comments