Skip to content

Commit 8ecca50

Browse files
committed
Merge pull request #1123 from smarter/refactor/doReport
ConsoleReporter: handling of non-sensical messages is now reusable
2 parents 11bd355 + 03486df commit 8ecca50

File tree

9 files changed

+91
-72
lines changed

9 files changed

+91
-72
lines changed

src/dotty/tools/dotc/reporting/ConsoleReporter.scala

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import scala.reflect.internal.util._
1616
class ConsoleReporter(
1717
reader: BufferedReader = Console.in,
1818
writer: PrintWriter = new PrintWriter(Console.err, true))
19-
extends Reporter with UniqueMessagePositions {
19+
extends Reporter with UniqueMessagePositions with HideNonSensicalMessages {
2020

2121
/** maximal number of error messages to be printed */
2222
protected def ErrorLimit = 100
@@ -40,21 +40,17 @@ class ConsoleReporter(
4040
}
4141
}
4242

43-
override def doReport(d: Diagnostic)(implicit ctx: Context): Boolean = {
44-
val issue = !(d.isSuppressed && hasErrors)
45-
if (issue) d match {
46-
case d: Error =>
47-
printMessageAndPos(s"error: ${d.msg}", d.pos)
48-
if (ctx.settings.prompt.value) displayPrompt()
49-
case d: ConditionalWarning if !d.enablingOption.value =>
50-
case d: MigrationWarning =>
51-
printMessageAndPos(s"migration warning: ${d.msg}", d.pos)
52-
case d: Warning =>
53-
printMessageAndPos(s"warning: ${d.msg}", d.pos)
54-
case _ =>
55-
printMessageAndPos(d.msg, d.pos)
56-
}
57-
issue
43+
override def doReport(d: Diagnostic)(implicit ctx: Context): Unit = d match {
44+
case d: Error =>
45+
printMessageAndPos(s"error: ${d.msg}", d.pos)
46+
if (ctx.settings.prompt.value) displayPrompt()
47+
case d: ConditionalWarning if !d.enablingOption.value =>
48+
case d: MigrationWarning =>
49+
printMessageAndPos(s"migration warning: ${d.msg}", d.pos)
50+
case d: Warning =>
51+
printMessageAndPos(s"warning: ${d.msg}", d.pos)
52+
case _ =>
53+
printMessageAndPos(d.msg, d.pos)
5854
}
5955

6056
def displayPrompt(): Unit = {
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package dotty.tools
2+
package dotc
3+
package reporting
4+
5+
import util.SourcePosition
6+
7+
object Diagnostic {
8+
9+
// Error levels
10+
val ERROR = 2
11+
val WARNING = 1
12+
val INFO = 0
13+
14+
val nonSensicalStartTag = "<nonsensical>"
15+
val nonSensicalEndTag = "</nonsensical>"
16+
}
17+
18+
class Diagnostic(msgFn: => String, val pos: SourcePosition, val level: Int) extends Exception {
19+
import Diagnostic._
20+
private var myMsg: String = null
21+
private var myIsNonSensical: Boolean = false
22+
23+
/** The message to report */
24+
def msg: String = {
25+
if (myMsg == null) {
26+
myMsg = msgFn
27+
if (myMsg.contains(nonSensicalStartTag)) {
28+
myIsNonSensical = true
29+
// myMsg might be composed of several d"..." invocations -> nested nonsensical tags possible
30+
myMsg = myMsg.replaceAllLiterally(nonSensicalStartTag, "").replaceAllLiterally(nonSensicalEndTag, "")
31+
}
32+
}
33+
myMsg
34+
}
35+
36+
/** A message is non-sensical if it contains references to <nonsensical> tags.
37+
* Such tags are inserted by the error diagnostic framework if a message
38+
* contains references to internally generated error types. Normally we
39+
* want to suppress error messages referring to types like this because
40+
* they look weird and are normally follow-up errors to something that
41+
* was diagnosed before.
42+
*/
43+
def isNonSensical = { msg; myIsNonSensical }
44+
45+
override def toString = s"$getClass at $pos: $msg"
46+
override def getMessage() = msg
47+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package dotty.tools
2+
package dotc
3+
package reporting
4+
5+
import core.Contexts.Context
6+
7+
/**
8+
* This trait implements `isHidden` so that we avoid reporting non-sensical messages.
9+
*/
10+
trait HideNonSensicalMessages extends Reporter {
11+
/** Hides non-sensical messages, unless we haven't reported any error yet or
12+
* `-Yshow-suppressed-errors` is set.
13+
*/
14+
override def isHidden(d: Diagnostic)(implicit ctx: Context): Boolean =
15+
super.isHidden(d) || {
16+
d.isNonSensical &&
17+
hasErrors && // if there are no errors yet, report even if diagnostic is non-sensical
18+
!ctx.settings.YshowSuppressedErrors.value
19+
}
20+
}

src/dotty/tools/dotc/reporting/Reporter.scala

Lines changed: 6 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -10,46 +10,10 @@ import collection.mutable
1010
import config.Settings.Setting
1111
import config.Printers
1212
import java.lang.System.currentTimeMillis
13-
import typer.ErrorReporting.DiagnosticString
1413
import typer.Mode
14+
import Diagnostic.{ERROR, WARNING, INFO}
1515

1616
object Reporter {
17-
18-
private val ERROR = 2
19-
private val WARNING = 1
20-
private val INFO = 0
21-
22-
class Diagnostic(msgFn: => String, val pos: SourcePosition, val level: Int) extends Exception {
23-
import DiagnosticString._
24-
25-
private var myMsg: String = null
26-
private var myIsNonSensical: Boolean = false
27-
28-
/** The message to report */
29-
def msg: String = {
30-
if (myMsg == null) {
31-
myMsg = msgFn
32-
if (myMsg.contains(nonSensicalStartTag)) {
33-
myIsNonSensical = true
34-
// myMsg might be composed of several d"..." invocations -> nested nonsensical tags possible
35-
myMsg = myMsg.replaceAllLiterally(nonSensicalStartTag, "").replaceAllLiterally(nonSensicalEndTag, "")
36-
}
37-
}
38-
myMsg
39-
}
40-
41-
/** Report in current reporter */
42-
def report(implicit ctx: Context) = ctx.reporter.report(this)
43-
44-
def isNonSensical = { msg; myIsNonSensical }
45-
def isSuppressed(implicit ctx: Context): Boolean = !ctx.settings.YshowSuppressedErrors.value && isNonSensical
46-
47-
override def toString = s"$getClass at $pos: $msg"
48-
override def getMessage() = msg
49-
50-
def checkingStr: String = msgFn
51-
}
52-
5317
class Error(msgFn: => String, pos: SourcePosition) extends Diagnostic(msgFn, pos, ERROR)
5418
class Warning(msgFn: => String, pos: SourcePosition) extends Diagnostic(msgFn, pos, WARNING)
5519
class Info(msgFn: => String, pos: SourcePosition) extends Diagnostic(msgFn, pos, INFO)
@@ -195,10 +159,8 @@ trait Reporting { this: Context =>
195159
*/
196160
abstract class Reporter {
197161

198-
/** Report a diagnostic, unless it is suppressed because it is nonsensical
199-
* @return a diagnostic was reported.
200-
*/
201-
def doReport(d: Diagnostic)(implicit ctx: Context): Boolean
162+
/** Report a diagnostic */
163+
def doReport(d: Diagnostic)(implicit ctx: Context): Unit
202164

203165
/** Whether very long lines can be truncated. This exists so important
204166
* debugging information (like printing the classpath) is not rendered
@@ -239,7 +201,8 @@ abstract class Reporter {
239201
}
240202

241203
def report(d: Diagnostic)(implicit ctx: Context): Unit =
242-
if (!isHidden(d) && doReport(d)(ctx.addMode(Mode.Printing)))
204+
if (!isHidden(d)) {
205+
doReport(d)(ctx.addMode(Mode.Printing))
243206
d match {
244207
case d: ConditionalWarning if !d.enablingOption.value => unreportedWarnings(d.enablingOption.name) += 1
245208
case d: Warning => warningCount += 1
@@ -249,6 +212,7 @@ abstract class Reporter {
249212
case d: Info => // nothing to do here
250213
// match error if d is something else
251214
}
215+
}
252216

253217
def incomplete(d: Diagnostic)(implicit ctx: Context): Unit =
254218
incompleteHandler(d)(ctx)

src/dotty/tools/dotc/reporting/StoreReporter.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ package reporting
44

55
import core.Contexts.Context
66
import collection.mutable
7-
import Reporter.{Diagnostic, Error, Warning}
7+
import Reporter.{Error, Warning}
88
import config.Printers._
99

1010
/**
@@ -14,11 +14,10 @@ class StoreReporter(outer: Reporter) extends Reporter {
1414

1515
private var infos: mutable.ListBuffer[Diagnostic] = null
1616

17-
def doReport(d: Diagnostic)(implicit ctx: Context): Boolean = {
17+
def doReport(d: Diagnostic)(implicit ctx: Context): Unit = {
1818
typr.println(s">>>> StoredError: ${d.msg}") // !!! DEBUG
1919
if (infos == null) infos = new mutable.ListBuffer
2020
infos += d
21-
true
2221
}
2322

2423
override def hasPending: Boolean = infos != null && {

src/dotty/tools/dotc/reporting/ThrowingReporter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import Reporter._
1111
* info to the underlying reporter.
1212
*/
1313
class ThrowingReporter(reportInfo: Reporter) extends Reporter {
14-
def doReport(d: Diagnostic)(implicit ctx: Context): Boolean = d match {
14+
def doReport(d: Diagnostic)(implicit ctx: Context): Unit = d match {
1515
case _: Error => throw d
1616
case _ => reportInfo.doReport(d)
1717
}

src/dotty/tools/dotc/reporting/UniqueMessagePositions.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ package reporting
44

55
import scala.collection.mutable
66
import util.{SourcePosition, SourceFile}
7-
import Reporter.Diagnostic
87
import core.Contexts.Context
98

109
/**

src/dotty/tools/dotc/typer/ErrorReporting.scala

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import Trees._
88
import Types._, ProtoTypes._, Contexts._, Decorators._, Denotations._, Symbols._
99
import Applications._, Implicits._, Flags._
1010
import util.Positions._
11+
import reporting.Diagnostic
1112
import printing.Showable
1213
import printing.Disambiguation.disambiguated
1314

@@ -127,7 +128,6 @@ object ErrorReporting {
127128
* message composition methods, this is crucial.
128129
*/
129130
implicit class DiagnosticString(val sc: StringContext) extends AnyVal {
130-
import DiagnosticString._
131131
def d(args: Any*)(implicit ctx: Context): String = {
132132
def isSensical(arg: Any): Boolean = arg match {
133133
case l: Seq[_] => l.forall(isSensical(_))
@@ -139,13 +139,8 @@ object ErrorReporting {
139139
}
140140

141141
val s = new StringInterpolators(sc).i(args : _*)
142-
if (args.forall(isSensical(_))) s else nonSensicalStartTag + s + nonSensicalEndTag
142+
if (args.forall(isSensical(_))) s
143+
else Diagnostic.nonSensicalStartTag + s + Diagnostic.nonSensicalEndTag
143144
}
144145
}
145-
146-
object DiagnosticString {
147-
final val nonSensicalStartTag = "<nonsensical>"
148-
final val nonSensicalEndTag = "</nonsensical>"
149-
}
150-
151146
}

src/dotty/tools/dotc/typer/Inferencing.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import util.{Stats, SimpleMap}
1515
import util.common._
1616
import Decorators._
1717
import Uniques._
18-
import ErrorReporting.{errorType, DiagnosticString}
1918
import config.Printers._
2019
import annotation.tailrec
2120
import collection.mutable

0 commit comments

Comments
 (0)