aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/reporting/Reporter.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-05-04 13:42:45 +0200
committerSamuel Gruetter <samuel.gruetter@epfl.ch>2014-05-20 13:37:35 +0200
commit94ceb9895a539b05fd81c8abe040c276178b5507 (patch)
tree84992aee9920f62e4ffbf62529b32cffd2c3b505 /src/dotty/tools/dotc/reporting/Reporter.scala
parent1b32071acef5c7c2c08e21ee577c7cc709876ffa (diff)
downloaddotty-94ceb9895a539b05fd81c8abe040c276178b5507.tar.gz
dotty-94ceb9895a539b05fd81c8abe040c276178b5507.tar.bz2
dotty-94ceb9895a539b05fd81c8abe040c276178b5507.zip
Reporter refactoring
Refactored reporters to increase clarity and to pave the way for having Diagnostics subclasses.
Diffstat (limited to 'src/dotty/tools/dotc/reporting/Reporter.scala')
-rw-r--r--src/dotty/tools/dotc/reporting/Reporter.scala166
1 files changed, 70 insertions, 96 deletions
diff --git a/src/dotty/tools/dotc/reporting/Reporter.scala b/src/dotty/tools/dotc/reporting/Reporter.scala
index b0404c6b3..82b0a1158 100644
--- a/src/dotty/tools/dotc/reporting/Reporter.scala
+++ b/src/dotty/tools/dotc/reporting/Reporter.scala
@@ -14,10 +14,17 @@ import typer.ErrorReporting.DiagnosticString
object Reporter {
- class Diagnostic(msgFn: => String, val pos: SourcePosition, val severity: Severity) extends Exception {
+ 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
@@ -29,48 +36,32 @@ object Reporter {
}
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"$severity at $pos: $msg"
- override def getMessage() = msg
-
- def promotedSeverity(implicit ctx: Context): Severity =
- if (isConditionalWarning(severity) && enablingOption(severity).value) WARNING
- else severity
- }
- def Diagnostic(msgFn: => String, pos: SourcePosition, severity: Severity) =
- new Diagnostic(msgFn, pos, severity)
-
- class Severity(val level: Int) extends AnyVal {
- override def toString = this match {
- case VerboseINFO => "VerboseINFO"
- case INFO => "INFO"
- case DeprecationWARNING => "DeprecationWARNING"
- case UncheckedWARNING => "UncheckedWARNING"
- case FeatureWARNING => "FeatureWARNING"
- case WARNING => "WARNING"
- case ERROR => "ERROR"
- }
+ override def toString = s"$getClass at $pos: $msg"
+ override def getMessage() = msg
}
- final val VerboseINFO = new Severity(0)
- final val INFO = new Severity(1)
- final val DeprecationWARNING = new Severity(2)
- final val UncheckedWARNING = new Severity(3)
- final val FeatureWARNING = new Severity(4)
- final val WARNING = new Severity(5)
- final val ERROR = new Severity(6)
-
- def isConditionalWarning(s: Severity) =
- DeprecationWARNING.level <= s.level && s.level <= FeatureWARNING.level
+ 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)
- val conditionalWarnings = List(DeprecationWARNING, UncheckedWARNING, FeatureWARNING)
-
- private def enablingOption(warning: Severity)(implicit ctx: Context) = warning match {
- case DeprecationWARNING => ctx.settings.deprecation
- case UncheckedWARNING => ctx.settings.unchecked
- case FeatureWARNING => ctx.settings.feature
+ abstract class ConditionalWarning(msgFn: => String, pos: SourcePosition) extends Warning(msgFn, pos) {
+ def enablingOption(implicit ctx: Context): Setting[Boolean]
+ }
+ class FeatureWarning(msgFn: => String, pos: SourcePosition) extends ConditionalWarning(msgFn, pos) {
+ def enablingOption(implicit ctx: Context) = ctx.settings.feature
+ }
+ class UncheckedWarning(msgFn: => String, pos: SourcePosition) extends ConditionalWarning(msgFn, pos) {
+ def enablingOption(implicit ctx: Context) = ctx.settings.unchecked
+ }
+ class DeprecationWarning(msgFn: => String, pos: SourcePosition) extends ConditionalWarning(msgFn, pos) {
+ def enablingOption(implicit ctx: Context) = ctx.settings.deprecation
}
}
@@ -80,30 +71,30 @@ trait Reporting { this: Context =>
/** For sending messages that are printed only if -verbose is set */
def inform(msg: => String, pos: SourcePosition = NoSourcePosition): Unit =
- reporter.report(Diagnostic(msg, pos, VerboseINFO))
+ if (this.settings.verbose.value) echo(msg, pos)
def echo(msg: => String, pos: SourcePosition = NoSourcePosition): Unit =
- reporter.report(Diagnostic(msg, pos, INFO))
+ reporter.report(new Info(msg, pos))
def deprecationWarning(msg: => String, pos: SourcePosition = NoSourcePosition): Unit =
- reporter.report(Diagnostic(msg, pos, DeprecationWARNING))
+ reporter.report(new DeprecationWarning(msg, pos))
def uncheckedWarning(msg: => String, pos: SourcePosition = NoSourcePosition): Unit =
- reporter.report(Diagnostic(msg, pos, UncheckedWARNING))
+ reporter.report(new UncheckedWarning(msg, pos))
def featureWarning(msg: => String, pos: SourcePosition = NoSourcePosition): Unit =
- reporter.report(Diagnostic(msg, pos, FeatureWARNING))
+ reporter.report(new FeatureWarning(msg, pos))
def warning(msg: => String, pos: SourcePosition = NoSourcePosition): Unit =
- reporter.report(Diagnostic(msg, pos, WARNING))
+ reporter.report(new Warning(msg, pos))
def error(msg: => String, pos: SourcePosition = NoSourcePosition): Unit = {
// println("*** ERROR: " + msg) // !!! DEBUG
- reporter.report(Diagnostic(msg, pos, ERROR))
+ reporter.report(new Error(msg, pos))
}
def incompleteInputError(msg: String, pos: SourcePosition = NoSourcePosition)(implicit ctx: Context): Unit =
- reporter.incomplete(Diagnostic(msg, pos, ERROR))(ctx)
+ reporter.incomplete(new Error(msg, pos))(ctx)
/** Log msg if current phase or its precedessor is mentioned in
* settings.log.
@@ -209,71 +200,54 @@ abstract class Reporter {
finally incompleteHandler = saved
}
- protected def isHidden(d: Diagnostic)(implicit ctx: Context) = d.promotedSeverity match {
- case VerboseINFO => !ctx.settings.verbose.value
- case DeprecationWARNING | UncheckedWARNING | FeatureWARNING => true
- case _ => false
- }
+ var errorCount = 0
+ var warningCount = 0
+ def hasErrors = errorCount > 0
+ def hasWarnings = warningCount > 0
- val count = new Array[Int](ERROR.level + 1)
+ val unreportedWarnings = new mutable.HashMap[String, Int] {
+ override def default(key: String) = 0
+ }
- def report(d: Diagnostic)(implicit ctx: Context): Unit =
- if (!isHidden(d)) {
- doReport(d)
- if (!d.isSuppressed) count(d.promotedSeverity.level) += 1
+ def report(d: Diagnostic)(implicit ctx: Context): Unit = if (!isHidden(d)) {
+ doReport(d)
+ if (!d.isSuppressed) d match {
+ case d: ConditionalWarning if !d.enablingOption.value => unreportedWarnings(d.enablingOption.name) += 1
+ case d: Warning => warningCount += 1
+ case d: Error => errorCount += 1
+ case d: Info => // nothing to do here
+ // match error if d is something else
}
+ }
def incomplete(d: Diagnostic)(implicit ctx: Context): Unit =
incompleteHandler(d)(ctx)
- def hasErrors = count(ERROR.level) > 0
- def hasWarnings = count(WARNING.level) > 0
- def errorCounts: Any = count.clone
-
- def wasSilent[T](counts: Any): Boolean = {
- val prevCount = counts.asInstanceOf[Array[Int]]
- var i = 0
- while (i < count.length) {
- if (prevCount(i) != count(i)) return false
- i += 1
- }
- true
+ /** Print a summary */
+ def printSummary(implicit ctx: Context): Unit = {
+ if (warningCount > 0) ctx.echo(countString(warningCount, "warning") + " found")
+ if (errorCount > 0) ctx.echo(countString(errorCount, "error") + " found")
+ for ((settingName, count) <- unreportedWarnings)
+ ctx.echo(s"there were $count ${settingName.tail} warning(s); re-run with $settingName for details")
}
/** Returns a string meaning "n elements". */
- private def countElementsAsString(n: Int, elements: String): String =
- n match {
- case 0 => "no " + elements + "s"
- case 1 => "one " + elements
- case 2 => "two " + elements + "s"
- case 3 => "three " + elements + "s"
- case 4 => "four " + elements + "s"
- case _ => n + " " + elements + "s"
- }
-
- protected def label(severity: Severity): String = severity match {
- case ERROR => "error: "
- case WARNING => "warning: "
- case _ => ""
+ private def countString(n: Int, elements: String): String = n match {
+ case 0 => "no " + elements + "s"
+ case 1 => "one " + elements
+ case 2 => "two " + elements + "s"
+ case 3 => "three " + elements + "s"
+ case 4 => "four " + elements + "s"
+ case _ => n + " " + elements + "s"
}
- protected def countString(severity: Severity) = {
- assert(severity.level >= WARNING.level)
- countElementsAsString(count(severity.level), label(severity).dropRight(2))
- }
+ /** Should this diagnostic not be reported at all? */
+ def isHidden(d: Diagnostic)(implicit ctx: Context): Boolean = false
- def printSummary(implicit ctx: Context): Unit = {
- if (count(WARNING.level) > 0) ctx.echo(countString(WARNING) + " found")
- if ( count(ERROR.level) > 0) ctx.echo(countString(ERROR ) + " found")
- for (cwarning <- conditionalWarnings) {
- val unreported = count(cwarning.level)
- if (unreported > 0) {
- val what = enablingOption(cwarning).name.tail
- ctx.warning(s"there were $unreported $what warning(s); re-run with -$what for details")
- }
- }
- }
+ /** Does this reporter contain not yet reported errors or warnings? */
+ def hasPending: Boolean = false
+ /** Issue all error messages in this reporter to next outer one, or make sure they are written. */
def flush()(implicit ctx: Context): Unit = {}
}