From 00a3dbdbacb37f4d4f95e572828d7cb5793ea74b Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 24 Jan 2022 18:06:04 +0100 Subject: [PATCH 1/6] Output other compiler errors Fixes #14303 --- .../dotty/tools/vulpix/ParallelTesting.scala | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala index 0b649943f494..b0ba9b2c041d 100644 --- a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala +++ b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala @@ -505,19 +505,28 @@ trait ParallelTesting extends RunnerOrchestration { self => } private def parseErrors(errorsText: String, compilerVersion: String) = - val errorPattern = """.*Error: (.*\.scala):(\d+):(\d+).*""".r - errorsText.linesIterator.toSeq.collect { - case errorPattern(filePath, line, column) => - val lineNum = line.toInt - val columnNum = column.toInt - val abstractFile = AbstractFile.getFile(filePath) - val sourceFile = SourceFile(abstractFile, Codec.UTF8) - val offset = sourceFile.lineToOffset(lineNum - 1) + columnNum - 1 - val span = Spans.Span(offset) - val sourcePos = SourcePosition(sourceFile, span) - - Diagnostic.Error(s"Compilation of $filePath with Scala $compilerVersion failed at line: $line, column: $column. Full error output:\n\n$errorsText\n", sourcePos) - } + val errorPattern = """^.*Error: (.*\.scala):(\d+):(\d+).*""".r + val summaryPattern = """\d+ (?:warning|error)s? found""".r + val indent = " " + var diagnostics = List.empty[Diagnostic.Error] + for line <- errorsText.linesIterator do + line match + case error @ errorPattern(filePath, line, column) => + val lineNum = line.toInt + val columnNum = column.toInt + val abstractFile = AbstractFile.getFile(filePath) + val sourceFile = SourceFile(abstractFile, Codec.UTF8) + val offset = sourceFile.lineToOffset(lineNum - 1) + columnNum - 1 + val span = Spans.Span(offset) + val sourcePos = SourcePosition(sourceFile, span) + diagnostics ::= Diagnostic.Error(s"Compilation of $filePath with Scala $compilerVersion failed at line: $line, column: $column. Full error output:\n\n$indent$error\n", sourcePos) + case summaryPattern() => // Ignored + case errorLine => + diagnostics match + case head :: tail => + diagnostics = Diagnostic.Error(s"${head.msg.rawMessage}$indent$errorLine\n", head.pos) :: tail + case Nil => + diagnostics.reverse protected def compileWithOtherCompiler(compiler: String, files: Array[JFile], flags: TestFlags, targetDir: JFile): TestReporter = val compilerDir = getCompiler(compiler).toString @@ -531,9 +540,9 @@ trait ParallelTesting extends RunnerOrchestration { self => val flags1 = flags.copy(defaultClassPath = substituteClasspath(flags.defaultClassPath)) .withClasspath(targetDir.getPath) .and("-d", targetDir.getPath) + .and("-pagewidth", "80") - val dummyStream = new PrintStream(new ByteArrayOutputStream()) - val reporter = TestReporter.reporter(dummyStream, ERROR) + val reporter = TestReporter.reporter(System.out, ERROR) val command = Array(compilerDir + "/bin/scalac") ++ flags1.all ++ files.map(_.getPath) val process = Runtime.getRuntime.exec(command) From c99694f8e2b7f467c8e1003ae26a0d7718af32cd Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 25 Jan 2022 09:57:24 +0100 Subject: [PATCH 2/6] Make errors from other compilers simpler to read --- .../dotty/tools/vulpix/ParallelTesting.scala | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala index b0ba9b2c041d..a07c8cf97455 100644 --- a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala +++ b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala @@ -504,11 +504,19 @@ trait ParallelTesting extends RunnerOrchestration { self => reporter } - private def parseErrors(errorsText: String, compilerVersion: String) = + private def parseErrors(errorsText: String, compilerVersion: String, pageWidth: Int) = val errorPattern = """^.*Error: (.*\.scala):(\d+):(\d+).*""".r val summaryPattern = """\d+ (?:warning|error)s? found""".r val indent = " " var diagnostics = List.empty[Diagnostic.Error] + def barLine(start: Boolean) = s"$indent${if start then "╭" else "╰"}${"┄" * pageWidth}${if start then "╮" else "╯"}\n" + def errorLine(line: String) = s"$indent┆${String.format(s"%-${pageWidth}s", stripAnsi(line))}┆\n" + def stripAnsi(str: String): String = str.replaceAll("\u001b\\[\\d+m", "") + def addToLast(str: String): Unit = + diagnostics match + case head :: tail => + diagnostics = Diagnostic.Error(s"${head.msg.rawMessage}$str", head.pos) :: tail + case Nil => for line <- errorsText.linesIterator do line match case error @ errorPattern(filePath, line, column) => @@ -519,13 +527,11 @@ trait ParallelTesting extends RunnerOrchestration { self => val offset = sourceFile.lineToOffset(lineNum - 1) + columnNum - 1 val span = Spans.Span(offset) val sourcePos = SourcePosition(sourceFile, span) - diagnostics ::= Diagnostic.Error(s"Compilation of $filePath with Scala $compilerVersion failed at line: $line, column: $column. Full error output:\n\n$indent$error\n", sourcePos) + addToLast(barLine(start = false)) + diagnostics ::= Diagnostic.Error(s"Compilation of $filePath with Scala $compilerVersion failed at line: $line, column: $column.\nFull error output:\n${barLine(start = true)}${errorLine(error)}", sourcePos) case summaryPattern() => // Ignored - case errorLine => - diagnostics match - case head :: tail => - diagnostics = Diagnostic.Error(s"${head.msg.rawMessage}$indent$errorLine\n", head.pos) :: tail - case Nil => + case line => addToLast(errorLine(line)) + addToLast(barLine(start = false)) diagnostics.reverse protected def compileWithOtherCompiler(compiler: String, files: Array[JFile], flags: TestFlags, targetDir: JFile): TestReporter = @@ -537,10 +543,11 @@ trait ParallelTesting extends RunnerOrchestration { self => else o }.mkString(JFile.pathSeparator) + val pageWidth = 80 val flags1 = flags.copy(defaultClassPath = substituteClasspath(flags.defaultClassPath)) .withClasspath(targetDir.getPath) .and("-d", targetDir.getPath) - .and("-pagewidth", "80") + .and("-pagewidth", pageWidth.toString) val reporter = TestReporter.reporter(System.out, ERROR) @@ -548,7 +555,7 @@ trait ParallelTesting extends RunnerOrchestration { self => val process = Runtime.getRuntime.exec(command) val errorsText = Source.fromInputStream(process.getErrorStream).mkString if process.waitFor() != 0 then - val diagnostics = parseErrors(errorsText, compiler) + val diagnostics = parseErrors(errorsText, compiler, pageWidth) diagnostics.foreach { diag => val context = (new ContextBase).initialCtx reporter.report(diag)(using context) From c5d770f2be097bb347eddc5d116f22a9ca71a70d Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 25 Jan 2022 11:39:49 +0100 Subject: [PATCH 3/6] Do not report warnings --- compiler/test/dotty/tools/vulpix/ParallelTesting.scala | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala index a07c8cf97455..948a1a3b16e7 100644 --- a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala +++ b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala @@ -506,6 +506,7 @@ trait ParallelTesting extends RunnerOrchestration { self => private def parseErrors(errorsText: String, compilerVersion: String, pageWidth: Int) = val errorPattern = """^.*Error: (.*\.scala):(\d+):(\d+).*""".r + val warnPattern = """^.*Warning: (.*\.scala):(\d+):(\d+).*""".r val summaryPattern = """\d+ (?:warning|error)s? found""".r val indent = " " var diagnostics = List.empty[Diagnostic.Error] @@ -517,9 +518,13 @@ trait ParallelTesting extends RunnerOrchestration { self => case head :: tail => diagnostics = Diagnostic.Error(s"${head.msg.rawMessage}$str", head.pos) :: tail case Nil => + var inError = false for line <- errorsText.linesIterator do line match + case error @ warnPattern(filePath, line, column) => + inError = false case error @ errorPattern(filePath, line, column) => + inError = true val lineNum = line.toInt val columnNum = column.toInt val abstractFile = AbstractFile.getFile(filePath) @@ -530,7 +535,8 @@ trait ParallelTesting extends RunnerOrchestration { self => addToLast(barLine(start = false)) diagnostics ::= Diagnostic.Error(s"Compilation of $filePath with Scala $compilerVersion failed at line: $line, column: $column.\nFull error output:\n${barLine(start = true)}${errorLine(error)}", sourcePos) case summaryPattern() => // Ignored - case line => addToLast(errorLine(line)) + case line if inError => addToLast(errorLine(line)) + case _ => addToLast(barLine(start = false)) diagnostics.reverse From 9dd77f51a98e6bcca827421fa4bd05700c799365 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 25 Jan 2022 11:51:07 +0100 Subject: [PATCH 4/6] Do not harcode other compile -pagewidth --- compiler/test/dotty/tools/vulpix/ParallelTesting.scala | 2 +- compiler/test/dotty/tools/vulpix/TestConfiguration.scala | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala index 948a1a3b16e7..f6d8d418576f 100644 --- a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala +++ b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala @@ -549,7 +549,7 @@ trait ParallelTesting extends RunnerOrchestration { self => else o }.mkString(JFile.pathSeparator) - val pageWidth = 80 + val pageWidth = TestConfiguration.pageWidth - 20 val flags1 = flags.copy(defaultClassPath = substituteClasspath(flags.defaultClassPath)) .withClasspath(targetDir.getPath) .and("-d", targetDir.getPath) diff --git a/compiler/test/dotty/tools/vulpix/TestConfiguration.scala b/compiler/test/dotty/tools/vulpix/TestConfiguration.scala index caa7bc911633..b43dcbdd6046 100644 --- a/compiler/test/dotty/tools/vulpix/TestConfiguration.scala +++ b/compiler/test/dotty/tools/vulpix/TestConfiguration.scala @@ -6,8 +6,10 @@ import java.io.File object TestConfiguration { + val pageWidth = 120 + val noCheckOptions = Array( - "-pagewidth", "120", + "-pagewidth", pageWidth.toString, "-color:never", "-Xtarget", defaultTarget ) From a61fec544741d19e6cbf927a97c9371b570a045f Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 25 Jan 2022 12:01:56 +0100 Subject: [PATCH 5/6] Properly report errors Based on `compileFromTasty` reporter --- compiler/test/dotty/tools/vulpix/ParallelTesting.scala | 3 ++- tests/neg/i14303/A_1_c3.0.0.scala | 5 +++++ tests/neg/i14303/B_2.scala | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 tests/neg/i14303/A_1_c3.0.0.scala create mode 100644 tests/neg/i14303/B_2.scala diff --git a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala index f6d8d418576f..242228290805 100644 --- a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala +++ b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala @@ -555,7 +555,8 @@ trait ParallelTesting extends RunnerOrchestration { self => .and("-d", targetDir.getPath) .and("-pagewidth", pageWidth.toString) - val reporter = TestReporter.reporter(System.out, ERROR) + val reporter = TestReporter.reporter(realStdout, logLevel = + if (suppressErrors || suppressAllOutput) ERROR + 1 else ERROR) val command = Array(compilerDir + "/bin/scalac") ++ flags1.all ++ files.map(_.getPath) val process = Runtime.getRuntime.exec(command) diff --git a/tests/neg/i14303/A_1_c3.0.0.scala b/tests/neg/i14303/A_1_c3.0.0.scala new file mode 100644 index 000000000000..4e1d7cc57472 --- /dev/null +++ b/tests/neg/i14303/A_1_c3.0.0.scala @@ -0,0 +1,5 @@ +def a: Int = { + 3 + 4 +} +def f: Int = match // error // error diff --git a/tests/neg/i14303/B_2.scala b/tests/neg/i14303/B_2.scala new file mode 100644 index 000000000000..39441cd7c630 --- /dev/null +++ b/tests/neg/i14303/B_2.scala @@ -0,0 +1 @@ +def test() = f // error \ No newline at end of file From 8b2faa5c60cd536d32a966cc7327697a533af0ef Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 25 Jan 2022 13:10:25 +0100 Subject: [PATCH 6/6] Show broken source file errors --- compiler/test/dotty/tools/vulpix/ParallelTesting.scala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala index 242228290805..2f32e4eff341 100644 --- a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala +++ b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala @@ -27,7 +27,7 @@ import dotc.interfaces.Diagnostic.ERROR import dotc.reporting.{Reporter, TestReporter} import dotc.reporting.Diagnostic import dotc.config.Config -import dotc.util.{DiffUtil, SourceFile, SourcePosition, Spans} +import dotc.util.{DiffUtil, SourceFile, SourcePosition, Spans, NoSourcePosition} import io.AbstractFile import dotty.tools.vulpix.TestConfiguration.defaultOptions @@ -506,6 +506,7 @@ trait ParallelTesting extends RunnerOrchestration { self => private def parseErrors(errorsText: String, compilerVersion: String, pageWidth: Int) = val errorPattern = """^.*Error: (.*\.scala):(\d+):(\d+).*""".r + val brokenClassPattern = """^class file (.*) is broken.*""".r val warnPattern = """^.*Warning: (.*\.scala):(\d+):(\d+).*""".r val summaryPattern = """\d+ (?:warning|error)s? found""".r val indent = " " @@ -534,6 +535,9 @@ trait ParallelTesting extends RunnerOrchestration { self => val sourcePos = SourcePosition(sourceFile, span) addToLast(barLine(start = false)) diagnostics ::= Diagnostic.Error(s"Compilation of $filePath with Scala $compilerVersion failed at line: $line, column: $column.\nFull error output:\n${barLine(start = true)}${errorLine(error)}", sourcePos) + case error @ brokenClassPattern(filePath) => + inError = true + diagnostics ::= Diagnostic.Error(s"$error\nFull error output:\n${barLine(start = true)}${errorLine(error)}", NoSourcePosition) case summaryPattern() => // Ignored case line if inError => addToLast(errorLine(line)) case _ =>