aboutsummaryrefslogtreecommitdiff
path: root/sbt-bridge/bridge/src/main/scala/xsbt/CompilerInterface.scala
diff options
context:
space:
mode:
Diffstat (limited to 'sbt-bridge/bridge/src/main/scala/xsbt/CompilerInterface.scala')
-rw-r--r--sbt-bridge/bridge/src/main/scala/xsbt/CompilerInterface.scala72
1 files changed, 72 insertions, 0 deletions
diff --git a/sbt-bridge/bridge/src/main/scala/xsbt/CompilerInterface.scala b/sbt-bridge/bridge/src/main/scala/xsbt/CompilerInterface.scala
new file mode 100644
index 000000000..bf1488dad
--- /dev/null
+++ b/sbt-bridge/bridge/src/main/scala/xsbt/CompilerInterface.scala
@@ -0,0 +1,72 @@
+/* sbt -- Simple Build Tool
+ * Copyright 2008, 2009 Mark Harrah
+ */
+package xsbt
+
+import xsbti.{ AnalysisCallback, Logger, Problem, Reporter, Severity, DependencyContext }
+import xsbti.api.SourceAPI
+import xsbti.compile._
+import Log.debug
+import java.io.File
+
+import dotty.tools.dotc.core.Contexts.ContextBase
+import dotty.tools.dotc.{ Main => DottyMain }
+import dotty.tools.dotc.interfaces._
+
+import java.net.URLClassLoader
+
+final class CompilerInterface {
+ def newCompiler(options: Array[String], output: Output, initialLog: Logger,
+ initialDelegate: Reporter, resident: Boolean): CachedCompiler = {
+ // The classloader that sbt uses to load the compiler bridge is broken
+ // (see CompilerClassLoader#fixBridgeLoader for details). To workaround
+ // this we construct our own ClassLoader and then run the following code
+ // with it:
+ // new CachedCompilerImpl(options, output, resident)
+
+ val bridgeLoader = getClass.getClassLoader
+ val fixedLoader = CompilerClassLoader.fixBridgeLoader(bridgeLoader)
+ val cciClass = fixedLoader.loadClass("xsbt.CachedCompilerImpl")
+ cciClass.getConstructors.head
+ .newInstance(options, output, resident: java.lang.Boolean)
+ .asInstanceOf[CachedCompiler]
+ }
+
+ def run(sources: Array[File], changes: DependencyChanges, callback: AnalysisCallback, log: Logger,
+ delegate: Reporter, progress: CompileProgress, cached: CachedCompiler): Unit =
+ cached.run(sources, changes, callback, log, delegate, progress)
+}
+
+class CachedCompilerImpl(args: Array[String], output: Output, resident: Boolean) extends CachedCompiler {
+ val outputArgs =
+ output match {
+ case multi: MultipleOutput =>
+ ???
+ case single: SingleOutput =>
+ List("-d", single.outputDirectory.getAbsolutePath.toString)
+ }
+
+ def commandArguments(sources: Array[File]): Array[String] =
+ (outputArgs ++ args.toList ++ sources.map(_.getAbsolutePath).sortWith(_ < _)).toArray[String]
+
+ def run(sources: Array[File], changes: DependencyChanges, callback: AnalysisCallback, log: Logger, delegate: Reporter, progress: CompileProgress): Unit = synchronized {
+ run(sources.toList, changes, callback, log, delegate, progress)
+ }
+ private[this] def run(sources: List[File], changes: DependencyChanges, callback: AnalysisCallback, log: Logger, delegate: Reporter, compileProgress: CompileProgress): Unit = {
+ debug(log, args.mkString("Calling Dotty compiler with arguments (CompilerInterface):\n\t", "\n\t", ""))
+ val ctx = (new ContextBase).initialCtx.fresh
+ .setSbtCallback(callback)
+ .setReporter(new DelegatingReporter(delegate))
+
+ val cl = getClass.getClassLoader.asInstanceOf[URLClassLoader]
+
+ val reporter = DottyMain.process(commandArguments(sources.toArray), ctx)
+ if (reporter.hasErrors) {
+ throw new InterfaceCompileFailed(args, Array())
+ }
+ }
+}
+
+class InterfaceCompileFailed(override val arguments: Array[String], override val problems: Array[Problem]) extends xsbti.CompileFailed {
+ override val toString = "Compilation failed"
+}