mirror of https://github.com/sbt/sbt.git
Scaladoc, run, and console interfaces
This commit is contained in:
parent
32dae0bfd1
commit
7bb72ecb8b
|
|
@ -2,7 +2,7 @@ package xsbt
|
|||
|
||||
import xsbti.{AnalysisCallback, Logger => xLogger}
|
||||
import java.io.File
|
||||
import java.net.URLClassLoader
|
||||
import java.net.{URL, URLClassLoader}
|
||||
|
||||
/** Interface to the Scala compiler that uses the dependency analysis plugin. This class uses the Scala library and compiler
|
||||
* provided by scalaInstance. This class requires a ComponentManager in order to obtain the interface code to scalac and
|
||||
|
|
@ -16,16 +16,16 @@ class AnalyzingCompiler(scalaInstance: ScalaInstance, manager: ComponentManager)
|
|||
callback: AnalysisCallback, maximumErrors: Int, log: CompileLogger)
|
||||
{
|
||||
val arguments = (new CompilerArguments(scalaInstance))(sources, classpath, outputDirectory, options, compilerOnClasspath)
|
||||
val interfaceClass = getInterfaceClass("xsbt.CompilerInterface", log)
|
||||
val interface = interfaceClass.newInstance.asInstanceOf[AnyRef]
|
||||
call("xsbt.CompilerInterface", log)(
|
||||
classOf[Array[String]], classOf[AnalysisCallback], classOf[Int], classOf[xLogger] ) (
|
||||
arguments.toArray[String] : Array[String], callback, maximumErrors: java.lang.Integer, log )
|
||||
// this is commented out because of Scala ticket #2365
|
||||
/*val runnable = interface.asInstanceOf[{ def run(args: Array[String], callback: AnalysisCallback, maximumErrors: Int, log: xLogger): Unit }]
|
||||
/*
|
||||
val interface = getInterfaceClass(interface, log).newInstance.asInstanceOf[AnyRef]
|
||||
val runnable = interface.asInstanceOf[{ def run(args: Array[String], callback: AnalysisCallback, maximumErrors: Int, log: xLogger): Unit }]
|
||||
// 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)*/
|
||||
|
||||
val method = interfaceClass.getMethod("run", classOf[Array[String]], classOf[AnalysisCallback], classOf[Int], classOf[xLogger])
|
||||
method.invoke(interface, arguments.toArray[String] : Array[String], callback, maximumErrors: java.lang.Integer, 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)
|
||||
|
|
@ -33,10 +33,31 @@ class AnalyzingCompiler(scalaInstance: ScalaInstance, manager: ComponentManager)
|
|||
maximumErrors: Int, log: CompileLogger): Unit =
|
||||
{
|
||||
val arguments = (new CompilerArguments(scalaInstance))(sources, classpath, outputDirectory, options, compilerOnClasspath)
|
||||
val interfaceClass = getInterfaceClass("xsbt.ScaladocInterface", log)
|
||||
call("xsbt.ScaladocInterface", log) (classOf[Array[String]], classOf[Int], classOf[xLogger]) (arguments.toArray[String] : Array[String], maximumErrors: java.lang.Integer, log)
|
||||
}
|
||||
def run(classpath: Set[File], mainClass: String, options: Seq[String], log: CompileLogger)
|
||||
{
|
||||
val arguments = new CompilerArguments(scalaInstance)
|
||||
val classpathURLs = arguments.finishClasspath(classpath, true).toSeq
|
||||
val bootClasspath = FileUtilities.pathSplit( arguments.createBootClasspath )
|
||||
val extraURLs = bootClasspath.filter(_.length > 0).map(new File(_))
|
||||
val classpathArray = (classpathURLs ++ extraURLs).map(_.toURI.toURL).toArray[URL]
|
||||
call("xsbt.RunInterface", log)(classOf[Array[URL]], classOf[String], classOf[Array[String]], classOf[xLogger]) (
|
||||
classpathArray : Array[URL], mainClass, options.toArray[String] : Array[String], log
|
||||
)
|
||||
}
|
||||
def console(classpath: Set[File], initialCommands: String, log: CompileLogger): Unit =
|
||||
{
|
||||
val classpathString = CompilerArguments.absString(classpath)
|
||||
val bootClasspath = (new CompilerArguments(scalaInstance)).createBootClasspath
|
||||
call("xsbt.ConsoleInterface", log) (classOf[String], classOf[String], classOf[String], classOf[xLogger]) (bootClasspath, classpathString, initialCommands, log)
|
||||
}
|
||||
private def call(interfaceClassName: String, log: CompileLogger)(argTypes: Class[_]*)(args: AnyRef*)
|
||||
{
|
||||
val interfaceClass = getInterfaceClass(interfaceClassName, log)
|
||||
val interface = interfaceClass.newInstance.asInstanceOf[AnyRef]
|
||||
val method = interfaceClass.getMethod("run", classOf[Array[String]], classOf[Int], classOf[xLogger])
|
||||
method.invoke(interface, arguments.toArray[String] : Array[String], maximumErrors: java.lang.Integer, log)
|
||||
val method = interfaceClass.getMethod("run", argTypes : _*)
|
||||
method.invoke(interface, args: _*)
|
||||
}
|
||||
private def getInterfaceClass(name: String, log: CompileLogger) =
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package xsbt
|
||||
|
||||
import java.io.File
|
||||
import CompilerArguments.{abs, absString}
|
||||
|
||||
/** Forms the list of options that is passed to the compiler from the required inputs and other options.
|
||||
* The directory containing scala-library.jar and scala-compiler.jar (scalaLibDirectory) is required in
|
||||
|
|
@ -13,11 +14,13 @@ class CompilerArguments(scalaInstance: ScalaInstance)
|
|||
{
|
||||
checkScalaHomeUnset()
|
||||
val bootClasspathOption = Seq("-bootclasspath", createBootClasspath)
|
||||
val cpWithCompiler = classpath ++ (if(compilerOnClasspath) scalaInstance.compilerJar :: Nil else Nil)
|
||||
val classpathOption = Seq("-cp", abs(cpWithCompiler).mkString(File.pathSeparator) )
|
||||
val cpWithCompiler = finishClasspath(classpath, compilerOnClasspath)
|
||||
val classpathOption = Seq("-cp", absString(cpWithCompiler) )
|
||||
val outputOption = Seq("-d", outputDirectory.getAbsolutePath)
|
||||
options ++ outputOption ++ bootClasspathOption ++ classpathOption ++ abs(sources)
|
||||
}
|
||||
def finishClasspath(classpath: Set[File], compilerOnClasspath: Boolean): Set[File] =
|
||||
classpath ++ (if(compilerOnClasspath) scalaInstance.compilerJar :: Nil else Nil)
|
||||
protected def abs(files: Set[File]) = files.map(_.getAbsolutePath)
|
||||
protected def checkScalaHomeUnset()
|
||||
{
|
||||
|
|
@ -25,10 +28,17 @@ class CompilerArguments(scalaInstance: ScalaInstance)
|
|||
assert((scalaHome eq null) || scalaHome.isEmpty, "'scala.home' should not be set (was " + scalaHome + ")")
|
||||
}
|
||||
/** Add the correct Scala library jar to the boot classpath.*/
|
||||
protected def createBootClasspath =
|
||||
def createBootClasspath =
|
||||
{
|
||||
val originalBoot = System.getProperty("sun.boot.class.path", "")
|
||||
val newBootPrefix = if(originalBoot.isEmpty) "" else originalBoot + File.pathSeparator
|
||||
newBootPrefix + scalaInstance.libraryJar.getAbsolutePath
|
||||
}
|
||||
}
|
||||
object CompilerArguments
|
||||
{
|
||||
def abs(files: Seq[File]): Seq[String] = files.map(_.getAbsolutePath)
|
||||
def abs(files: Set[File]): Seq[String] = abs(files.toSeq)
|
||||
def absString(files: Seq[File]): String = abs(files).mkString(File.pathSeparator)
|
||||
def absString(files: Set[File]): String = absString(files.toSeq)
|
||||
}
|
||||
|
|
@ -58,38 +58,4 @@ class CompilerInterface
|
|||
}
|
||||
}
|
||||
}
|
||||
class ScaladocInterface
|
||||
{
|
||||
def run(args: Array[String], maximumErrors: Int, log: Logger)
|
||||
{
|
||||
import scala.tools.nsc.{doc, CompilerCommand, Global}
|
||||
val reporter = new LoggerReporter(maximumErrors, log)
|
||||
val docSettings: doc.Settings = new doc.Settings(reporter.error)
|
||||
val command = new CompilerCommand(args.toList, docSettings, error, false)
|
||||
trait Compat27 { def computeInternalPhases(): Unit = () }
|
||||
val phasesSet = scala.collection.mutable.Set[scala.tools.nsc.SubComponent]() // for 2.7 source compatibility
|
||||
object compiler extends Global(command.settings, reporter) with Compat27
|
||||
{
|
||||
override def onlyPresentation = true
|
||||
override def computeInternalPhases() {
|
||||
phasesSet += syntaxAnalyzer
|
||||
phasesSet += analyzer.namerFactory
|
||||
phasesSet += analyzer.typerFactory
|
||||
}
|
||||
}
|
||||
if(!reporter.hasErrors)
|
||||
{
|
||||
val run = new compiler.Run
|
||||
run compile command.files
|
||||
val generator = new doc.DefaultDocDriver
|
||||
{
|
||||
lazy val global: compiler.type = compiler
|
||||
lazy val settings = docSettings
|
||||
}
|
||||
generator.process(run.units)
|
||||
}
|
||||
reporter.printSummary()
|
||||
if(reporter.hasErrors) throw new InterfaceCompileFailed(args, "Scaladoc generation failed")
|
||||
}
|
||||
}
|
||||
class InterfaceCompileFailed(val arguments: Array[String], override val toString: String) extends xsbti.CompileFailed
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2008, 2009 Mark Harrah
|
||||
*/
|
||||
package xsbt
|
||||
|
||||
import xsbti.Logger
|
||||
import scala.tools.nsc.{GenericRunnerCommand,InterpreterLoop}
|
||||
|
||||
class ConsoleInterface
|
||||
{
|
||||
def run(bootClasspathString: String, classpathString: String, initialCommands: String, log: Logger)
|
||||
{
|
||||
val settings = Settings(log)
|
||||
settings.bootclasspath.value = bootClasspathString
|
||||
settings.classpath.value = classpathString
|
||||
log.info(Message("Starting scala interpreter..."))
|
||||
log.debug(Message(" Classpath: " + settings.classpath.value))
|
||||
log.info(Message(""))
|
||||
val loop = new InterpreterLoop {
|
||||
override def createInterpreter() = {
|
||||
super.createInterpreter()
|
||||
if(!initialCommands.isEmpty) interpreter.interpret(initialCommands)
|
||||
}
|
||||
}
|
||||
loop.main(settings)
|
||||
}
|
||||
}
|
||||
object Settings
|
||||
{
|
||||
def apply(log: Logger) =
|
||||
{
|
||||
val command = new GenericRunnerCommand(Nil, message => log.error(Message(message)))
|
||||
if(command.ok)
|
||||
command.settings
|
||||
else
|
||||
throw new InterfaceCompileFailed(Array(), command.usageMsg)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2008, 2009 Mark Harrah
|
||||
*/
|
||||
package xsbt
|
||||
|
||||
import xsbti.Logger
|
||||
import scala.tools.nsc.ObjectRunner
|
||||
|
||||
import java.net.URL
|
||||
|
||||
class RunInterface
|
||||
{
|
||||
def run(classpathURLs: Array[URL], mainClass: String, options: Array[String], log: Logger)
|
||||
{
|
||||
log.info(Message("Running " + mainClass + " ..."))
|
||||
log.debug(Message(" Classpath:" + classpathURLs.mkString("\n\t", "\n\t","")))
|
||||
try { ObjectRunner.run(classpathURLs.toList, mainClass, options.toList) }
|
||||
catch { case e: java.lang.reflect.InvocationTargetException => throw e.getCause }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/* sbt -- Simple Build Tool
|
||||
* Copyright 2008, 2009 Mark Harrah
|
||||
*/
|
||||
package xsbt
|
||||
|
||||
import xsbti.Logger
|
||||
import scala.tools.nsc.SubComponent
|
||||
|
||||
class ScaladocInterface
|
||||
{
|
||||
def run(args: Array[String], maximumErrors: Int, log: Logger)
|
||||
{
|
||||
import scala.tools.nsc.{doc, CompilerCommand, Global}
|
||||
val reporter = new LoggerReporter(maximumErrors, log)
|
||||
val docSettings: doc.Settings = new doc.Settings(reporter.error)
|
||||
val command = new CompilerCommand(args.toList, docSettings, error, false)
|
||||
trait Compat27 { def computeInternalPhases(): Unit = () }
|
||||
val phasesSet = scala.collection.mutable.Set[scala.tools.nsc.SubComponent]() // for 2.7 source compatibility
|
||||
object compiler extends Global(command.settings, reporter) with Compat27
|
||||
{
|
||||
override def onlyPresentation = true
|
||||
override def computeInternalPhases() {
|
||||
phasesSet += syntaxAnalyzer
|
||||
phasesSet += analyzer.namerFactory
|
||||
phasesSet += analyzer.typerFactory
|
||||
}
|
||||
}
|
||||
if(!reporter.hasErrors)
|
||||
{
|
||||
val run = new compiler.Run
|
||||
run compile command.files
|
||||
val generator = new doc.DefaultDocDriver
|
||||
{
|
||||
lazy val global: compiler.type = compiler
|
||||
lazy val settings = docSettings
|
||||
}
|
||||
generator.process(run.units)
|
||||
}
|
||||
reporter.printSummary()
|
||||
if(reporter.hasErrors) throw new InterfaceCompileFailed(args, "Scaladoc generation failed")
|
||||
}
|
||||
}
|
||||
|
|
@ -369,4 +369,10 @@ object FileUtilities
|
|||
transfer(in, out)
|
||||
out.toByteArray
|
||||
}
|
||||
|
||||
/** A pattern used to split a String by path separator characters.*/
|
||||
private val PathSeparatorPattern = java.util.regex.Pattern.compile(File.pathSeparator)
|
||||
|
||||
/** Splits a String around path separator characters. */
|
||||
def pathSplit(s: String) = PathSeparatorPattern.split(s)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue