aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/reporting/ConsoleReporter.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc/reporting/ConsoleReporter.scala')
-rw-r--r--src/dotty/tools/dotc/reporting/ConsoleReporter.scala86
1 files changed, 64 insertions, 22 deletions
diff --git a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala
index 92eea9fa9..a5979bd5b 100644
--- a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala
+++ b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala
@@ -8,13 +8,14 @@ import core.Contexts._
import Reporter._
import java.io.{ BufferedReader, IOException, PrintWriter }
import scala.reflect.internal.util._
-import diagnostic.Message
-import diagnostic.MessageContainer
+import printing.SyntaxHighlighting._
+import printing.Highlighting._
+import diagnostic.{ Message, MessageContainer }
import diagnostic.messages._
/**
- * This class implements a Reporter that displays messages on a text
- * console.
+ * This class implements a more Fancy version (with colors!) of the regular
+ * `ConsoleReporter`
*/
class ConsoleReporter(
reader: BufferedReader = Console.in,
@@ -26,32 +27,72 @@ class ConsoleReporter(
/** maximal number of error messages to be printed */
protected def ErrorLimit = 100
- def printSourceLine(pos: SourcePosition) =
- printMessage(pos.lineContent.stripLineEnd)
-
- def printColumnMarker(pos: SourcePosition) =
- if (pos.exists) { printMessage(" " * pos.column + "^") }
-
/** Prints the message. */
def printMessage(msg: String): Unit = { writer.print(msg + "\n"); writer.flush() }
+ def stripColor(str: String): String =
+ str.replaceAll("\u001B\\[[;\\d]*m", "")
+
+ def sourceLine(pos: SourcePosition)(implicit ctx: Context): (String, Int) = {
+ val lineNum = s"${pos.line}:"
+ (lineNum + hl"${pos.lineContent.stripLineEnd}", lineNum.length)
+ }
+
+ def columnMarker(pos: SourcePosition, offset: Int)(implicit ctx: Context) =
+ if (pos.startLine == pos.endLine) {
+ val whitespace = " " * (pos.column + offset)
+ val carets =
+ Red("^" * math.max(1, pos.endColumn - pos.startColumn))
+
+ whitespace + carets.show
+ } else {
+ Red(" " * (pos.column + offset) + "^").show
+ }
+
+ def errorMsg(pos: SourcePosition, msg: String, offset: Int)(implicit ctx: Context) = {
+ var hasLongLines = false
+ val leastWhitespace = msg.lines.foldLeft(Int.MaxValue) { (minPad, line) =>
+ val lineLength = stripColor(line).length
+ val padding =
+ math.min(math.max(0, ctx.settings.pageWidth.value - offset - lineLength), offset + pos.startColumn)
+
+ if (padding < minPad) padding
+ else minPad
+ }
+
+ msg
+ .lines
+ .map { line => " " * leastWhitespace + line }
+ .mkString(sys.props("line.separator"))
+ }
+
+ def posStr(pos: SourcePosition, kind: String, errorId: String)(implicit ctx: Context) =
+ if (pos.exists) Blue({
+ val file = pos.source.file.toString
+ val errId = if (errorId != "") s"[$errorId] " else ""
+ val prefix = s"-- ${errId}${kind}: $file "
+ prefix +
+ ("-" * math.max(ctx.settings.pageWidth.value - stripColor(prefix).length, 0))
+ }).show else ""
+
/** Prints the message with the given position indication. */
def printMessageAndPos(msg: Message, pos: SourcePosition, kind: String)(implicit ctx: Context): Unit = {
- val posStr = if (pos.exists) s"$pos: " else ""
- printMessage(s"${posStr}${kind}: ${msg.msg}")
+ printMessage(posStr(pos, kind, msg.errorId))
if (pos.exists) {
- printSourceLine(pos)
- printColumnMarker(pos)
- }
+ val (src, offset) = sourceLine(pos)
+ val marker = columnMarker(pos, offset)
+ val err = errorMsg(pos, msg.msg, offset)
+
+ printMessage(List(src, marker, err).mkString("\n"))
+ } else printMessage(msg.msg)
}
- def printExplanation(m: Message)(implicit ctx: Context): Unit =
- printMessage(
- s"""|
- |Explanation
- |===========
- |${m.explanation}""".stripMargin
- )
+ def printExplanation(m: Message)(implicit ctx: Context): Unit = {
+ printMessage(hl"""|
+ |${Blue("Explanation")}
+ |${Blue("===========")}""".stripMargin)
+ printMessage(m.explanation)
+ }
override def doReport(m: MessageContainer)(implicit ctx: Context): Unit = {
m match {
@@ -87,3 +128,4 @@ class ConsoleReporter(
override def flush()(implicit ctx: Context): Unit = { writer.flush() }
}
+