From 30b54109e3f535b417249057c2a548808082e06b Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Fri, 16 Sep 2016 22:07:36 +0200 Subject: Factor out explanation header to Reporter --- .../tools/dotc/reporting/ConsoleReporter.scala | 36 +++++++++++++++------- .../dotc/reporting/FancyConsoleReporter.scala | 31 ++++++++++++++++--- src/dotty/tools/dotc/reporting/Reporter.scala | 12 ++------ .../tools/dotc/reporting/diagnostic/Message.scala | 10 ++++++ .../dotc/reporting/diagnostic/MessageCreator.scala | 10 ------ .../tools/dotc/reporting/diagnostic/syntax.scala | 4 +-- .../tools/dotc/reporting/diagnostic/tpe.scala | 16 +++++++--- 7 files changed, 77 insertions(+), 42 deletions(-) (limited to 'src/dotty/tools/dotc/reporting') diff --git a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala index 3a4f60aeb..a00813328 100644 --- a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala +++ b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala @@ -20,6 +20,8 @@ class ConsoleReporter( writer: PrintWriter = new PrintWriter(Console.err, true)) extends Reporter with UniqueMessagePositions with HideNonSensicalMessages { + import Message._ + /** maximal number of error messages to be printed */ protected def ErrorLimit = 100 @@ -42,17 +44,29 @@ class ConsoleReporter( } } - override def doReport(m: Message)(implicit ctx: Context): Unit = m match { - case m: Error => - printMessageAndPos(m.message, m.pos, m.kind) - if (ctx.settings.prompt.value) displayPrompt() - case m: ConditionalWarning if !m.enablingOption.value => - case m: MigrationWarning => - printMessageAndPos(m.message, m.pos, m.kind) - case m: Warning => - printMessageAndPos(m.message, m.pos, m.kind) - case _ => - printMessageAndPos(m.message, m.pos, m.kind) + def printExplanation(m: Message): Unit = + printMessage( + s"""| + |Explanation + |=========== + |${m.explanation}""".stripMargin + ) + + override def doReport(m: Message)(implicit ctx: Context): Unit = { + m match { + case m: Error => + printMessageAndPos(m.message, m.pos, m.kind) + if (ctx.settings.prompt.value) displayPrompt() + case m: ConditionalWarning if !m.enablingOption.value => + case m: MigrationWarning => + printMessageAndPos(m.message, m.pos, m.kind) + case m: Warning => + printMessageAndPos(m.message, m.pos, m.kind) + case _ => + printMessageAndPos(m.message, m.pos, m.kind) + } + + if (ctx.shouldExplain(m)) printExplanation(m) } def displayPrompt(): Unit = { diff --git a/src/dotty/tools/dotc/reporting/FancyConsoleReporter.scala b/src/dotty/tools/dotc/reporting/FancyConsoleReporter.scala index 80f15a4b0..3fc9ab473 100644 --- a/src/dotty/tools/dotc/reporting/FancyConsoleReporter.scala +++ b/src/dotty/tools/dotc/reporting/FancyConsoleReporter.scala @@ -9,6 +9,8 @@ import Reporter._ import java.io.{ BufferedReader, IOException, PrintWriter } import scala.reflect.internal.util._ import printing.SyntaxHighlighting._ +import printing.Highlighting._ +import diagnostic.Message /** * This class implements a more Fancy version (with colors!) of the regular @@ -56,7 +58,7 @@ class FancyConsoleReporter( } def posStr(pos: SourcePosition, kind: String)(implicit ctx: Context) = - if (pos.exists) { + if (pos.exists) Blue({ val file = pos.source.file.toString val outer = if (pos.outer.exists) { @@ -64,12 +66,11 @@ class FancyConsoleReporter( printStr(pos.outer) + "\n" + "-" * ctx.settings.pageWidth.value } else "" - val prefix = s"${Console.CYAN}-- $kind: $file " + val prefix = s"-- $kind: $file " prefix + ("-" * math.max(ctx.settings.pageWidth.value - prefix.replaceAll("\u001B\\[[;\\d]*m", "").length, 0)) + - "\n" + outer + NoColor - } - else "" + "\n" + outer + }).toString else "" /** Prints the message with the given position indication. */ override def printMessageAndPos(msg: String, pos: SourcePosition, kind: String = "")(implicit ctx: Context): Unit = { @@ -82,4 +83,24 @@ class FancyConsoleReporter( printMessage(List(src, marker, err).mkString("\n")) } else printMessage(msg) } + + override def printExplanation(m: Message): Unit = + printMessage( + s"""| + |${Blue("Explanation")} + |${Blue("===========")} + |${m.explanation}""".stripMargin + ) + + + override def summary: String = { + val b = new mutable.ListBuffer[String] + if (warningCount > 0) + b += countString(warningCount, Yellow("warning")) + " found" + if (errorCount > 0) + b += countString(errorCount, Red("error")) + " found" + for ((settingName, count) <- unreportedWarnings) + b += s"there were $count ${settingName.tail} ${Yellow("warning(s)")}; re-run with $settingName for details" + b.mkString("\n") + } } diff --git a/src/dotty/tools/dotc/reporting/Reporter.scala b/src/dotty/tools/dotc/reporting/Reporter.scala index 5c3dcccb7..fe226b284 100644 --- a/src/dotty/tools/dotc/reporting/Reporter.scala +++ b/src/dotty/tools/dotc/reporting/Reporter.scala @@ -75,11 +75,8 @@ trait Reporting { this: Context => def warning(msg: => String, pos: SourcePosition = NoSourcePosition): Unit = reporter.report(new Warning(msg, pos)) - def explainWarning(msg: => MessageCreator, pos: SourcePosition = NoSourcePosition): Unit = { + def explainWarning(msg: => MessageCreator, pos: SourcePosition = NoSourcePosition): Unit = reporter.report(msg.warning(pos)) - if (this.shouldExplain(msg)) - reporter.report(new Info(msg.explanation, NoSourcePosition)) - } def strictWarning(msg: => String, pos: SourcePosition = NoSourcePosition): Unit = if (this.settings.strict.value) error(msg, pos) @@ -90,11 +87,8 @@ trait Reporting { this: Context => reporter.report(new Error(msg, pos)) } - def explainError(msg: => MessageCreator, pos: SourcePosition = NoSourcePosition): Unit = { + def explainError(msg: => MessageCreator, pos: SourcePosition = NoSourcePosition): Unit = reporter.report(msg.error(pos)) - if (this.shouldExplain(msg)) - reporter.report(new Info(msg.explanation, NoSourcePosition)) - } def errorOrMigrationWarning(msg: => String, pos: SourcePosition = NoSourcePosition): Unit = if (ctx.scala2Mode) migrationWarning(msg, pos) else error(msg, pos) @@ -271,7 +265,7 @@ abstract class Reporter extends interfaces.ReporterResult { } /** Returns a string meaning "n elements". */ - private def countString(n: Int, elements: String): String = n match { + protected def countString(n: Int, elements: String): String = n match { case 0 => "no " + elements + "s" case 1 => "one " + elements case 2 => "two " + elements + "s" diff --git a/src/dotty/tools/dotc/reporting/diagnostic/Message.scala b/src/dotty/tools/dotc/reporting/diagnostic/Message.scala index d7cfa2e2b..b3c19820f 100644 --- a/src/dotty/tools/dotc/reporting/diagnostic/Message.scala +++ b/src/dotty/tools/dotc/reporting/diagnostic/Message.scala @@ -11,6 +11,16 @@ import java.util.Optional object Message { val nonSensicalStartTag = "" val nonSensicalEndTag = "" + + implicit class MessageContext(val c: Context) extends AnyVal { + def shouldExplain(msg: Message): Boolean = { + implicit val ctx: Context = c + msg.explanation match { + case "" => false + case _ => ctx.settings.explain.value + } + } + } } class Message( diff --git a/src/dotty/tools/dotc/reporting/diagnostic/MessageCreator.scala b/src/dotty/tools/dotc/reporting/diagnostic/MessageCreator.scala index d74099f4f..4be325b63 100644 --- a/src/dotty/tools/dotc/reporting/diagnostic/MessageCreator.scala +++ b/src/dotty/tools/dotc/reporting/diagnostic/MessageCreator.scala @@ -7,16 +7,6 @@ import util.{SourcePosition, NoSourcePosition} import core.Contexts.Context object MessageCreator { - implicit class DiagnosticContext(val c: Context) extends AnyVal { - def shouldExplain(msg: MessageCreator): Boolean = { - implicit val ctx: Context = c - msg match { - case NoExplanation(_) => false - case _ => ctx.settings.explain.value - } - } - } - implicit def toNoExplanation(str: String) = new NoExplanation(str) } diff --git a/src/dotty/tools/dotc/reporting/diagnostic/syntax.scala b/src/dotty/tools/dotc/reporting/diagnostic/syntax.scala index 675cacbed..b9a662c7d 100644 --- a/src/dotty/tools/dotc/reporting/diagnostic/syntax.scala +++ b/src/dotty/tools/dotc/reporting/diagnostic/syntax.scala @@ -29,9 +29,7 @@ object syntax { | // perform your cleanup here! |}""".stripMargin - hl"""|Explanation: - |============ - |A ${"try"} expression should be followed by some mechanism to handle any exceptions + hl"""|A ${"try"} expression should be followed by some mechanism to handle any exceptions |thrown. Typically a ${"catch"} expression follows the ${"try"} and pattern matches |on any expected exceptions. For example: | diff --git a/src/dotty/tools/dotc/reporting/diagnostic/tpe.scala b/src/dotty/tools/dotc/reporting/diagnostic/tpe.scala index 4aa24c440..ee221f80d 100644 --- a/src/dotty/tools/dotc/reporting/diagnostic/tpe.scala +++ b/src/dotty/tools/dotc/reporting/diagnostic/tpe.scala @@ -4,7 +4,7 @@ package reporting package diagnostic import dotc.core._ -import Contexts.Context, Decorators._, Symbols._ +import Contexts.Context, Decorators._, Symbols._, Names._ import dotc.printing.SyntaxHighlighting._ import util.{SourcePosition, NoSourcePosition} @@ -35,13 +35,21 @@ object tpe { val caseDef = s"case $pat$guard => $body" - hl"""|Explanation - |=========== - |For each ${"case"} bound variable names have to be unique. In: + hl"""|For each ${"case"} bound variable names have to be unique. In: | |$caseDef | |`${bind.name}` is not unique. Rename one of the bound variables!""".stripMargin } } + + class MissingIdent(tree: untpd.Ident, treeKind: String, name: Name)(implicit ctx: Context) extends MessageCreator { + val kind = "Missing identifier" + val msg = em"not found: $treeKind$name" + + val explanation = { + hl"""|An identifier for `${name.show}` is missing. This means that something + |has either been misspelt or you're forgetting an import""".stripMargin + } + } } -- cgit v1.2.3