diff --git a/compiler/src/dotty/tools/dotc/reporting/ConsoleReporter.scala b/compiler/src/dotty/tools/dotc/reporting/ConsoleReporter.scala index 0609dd8c643c..f872968006b0 100644 --- a/compiler/src/dotty/tools/dotc/reporting/ConsoleReporter.scala +++ b/compiler/src/dotty/tools/dotc/reporting/ConsoleReporter.scala @@ -12,27 +12,30 @@ import Diagnostic.{ Error, ConditionalWarning } class ConsoleReporter( reader: BufferedReader = Console.in, writer: PrintWriter = new PrintWriter(Console.err, true) -) extends AbstractReporter { +) extends ConsoleReporter.AbstractConsoleReporter { + override def printMessage(msg: String): Unit = { writer.print(msg + "\n"); writer.flush() } + override def flush()(using Context): Unit = writer.flush() - import Diagnostic._ - - /** Prints the message. */ - def printMessage(msg: String): Unit = { writer.print(msg + "\n"); writer.flush() } - - /** Prints the message with the given position indication. */ - def doReport(dia: Diagnostic)(using Context): Unit = { + override def doReport(dia: Diagnostic)(using Context): Unit = { + super.doReport(dia) dia match - case dia: Error => - printMessage(messageAndPos(dia)) - if (ctx.settings.Xprompt.value) Reporter.displayPrompt(reader, writer) - case dia => - printMessage(messageAndPos(dia)) - - if shouldExplain(dia) then - printMessage(explanation(dia.msg)) - else if dia.msg.canExplain then - printMessage("\nlonger explanation available when compiling with `-explain`") + case dia: Error if ctx.settings.Xprompt.value => Reporter.displayPrompt(reader, writer) + case _ => } +} + +object ConsoleReporter { + abstract class AbstractConsoleReporter extends AbstractReporter { + /** Prints the message. */ + def printMessage(msg: String): Unit - override def flush()(using Context): Unit = { writer.flush() } + /** Prints the message with the given position indication. */ + def doReport(dia: Diagnostic)(using Context): Unit = { + printMessage(messageAndPos(dia)) + if Diagnostic.shouldExplain(dia) then + printMessage(explanation(dia.msg)) + else if dia.msg.canExplain then + printMessage("\nlonger explanation available when compiling with `-explain`") + } + } } diff --git a/compiler/src/dotty/tools/repl/ReplDriver.scala b/compiler/src/dotty/tools/repl/ReplDriver.scala index b2a8f9afb88e..40876b260394 100644 --- a/compiler/src/dotty/tools/repl/ReplDriver.scala +++ b/compiler/src/dotty/tools/repl/ReplDriver.scala @@ -1,6 +1,6 @@ package dotty.tools.repl -import java.io.{File => JFile, PrintStream, PrintWriter} +import java.io.{File => JFile, PrintStream} import java.nio.charset.StandardCharsets import dotty.tools.dotc.ast.Trees._ @@ -425,12 +425,12 @@ class ReplDriver(settings: Array[String], state } - /** Like ConsoleReporter, but without file paths or real -Xprompt'ing */ - private object ReplConsoleReporter extends ConsoleReporter( - reader = null, // this short-circuits the -Xprompt display from waiting for an input - writer = new PrintWriter(out, /* autoFlush = */ true), // write to out, not Console.err - ) { + /** Like ConsoleReporter, but without file paths, -Xprompt displaying, + * and using a PrintStream rather than a PrintWriter so messages aren't re-encoded. */ + private object ReplConsoleReporter extends ConsoleReporter.AbstractConsoleReporter { override def posFileStr(pos: SourcePosition) = "" // omit file paths + override def printMessage(msg: String): Unit = out.println(msg) + override def flush()(using Context): Unit = out.flush() } /** Print warnings & errors using ReplConsoleReporter, and info straight to out */ diff --git a/compiler/test-resources/pending/repl/errmsgs b/compiler/test-resources/repl/errmsgs similarity index 96% rename from compiler/test-resources/pending/repl/errmsgs rename to compiler/test-resources/repl/errmsgs index f1207276df6d..14e9d44fa0b8 100644 --- a/compiler/test-resources/pending/repl/errmsgs +++ b/compiler/test-resources/repl/errmsgs @@ -51,19 +51,19 @@ scala> abstract class C { type T; val x: T; val s: Unit = { type T = String; var 1 | abstract class C { type T; val x: T; val s: Unit = { type T = String; var y: T = x; locally { def f() = { type T = Int; val z: T = y }; f() } }; } | ^ |Found: (C.this.x : C.this.T) - |Required: T? + |Required: T² | |where: T is a type in class C - | T? is a type in the initializer of value s which is an alias of String + | T² is a type in the initializer of value s which is an alias of String longer explanation available when compiling with `-explain` -- [E007] Type Mismatch Error: ------------------------------------------------- 1 | abstract class C { type T; val x: T; val s: Unit = { type T = String; var y: T = x; locally { def f() = { type T = Int; val z: T = y }; f() } }; } | ^ |Found: (y : T) - |Required: T? + |Required: T² | |where: T is a type in the initializer of value s which is an alias of String - | T? is a type in method f which is an alias of Int + | T² is a type in method f which is an alias of Int longer explanation available when compiling with `-explain` 2 errors found scala> class Foo() { def bar: Int = 1 }; val foo = new Foo(); foo.barr