From 15db5f6053badd49aae62a699aa59745288c932d Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Thu, 15 Sep 2016 19:20:53 +0200 Subject: Add smart comment formatting in ConsoleReporter --- .../tools/dotc/reporting/ConsoleReporter.scala | 72 +++++++++++++++++++--- 1 file changed, 65 insertions(+), 7 deletions(-) (limited to 'src/dotty/tools/dotc') diff --git a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala index deb772db5..a681c1552 100644 --- a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala +++ b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala @@ -8,6 +8,7 @@ import core.Contexts._ import Reporter._ import java.io.{ BufferedReader, IOException, PrintWriter } import scala.reflect.internal.util._ +import printing.SyntaxHighlighting._ /** * This class implements a Reporter that displays messages on a text @@ -21,6 +22,7 @@ class ConsoleReporter( /** maximal number of error messages to be printed */ protected def ErrorLimit = 100 +<<<<<<< HEAD def printPos(pos: SourcePosition): Unit = if (pos.exists) { printMessage(pos.lineContent.stripLineEnd) @@ -30,26 +32,82 @@ class ConsoleReporter( printPos(pos.outer) } } +======= + def sourceLine(pos: SourcePosition): (String, Int) = { + val lineNum = s"${pos.line}:" + (lineNum + hl"${pos.lineContent.stripLineEnd}", lineNum.length) + } + + def columnMarker(pos: SourcePosition, offset: Int) = + if (pos.startLine == pos.endLine) { + val whitespace = " " * (pos.column + offset) + val carets = + AnnotationColor + + ("^" * math.max(1, pos.endColumn - pos.startColumn)) + + NoColor + + whitespace + carets + } else { + " " * (pos.column + offset) + AnnotationColor + "^" + NoColor + } + + 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 = + line.replaceAll("\u001B\\[[;\\d]*m", "").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)(implicit ctx: Context) = + if (pos.exists) { + val file = pos.source.file.toString + + val outer = if (pos.outer.exists) { + s"This location is in code that was inlined at ${pos.outer}:\n" + + printStr(pos.outer) + "\n" + "-" * ctx.settings.pageWidth.value + } else "" + + s"${Console.CYAN}$kind: $file " + + "-" * math.max(ctx.settings.pageWidth.value - file.length - kind.length - 1, 0) + + "\n" + outer + NoColor + } + else "" /** Prints the message. */ def printMessage(msg: String): Unit = { writer.print(msg + "\n"); writer.flush() } /** Prints the message with the given position indication. */ - def printMessageAndPos(msg: String, pos: SourcePosition)(implicit ctx: Context): Unit = { - val posStr = if (pos.exists) s"$pos: " else "" - printMessage(posStr + msg) - printPos(pos) + def printMessageAndPos(msg: String, pos: SourcePosition, kind: String = "")(implicit ctx: Context): Unit = { + printMessage(posStr(pos, kind)) + if (pos.exists) { + val (src, offset) = sourceLine(pos) + val marker = columnMarker(pos, offset) + val err = errorMsg(pos, msg, offset) + + printMessage(List(src, marker, err).mkString("\n")) + } else printMessage(msg) } override def doReport(d: Diagnostic)(implicit ctx: Context): Unit = d match { case d: Error => - printMessageAndPos(s"error: ${d.message}", d.pos) + printMessageAndPos(d.message, d.pos, "Error in") if (ctx.settings.prompt.value) displayPrompt() case d: ConditionalWarning if !d.enablingOption.value => case d: MigrationWarning => - printMessageAndPos(s"migration warning: ${d.message}", d.pos) + printMessageAndPos(d.message, d.pos, "Migration Warning in") case d: Warning => - printMessageAndPos(s"warning: ${d.message}", d.pos) + printMessageAndPos(d.message, d.pos, "Warning in") case _ => printMessageAndPos(d.message, d.pos) } -- cgit v1.2.3