aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/Driver.scala
diff options
context:
space:
mode:
authorFelix Mulder <felix.mulder@gmail.com>2016-11-02 11:08:28 +0100
committerGuillaume Martres <smarter@ubuntu.com>2016-11-22 01:35:07 +0100
commit8a61ff432543a29234193cd1f7c14abd3f3d31a0 (patch)
treea8147561d307af862c295cfc8100d271063bb0dd /compiler/src/dotty/tools/dotc/Driver.scala
parent6a455fe6da5ff9c741d91279a2dc6fe2fb1b472f (diff)
downloaddotty-8a61ff432543a29234193cd1f7c14abd3f3d31a0.tar.gz
dotty-8a61ff432543a29234193cd1f7c14abd3f3d31a0.tar.bz2
dotty-8a61ff432543a29234193cd1f7c14abd3f3d31a0.zip
Move compiler and compiler tests to compiler dir
Diffstat (limited to 'compiler/src/dotty/tools/dotc/Driver.scala')
-rw-r--r--compiler/src/dotty/tools/dotc/Driver.scala134
1 files changed, 134 insertions, 0 deletions
diff --git a/compiler/src/dotty/tools/dotc/Driver.scala b/compiler/src/dotty/tools/dotc/Driver.scala
new file mode 100644
index 000000000..f54a23ad2
--- /dev/null
+++ b/compiler/src/dotty/tools/dotc/Driver.scala
@@ -0,0 +1,134 @@
+package dotty.tools.dotc
+
+import dotty.tools.FatalError
+import config.CompilerCommand
+import core.Contexts.{Context, ContextBase}
+import util.DotClass
+import reporting._
+import scala.util.control.NonFatal
+
+/** Run the Dotty compiler.
+ *
+ * Extending this class lets you customize many aspect of the compilation
+ * process, but in most cases you only need to call [[process]] on the
+ * existing object [[Main]].
+ */
+abstract class Driver extends DotClass {
+
+ protected def newCompiler(implicit ctx: Context): Compiler
+
+ protected def emptyReporter: Reporter = new StoreReporter(null)
+
+ protected def doCompile(compiler: Compiler, fileNames: List[String])(implicit ctx: Context): Reporter =
+ if (fileNames.nonEmpty)
+ try {
+ val run = compiler.newRun
+ run.compile(fileNames)
+ run.printSummary()
+ }
+ catch {
+ case ex: FatalError =>
+ ctx.error(ex.getMessage) // signals that we should fail compilation.
+ ctx.reporter
+ }
+ else ctx.reporter
+
+ protected def initCtx = (new ContextBase).initialCtx
+
+ protected def sourcesRequired = true
+
+ def setup(args: Array[String], rootCtx: Context): (List[String], Context) = {
+ val ctx = rootCtx.fresh
+ val summary = CompilerCommand.distill(args)(ctx)
+ ctx.setSettings(summary.sstate)
+ val fileNames = CompilerCommand.checkUsage(summary, sourcesRequired)(ctx)
+ (fileNames, ctx)
+ }
+
+ /** Entry point to the compiler that can be conveniently used with Java reflection.
+ *
+ * This entry point can easily be used without depending on the `dotty` package,
+ * you only need to depend on `dotty-interfaces` and call this method using
+ * reflection. This allows you to write code that will work against multiple
+ * versions of dotty without recompilation.
+ *
+ * The trade-off is that you can only pass a SimpleReporter to this method
+ * and not a normal Reporter which is more powerful.
+ *
+ * Usage example: [[https://github.com/lampepfl/dotty/tree/master/test/test/InterfaceEntryPointTest.scala]]
+ *
+ * @param args Arguments to pass to the compiler.
+ * @param simple 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
+ */
+ final def process(args: Array[String], simple: interfaces.SimpleReporter,
+ callback: interfaces.CompilerCallback): interfaces.ReporterResult = {
+ val reporter = if (simple == null) null else Reporter.fromSimpleReporter(simple)
+ process(args, reporter, callback)
+ }
+
+ /** Principal entry point to the compiler.
+ *
+ * Usage example: [[https://github.com/lampepfl/dotty/tree/master/test/test/OtherEntryPointsTest.scala]]
+ * in method `runCompiler`
+ *
+ * @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: interfaces.CompilerCallback = null): Reporter = {
+ val ctx = initCtx.fresh
+ if (reporter != null)
+ ctx.setReporter(reporter)
+ if (callback != null)
+ ctx.setCompilerCallback(callback)
+ process(args, ctx)
+ }
+
+ /** 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: Reporter, null: interfaces.CompilerCallback)
+
+ /** 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.
+ *
+ * Usage example: [[https://github.com/lampepfl/dotty/tree/master/test/test/OtherEntryPointsTest.scala]]
+ * in method `runCompilerWithContext`
+ *
+ * @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(ctx), fileNames)(ctx)
+ }
+
+ def main(args: Array[String]): Unit = {
+ // Preload scala.util.control.NonFatal. Otherwise, when trying to catch a StackOverflowError,
+ // we may try to load it but fail with another StackOverflowError and lose the original exception,
+ // see <https://groups.google.com/forum/#!topic/scala-user/kte6nak-zPM>.
+ val _ = NonFatal
+ sys.exit(if (process(args).hasErrors) 1 else 0)
+ }
+}