diff --git a/compile/AnalyzingCompiler.scala b/compile/AnalyzingCompiler.scala index 083fae02a..24132ca74 100644 --- a/compile/AnalyzingCompiler.scala +++ b/compile/AnalyzingCompiler.scala @@ -31,12 +31,15 @@ class AnalyzingCompiler(val scalaInstance: ScalaInstance, val manager: Component val arguments = (new CompilerArguments(scalaInstance, cp))(sources, classpath, outputDirectory, options) call("xsbt.ScaladocInterface", log) (classOf[Array[String]], classOf[Int], classOf[xLogger]) (arguments.toArray[String] : Array[String], maximumErrors: java.lang.Integer, log) } - def console(classpath: Seq[File], options: Seq[String], initialCommands: String, log: Logger): Unit = + def console(classpath: Seq[File], options: Seq[String], initialCommands: String, log: Logger)(loader: Option[ClassLoader] = None, bindings: Seq[(String, Any)] = Nil): Unit = { val arguments = new CompilerArguments(scalaInstance, cp) val classpathString = CompilerArguments.absString(arguments.finishClasspath(classpath)) val bootClasspath = if(cp.autoBoot) arguments.createBootClasspath else "" - call("xsbt.ConsoleInterface", log) (classOf[Array[String]], classOf[String], classOf[String], classOf[String], classOf[xLogger]) (options.toArray[String]: Array[String], bootClasspath, classpathString, initialCommands, log) + val (names, values) = bindings.unzip + call("xsbt.ConsoleInterface", log)( + classOf[Array[String]], classOf[String], classOf[String], classOf[String], classOf[ClassLoader], classOf[Array[String]], classOf[Array[Any]], classOf[xLogger])( + options.toArray[String]: Array[String], bootClasspath, classpathString, initialCommands, loader.orNull, names.toArray[String], values.toArray[Any], log) } def force(log: Logger): Unit = getInterfaceJar(log) private def call(interfaceClassName: String, log: Logger)(argTypes: Class[_]*)(args: AnyRef*) diff --git a/compile/api/ShowAPI.scala b/compile/api/ShowAPI.scala index 82df7b85a..bbc08e702 100644 --- a/compile/api/ShowAPI.scala +++ b/compile/api/ShowAPI.scala @@ -269,6 +269,9 @@ trait ShowTypeParameters } } +// this class is a hack to resolve some diverging implicit errors. +// I'm pretty sure the cause is the Show[Seq[T]] dominating Show[X] issue. +// It could probably be reduced a bit if that is the case (below was trial and error) object DefaultShowAPI extends ShowBase with ShowBasicTypes with ShowValueParameters { def apply(d: Definition) = ShowAPI.show(d) diff --git a/compile/interface/ConsoleInterface.scala b/compile/interface/ConsoleInterface.scala index e5568d3cf..6acf881e6 100644 --- a/compile/interface/ConsoleInterface.scala +++ b/compile/interface/ConsoleInterface.scala @@ -4,26 +4,51 @@ package xsbt import xsbti.Logger -import scala.tools.nsc.{GenericRunnerCommand,InterpreterLoop} +import scala.tools.nsc.{GenericRunnerCommand, Interpreter, InterpreterLoop, ObjectRunner, Settings} +import scala.tools.nsc.interpreter.InteractiveReader +import scala.tools.nsc.reporters.Reporter +import scala.tools.nsc.util.ClassPath class ConsoleInterface { - def run(args: Array[String], bootClasspathString: String, classpathString: String, initialCommands: String, log: Logger) + def run(args: Array[String], bootClasspathString: String, classpathString: String, initialCommands: String, loader: ClassLoader, bindNames: Array[String], bindValues: Array[Any], log: Logger) { - val settings = MakeSettings(args.toList, log) + val options = args.toList + lazy val interpreterSettings = xsbt.MakeSettings(options, log) + val compilerSettings = xsbt.MakeSettings(options, log) + if(!bootClasspathString.isEmpty) - settings.bootclasspath.value = bootClasspathString - settings.classpath.value = classpathString + compilerSettings.bootclasspath.value = bootClasspathString + compilerSettings.classpath.value = classpathString log.info(Message("Starting scala interpreter...")) - log.debug(Message(" Classpath: " + settings.classpath.value)) + log.debug(Message(" Boot classpath: " + compilerSettings.bootclasspath.value)) + log.debug(Message(" Classpath: " + compilerSettings.classpath.value)) log.info(Message("")) val loop = new InterpreterLoop { + override def createInterpreter() = { - super.createInterpreter() - if(!initialCommands.isEmpty) interpreter.interpret(initialCommands) + + if(loader ne null) + { + in = InteractiveReader.createDefault() + interpreter = new Interpreter(settings) + { + override protected def parentClassLoader = if(loader eq null) super.parentClassLoader else loader + override protected def newCompiler(settings: Settings, reporter: Reporter) = super.newCompiler(compilerSettings, reporter) + } + interpreter.setContextClassLoader() + } + else + super.createInterpreter() + + for( (id, value) <- bindNames zip bindValues) + interpreter.bind(id, value.asInstanceOf[AnyRef].getClass.getName, value) + + if(!initialCommands.isEmpty) + interpreter.interpret(initialCommands) } } - loop.main(settings) + loop.main(if(loader eq null) compilerSettings else interpreterSettings) } } object MakeSettings diff --git a/main/Console.scala b/main/Console.scala index 239a35bba..97d61a145 100644 --- a/main/Console.scala +++ b/main/Console.scala @@ -1,7 +1,7 @@ /* sbt -- Simple Build Tool - * Copyright 2008, 2009 Mark Harrah + * Copyright 2008, 2009, 2010 Mark Harrah */ -/*package sbt +package sbt import java.io.File import compile.AnalyzingCompiler @@ -9,12 +9,55 @@ import compile.AnalyzingCompiler final class Console(compiler: AnalyzingCompiler) extends NotNull { /** Starts an interactive scala interpreter session with the given classpath.*/ - def apply(classpath: Iterable[File], log: Logger): Option[String] = + def apply(classpath: Seq[File], log: Logger): Option[String] = apply(classpath, Nil, "", log) - def apply(classpath: Iterable[File], options: Seq[String], initialCommands: String, log: Logger): Option[String] = + def apply(classpath: Seq[File], options: Seq[String], initialCommands: String, log: Logger): Option[String] = + apply(classpath, options, initialCommands)(None, Nil)(log) + + def apply(classpath: Seq[File], options: Seq[String], loader: ClassLoader, initialCommands: String)(bindings: (String, Any)*)(implicit log: Logger): Option[String] = + apply(classpath, options, initialCommands)(Some(loader), bindings) + + def apply(classpath: Seq[File], options: Seq[String], initialCommands: String)(loader: Option[ClassLoader], bindings: Seq[(String, Any)])(implicit log: Logger): Option[String] = { - def console0 = compiler.console(Path.getFiles(classpath), options, initialCommands, log) + def console0 = compiler.console(classpath, options, initialCommands, log)(loader, bindings) JLine.withJLine( Run.executeTrapExit(console0, log) ) } -}*/ \ No newline at end of file +} +object Console +{ + val SbtInitial = "import sbt._; import Process._; import current._" + + def apply(conf: build.Compile)(implicit log: Logger): Console = new Console( compiler(conf) ) + def compiler(conf: build.Compile)(implicit log: Logger): AnalyzingCompiler = + { + val componentManager = new ComponentManager(conf.launcher.globalLock, conf.configuration.provider.components, log) + new AnalyzingCompiler(conf.instance, componentManager, log) + } + def sbtDefault(conf: build.Compile, value: Any)(implicit log: Logger) + { + val c = new Console(compiler(conf)) + val loader = value.asInstanceOf[AnyRef].getClass.getClassLoader + c.apply(conf.compileClasspath, Nil, loader, SbtInitial)("current" -> value) + } +} + + +final class Scaladoc(maximumErrors: Int, compiler: AnalyzingCompiler) +{ + final def apply(label: String, sources: Seq[File], classpath: Seq[File], outputDirectory: File, options: Seq[String])(implicit log: Logger) + { + log.info(actionStartMessage(label)) + if(sources.isEmpty) + log.info(actionNothingToDoMessage) + else + { + IO.createDirectory(outputDirectory) + compiler.doc(sources, classpath, outputDirectory, options, maximumErrors, log) + log.info(actionSuccessfulMessage) + } + } + def actionStartMessage(label: String) = "Generating API documentation for " + label + " sources..." + val actionNothingToDoMessage = "No sources specified." + val actionSuccessfulMessage = "API documentation generation successful." +} \ No newline at end of file