From eece2fb42c045fed3687795b4627fb70c7b28fed Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 17 Feb 2016 18:20:07 +0100 Subject: [PATCH] Refactor Diagnostic Break it out from Reporter and eliminate all dependencies to Context. This is done so that Diagnostics can be part of a public and minimal compiler API. --- .../dotc/reporting/ConsoleReporter.scala | 5 +- .../tools/dotc/reporting/Diagnostic.scala | 47 +++++++++++++++++++ src/dotty/tools/dotc/reporting/Reporter.scala | 37 +-------------- .../tools/dotc/reporting/StoreReporter.scala | 2 +- .../reporting/UniqueMessagePositions.scala | 1 - .../tools/dotc/typer/ErrorReporting.scala | 10 ++-- 6 files changed, 56 insertions(+), 46 deletions(-) create mode 100644 src/dotty/tools/dotc/reporting/Diagnostic.scala diff --git a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala index 8f1fbf797a63..dcfbd717dc4e 100644 --- a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala +++ b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala @@ -41,7 +41,10 @@ class ConsoleReporter( } override def doReport(d: Diagnostic)(implicit ctx: Context): Boolean = { - val issue = !(d.isSuppressed && hasErrors) + val issue = + !d.isNonSensical || + !hasErrors || // if there are no errors yet, report even if diagnostic is non-sensical + ctx.settings.YshowSuppressedErrors.value if (issue) d match { case d: Error => printMessageAndPos(s"error: ${d.msg}", d.pos) diff --git a/src/dotty/tools/dotc/reporting/Diagnostic.scala b/src/dotty/tools/dotc/reporting/Diagnostic.scala new file mode 100644 index 000000000000..c57be3d26190 --- /dev/null +++ b/src/dotty/tools/dotc/reporting/Diagnostic.scala @@ -0,0 +1,47 @@ +package dotty.tools +package dotc +package reporting + +import util.SourcePosition + +object Diagnostic { + + // Error levels + val ERROR = 2 + val WARNING = 1 + val INFO = 0 + + val nonSensicalStartTag = "" + val nonSensicalEndTag = "" +} + +class Diagnostic(msgFn: => String, val pos: SourcePosition, val level: Int) extends Exception { + import Diagnostic._ + private var myMsg: String = null + private var myIsNonSensical: Boolean = false + + /** The message to report */ + def msg: String = { + if (myMsg == null) { + myMsg = msgFn + if (myMsg.contains(nonSensicalStartTag)) { + myIsNonSensical = true + // myMsg might be composed of several d"..." invocations -> nested nonsensical tags possible + myMsg = myMsg.replaceAllLiterally(nonSensicalStartTag, "").replaceAllLiterally(nonSensicalEndTag, "") + } + } + myMsg + } + + /** A message is non-sensical if it contains references to tags. + * Such tags are inserted by the error diagnostic framework if a message + * contains references to internally generated error types. Normally we + * want to suppress error messages referring to types like this because + * they look weird and are normally follow-up errors to something that + * was diagnosed before. + */ + def isNonSensical = { msg; myIsNonSensical } + + override def toString = s"$getClass at $pos: $msg" + override def getMessage() = msg +} diff --git a/src/dotty/tools/dotc/reporting/Reporter.scala b/src/dotty/tools/dotc/reporting/Reporter.scala index 5ed7360da3a4..4914f03b7cbd 100644 --- a/src/dotty/tools/dotc/reporting/Reporter.scala +++ b/src/dotty/tools/dotc/reporting/Reporter.scala @@ -12,44 +12,9 @@ import config.Printers import java.lang.System.currentTimeMillis import typer.ErrorReporting.DiagnosticString import typer.Mode +import Diagnostic.{ERROR, WARNING, INFO} object Reporter { - - private val ERROR = 2 - private val WARNING = 1 - private val INFO = 0 - - class Diagnostic(msgFn: => String, val pos: SourcePosition, val level: Int) extends Exception { - import DiagnosticString._ - - private var myMsg: String = null - private var myIsNonSensical: Boolean = false - - /** The message to report */ - def msg: String = { - if (myMsg == null) { - myMsg = msgFn - if (myMsg.contains(nonSensicalStartTag)) { - myIsNonSensical = true - // myMsg might be composed of several d"..." invocations -> nested nonsensical tags possible - myMsg = myMsg.replaceAllLiterally(nonSensicalStartTag, "").replaceAllLiterally(nonSensicalEndTag, "") - } - } - myMsg - } - - /** Report in current reporter */ - def report(implicit ctx: Context) = ctx.reporter.report(this) - - def isNonSensical = { msg; myIsNonSensical } - def isSuppressed(implicit ctx: Context): Boolean = !ctx.settings.YshowSuppressedErrors.value && isNonSensical - - override def toString = s"$getClass at $pos: $msg" - override def getMessage() = msg - - def checkingStr: String = msgFn - } - class Error(msgFn: => String, pos: SourcePosition) extends Diagnostic(msgFn, pos, ERROR) class Warning(msgFn: => String, pos: SourcePosition) extends Diagnostic(msgFn, pos, WARNING) class Info(msgFn: => String, pos: SourcePosition) extends Diagnostic(msgFn, pos, INFO) diff --git a/src/dotty/tools/dotc/reporting/StoreReporter.scala b/src/dotty/tools/dotc/reporting/StoreReporter.scala index 8209839eb063..53f03f1fe8e7 100644 --- a/src/dotty/tools/dotc/reporting/StoreReporter.scala +++ b/src/dotty/tools/dotc/reporting/StoreReporter.scala @@ -4,7 +4,7 @@ package reporting import core.Contexts.Context import collection.mutable -import Reporter.{Diagnostic, Error, Warning} +import Reporter.{Error, Warning} import config.Printers._ /** diff --git a/src/dotty/tools/dotc/reporting/UniqueMessagePositions.scala b/src/dotty/tools/dotc/reporting/UniqueMessagePositions.scala index c1f240a23940..32554e6b6b16 100644 --- a/src/dotty/tools/dotc/reporting/UniqueMessagePositions.scala +++ b/src/dotty/tools/dotc/reporting/UniqueMessagePositions.scala @@ -4,7 +4,6 @@ package reporting import scala.collection.mutable import util.{SourcePosition, SourceFile} -import Reporter.Diagnostic import core.Contexts.Context /** diff --git a/src/dotty/tools/dotc/typer/ErrorReporting.scala b/src/dotty/tools/dotc/typer/ErrorReporting.scala index b3089c99ca03..e093026122f4 100644 --- a/src/dotty/tools/dotc/typer/ErrorReporting.scala +++ b/src/dotty/tools/dotc/typer/ErrorReporting.scala @@ -8,6 +8,7 @@ import Trees._ import Types._, ProtoTypes._, Contexts._, Decorators._, Denotations._, Symbols._ import Applications._, Implicits._, Flags._ import util.Positions._ +import reporting.Diagnostic import printing.Showable import printing.Disambiguation.disambiguated @@ -139,13 +140,8 @@ object ErrorReporting { } val s = new StringInterpolators(sc).i(args : _*) - if (args.forall(isSensical(_))) s else nonSensicalStartTag + s + nonSensicalEndTag + if (args.forall(isSensical(_))) s + else Diagnostic.nonSensicalStartTag + s + Diagnostic.nonSensicalEndTag } } - - object DiagnosticString { - final val nonSensicalStartTag = "" - final val nonSensicalEndTag = "" - } - }