diff options
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r-- | src/dotty/tools/dotc/Compiler.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/CompilerCallback.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/Driver.scala | 68 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Contexts.scala | 24 | ||||
-rw-r--r-- | src/dotty/tools/dotc/reporting/ConsoleReporter.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/reporting/Reporter.scala | 21 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/TreeChecker.scala | 3 |
7 files changed, 80 insertions, 44 deletions
diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala index 42d223fe9..199657864 100644 --- a/src/dotty/tools/dotc/Compiler.scala +++ b/src/dotty/tools/dotc/Compiler.scala @@ -111,15 +111,13 @@ class Compiler { .setOwner(defn.RootClass) .setTyper(new Typer) .setMode(Mode.ImplicitsEnabled) - .setTyperState(new MutableTyperState(ctx.typerState, rootReporter(ctx), isCommittable = true)) + .setTyperState(new MutableTyperState(ctx.typerState, ctx.typerState.reporter, isCommittable = true)) ctx.definitions.init(start) // set context of definitions to start def addImport(ctx: Context, refFn: () => TermRef) = ctx.fresh.setImportInfo(ImportInfo.rootImport(refFn)(ctx)) (start.setRunInfo(new RunInfo(start)) /: defn.RootImportFns)(addImport) } - protected def rootReporter(implicit ctx: Context): Reporter = new ConsoleReporter()(ctx) - def reset()(implicit ctx: Context): Unit = { ctx.base.reset() ctx.runInfo.clear() diff --git a/src/dotty/tools/dotc/CompilerCallback.scala b/src/dotty/tools/dotc/CompilerCallback.scala index 98e8e2713..e2f56430b 100644 --- a/src/dotty/tools/dotc/CompilerCallback.scala +++ b/src/dotty/tools/dotc/CompilerCallback.scala @@ -18,7 +18,7 @@ import java.io.File * } * dotty.tools.dotc.process(args, callback) * // Or, if you have a custom root context `rootCtx`: - * dotty.tools.dotc.process(args, rootCtx.setCompilerCallback(callback)) + * dotty.tools.dotc.process(args, rootCtx.fresh.setCompilerCallback(callback)) * }}} */ trait CompilerCallback { diff --git a/src/dotty/tools/dotc/Driver.scala b/src/dotty/tools/dotc/Driver.scala index 1627b6e48..7f22fc774 100644 --- a/src/dotty/tools/dotc/Driver.scala +++ b/src/dotty/tools/dotc/Driver.scala @@ -33,28 +33,64 @@ abstract class Driver extends DotClass { protected def sourcesRequired = true def setup(args: Array[String], rootCtx: Context): (List[String], Context) = { - val summary = CompilerCommand.distill(args)(rootCtx) - // FIXME: We should reuse rootCtx instead of creating newCtx, but this - // makes some tests fail with "denotation module _root_ invalid in run 2." - val newCtx = initCtx.setCompilerCallback(rootCtx.compilerCallback) - implicit val ctx: Context = newCtx.fresh.setSettings(summary.sstate) - val fileNames = CompilerCommand.checkUsage(summary, sourcesRequired) + val ctx = rootCtx.fresh + val summary = CompilerCommand.distill(args)(ctx) + ctx.setSettings(summary.sstate) + val fileNames = CompilerCommand.checkUsage(summary, sourcesRequired)(ctx) (fileNames, ctx) } - def process(args: Array[String], rootCtx: Context): Reporter = { - val (fileNames, ctx) = setup(args, rootCtx) - doCompile(newCompiler(), fileNames)(ctx) - } - def process(args: Array[String], callback: CompilerCallback): Reporter = { - process(args, initCtx.setCompilerCallback(callback)) + /** Principal entry point to the compiler. + * Creates a new compiler instance and run it with arguments `args`. + * + * The optional arguments of this method all have `null` as their default + * value, this makes it easier to call this method by reflection or from Java. + * + * @param args Arguments to pass to the compiler. + * @param reporter Used to log errors, warnings, and info messages. + * The default reporter is used if this is `null`. + * @param callback Used to execute custom code during the compilation + * process. No callbacks will be executed if this is `null`. + * @return The `Reporter` used. Use `Reporter#hasErrors` to check + * if compilation succeeded. + */ + final def process(args: Array[String], reporter: Reporter = null, + callback: CompilerCallback = null): Reporter = { + val ctx = initCtx.fresh + if (reporter != null) + ctx.setReporter(reporter) + if (callback != null) + ctx.setCompilerCallback(callback) + process(args, ctx) } - // We overload `process` instead of using a default argument so that we - // can easily call this method using reflection from `RawCompiler` in sbt. - def process(args: Array[String]): Reporter = { - process(args, initCtx) + /** Entry point to the compiler with no optional arguments. + * + * This overload is provided for compatibility reasons: the + * `RawCompiler` of sbt expects this method to exist and calls + * it using reflection. Keeping it means that we can change + * the other overloads without worrying about breaking compatibility + * with sbt. + */ + final def process(args: Array[String]): Reporter = + process(args, null, null) + + /** Entry point to the compiler using a custom `Context`. + * + * In most cases, you do not need a custom `Context` and should + * instead use one of the other overloads of `process`. However, + * the other overloads cannot be overriden, instead you + * should override this one which they call internally. + * + * @param args Arguments to pass to the compiler. + * @param rootCtx The root Context to use. + * @return The `Reporter` used. Use `Reporter#hasErrors` to check + * if compilation succeeded. + */ + def process(args: Array[String], rootCtx: Context): Reporter = { + val (fileNames, ctx) = setup(args, rootCtx) + doCompile(newCompiler(), fileNames)(ctx) } def main(args: Array[String]): Unit = { diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala index ae221cc3e..b205a40f0 100644 --- a/src/dotty/tools/dotc/core/Contexts.scala +++ b/src/dotty/tools/dotc/core/Contexts.scala @@ -72,22 +72,16 @@ object Contexts { def next = { val c = current; current = current.outer; c } } - /** Set the compiler callback, shared by all contexts with the same `base` */ - def setCompilerCallback(callback: CompilerCallback): this.type = { - base.compilerCallback = callback; this - } - /** The outer context */ private[this] var _outer: Context = _ protected def outer_=(outer: Context) = _outer = outer def outer: Context = _outer - // protected def compilerCallback_=(callback: CompilerCallback) = - // _compilerCallback = callback - // def compilerCallback: CompilerCallback = _compilerCallback - // def setCompilerCallback(callback: CompilerCallback): this.type = { - // this.compilerCallback = callback; this - // } + /** The compiler callback implementation, or null if no callback will be called. */ + private[this] var _compilerCallback: CompilerCallback = _ + protected def compilerCallback_=(callback: CompilerCallback) = + _compilerCallback = callback + def compilerCallback: CompilerCallback = _compilerCallback /** The current context */ private[this] var _period: Period = _ @@ -426,7 +420,9 @@ object Contexts { abstract class FreshContext extends Context { def setPeriod(period: Period): this.type = { this.period = period; this } def setMode(mode: Mode): this.type = { this.mode = mode; this } + def setCompilerCallback(callback: CompilerCallback): this.type = { this.compilerCallback = callback; this } def setTyperState(typerState: TyperState): this.type = { this.typerState = typerState; this } + def setReporter(reporter: Reporter): this.type = setTyperState(typerState.withReporter(reporter)) def setNewTyperState: this.type = setTyperState(typerState.fresh(isCommittable = true)) def setExploreTyperState: this.type = setTyperState(typerState.fresh(isCommittable = false)) def setPrinterFn(printer: Context => Printer): this.type = { this.printerFn = printer; this } @@ -481,7 +477,7 @@ object Contexts { outer = NoContext period = InitialPeriod mode = Mode.None - typerState = new TyperState(new ThrowingReporter(new ConsoleReporter()(this))) + typerState = new TyperState(new ConsoleReporter()) printerFn = new RefinedPrinter(_) owner = NoSymbol sstate = settings.defaultState @@ -536,10 +532,6 @@ object Contexts { /** The essential mutable state of a context base, collected into a common class */ class ContextState { - - /** The compiler callback implementation, or null if unset */ - var compilerCallback: CompilerCallback = _ - // Symbols state /** A counter for unique ids */ diff --git a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala index 45268b673..e9b9964c3 100644 --- a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala +++ b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala @@ -15,7 +15,7 @@ import scala.reflect.internal.util._ */ class ConsoleReporter( reader: BufferedReader = Console.in, - writer: PrintWriter = new PrintWriter(Console.err, true))(ctx: Context) + writer: PrintWriter = new PrintWriter(Console.err, true)) extends Reporter with UniqueMessagePositions { /** maximal number of error messages to be printed */ diff --git a/src/dotty/tools/dotc/reporting/Reporter.scala b/src/dotty/tools/dotc/reporting/Reporter.scala index f98d85ce9..5ed7360da 100644 --- a/src/dotty/tools/dotc/reporting/Reporter.scala +++ b/src/dotty/tools/dotc/reporting/Reporter.scala @@ -247,12 +247,23 @@ abstract class Reporter { incompleteHandler(d)(ctx) - /** Print a summary */ - def printSummary(implicit ctx: Context): Unit = { - if (warningCount > 0) ctx.println(countString(warningCount, "warning") + " found") - if (errorCount > 0) ctx.println(countString(errorCount, "error") + " found") + /** Summary of warnings and errors */ + def summary: String = { + val b = new mutable.ListBuffer[String] + if (warningCount > 0) + b += countString(warningCount, "warning") + " found" + if (errorCount > 0) + b += countString(errorCount, "error") + " found" for ((settingName, count) <- unreportedWarnings) - ctx.println(s"there were $count ${settingName.tail} warning(s); re-run with $settingName for details") + b += s"there were $count ${settingName.tail} warning(s); re-run with $settingName for details" + b.mkString("\n") + } + + /** Print the summary of warnings and errors */ + def printSummary(implicit ctx: Context): Unit = { + val s = summary + if (s != "") + ctx.println(s) } /** Returns a string meaning "n elements". */ diff --git a/src/dotty/tools/dotc/transform/TreeChecker.scala b/src/dotty/tools/dotc/transform/TreeChecker.scala index daf76f471..150a632a1 100644 --- a/src/dotty/tools/dotc/transform/TreeChecker.scala +++ b/src/dotty/tools/dotc/transform/TreeChecker.scala @@ -118,8 +118,7 @@ class TreeChecker extends Phase with SymTransformer { val prevPhase = ctx.phase.prev // can be a mini-phase val squahsedPhase = ctx.squashed(prevPhase) ctx.println(s"checking ${ctx.compilationUnit} after phase ${squahsedPhase}") - val checkingCtx = ctx.fresh - .setTyperState(ctx.typerState.withReporter(new ThrowingReporter(ctx.reporter))) + val checkingCtx = ctx.fresh.setReporter(new ThrowingReporter(ctx.reporter)) val checker = new Checker(previousPhases(phasesToRun.toList)(ctx)) try checker.typedExpr(ctx.compilationUnit.tpdTree)(checkingCtx) catch { |