aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Mulder <felix.mulder@gmail.com>2016-11-04 14:23:45 +0100
committerFelix Mulder <felix.mulder@gmail.com>2016-11-04 14:43:31 +0100
commitf9328badfe54f9c1d5c9bf9ab528e5ed14849a88 (patch)
tree260cad265b2f6708e06ec2ac72291e0107d2aea7
parent8ea583671a0dc88a9a8ef59eb4f60d70541adfce (diff)
downloaddotty-f9328badfe54f9c1d5c9bf9ab528e5ed14849a88.tar.gz
dotty-f9328badfe54f9c1d5c9bf9ab528e5ed14849a88.tar.bz2
dotty-f9328badfe54f9c1d5c9bf9ab528e5ed14849a88.zip
Clean up in ConsoleReporter & MessageRendering
-rw-r--r--src/dotty/tools/dotc/reporting/ConsoleReporter.scala35
-rw-r--r--src/dotty/tools/dotc/reporting/MessageRendering.scala48
2 files changed, 51 insertions, 32 deletions
diff --git a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala
index 99a80982f..95f468995 100644
--- a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala
+++ b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala
@@ -2,11 +2,10 @@ package dotty.tools
package dotc
package reporting
-import util.SourcePosition
import core.Contexts._
import java.io.{ BufferedReader, PrintWriter }
import diagnostic.{ Message, MessageContainer }
-import diagnostic.messages._
+import diagnostic.messages.{ Error, Warning, ConditionalWarning }
/**
* This class implements a Reporter that displays messages on a text console
@@ -25,36 +24,29 @@ class ConsoleReporter(
def printMessage(msg: String): Unit = { writer.print(msg + "\n"); writer.flush() }
/** Prints the message with the given position indication. */
- def printMessageAndPos(msg: Message, pos: SourcePosition, diagnosticLevel: String)(implicit ctx: Context): Boolean = {
- printMessage(messageAndPos(msg, pos, diagnosticLevel))
- true
- }
-
- def printExplanation(m: Message)(implicit ctx: Context): Unit = {
- printMessage(explanation(m))
- }
-
- override def doReport(m: MessageContainer)(implicit ctx: Context): Unit = {
+ def doReport(m: MessageContainer)(implicit ctx: Context): Unit = {
val didPrint = m match {
case m: Error =>
- val didPrint = printMessageAndPos(m.contained, m.pos, diagnosticLevel(m))
+ printMessage(messageAndPos(m.contained, m.pos, diagnosticLevel(m)))
if (ctx.settings.prompt.value) displayPrompt()
- didPrint
+ true
case m: ConditionalWarning if !m.enablingOption.value =>
false
case m =>
- printMessageAndPos(m.contained, m.pos, diagnosticLevel(m))
+ printMessage(messageAndPos(m.contained, m.pos, diagnosticLevel(m)))
+ true
}
if (didPrint && ctx.shouldExplain(m))
- printExplanation(m.contained)
+ printMessage(explanation(m.contained))
else if (didPrint && m.contained.explanation.nonEmpty)
printMessage("\nlonger explanation available when compiling with `-explain`")
}
- def displayPrompt(): Unit = {
- writer.print("\na)bort, s)tack, r)esume: ")
- writer.flush()
+ /** Show prompt if `-Xprompt` is passed as a flag to the compiler */
+ def displayPrompt()(implicit ctx: Context): Unit = {
+ printMessage("\na)bort, s)tack, r)esume: ")
+ flush()
if (reader != null) {
val response = reader.read().asInstanceOf[Char].toLower
if (response == 'a' || response == 's') {
@@ -62,11 +54,10 @@ class ConsoleReporter(
if (response == 'a')
sys.exit(1)
}
- writer.print("\n")
- writer.flush()
+ print("\n")
+ flush()
}
}
override def flush()(implicit ctx: Context): Unit = { writer.flush() }
}
-
diff --git a/src/dotty/tools/dotc/reporting/MessageRendering.scala b/src/dotty/tools/dotc/reporting/MessageRendering.scala
index 79632c965..24d583b19 100644
--- a/src/dotty/tools/dotc/reporting/MessageRendering.scala
+++ b/src/dotty/tools/dotc/reporting/MessageRendering.scala
@@ -12,15 +12,30 @@ import util.SourcePosition
import scala.collection.mutable
trait MessageRendering {
+ /** Remove ANSI coloring from `str`, useful for getting real length of
+ * strings
+ *
+ * @return string stripped of ANSI escape codes
+ */
def stripColor(str: String): String =
str.replaceAll("\u001B\\[[;\\d]*m", "")
+ /** When inlining a method call, if there's an error we'd like to get the
+ * outer context and the `pos` at which the call was inlined.
+ *
+ * @return a list of strings with inline locations
+ */
def outer(pos: SourcePosition, prefix: String)(implicit ctx: Context): List[String] =
if (pos.outer.exists) {
s"$prefix| This location is in code that was inlined at ${pos.outer}" ::
outer(pos.outer, prefix)
} else Nil
+ /** Get the sourcelines before and after the position, as well as the offset
+ * for rendering line numbers
+ *
+ * @return (lines before error, lines after error, line numbers offset)
+ */
def sourceLines(pos: SourcePosition)(implicit ctx: Context): (List[String], List[String], Int) = {
var maxLen = Int.MinValue
def render(xs: List[Int]) =
@@ -39,6 +54,7 @@ trait MessageRendering {
(render(before), render(after), maxLen)
}
+ /** The column markers aligned under the error */
def columnMarker(pos: SourcePosition, offset: Int)(implicit ctx: Context): String = {
val prefix = " " * (offset - 1)
val whitespace = " " * pos.startColumn
@@ -51,21 +67,30 @@ trait MessageRendering {
s"$prefix|$whitespace${carets.show}"
}
+ /** The error message (`msg`) aligned under `pos`
+ *
+ * @return aligned error message
+ */
def errorMsg(pos: SourcePosition, msg: String, offset: Int)(implicit ctx: Context): String = {
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)
+ val currPad = math.min(
+ math.max(0, ctx.settings.pageWidth.value - offset - lineLength),
+ offset + pos.startColumn
+ )
- if (padding < minPad) padding
- else minPad
+ math.min(currPad, minPad)
}
msg.lines
- .map { line => " " * (offset - 1) + "|" + (" " * (leastWhitespace - offset)) + line }
+ .map { line => " " * (offset - 1) + "|" + (" " * (leastWhitespace - offset)) + line}
.mkString(sys.props("line.separator"))
}
+ /** The separator between errors containing the source file and error type
+ *
+ * @return separator containing error location and kind
+ */
def posStr(pos: SourcePosition, diagnosticLevel: String, message: Message)(implicit ctx: Context): String =
if (pos.exists) Blue({
val file = pos.source.file.toString
@@ -82,15 +107,19 @@ trait MessageRendering {
("-" * math.max(ctx.settings.pageWidth.value - stripColor(prefix).length, 0))
}).show else ""
+ /** Explanation rendered under "Explanation" header */
def explanation(m: Message)(implicit ctx: Context): String = {
- val sb = new StringBuilder(hl"""|
- |${Blue("Explanation")}
- |${Blue("===========")}""".stripMargin)
+ val sb = new StringBuilder(
+ hl"""|
+ |${Blue("Explanation")}
+ |${Blue("===========")}"""
+ )
sb.append('\n').append(m.explanation)
if (m.explanation.lastOption != Some('\n')) sb.append('\n')
sb.toString
}
+ /** The whole message rendered from `msg` */
def messageAndPos(msg: Message, pos: SourcePosition, diagnosticLevel: String)(implicit ctx: Context): String = {
val sb = mutable.StringBuilder.newBuilder
sb.append(posStr(pos, diagnosticLevel, msg)).append('\n')
@@ -103,7 +132,7 @@ trait MessageRendering {
sb.toString
}
- def diagnosticLevel(cont: MessageContainer): String = {
+ def diagnosticLevel(cont: MessageContainer): String =
cont match {
case m: Error => "Error"
case m: FeatureWarning => "Feature Warning"
@@ -113,5 +142,4 @@ trait MessageRendering {
case m: Warning => "Warning"
case m: Info => "Info"
}
- }
}