Skip to content

Commit 235e69d

Browse files
authored
Merge pull request scala#6635 from som-snytt/topic/nail-reporter
Prefer internal.Reporter
2 parents 4d6a9ba + 7ca0a7f commit 235e69d

32 files changed

+469
-280
lines changed

src/compiler/scala/reflect/macros/contexts/FrontEnds.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ trait FrontEnds {
88

99
def echo(pos: Position, msg: String): Unit = universe.reporter.echo(pos, msg)
1010

11-
def info(pos: Position, msg: String, force: Boolean): Unit = universe.reporter.info(pos, msg, force)
11+
@deprecated("Use echo, info messages are always forced", since="2.13.0")
12+
def info(pos: Position, msg: String, force: Boolean): Unit = universe.reporter.echo(pos, msg)
1213

1314
def hasWarnings: Boolean = universe.reporter.hasErrors
1415

src/compiler/scala/tools/nsc/CompileServer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ class StandardCompileServer(fixPort: Int = 0) extends SocketServer(fixPort) {
159159
throw ex
160160
}
161161
}
162-
reporter.printSummary()
162+
reporter.finish()
163163
if (isMemoryFullEnough()) {
164164
info("Nulling out compiler due to memory utilization.")
165165
clearCompiler()

src/compiler/scala/tools/nsc/Driver.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package scala
22
package tools.nsc
33

4-
import scala.tools.nsc.reporters.{ ConsoleReporter, Reporter }
4+
import scala.tools.nsc.reporters.DisplayReporter
55
import Properties.{ versionMsg, residentPromptString }
6+
import scala.reflect.internal.Reporter
67
import scala.reflect.internal.util.FakePos
78

89
abstract class Driver {
@@ -39,7 +40,7 @@ abstract class Driver {
3940

4041
def process(args: Array[String]): Boolean = {
4142
val ss = new Settings(scalacError)
42-
reporter = new ConsoleReporter(ss) // for reporting early config errors, before compiler is constructed
43+
reporter = DisplayReporter(ss) // for reporting early config errors, before compiler is constructed
4344
command = new CompilerCommand(args.toList, ss)
4445
settings = command.settings
4546

src/compiler/scala/tools/nsc/Global.scala

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ import java.nio.charset.{Charset, CharsetDecoder, IllegalCharsetNameException, U
1313

1414
import scala.collection.{immutable, mutable}
1515
import io.{AbstractFile, Path, SourceReader}
16-
import reporters.Reporter
1716
import util.{ClassPath, returning}
17+
import reporters.{Reporter => LegacyReporter}
1818
import scala.reflect.ClassTag
19+
import scala.reflect.internal.{Reporter => InternalReporter}
1920
import scala.reflect.internal.util.{BatchSourceFile, FreshNameCreator, NoSourceFile, ScalaClassLoader, ScriptSourceFile, SourceFile, StatisticsStatics}
2021
import scala.reflect.internal.pickling.PickleBuffer
2122
import symtab.{Flags, SymbolTable, SymbolTrackers}
@@ -34,7 +35,7 @@ import scala.tools.nsc.ast.{TreeGen => AstTreeGen}
3435
import scala.tools.nsc.classpath._
3536
import scala.tools.nsc.profile.Profiler
3637

37-
class Global(var currentSettings: Settings, reporter0: Reporter)
38+
class Global(var currentSettings: Settings, reporter0: LegacyReporter)
3839
extends SymbolTable
3940
with CompilationUnits
4041
with Plugins
@@ -76,21 +77,16 @@ class Global(var currentSettings: Settings, reporter0: Reporter)
7677

7778
override def settings = currentSettings
7879

79-
private[this] var currentReporter: Reporter = { reporter = reporter0 ; currentReporter }
80+
private[this] var currentReporter: LegacyReporter = { reporter = reporter0 ; currentReporter }
8081

81-
def reporter: Reporter = currentReporter
82-
def reporter_=(newReporter: Reporter): Unit =
83-
currentReporter = newReporter match {
84-
case _: reporters.ConsoleReporter | _: reporters.LimitingReporter => newReporter
85-
case _ if settings.maxerrs.isSetByUser && settings.maxerrs.value < settings.maxerrs.default =>
86-
new reporters.LimitingReporter(settings, newReporter)
87-
case _ => newReporter
88-
}
82+
def reporter: LegacyReporter = currentReporter
83+
// enforce maxerrs if necessary
84+
def reporter_=(newReporter: LegacyReporter): Unit = currentReporter = LegacyReporter.limitedReporter(settings, newReporter)
8985

9086
/** Switch to turn on detailed type logs */
9187
var printTypings = settings.Ytyperdebug.value
9288

93-
def this(reporter: Reporter) =
89+
def this(reporter: LegacyReporter) =
9490
this(new Settings(err => reporter.error(null, err)), reporter)
9591

9692
def this(settings: Settings) =
@@ -338,7 +334,7 @@ class Global(var currentSettings: Settings, reporter0: Reporter)
338334
}
339335

340336
def loadReader(name: String): Option[SourceReader] = {
341-
def ccon = Class.forName(name).getConstructor(classOf[CharsetDecoder], classOf[Reporter])
337+
def ccon = Class.forName(name).getConstructor(classOf[CharsetDecoder], classOf[InternalReporter])
342338

343339
try Some(ccon.newInstance(charset.newDecoder(), reporter).asInstanceOf[SourceReader])
344340
catch { case ex: Throwable =>
@@ -395,9 +391,10 @@ class Global(var currentSettings: Settings, reporter0: Reporter)
395391

396392
/** Is current phase cancelled on this unit? */
397393
def cancelled(unit: CompilationUnit) = {
394+
val isCanceled = reporter.cancelled
398395
// run the typer only if in `createJavadoc` mode
399396
val maxJavaPhase = if (createJavadoc) currentRun.typerPhase.id else currentRun.namerPhase.id
400-
reporter.cancelled || unit.isJava && this.id > maxJavaPhase
397+
isCanceled || unit.isJava && this.id > maxJavaPhase
401398
}
402399

403400
final def withCurrentUnit(unit: CompilationUnit)(task: => Unit): Unit = {
@@ -1266,7 +1263,7 @@ class Global(var currentSettings: Settings, reporter0: Reporter)
12661263
}
12671264

12681265
// for sbt
1269-
def cancel(): Unit = { reporter.cancelled = true }
1266+
def cancel(): Unit = reporter.cancelled = true
12701267

12711268
private def currentProgress = (phasec * size) + unitc
12721269
private def totalProgress = (phaseDescriptors.size - 1) * size // -1: drops terminal phase
@@ -1656,14 +1653,16 @@ class Global(var currentSettings: Settings, reporter0: Reporter)
16561653
}
16571654

16581655
object Global {
1659-
def apply(settings: Settings, reporter: Reporter): Global = new Global(settings, reporter)
1656+
def apply(settings: Settings, reporter: LegacyReporter): Global = new Global(settings, reporter)
16601657

16611658
def apply(settings: Settings): Global = new Global(settings, reporter(settings))
16621659

1663-
private def reporter(settings: Settings): Reporter = {
1660+
private def reporter(settings: Settings): LegacyReporter = {
16641661
//val loader = ScalaClassLoader(getClass.getClassLoader) // apply does not make delegate
16651662
val loader = new ClassLoader(getClass.getClassLoader) with ScalaClassLoader
1666-
loader.create[Reporter](settings.reporter.value, settings.errorFn)(settings)
1663+
val res = loader.create[InternalReporter](settings.reporter.value, settings.errorFn)(settings)
1664+
if (res.isInstanceOf[LegacyReporter]) res.asInstanceOf[LegacyReporter]
1665+
else res: LegacyReporter // adaptable
16671666
}
16681667
private object InitPhase extends Phase(null) {
16691668
def name = "<init phase>"

src/compiler/scala/tools/nsc/Reporting.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ trait Reporting extends scala.reflect.internal.Reporting { self: ast.Positions w
9797
val explain = (
9898
if (reportedFeature contains featureTrait) "" else
9999
s"""|
100+
|----
100101
|This can be achieved by adding the import clause 'import $fqname'
101102
|or by setting the compiler option -language:$featureName.
102103
|See the Scaladoc for value $fqname for a discussion

src/compiler/scala/tools/nsc/ast/DocComments.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,8 @@ trait DocComments { self: Global =>
254254
val sectionTextBounds = extractSectionText(parent, section)
255255
cleanupSectionText(parent.substring(sectionTextBounds._1, sectionTextBounds._2))
256256
case None =>
257-
reporter.info(sym.pos, "The \"" + getSectionHeader + "\" annotation of the " + sym +
258-
" comment contains @inheritdoc, but the corresponding section in the parent is not defined.", force = true)
257+
reporter.echo(sym.pos, "The \"" + getSectionHeader + "\" annotation of the " + sym +
258+
" comment contains @inheritdoc, but the corresponding section in the parent is not defined.")
259259
"<invalid inheritdoc annotation>"
260260
}
261261

src/compiler/scala/tools/nsc/io/SourceReader.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import java.io.{ FileInputStream, IOException }
1111
import java.nio.{ByteBuffer, CharBuffer}
1212
import java.nio.channels.{ ReadableByteChannel, Channels }
1313
import java.nio.charset.{CharsetDecoder, CoderResult}
14-
import scala.tools.nsc.reporters._
14+
import scala.reflect.internal.Reporter
1515

1616
/** This class implements methods to read and decode source files. */
1717
class SourceReader(decoder: CharsetDecoder, reporter: Reporter) {

src/compiler/scala/tools/nsc/reporters/AbstractReporter.scala

Lines changed: 19 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -10,72 +10,32 @@ import scala.collection.mutable
1010
import scala.tools.nsc.Settings
1111
import scala.reflect.internal.util.Position
1212

13-
/** This reporter implements filtering by severity and position.
13+
/** This reporter uses filtering by severity and position,
14+
* including two-tiered INFO messaging,
15+
* and also handles prompting and debug output.
1416
*/
15-
abstract class AbstractReporter extends Reporter {
17+
@deprecated("Use PositionFiltering", since="2.13")
18+
abstract class AbstractReporter extends Reporter with PositionFiltering {
1619
val settings: Settings
1720
def display(pos: Position, msg: String, severity: Severity): Unit
1821
def displayPrompt(): Unit
1922

20-
private val positions = mutable.Map[Position, Severity]() withDefaultValue INFO
21-
private val messages = mutable.Map[Position, List[String]]() withDefaultValue Nil
23+
protected def noWarnings = settings.nowarnings.value
24+
private def isVerbose = settings.verbose.value
25+
private def isPromptSet = settings.prompt.value
26+
private def isDebug = settings.debug.value
2227

23-
override def reset(): Unit = {
24-
super.reset()
25-
positions.clear()
26-
messages.clear()
27-
}
28-
29-
private def isVerbose = settings.verbose.value
30-
private def noWarnings = settings.nowarnings.value
31-
private def isPromptSet = settings.prompt.value
32-
private def isDebug = settings.debug
28+
protected def suppressed(pos: Position, msg: String, severity: Severity): Unit =
29+
if (isPromptSet) countAndDisplay(pos, msg, severity)
30+
else if (isDebug) countAndDisplay(pos, "[ suppressed ] " + msg, severity)
3331

34-
protected def info0(pos: Position, msg: String, severity: Severity, force: Boolean): Unit = {
35-
if (severity == INFO) {
36-
if (isVerbose || force) {
37-
severity.count += 1
38-
display(pos, msg, severity)
39-
}
40-
}
41-
else {
42-
val hidden = testAndLog(pos, severity, msg)
43-
if (severity == WARNING && noWarnings) ()
44-
else {
45-
if (!hidden || isPromptSet) {
46-
severity.count += 1
47-
display(pos, msg, severity)
48-
}
49-
else if (isDebug) {
50-
severity.count += 1
51-
display(pos, "[ suppressed ] " + msg, severity)
52-
}
32+
protected def info0(pos: Position, msg: String, severity: Severity, force: Boolean): Unit =
33+
if (filter(pos, msg, severity) && (severity != INFO || (force || isVerbose)))
34+
countAndDisplay(pos, msg, severity)
5335

54-
if (isPromptSet)
55-
displayPrompt()
56-
}
57-
}
36+
private def countAndDisplay(pos: Position, msg: String, severity: Severity): Unit = {
37+
severity.count += 1
38+
display(pos, msg, severity)
39+
if (isPromptSet && severity != INFO) displayPrompt()
5840
}
59-
60-
61-
/** Logs a position and returns true if it was already logged.
62-
* @note Two positions are considered identical for logging if they have the same point.
63-
*/
64-
private def testAndLog(pos: Position, severity: Severity, msg: String): Boolean =
65-
pos != null && pos.isDefined && {
66-
val fpos = pos.focus
67-
val suppress = positions(fpos) match {
68-
case ERROR => true // already error at position
69-
case highest
70-
if highest.id > severity.id => true // already message higher than present severity
71-
case `severity` => messages(fpos) contains msg // already issued this exact message
72-
case _ => false // good to go
73-
}
74-
75-
suppress || {
76-
positions(fpos) = severity
77-
messages(fpos) ::= msg
78-
false
79-
}
80-
}
8141
}

src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala

Lines changed: 6 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -15,82 +15,18 @@ import scala.tools.util.SystemExit
1515

1616
/** This class implements a Reporter that displays messages on a text console.
1717
*/
18-
class ConsoleReporter(val settings: Settings, reader: BufferedReader, writer: PrintWriter, echoWriter: PrintWriter) extends AbstractReporter {
18+
class ConsoleReporter(val settings: Settings, val reader: BufferedReader, val writer: PrintWriter, val echoWriter: PrintWriter) extends AbstractReporter with PrintReporter with SummaryReporter {
1919
def this(settings: Settings) = this(settings, Console.in, new PrintWriter(Console.err, true), new PrintWriter(Console.out, true))
20-
def this(settings: Settings, reader: BufferedReader, writer: PrintWriter) =
21-
this(settings, reader, writer, writer)
20+
def this(settings: Settings, reader: BufferedReader, writer: PrintWriter) = this(settings, reader, writer, writer)
2221

23-
/** Whether a short file name should be displayed before errors */
24-
var shortname: Boolean = false
25-
26-
/** maximal number of error messages to be printed */
27-
@deprecated("configured by settings.maxerrs", since="2.12.2")
28-
final val ERROR_LIMIT = 100
29-
30-
private def label(severity: Severity): String = severity match {
31-
case ERROR => "error"
32-
case WARNING => "warning"
33-
case INFO => ""
34-
}
35-
36-
protected def clabel(severity: Severity): String = label(severity) match {
37-
case "" => ""
38-
case s => s"$s: "
39-
}
40-
41-
/** Prints the message. */
42-
def printMessage(msg: String): Unit = {
43-
writer.println(trimTrailing(msg))
44-
writer.flush()
45-
}
46-
47-
/** Prints the message to the echoWriter, which is usually stdout. */
48-
override def echo(msg: String): Unit = {
49-
echoWriter.println(trimTrailing(msg))
50-
echoWriter.flush()
51-
}
52-
53-
/** Prints the message with the given position indication. */
54-
def printMessage(posIn: Position, msg: String): Unit = printMessage(formatMessage(posIn, msg, shortname))
55-
56-
def print(pos: Position, msg: String, severity: Severity): Unit = printMessage(pos, s"${clabel(severity)}${msg}")
57-
58-
/** Prints the column marker of the given position. */
59-
def printColumnMarker(pos: Position): Unit = if (pos.isDefined) printMessage(" " * (pos.column - 1) + "^")
60-
61-
/** Prints the number of warnings and errors if there are any. */
62-
def printSummary(): Unit =
63-
for (k <- List(WARNING, ERROR) if k.count > 0) printMessage(s"${countAs(k.count, label(k))} found")
64-
65-
def display(pos: Position, msg: String, severity: Severity): Unit = {
22+
// limit errors and warnings; AbstractReporter counts them because of forced INFO special case
23+
override def display(pos: Position, msg: String, severity: Severity): Unit = {
6624
// the count includes the current message
6725
val ok = severity match {
6826
case ERROR => ERROR.count <= settings.maxerrs.value
6927
case WARNING => WARNING.count <= settings.maxwarns.value
70-
case _ => true
28+
case _ => true
7129
}
72-
if (ok) print(pos, msg, severity)
30+
if (ok) super.display(pos, msg, severity)
7331
}
74-
75-
def displayPrompt(): Unit = {
76-
writer.println()
77-
writer.print("a)bort, s)tack, r)esume: ")
78-
writer.flush()
79-
if (reader != null) {
80-
reader.read match {
81-
case 'a' | 'A' =>
82-
new Throwable().printStackTrace(writer)
83-
throw SystemExit(1)
84-
case 's' | 'S' =>
85-
new Throwable().printStackTrace(writer)
86-
writer.println()
87-
writer.flush()
88-
case _ =>
89-
}
90-
}
91-
}
92-
93-
override def flush() = writer.flush()
94-
95-
override def finish() = printSummary()
9632
}

0 commit comments

Comments
 (0)