2009-09-05 21:01:04 +02:00
|
|
|
package xsbt
|
|
|
|
|
|
2010-01-16 01:05:23 +01:00
|
|
|
import sbt.ComponentManager
|
2009-09-05 21:01:04 +02:00
|
|
|
import xsbti.{AnalysisCallback, Logger => xLogger}
|
|
|
|
|
import java.io.File
|
2009-10-08 03:27:53 +02:00
|
|
|
import java.net.{URL, URLClassLoader}
|
2009-09-05 21:01:04 +02:00
|
|
|
|
|
|
|
|
/** Interface to the Scala compiler that uses the dependency analysis plugin. This class uses the Scala library and compiler
|
2009-09-06 22:05:31 +02:00
|
|
|
* provided by scalaInstance. This class requires a ComponentManager in order to obtain the interface code to scalac and
|
|
|
|
|
* the analysis plugin. Because these call Scala code for a different Scala version than the one used for this class, they must
|
|
|
|
|
* be compiled for the version of Scala being used.*/
|
2009-10-10 01:12:14 +02:00
|
|
|
class AnalyzingCompiler(val scalaInstance: ScalaInstance, val manager: ComponentManager) extends NotNull
|
2009-09-05 21:01:04 +02:00
|
|
|
{
|
|
|
|
|
def apply(sources: Set[File], classpath: Set[File], outputDirectory: File, options: Seq[String], callback: AnalysisCallback, maximumErrors: Int, log: CompileLogger): Unit =
|
|
|
|
|
apply(sources, classpath, outputDirectory, options, false, callback, maximumErrors, log)
|
|
|
|
|
def apply(sources: Set[File], classpath: Set[File], outputDirectory: File, options: Seq[String], compilerOnClasspath: Boolean,
|
|
|
|
|
callback: AnalysisCallback, maximumErrors: Int, log: CompileLogger)
|
|
|
|
|
{
|
|
|
|
|
val arguments = (new CompilerArguments(scalaInstance))(sources, classpath, outputDirectory, options, compilerOnClasspath)
|
2009-10-08 03:27:53 +02:00
|
|
|
call("xsbt.CompilerInterface", log)(
|
|
|
|
|
classOf[Array[String]], classOf[AnalysisCallback], classOf[Int], classOf[xLogger] ) (
|
|
|
|
|
arguments.toArray[String] : Array[String], callback, maximumErrors: java.lang.Integer, log )
|
2009-10-03 15:39:16 +02:00
|
|
|
// this is commented out because of Scala ticket #2365
|
2009-10-08 03:27:53 +02:00
|
|
|
/*
|
|
|
|
|
val interface = getInterfaceClass(interface, log).newInstance.asInstanceOf[AnyRef]
|
|
|
|
|
val runnable = interface.asInstanceOf[{ def run(args: Array[String], callback: AnalysisCallback, maximumErrors: Int, log: xLogger): Unit }]
|
2009-10-03 15:39:16 +02:00
|
|
|
// these arguments are safe to pass across the ClassLoader boundary because the types are defined in Java
|
|
|
|
|
// so they will be binary compatible across all versions of Scala
|
|
|
|
|
runnable.run(arguments.toArray, callback, maximumErrors, log)*/
|
|
|
|
|
}
|
|
|
|
|
def doc(sources: Set[File], classpath: Set[File], outputDirectory: File, options: Seq[String], maximumErrors: Int, log: CompileLogger): Unit =
|
|
|
|
|
doc(sources, classpath, outputDirectory, options, false, maximumErrors, log)
|
|
|
|
|
def doc(sources: Set[File], classpath: Set[File], outputDirectory: File, options: Seq[String], compilerOnClasspath: Boolean,
|
|
|
|
|
maximumErrors: Int, log: CompileLogger): Unit =
|
|
|
|
|
{
|
|
|
|
|
val arguments = (new CompilerArguments(scalaInstance))(sources, classpath, outputDirectory, options, compilerOnClasspath)
|
2009-10-08 03:27:53 +02:00
|
|
|
call("xsbt.ScaladocInterface", log) (classOf[Array[String]], classOf[Int], classOf[xLogger]) (arguments.toArray[String] : Array[String], maximumErrors: java.lang.Integer, log)
|
|
|
|
|
}
|
|
|
|
|
def console(classpath: Set[File], initialCommands: String, log: CompileLogger): Unit =
|
|
|
|
|
{
|
2009-10-10 01:12:14 +02:00
|
|
|
val arguments = new CompilerArguments(scalaInstance)
|
|
|
|
|
val classpathString = CompilerArguments.absString(arguments.finishClasspath(classpath, true))
|
|
|
|
|
val bootClasspath = arguments.createBootClasspath
|
2009-10-08 03:27:53 +02:00
|
|
|
call("xsbt.ConsoleInterface", log) (classOf[String], classOf[String], classOf[String], classOf[xLogger]) (bootClasspath, classpathString, initialCommands, log)
|
|
|
|
|
}
|
2010-01-28 00:22:42 +01:00
|
|
|
def force(log: CompileLogger): Unit = getInterfaceJar(log)
|
2009-10-08 03:27:53 +02:00
|
|
|
private def call(interfaceClassName: String, log: CompileLogger)(argTypes: Class[_]*)(args: AnyRef*)
|
|
|
|
|
{
|
|
|
|
|
val interfaceClass = getInterfaceClass(interfaceClassName, log)
|
2009-10-03 15:39:16 +02:00
|
|
|
val interface = interfaceClass.newInstance.asInstanceOf[AnyRef]
|
2009-10-08 03:27:53 +02:00
|
|
|
val method = interfaceClass.getMethod("run", argTypes : _*)
|
2009-10-10 01:12:14 +02:00
|
|
|
try { method.invoke(interface, args: _*) }
|
|
|
|
|
catch { case e: java.lang.reflect.InvocationTargetException => throw e.getCause }
|
2009-10-03 15:39:16 +02:00
|
|
|
}
|
|
|
|
|
private def getInterfaceClass(name: String, log: CompileLogger) =
|
|
|
|
|
{
|
2010-01-28 00:22:42 +01:00
|
|
|
val interfaceJar = getInterfaceJar(log)
|
2009-09-05 21:01:04 +02:00
|
|
|
val dual = createDualLoader(scalaInstance.loader, getClass.getClassLoader) // this goes to scalaLoader for scala classes and sbtLoader for xsbti classes
|
|
|
|
|
val interfaceLoader = new URLClassLoader(Array(interfaceJar.toURI.toURL), dual)
|
2009-10-03 15:39:16 +02:00
|
|
|
Class.forName(name, true, interfaceLoader)
|
2009-09-05 21:01:04 +02:00
|
|
|
}
|
2010-01-28 00:22:42 +01:00
|
|
|
private def getInterfaceJar(log: CompileLogger) =
|
|
|
|
|
{
|
|
|
|
|
// this is the instance used to compile the interface component
|
|
|
|
|
val componentCompiler = newComponentCompiler(log)
|
|
|
|
|
log.debug("Getting " + ComponentCompiler.compilerInterfaceID + " from component compiler for Scala " + scalaInstance.version)
|
|
|
|
|
componentCompiler(ComponentCompiler.compilerInterfaceID)
|
|
|
|
|
}
|
2009-10-03 15:39:16 +02:00
|
|
|
def newComponentCompiler(log: CompileLogger) = new ComponentCompiler(new RawCompiler(scalaInstance, log), manager)
|
2009-09-05 21:01:04 +02:00
|
|
|
protected def createDualLoader(scalaLoader: ClassLoader, sbtLoader: ClassLoader): ClassLoader =
|
|
|
|
|
{
|
|
|
|
|
val xsbtiFilter = (name: String) => name.startsWith("xsbti.")
|
|
|
|
|
val notXsbtiFilter = (name: String) => !xsbtiFilter(name)
|
|
|
|
|
new DualLoader(scalaLoader, notXsbtiFilter, x => true, sbtLoader, xsbtiFilter, x => false)
|
|
|
|
|
}
|
|
|
|
|
override def toString = "Analyzing compiler (Scala " + scalaInstance.actualVersion + ")"
|
2009-10-02 04:59:02 +02:00
|
|
|
}
|