aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGuillaume Martres <smarter@ubuntu.com>2016-02-05 00:34:02 +0100
committerGuillaume Martres <smarter@ubuntu.com>2016-02-05 00:34:02 +0100
commit9d8c92d1d52fcfa95d57ce88d91dbb84c8ecfbd1 (patch)
tree83b51507c3548d95a02840b83d530e3b6c700e0f /src
parent93dd1cf1fdbf56ca3c153aa5a25fb4c48782acf5 (diff)
parent7eba7f7a6778cc0ddfb2ce81dee64dd4fa23490a (diff)
downloaddotty-9d8c92d1d52fcfa95d57ce88d91dbb84c8ecfbd1.tar.gz
dotty-9d8c92d1d52fcfa95d57ce88d91dbb84c8ecfbd1.tar.bz2
dotty-9d8c92d1d52fcfa95d57ce88d91dbb84c8ecfbd1.zip
Merge pull request #1052 from smarter/fix/driver-api
Improve and document the Driver#process API, fix partest logging
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/Compiler.scala4
-rw-r--r--src/dotty/tools/dotc/CompilerCallback.scala2
-rw-r--r--src/dotty/tools/dotc/Driver.scala68
-rw-r--r--src/dotty/tools/dotc/core/Contexts.scala24
-rw-r--r--src/dotty/tools/dotc/reporting/ConsoleReporter.scala2
-rw-r--r--src/dotty/tools/dotc/reporting/Reporter.scala21
-rw-r--r--src/dotty/tools/dotc/transform/TreeChecker.scala3
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 {