From a39551f990be08dc7168374e74228b9388160aec Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 19 Jul 2013 20:14:08 +0200 Subject: Integrated reporting into TyperState. --- src/dotty/tools/dotc/core/Contexts.scala | 14 +++++-------- src/dotty/tools/dotc/core/TyperState.scala | 24 +++++++++++----------- .../tools/dotc/reporting/ConsoleReporter.scala | 4 ++-- src/dotty/tools/dotc/reporting/Reporter.scala | 8 +++++--- src/dotty/tools/dotc/reporting/StoreReporter.scala | 5 ++--- .../tools/dotc/reporting/ThrowingReporter.scala | 15 ++++++++++++++ src/dotty/tools/dotc/typer/Implicits.scala | 2 +- 7 files changed, 42 insertions(+), 30 deletions(-) create mode 100644 src/dotty/tools/dotc/reporting/ThrowingReporter.scala (limited to 'src') diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala index d92ed35fc..f7adbc184 100644 --- a/src/dotty/tools/dotc/core/Contexts.scala +++ b/src/dotty/tools/dotc/core/Contexts.scala @@ -136,11 +136,6 @@ object Contexts { protected def importInfo_=(importInfo: ImportInfo) = _importInfo = importInfo def importInfo: ImportInfo = _importInfo - /** The current reporter */ - private[this] var _reporter: Reporter = _ - protected def reporter_=(reporter: Reporter) = _reporter = reporter - def reporter: Reporter = _reporter - /** The current compiler-run specific Info */ private[this] var _runInfo: RunInfo = _ protected def runInfo_=(runInfo: RunInfo) = _runInfo = runInfo @@ -202,6 +197,9 @@ object Contexts { println("=== end context creation trace ===") } + /** The current reporter */ + def reporter: Reporter = typerState.reporter + /** Is this a context for the members of a class definition? */ def isClassDefContext: Boolean = owner.isClass && (owner ne outer.owner) @@ -252,12 +250,12 @@ object Contexts { _condensed = base.initialCtx.fresh .withPeriod(period) // typerState and its constraint is not preserved in condensed + // reporter is always ThrowingReporter .withPlainPrinter(plainPrinter) .withRefinedPrinter(refinedPrinter) .withOwner(owner) .withSettings(sstate) // tree is not preserved in condensed - .withReporter(reporter) .withRunInfo(runInfo) .withDiagnostics(diagnostics) .withMoreProperties(moreProperties) @@ -301,7 +299,6 @@ object Contexts { def withNewScope: this.type = { this.scope = newScope; this } def withTyper(typer: Typer): this.type = { this.typer = typer; this.scope = typer.scope; this } def withImportInfo(importInfo: ImportInfo): this.type = { this.importInfo = importInfo; this } - def withReporter(reporter: Reporter): this.type = { this.reporter = reporter; this } def withRunInfo(runInfo: RunInfo): this.type = { this.runInfo = runInfo; this } def withDiagnostics(diagnostics: Option[StringBuilder]): this.type = { this.diagnostics = diagnostics; this } def withMoreProperties(moreProperties: Map[String, Any]): this.type = { this.moreProperties = moreProperties; this } @@ -324,14 +321,13 @@ object Contexts { private class InitialContext(val base: ContextBase, settings: SettingGroup) extends FreshContext { outer = NoContext period = InitialPeriod - typerState = new TyperState + typerState = new TyperState(new ConsoleReporter()(this)) position = NoPosition plainPrinter = new PlainPrinter(_) refinedPrinter = new RefinedPrinter(_) owner = NoSymbol sstate = settings.defaultState tree = untpd.EmptyTree - reporter = new ConsoleReporter()(this) runInfo = new RunInfo diagnostics = None moreProperties = Map.empty diff --git a/src/dotty/tools/dotc/core/TyperState.scala b/src/dotty/tools/dotc/core/TyperState.scala index 89589c164..6bf2378ba 100644 --- a/src/dotty/tools/dotc/core/TyperState.scala +++ b/src/dotty/tools/dotc/core/TyperState.scala @@ -6,9 +6,9 @@ import Types._ import Flags._ import Contexts._ import util.SimpleMap -import reporting.Reporter.Diagnostic +import reporting._ -class TyperState extends DotClass { +class TyperState(val reporter: Reporter = ThrowingReporter) extends DotClass { /** The current constraint set */ def constraint: Constraint = new Constraint(SimpleMap.Empty) @@ -16,38 +16,38 @@ class TyperState extends DotClass { /** The currently uninstantiated TypeVars */ def undetVars: List[TypeVar] = Nil - /** The currently outstanding errors, warnings, or infos */ - def diagnostics: List[Diagnostic] = Nil - def constraint_=(c: Constraint): Unit = {} def undetVars_=(vs: List[TypeVar]): Unit = unsupported("undetVars_=") - def diagnostics_=(ds: List[Diagnostic]): Unit = unsupported("diagnostics_=") def fresh: TyperState = this + def commit()(implicit ctx: Context): Unit = unsupported("commit") + def copyFrom(tp: TyperState): Unit = unsupported("copyFrom") } -class MutableTyperState (previous: TyperState) extends TyperState { +class MutableTyperState(previous: TyperState, reporter: Reporter) +extends TyperState(reporter) { private var myConstraint: Constraint = previous.constraint private var myUndetVars: List[TypeVar] = previous.undetVars - private var myDiagnostics: List[Diagnostic] = Nil override def constraint = myConstraint override def undetVars = myUndetVars - override def diagnostics = myDiagnostics override def constraint_=(c: Constraint) = myConstraint = c override def undetVars_=(vs: List[TypeVar]) = myUndetVars = vs - override def diagnostics_=(ds: List[Diagnostic]) = myDiagnostics = ds - override def fresh: TyperState = new MutableTyperState(this) + override def fresh: TyperState = new MutableTyperState(this, new StoreReporter) + + override def commit()(implicit ctx: Context) = { + ctx.typerState.copyFrom(this) + reporter.flush() + } override def copyFrom(state: TyperState): Unit = { constraint = state.constraint undetVars = state.undetVars - // todo: do something about diagnostics (put reporter in state?) } } diff --git a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala index 461697bfc..ae677ecdc 100644 --- a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala +++ b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala @@ -16,7 +16,7 @@ import scala.reflect.internal.util._ class ConsoleReporter( reader: BufferedReader = Console.in, writer: PrintWriter = new PrintWriter(Console.err, true))(ctx: Context) - extends Reporter(ctx) with UniqueMessagePositions { + extends Reporter with UniqueMessagePositions { /** maximal number of error messages to be printed */ protected def ErrorLimit = 100 @@ -62,5 +62,5 @@ class ConsoleReporter( } } - override def flush() { writer.flush() } + override def flush()(implicit ctx: Context) { writer.flush() } } diff --git a/src/dotty/tools/dotc/reporting/Reporter.scala b/src/dotty/tools/dotc/reporting/Reporter.scala index 2f580c2f9..5ebc5934f 100644 --- a/src/dotty/tools/dotc/reporting/Reporter.scala +++ b/src/dotty/tools/dotc/reporting/Reporter.scala @@ -11,9 +11,11 @@ import config.Settings.Setting import java.lang.System.currentTimeMillis object Reporter { - class Diagnostic(msgFn: => String, val pos: SourcePosition, val severity: Severity) { + + class Diagnostic(msgFn: => String, val pos: SourcePosition, val severity: Severity) extends Exception { lazy val msg: String = msgFn override def toString = s"$severity at $pos: $msg" + override def getMessage() = msg } class Severity(val level: Int) extends AnyVal { @@ -127,7 +129,7 @@ trait Reporting { this: Context => * This interface provides methods to issue information, warning and * error messages. */ -abstract class Reporter(ctx: Context) { +abstract class Reporter { /** Report a diagnostic */ protected def doReport(d: Diagnostic)(implicit ctx: Context): Unit @@ -217,5 +219,5 @@ abstract class Reporter(ctx: Context) { } } - def flush(): Unit = {} + def flush()(implicit ctx: Context): Unit = {} } diff --git a/src/dotty/tools/dotc/reporting/StoreReporter.scala b/src/dotty/tools/dotc/reporting/StoreReporter.scala index 54daf2b6b..b20c5d504 100644 --- a/src/dotty/tools/dotc/reporting/StoreReporter.scala +++ b/src/dotty/tools/dotc/reporting/StoreReporter.scala @@ -9,14 +9,13 @@ import Reporter.Diagnostic /** * This class implements a Reporter that stores all messages */ -class StoreReporter(ctx: Context) extends Reporter(ctx) { +class StoreReporter extends Reporter { val infos = new mutable.ListBuffer[Diagnostic] protected def doReport(d: Diagnostic)(implicit ctx: Context): Unit = infos += d - def replay(implicit ctx: Context) = + override def flush()(implicit ctx: Context) = infos foreach ctx.reporter.report - } diff --git a/src/dotty/tools/dotc/reporting/ThrowingReporter.scala b/src/dotty/tools/dotc/reporting/ThrowingReporter.scala new file mode 100644 index 000000000..f1ee8ddb7 --- /dev/null +++ b/src/dotty/tools/dotc/reporting/ThrowingReporter.scala @@ -0,0 +1,15 @@ +package dotty.tools +package dotc +package reporting + +import core.Contexts.Context +import collection.mutable +import Reporter._ + +/** + * This class implements a Reporter that stores all messages + */ +object ThrowingReporter extends Reporter { + protected def doReport(d: Diagnostic)(implicit ctx: Context): Unit = + if (d.severity == ERROR) throw d else println(d) +} diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala index cedeb6af9..489233f90 100644 --- a/src/dotty/tools/dotc/typer/Implicits.scala +++ b/src/dotty/tools/dotc/typer/Implicits.scala @@ -185,7 +185,7 @@ trait Implicits { self: Typer => def inferImplicit(pt: Type, argument: Tree, pos: Position, reportAmbiguous: Boolean = true)(implicit ctx: Context): Tree = { new ImplicitSearch(pt, argument, pos).bestImplicit match { case SearchSuccess(_, tree, newCtx) => - ctx.typerState.copyFrom(newCtx.typerState) + newCtx.typerState.commit() tree case NoImplicitMatches => EmptyTree -- cgit v1.2.3