summaryrefslogtreecommitdiff
path: root/project/build
diff options
context:
space:
mode:
authormoix <moix@epfl.ch>2010-07-29 09:52:28 +0000
committermoix <moix@epfl.ch>2010-07-29 09:52:28 +0000
commite3ca222e48fa917d631c1ee6ecbc8a594ae76d10 (patch)
treec5c719ee1b38d5f238ee513279fda4f8cb263283 /project/build
parent26bbdbe3a21d17f5b2a94ea528eb4508d2b3b13e (diff)
downloadscala-e3ca222e48fa917d631c1ee6ecbc8a594ae76d10.tar.gz
scala-e3ca222e48fa917d631c1ee6ecbc8a594ae76d10.tar.bz2
scala-e3ca222e48fa917d631c1ee6ecbc8a594ae76d10.zip
First version of SBT build for Scala compiler/l...
First version of SBT build for Scala compiler/library (see README)
Diffstat (limited to 'project/build')
-rw-r--r--project/build/AdditionalResources.scala103
-rw-r--r--project/build/BasicLayer.scala266
-rw-r--r--project/build/Compilation.scala86
-rw-r--r--project/build/CompilationStep.scala38
-rw-r--r--project/build/ExternalTaskRunner.scala34
-rw-r--r--project/build/Packer.scala89
-rwxr-xr-xproject/build/Partest.scala160
-rw-r--r--project/build/PathConfig.scala38
-rw-r--r--project/build/SVN.scala34
-rw-r--r--project/build/ScalaSBTBuilder.scala179
-rw-r--r--project/build/ScalaTools.scala179
-rw-r--r--project/build/Scaladoc.scala51
12 files changed, 1257 insertions, 0 deletions
diff --git a/project/build/AdditionalResources.scala b/project/build/AdditionalResources.scala
new file mode 100644
index 0000000000..3db7fe6ed2
--- /dev/null
+++ b/project/build/AdditionalResources.scala
@@ -0,0 +1,103 @@
+import sbt._
+import java.util.jar.{Manifest}
+import java.io.{FileInputStream}
+import AdditionalResources._
+/**
+ * Additional tasks that are required to obtain a complete compiler and library pair, but that are not part of the
+ * compilation task. It copies additional files and generates the properties files
+ * @author Grégory Moix
+ */
+trait AdditionalResources {
+ self : BasicLayer =>
+
+ lazy val copyAdditionalFiles = task {
+ def copy0(steps:List[Step]):Option[String]= steps match{
+ case x::xs => x match{
+ case c:ResourcesToCopy => {
+ c.copy orElse copy0(xs)
+ }
+ case _ => copy0(xs)
+ }
+ case Nil => None
+ }
+ copy0(allSteps.topologicalSort)
+ }.dependsOn(externalCompilation)
+
+ lazy val writeProperties = task {
+ def write0(steps:List[Step]):Option[String]= steps match{
+ case x::xs => x match{
+ case c:PropertiesToWrite => {
+ c.writeProperties orElse write0(xs)
+ }
+ case _ => write0(xs)
+ }
+ case Nil => None
+ }
+ write0(allSteps.topologicalSort)
+ }.dependsOn(externalCompilation)
+
+
+
+
+}
+
+import sbt._
+import BasicLayer._
+object AdditionalResources {
+ /**
+ * A FileFilter that defines what are the files that will be copied
+ */
+ lazy val basicFilter = "*.tmpl" | "*.xml"| "*.js"| "*.css" | "*.properties" | "*.swf" | "*.png"
+
+}
+
+trait ResourcesToCopy {
+ self : CompilationStep =>
+ def getResources(from:Path,filter:FileFilter):PathFinder = (from ##)** filter
+ def getResources(from:Path):PathFinder = getResources(from,AdditionalResources.basicFilter)
+
+ def copyDestination:Path
+ def filesToCopy:PathFinder
+ def copy = {
+ try{
+ FileUtilities.copy(filesToCopy.get,copyDestination,log)
+ }catch{
+ case e=>Some(e.toString)
+ }
+ None
+ }
+}
+
+trait PropertiesToWrite {
+ self : CompilationStep =>
+
+ def propertyList:List[Tuple2[String,String]]
+ def propertyDestination:Path
+
+ def writeProperties:Option[String]={
+ import java.io._
+ import java.util.Properties
+
+ val properties = new Properties
+
+ def insert(list:List[Tuple2[String,String]]):Unit=list match{
+ case Nil =>
+ case x::xs => {
+ properties setProperty(x._1, x._2)
+ insert(xs)
+ }
+ }
+
+ try{
+ insert(propertyList)
+ val destFile = propertyDestination.asFile
+ val stream = new FileOutputStream(destFile)
+ properties.store(stream, null)
+ }catch{
+ case e => Some(e.toString)
+ }
+ None
+ }
+
+}
+
diff --git a/project/build/BasicLayer.scala b/project/build/BasicLayer.scala
new file mode 100644
index 0000000000..a28b593c1a
--- /dev/null
+++ b/project/build/BasicLayer.scala
@@ -0,0 +1,266 @@
+import sbt._
+import xsbt.{ScalaInstance}
+import BasicLayer._
+import scala.collection.immutable.{EmptyMap}
+
+/**
+ * Basic tasks and configuration shared by all layers. This class regroups the configuration and behaviour
+ * shared by all layers.
+ * @author Grégory Moix
+ */
+abstract class BasicLayer(val info:ProjectInfo,val versionNumber:String, previousLayer:Option[BasicLayer]) extends Project with ReflectiveProject
+ with AdditionalResources with Compilation{
+ override def dependencies = info.dependencies
+ lazy val projectRoot = info.projectPath
+
+ lazy val copyright = property[String]
+ lazy val partestVersionNumber = property[Version]
+
+
+ /**
+ * Before compiling the layer, we need to check that the previous layer
+ * was created correctly and compile it if necessary
+ */
+ lazy val startLayer = previousLayer match {
+ case Some(previous) => task{
+ None
+ }.dependsOn(previous.finishLayer)
+ case None => task{None}
+ }
+
+ lazy val build= task{
+ None
+ }.dependsOn(externalCompilation,copyAdditionalFiles,writeProperties)
+
+ /**
+ * Finish the compilation and ressources copy and generation
+ * It does nothing in itself. As sbt doesn't support conditional dependencies,
+ * it permit locker to override it in order to lock the layer when the compilation
+ * is finished.
+ */
+ lazy val finishLayer = task{None}.dependsOn(build)
+
+ def instanceScope[A](action: ScalaInstance => A):A={
+ val instance = ScalaInstance(instantiationLibraryJar.asFile, instantiationCompilerJar.asFile, info.launcher, msilJar.asFile, fjbgJar.asFile)
+ log.debug("Compiler will be instantiated by :" +instance.compilerJar +" and :" +instance.libraryJar )
+ action(instance)
+ }
+
+ // All path values must be lazy in order to avoid initialization issues (sbt way of doing things)
+ lazy val layerOutput = outputRootPath / name
+ lazy val pathLayout = new PathLayout(projectRoot, layerOutput)
+ lazy val manifestPath = projectRoot/"META-INF"/"MANIFEST.MF"
+
+ // Utility methods (for quick access)
+ def libraryOutput = libraryConfig.outputDirectory
+ def actorsOutput = actorsConfig.outputDirectory
+ def dbcOutput = dbcConfig.outputDirectory
+ def swingOutput = swingConfig.outputDirectory
+ def scalapOutput = scalapConfig.outputDirectory
+ def librarySrcDir = libraryConfig.srcDir
+ def compilerOutput = compilerConfig.outputDirectory
+ def compilerSrcDir = compilerConfig.srcDir
+ def actorsSrcDir = actorsConfig.srcDir
+ def swingSrcDir = swingConfig.srcDir
+ def outputLibraryJar = libraryWS.jarDestination
+ def outputCompilerJar = compilerConfig.jarDestination
+ def outputPartestJar = partestConfig.jarDestination
+ def outputScalapJar = scalapConfig.jarDestination
+
+ // CONFIGURATION OF THE COMPILTATION STEPS
+
+ /**
+ * Configuration of the core library compilation
+ */
+ lazy val libraryConfig = new CompilationStep("library", pathLayout ,log) with ResourcesToCopy with PropertiesToWrite{
+ def label = "["+name+"] library"
+ def options: Seq[String] = Seq("-sourcepath", pathConfig.sources.absolutePath.toString)
+ def dependencies = Nil
+ override def classpath = super.classpath +++ forkJoinJar
+
+ def copyDestination = outputDirectory
+ def filesToCopy = getResources(srcDir)
+
+ def propertyDestination = outputDirectory / "library.properties"
+ def propertyList = ("version.number",versionNumber)::("copyright.string",copyright.value)::Nil
+ }
+
+ /**
+ * Configuration of the compiler
+ */
+ lazy val compilerConfig = new CompilationStep("compiler", pathLayout, log) with ResourcesToCopy with PropertiesToWrite with Packaging{
+ def label = "["+name+"] compiler"
+ private def bootClassPath : String = {
+ System.getProperty("sun.boot.class.path")
+ }
+ override def classpath: PathFinder = super.classpath +++ fjbgJar +++ msilJar +++ jlineJar +++ antJar +++ forkJoinJar
+ def options = Seq("-bootclasspath",bootClassPath)
+ def dependencies = if (minimalCompilation) libraryConfig::Nil else libraryConfig::actorsConfig::dbcConfig::swingConfig::Nil
+
+ def copyDestination = outputDirectory
+ def filesToCopy = getResources(srcDir)
+
+ def propertyDestination = outputDirectory / "compiler.properties"
+ def propertyList = ("version.number",versionNumber)::("copyright.string",copyright.value)::Nil
+
+ def packagingDestination:Path = packingDestination
+ def jarName:String = compilerJarName
+ override def jarsToInclude = compilerAdditionalJars
+ override def manifest = {
+ import java.util.jar.Manifest
+ import java.io.FileInputStream
+ new Manifest(new FileInputStream(manifestPath.asFile))
+ }
+ override def jarContent = List(outputDirectory ##)
+
+ }
+
+ /**
+ * Config of the actors library
+ */
+ lazy val actorsConfig = new CompilationStep ("actors", pathLayout,log){
+ def label = "["+name+"] actors library"
+ override def classpath: PathFinder = super.classpath +++ forkJoinJar
+ def options: Seq[String] = Seq()
+ def dependencies = libraryConfig::Nil
+ }
+
+ /**
+ * Config of the dbc library
+ */
+ lazy val dbcConfig = new CompilationStep("dbc", pathLayout, log) with Packaging{
+ def label = "["+name+"] dbc library"
+ def options: Seq[String] = Seq()
+ def dependencies = libraryConfig::Nil
+
+ def packagingDestination=packingDestination
+ def jarName = dbcJarName
+ def jarContent = List(outputDirectory ##)
+
+ }
+
+ /**
+ * Config of the swing library
+ */
+ lazy val swingConfig = new CompilationStep("swing", pathLayout, log) with Packaging{
+ def label = "["+name+"] swing library"
+ def options: Seq[String] = Seq()
+ def dependencies = libraryConfig::actorsConfig::Nil
+
+ def packagingDestination=packingDestination
+ def jarName = swingJarName
+ def jarContent = List(outputDirectory ##)
+
+ }
+
+
+ /**
+ * Configuration of scalap tool
+ */
+ lazy val scalapConfig = new CompilationStep("scalap", pathLayout,log) with Packaging{
+ def label = "["+name+"] scalap"
+ def options: Seq[String] = Seq()
+ def dependencies = libraryConfig::compilerConfig::Nil
+
+ def packagingDestination=packingDestination
+ def jarName = scalapJarName
+ def jarContent = {
+ val decoderProperties = (srcDir ## )/ "decoder.properties"
+
+ List(outputDirectory ##, decoderProperties)
+ }
+ }
+
+ /**
+ * Configuration of the partest tool
+ */
+ lazy val partestConfig = new CompilationStep("partest", pathLayout,log) with ResourcesToCopy with PropertiesToWrite with Packaging{
+ def label = "["+name+"] partest"
+ override def classpath: PathFinder = super.classpath +++ antJar +++ forkJoinJar
+ def options: Seq[String] = Seq()
+ def dependencies = libraryConfig::compilerConfig::scalapConfig::actorsConfig::Nil
+
+ def copyDestination = outputDirectory
+ def filesToCopy = getResources(srcDir)
+
+ def propertyDestination = outputDirectory / "partest.properties"
+ def propertyList = ("version.number",partestVersionNumber.value.toString)::("copyright.string",copyright.value)::Nil
+
+ def packagingDestination=packingDestination
+ def jarName = partestJarName
+ def jarContent = List(outputDirectory ##)
+ }
+
+ // Grouping compilation steps
+ def minimalCompilation = false // It must be true for locker because we do not nedd to compile everything
+
+ def libraryWS:WrapperStep with Packaging
+ def toolsWS:WrapperStep
+
+
+ lazy val allSteps = new WrapperStep(libraryWS::compilerConfig::toolsWS::Nil)
+
+
+
+
+
+ //Needed Libraries
+ //TODO Check if not possible to manage some of them with the sbt dependency management (ivy)
+ lazy val lib = projectRoot / "lib"
+ lazy val forkJoinJar = lib / forkJoinJarName
+ lazy val jlineJar = lib / jlineJarName
+ lazy val antJar = lib / "ant" / "ant.jar"
+ lazy val fjbgJar = lib / fjbgJarName
+ lazy val msilJar = lib / msilJarName
+
+
+
+
+ //Paths location that must be defined layer by layer
+ /*
+ * We must define which are the libraries used to instantiate the compiler
+ * that will be used to compile this layer.
+ */
+ def instantiationCompilerJar:Path
+ def instantiationLibraryJar:Path
+ def packingDestination :Path = layerOutput / "pack"
+ def compilerAdditionalJars: List[Path] = Nil
+ def libraryAdditionalJars: List[Path] = Nil
+
+
+ /**
+ * Environment for storing properties that
+ * 1) need to be saved across sbt session
+ * 2) Are local to a layer
+ * Used to save the last version of the compiler used to build the layer (for discarding it's product if necessary)
+ */
+ lazy val layerEnvironment = new BasicEnvironment {
+ // use the project's Logger for any properties-related logging
+ def log = BasicLayer.this.log
+
+ // the properties file will be read from/stored to project/extra.properties
+ def envBackingPath = outputRootPath / ("build-"+name+".properties")
+
+ // define some properties that will go in project/extra.properties
+ lazy val lastCompilerVersion:Property[String] = propertyOptional[String]("")
+ }
+}
+
+object BasicLayer{
+ // Some path definitions related strings
+ val compilerJarName = "scala-compiler.jar"
+ val libraryJarName = "scala-library.jar"
+ val scalapJarName = "scalap.jar"
+ val dbcJarName = "scala-dbc.jar"
+ val swingJarName = "scala-swing.jar"
+ val partestJarName = "scala-partest.jar"
+ val fjbgJarName = "fjbg.jar"
+ val msilJarName = "msil.jar"
+ val jlineJarName = "jline.jar"
+ val forkJoinJarName = "forkjoin.jar"
+
+ implicit def stringToGlob(s:String):NameFilter=GlobFilter(s)
+
+
+
+}
diff --git a/project/build/Compilation.scala b/project/build/Compilation.scala
new file mode 100644
index 0000000000..42e3c55902
--- /dev/null
+++ b/project/build/Compilation.scala
@@ -0,0 +1,86 @@
+import sbt._
+import xsbt.{AnalyzingCompiler,ScalaInstance}
+
+/**
+ * This trait define the compilation task. It is possible to configure what it actually compiles by
+ * overriding the compilationSteps methods (useful because locker does not compile everything)
+ * @author Grégory Moix
+ */
+trait Compilation{
+ self : BasicLayer =>
+
+
+ def lastUsedCompilerVersion = layerEnvironment.lastCompilerVersion
+
+ def cleanCompilation:Option[String]= {
+ log.info("Cleaning the products of the compilation.")
+ FileUtilities.clean(layerOutput::Nil,true,log)
+ }
+
+ /**
+ * Execute the different compilation parts one after the others.
+ */
+ def compile:Option[String]={
+
+ instanceScope[Option[String]]{ scala =>
+ lazy val analyzing = new AnalyzingCompiler(scala,componentManager,xsbt.ClasspathOptions.manual,log)
+
+ def compilerVersionHasChanged:Boolean={
+ val lastVersion = lastUsedCompilerVersion.value
+ !(lastVersion.compareTo(scala.actualVersion) == 0)
+
+ }
+
+ def checkAndClean:Option[String]={
+ if (compilerVersionHasChanged){
+ log.info("The compiler version used to build this layer has changed since last time.")
+ lastUsedCompilerVersion.update(scala.actualVersion)
+ layerEnvironment.saveEnvironment
+ cleanCompilation
+ }else{
+ log.debug("The compiler version is unchanged. No need for cleaning.")
+ None
+ }
+ }
+
+ def compile0(steps:List[Step]):Option[String]= steps match{
+ case x::xs => x match{
+ case c:CompilationStep => {
+ val conditional = new CompileConditional(c, analyzing)
+ log.info("")
+ conditional.run orElse compile0(xs)
+ }
+ case _ => compile0(xs)
+ }
+ case Nil => None
+ }
+
+
+ checkAndClean orElse compile0(allSteps.topologicalSort)
+ }
+ }
+
+ /**
+ * Run the actual compilation. Should not be called directly because it is executed on the same jvm and that
+ * it could lead to memory issues. It is used only when launching a new sbt process to do the compilation.
+ */
+ lazy val compilation = task{compile}
+
+ /**
+ * Runs the compilation in another process in order to circumvent memory issues that
+ * arises when compiling every layer on the same jvm.
+ */
+ lazy val externalCompilation:ManagedTask=task{
+ val runner = new ExternalTaskRunner(projectRoot,this.name,compilation.name, log)
+ runner.runTask
+ }.dependsOn(startLayer)
+
+ /**
+ * This method permits to specify what are the different steps of the compilation process,
+ * meaning that you can customize exactly what is compiled by overriding it. It is overriden by
+ * the locker layer that doesn't compile actors, sbc, scalap, partest
+ */
+ def compilationSteps:List[CompileConfiguration] =
+ libraryConfig::actorsConfig::dbcConfig::swingConfig::compilerConfig::scalapConfig::partestConfig::Nil
+
+}
diff --git a/project/build/CompilationStep.scala b/project/build/CompilationStep.scala
new file mode 100644
index 0000000000..02d76b9a54
--- /dev/null
+++ b/project/build/CompilationStep.scala
@@ -0,0 +1,38 @@
+import sbt._
+import BasicLayer._
+trait Step extends Dag[Step] {
+ def dependencies:Iterable[Step]
+}
+
+class WrapperStep(contents:List[Step]) extends Step{
+ def dependencies = contents
+}
+
+abstract class CompilationStep(val name:String, val pathConfig:PathConfig, logger:Logger) extends CompileConfiguration with Step {
+ def this(name:String, layout:PathLayout,logger:Logger) = this(name, layout / name, logger)
+
+ // Utility methods (for quick access, ...)
+ def srcDir = pathConfig.sources
+
+ // Methods required for the compilation
+ def log: Logger = logger
+ def sourceRoots : PathFinder = pathConfig.sources
+ def sources: PathFinder = sourceRoots.descendentsExcept("*.java" | "*.scala", ".svn")
+ def projectPath: Path = pathConfig.projectRoot
+ def analysisPath: Path = pathConfig.analysis
+ def outputDirectory: Path = pathConfig.output
+ def classpath = {
+ def addDependenciesOutputTo(list:List[Step],acc:PathFinder):PathFinder = list match{
+ case Nil => acc
+ case x::xs => x match{
+ case c:CompilationStep => addDependenciesOutputTo(xs,acc +++ c.outputDirectory)
+ case w:WrapperStep => addDependenciesOutputTo(xs, addDependenciesOutputTo(dependencies.toList,acc))
+ }
+ }
+ addDependenciesOutputTo(dependencies.toList,outputDirectory)
+ }
+ def javaOptions: Seq[String] = Seq ("-target","1.5","-source","1.5","-g:none")
+ def maxErrors: Int = 100
+ def compileOrder = CompileOrder.JavaThenScala
+ def fingerprints = Fingerprints(Nil,Nil)
+}
diff --git a/project/build/ExternalTaskRunner.scala b/project/build/ExternalTaskRunner.scala
new file mode 100644
index 0000000000..c9ad97b970
--- /dev/null
+++ b/project/build/ExternalTaskRunner.scala
@@ -0,0 +1,34 @@
+import sbt._
+import ExternalTaskRunner._
+
+/**
+ * Provide a way to launch a specific task in a new sbt instance.
+ * As the compilation process need to be able to compile in a different process (due to memory related
+ * performance issue) and that in order to keep incremental compilation, we allow to launch a task from a
+ * specific project / sub-project in a different instance of sbt that disappear once the task has finished.
+ */
+class ExternalTaskRunner(root:Path,projectName:String, taskName :String, log: Logger ){
+
+ def runTask:Option[String] ={
+
+ val cmd:Seq[String] = Seq("project "+projectName,taskName) // TODO forward logging level (for example debug)
+ val externalSbt = Process(sbtCommand ++ cmd)
+ log.info("Launching task ["+taskName+"] of project ["+projectName+"] in new sbt instance")
+ externalSbt.! match{
+ case 0 => None
+ case _ => Some("External Task Failed")
+ }
+
+ }
+
+}
+
+object ExternalTaskRunner{
+ /**
+ * parameters needed to launch another instance of sbt
+ */
+ val sbtCommand = Seq("sbt") // TODO remove dependency on sbt being on the path of the user
+
+
+
+} \ No newline at end of file
diff --git a/project/build/Packer.scala b/project/build/Packer.scala
new file mode 100644
index 0000000000..8e3be9d9a3
--- /dev/null
+++ b/project/build/Packer.scala
@@ -0,0 +1,89 @@
+import sbt._
+import java.io.{File,FileInputStream}
+import java.util.jar.Manifest
+import BasicLayer._
+import FileUtilities._
+
+/**
+ * Create the jars of pack
+ * @author Grégory Moix
+ */
+trait Packer {
+ self: BasicLayer =>
+
+ def libraryToCopy:List[Path] = Nil
+
+ protected def jarPattern(path:PathFinder) = path.descendentsExcept(AllPassFilter, defaultExcludes || new ExactFilter("MANIFEST.MF")).get
+
+ def createJar(j:Packaging):Option[String] = {
+ def pack0(content:Iterable[Path])=jar(content.flatMap(jarPattern(_)),j.jarDestination, j.manifest, false, log)
+ j.jarsToInclude match {
+ case Nil => pack0(j.jarContent)
+ case list => {
+ withTemporaryDirectory(log) { tmp: File =>
+ val tmpPath = Path.fromFile(tmp)
+ log.debug("List of jars to be added : " +list)
+ def unzip0(l:List[Path]):Option[String] = l match {
+ case x::xs => {unzip(x,tmpPath,log);unzip0(xs)} //TODO properly handle failing of unzip
+ case Nil => None
+ }
+ unzip0(list)
+ log.debug("Content of temp folder"+ tmpPath.##.**( GlobFilter("*")))
+ pack0(j.jarContent ++ Set(tmpPath ##))
+ }
+ }
+ }
+ }
+
+ lazy val pack= task {
+
+ def iterate(steps:List[Step]):Option[String]= steps match{
+ case x::xs => x match{
+ case c:Packaging => {
+ createJar(c) orElse iterate(xs)
+ }
+ case _ => iterate(xs)
+ }
+ case Nil => None
+ }
+
+ def copy0 ={
+ copyFile(manifestPath,packingDestination/"META-INF"/"MANIFEST.MF",log) orElse {
+ copy(libraryToCopy,packingDestination , true,true,log) match {
+ case Right(_) => None
+ case Left(e) => Some(e)
+ }
+ }
+ }
+ iterate(allSteps.topologicalSort) orElse copy0
+ }.dependsOn(finishLayer)
+
+
+
+}
+
+trait Packaging extends Step{
+ def manifest = new Manifest
+ def jarDestination:Path = packagingDestination /"lib" / jarName
+ def packagingDestination:Path
+ def jarName:String
+ def jarsToInclude:List[Path] = Nil
+ def jarContent:Iterable[Path]
+
+}
+
+trait WrapperPackaging extends Packaging {
+ self : WrapperStep =>
+
+ def jarContent = {
+ def getContent(list:List[Step],acc:List[Path]):List[Path]= list match {
+ case Nil => acc
+ case x::xs => x match {
+ case w:WrapperStep => getContent(xs,getContent(w.dependencies.toList,acc))
+ case c:CompilationStep => getContent(xs,(c.outputDirectory ##)::acc)
+ }
+ }
+ getContent(dependencies.toList,Nil)
+ }
+
+}
diff --git a/project/build/Partest.scala b/project/build/Partest.scala
new file mode 100755
index 0000000000..b971c668d9
--- /dev/null
+++ b/project/build/Partest.scala
@@ -0,0 +1,160 @@
+/*
+import sbt._
+import java.io.File
+import java.net.URLClassLoader
+
+trait PartestRunner{
+ self: BasicLayer with Packer =>
+ import Partest._
+ lazy val testRoot = projectRoot / "test"
+ lazy val testFiles = testRoot / "files"
+ lazy val testLibs = testFiles / "lib"
+ lazy val testSuite= task{
+ val config = new TestConfiguration(
+ outputLibraryJar,
+ (outputLibraryJar +++ outputCompilerJar +++ outputPartestJar +++ outputScalapJar +++ antJar +++ jlineJar +++ (testLibs * "*.jar")).get,
+ (testFiles /"pos") * "*.scala",
+ (testFiles /"neg") * "*.scala",
+ (testFiles / "run") ** "*.scala",
+ (testFiles /"jvm") * "*.scala",
+ (testFiles / "res") * "*.res",
+ (testFiles / "buildmanager"),
+ Path.emptyPathFinder,
+ (testFiles/ "shootout") * "*.scala",
+ (testFiles /"scalap") ** "*.scala"
+ )
+ val javaHome = Path.fromFile(new File(System.getProperty("java.home")))
+ val java = javaHome / "bin" / "java"
+ val javac = javaHome / "bin" / "javac"
+
+ runTest(config,Some(java.asFile),Some(javac.asFile),None,Some("2400000"), false,true,false,true,false,log)
+ }
+
+}
+
+
+class TestConfiguration(val library:Path, val classpath:Iterable[Path],
+ posFiles:PathFinder,negFiles:PathFinder,runFiles:PathFinder, jvmFiles:PathFinder,
+ residentFiles:PathFinder,buildManagerFiles:PathFinder,scriptFiles:PathFinder,
+ shootoutFiles:PathFinder,scalapFiles:PathFinder){
+
+
+ private def getFilesAndDirs(path:PathFinder):Array[File]={
+ ( path * AllPassFilter --- (path * ((new ExactFilter(".svn")) || GlobFilter("*.obj")))).getFiles.toArray
+ }
+
+ private def getPosFiles = getFilesAndDirs(posFiles)
+ private def getNegFiles = getFilesAndDirs(negFiles)
+ private def getRunFiles = getFilesAndDirs(runFiles)
+ private def getJvmFiles = getFilesAndDirs(jvmFiles)
+ private def getResidentFiles = getFilesAndDirs(residentFiles)
+ private def getBuildManagerFiles = getFilesAndDirs(buildManagerFiles)
+ private def getScriptFiles = getFilesAndDirs(scriptFiles)
+ private def getShootoutFiles = getFilesAndDirs(shootoutFiles)
+ private def getScalapFiles = getFilesAndDirs(scalapFiles)
+
+ lazy val testFileSets = List(
+ (getPosFiles, "pos", "Compiling files that are expected to build"),
+ (getNegFiles, "neg", "Compiling files that are expected to fail"),
+ (getRunFiles, "run", "Compiling and running files"),
+ (getJvmFiles, "jvm", "Compiling and running files"),
+ (getResidentFiles, "res", "Running resident compiler scenarii"),
+ (getBuildManagerFiles, "buildmanager", "Running Build Manager scenarii"),
+ (getScriptFiles, "script", "Running script files"),
+ (getShootoutFiles, "shootout", "Running shootout tests"),
+ (getScalapFiles, "scalap", "Running scalap tests")
+ )
+
+
+}
+*/
+/**
+ * Based on scala.tools.partest.PartestTask
+ */
+/*
+object Partest{
+
+ def runTest(config:TestConfiguration,javacmd:Option[File],javaccmd:Option[File],scalacOpts:Option[String],timeout:Option[String],
+ showDiff:Boolean,showLog:Boolean,runFailed:Boolean,errorOnFailed:Boolean,debug:Boolean,log:Logger):Option[String] = {
+ if (debug)
+ System.setProperty("partest.debug", "true")
+
+ if (config.classpath.isEmpty)
+ return Some("The classpath is empty")
+
+
+ val classloader = new URLClassLoader(Array(config.classpath.toSeq.map(_.asURL):_*))
+
+ val antRunner: AnyRef =
+ classloader.loadClass("scala.tools.partest.nest.AntRunner").newInstance().asInstanceOf[AnyRef]
+ val antFileManager: AnyRef =
+ antRunner.getClass.getMethod("fileManager", Array[Class[_]](): _*).invoke(antRunner, Array[Object](): _*)
+
+ val runMethod =
+ antRunner.getClass.getMethod("reflectiveRunTestsForFiles", Array(classOf[Array[File]], classOf[String]): _*)
+
+ def runTestsForFiles(kindFiles: Array[File], kind: String): (Int, Int) = {
+ val result = runMethod.invoke(antRunner, Array(kindFiles, kind): _*).asInstanceOf[Int]
+ (result >> 16, result & 0x00FF)
+ }
+
+ def setFileManagerBooleanProperty(name: String, value: Boolean) {
+ val setMethod =
+ antFileManager.getClass.getMethod(name+"_$eq", Array(classOf[Boolean]): _*)
+ setMethod.invoke(antFileManager, Array(java.lang.Boolean.valueOf(value)).asInstanceOf[Array[Object]]: _*)
+ }
+
+ def setFileManagerStringProperty(name: String, value: String) {
+ val setMethod =
+ antFileManager.getClass.getMethod(name+"_$eq", Array(classOf[String]): _*)
+ setMethod.invoke(antFileManager, Array(value).asInstanceOf[Array[Object]]: _*)
+ }
+
+ setFileManagerBooleanProperty("showDiff", showDiff)
+ setFileManagerBooleanProperty("showLog", showLog)
+ setFileManagerBooleanProperty("failed", runFailed)
+ if (!javacmd.isEmpty)
+ setFileManagerStringProperty("JAVACMD", javacmd.get.getAbsolutePath)
+ if (!javaccmd.isEmpty)
+ setFileManagerStringProperty("JAVAC_CMD", javaccmd.get.getAbsolutePath)
+ setFileManagerStringProperty("CLASSPATH", config.classpath.mkString(File.pathSeparator))
+ setFileManagerStringProperty("LATEST_LIB", config.library.absolutePath)
+ if (!scalacOpts.isEmpty)
+ setFileManagerStringProperty("SCALAC_OPTS", scalacOpts.get)
+ if (!timeout.isEmpty)
+ setFileManagerStringProperty("timeout", timeout.get)
+
+ type TFSet = (Array[File], String, String)
+
+ val testFileSets = config.testFileSets
+
+ def runSet(set: TFSet): (Int, Int) = {
+ val (files, name, msg) = set
+ if (files.isEmpty) (0, 0)
+ else {
+ log.info(msg)
+ runTestsForFiles(files, name)
+ }
+ }
+
+ val _results = testFileSets map runSet
+ val allSuccesses = (_results map (_._1)).foldLeft(0)(_+_)
+ val allFailures = (_results map (_._2)).foldLeft(0)(_+_)
+
+ def f(msg:String):Option[String] =
+ if (errorOnFailed && allFailures > 0) Some(msg)
+ else {
+ log.info(msg)
+ None
+ }
+ def s = if (allFailures > 1) "s" else ""
+ val msg =
+ if (allFailures > 0) "Test suite finished with %d case%s failing.".format(allFailures, s)
+ else if (allSuccesses == 0) "There were no tests to run."
+ else "Test suite finished with no failures."
+
+ f(msg)
+ }
+
+
+}*/
diff --git a/project/build/PathConfig.scala b/project/build/PathConfig.scala
new file mode 100644
index 0000000000..3410f7c8e5
--- /dev/null
+++ b/project/build/PathConfig.scala
@@ -0,0 +1,38 @@
+import sbt._
+
+/**
+ * An abstract class for grouping all different paths that are needed to
+ * compile the a CompilationStep
+ * @author Grégory Moix
+ */
+abstract class PathConfig {
+ def projectRoot:Path
+ def sources:Path
+ def analysis:Path
+ def output:Path
+}
+
+/**
+ *
+ */
+
+class PathLayout(val projectRoot:Path, val outputDir:Path) {
+ lazy val srcDir = projectRoot / "src"
+ lazy val classesOutput = outputDir / " classes"
+ lazy val analysisOutput = outputDir / "analysis"
+
+ /**
+ * An utility method to easily create StandardPathConfig from a given path layout
+ */
+ def /(name:String)= new StandardPathConfig(this, name)
+}
+
+/**
+ *
+ */
+class StandardPathConfig(layout: PathLayout, name:String) extends PathConfig{
+ lazy val projectRoot = layout.projectRoot
+ lazy val sources = layout.srcDir / name
+ lazy val analysis = layout.analysisOutput / name
+ lazy val output = layout.classesOutput / name
+}
diff --git a/project/build/SVN.scala b/project/build/SVN.scala
new file mode 100644
index 0000000000..78624f3ba7
--- /dev/null
+++ b/project/build/SVN.scala
@@ -0,0 +1,34 @@
+import sbt._
+import java.io.{ByteArrayOutputStream}
+import scala.util.matching.{Regex}
+
+/**
+ * @param root the root of an svn repository
+ * @author Moix Grégory
+ */
+class SVN(root:Path){
+
+ /**
+ * Gets the revision number of the repository given through the constructor of the class
+ * It assumes that svn is installed on the running computer.
+ */
+ def getRevisionNumber:Int = {
+ val svnInfo = Process("svn info", root)
+ var result=0
+ val out= new ByteArrayOutputStream
+ val code:Int = svnInfo.#>(out).!
+ if(code == 0) {
+ val r = out.toString
+ val Pattern = new Regex("""Revision: (\d+)""","version")
+ val version = Pattern.findFirstMatchIn(r)
+ version match {
+ case Some(s)=> result=Integer.parseInt(s.group("version"))
+ case None => throw new UnableToGetRevisionNumberException
+ }
+ } else {
+ throw new UnableToGetRevisionNumberException
+ }
+ result
+ }
+}
+class UnableToGetRevisionNumberException extends RuntimeException \ No newline at end of file
diff --git a/project/build/ScalaSBTBuilder.scala b/project/build/ScalaSBTBuilder.scala
new file mode 100644
index 0000000000..10b90247bb
--- /dev/null
+++ b/project/build/ScalaSBTBuilder.scala
@@ -0,0 +1,179 @@
+import sbt._
+import BasicLayer._
+
+/**
+ * This class is the entry point for building scala with SBT.
+ * @author Grégory Moix
+ */
+class ScalaSBTBuilder(val info: ProjectInfo) extends Project with ReflectiveProject {
+ override def dependencies: Iterable[Project] = info.dependencies ++ locker.dependencies ++ quick.dependencies ++ strap.dependencies
+ override def shouldCheckOutputDirectories = false
+
+ // Main Tasks
+
+ lazy val replaceLocker=task{None}.dependsOn(locker.unlock)
+ lazy val build = task{None}.dependsOn(quick.binPack,quick.binQuick)
+ lazy val docs = quick.scaladoc
+
+ // Top level variables
+
+ /**
+ * The version number of the compiler that will be created by the run of sbt. It is initialised once
+ * the first time it is needed, meaning that this number will be kept
+ * until sbt quit.
+ */
+ lazy val versionNumber:String ={
+ def getTimeString:String ={
+ import java.util.Calendar;
+ import java.text.SimpleDateFormat;
+ val formatString = "yyyyMMddHHmmss"
+ new SimpleDateFormat(formatString) format( Calendar.getInstance.getTime)
+ }
+ def getVersion:String ={
+ val version:String = projectVersion.value.toString
+ val stopIndex = version.lastIndexOf('-')
+ stopIndex match{
+ case -1 => version
+ case i => version substring(0,i)
+ }
+ }
+ def getRevision:Int = {
+ new SVN(info.projectPath).getRevisionNumber
+ }
+
+ getVersion+".r"+getRevision+"-b"+getTimeString
+ }
+
+
+
+ /* LAYER DEFINITIONS
+ * We define here what's specific to each layer are they differ.
+ * The common behavior is defined in the BasicLayer class
+ * It is important that the class that extends BasicLayer are inner classes of ScalaSBTBuilder. If not, SBT will
+ * not know what the main project definition is, as it will find many classes that extends Project
+ */
+
+ lazy val locker=project(info.projectPath,"locker", new LockerLayer(_))
+ lazy val quick=project(info.projectPath,"quick",new QuickLayer(_,locker))
+ lazy val strap=project(info.projectPath,"strap", new StrapLayer(_, quick))
+
+ /**
+ * Definition of what is specific to the locker layer. It implements SimplePacker in order to
+ * be able to create palo (packed locker)
+ */
+ class LockerLayer(info:ProjectInfo) extends BasicLayer(info,versionNumber,None) with Packer{
+
+ import BasicLayer._
+
+ lazy val instantiationCompilerJar = lib / compilerJarName
+ lazy val instantiationLibraryJar = lib / libraryJarName
+ lazy val lockFile = layerOutput / "locker.lock"
+
+ /**
+ * We override the definition of the task method in order to make the tasks of this layer
+ * be executed only if the layer is not locked. Task of this layer that should be executed
+ * whether the layer is locked or not should call super.task instead
+ */
+ override def task(action : => Option[String])=
+ super.task{
+ if (lockFile.exists) {
+ log.info(name +" is locked")
+ None
+ }
+ else action
+ }
+
+ /**
+ * Task for locking locker
+ */
+ lazy val lock = super.task{
+ log.info("locking "+name)
+ FileUtilities.touch(lockFile,log)
+ }
+
+ /**
+ * Task for unlocking locker
+ */
+ lazy val unlock = super.task{
+ FileUtilities.clean(lockFile,log)
+ }
+
+ /**
+ * Making locker being locked when it has finished building
+ */
+ override lazy val finishLayer = lock.dependsOn(build)
+
+
+ override lazy val packingDestination:Path = outputRootPath /"palo"
+
+ /**
+ * We must override the compilation steps as we only want to compile
+ * the core library (and not actors,dbc, scalap, partest)
+ */
+ override lazy val libraryWS = {
+ new WrapperStep(libraryConfig::Nil) with WrapperPackaging{
+ def jarName = libraryJarName
+ def packagingDestination = packingDestination
+ }
+ }
+ override val minimalCompilation = true
+ override lazy val toolsWS = new WrapperStep(Nil)
+ }
+
+
+ /**
+ * Definition of what is specific to the quick layer. It implements Packer in order to create pack, ScalaTools
+ * for creating the binaries and Scaladoc to generate the documentation
+ */
+ class QuickLayer(info:ProjectInfo, previous:BasicLayer) extends BasicLayer(info,versionNumber,Some(previous))
+ with Packer with ScalaTools with Scaladoc{
+
+ lazy val instantiationCompilerJar = previous.compilerOutput
+ lazy val instantiationLibraryJar = previous.libraryOutput
+
+
+ override lazy val packingDestination:Path = outputRootPath/ "pack"
+ override def libraryToCopy = jlineJar::Nil
+ override def compilerAdditionalJars = msilJar::fjbgJar::Nil
+ override def libraryAdditionalJars = forkJoinJar::Nil
+
+
+ override lazy val libraryWS = new WrapperStep(libraryConfig::actorsConfig::dbcConfig::swingConfig::Nil)with Packaging{
+ def jarName = libraryJarName
+ def packagingDestination = packingDestination
+ def jarContent = List(libraryConfig.outputDirectory ## , actorsConfig.outputDirectory ## )
+ override def jarsToInclude = libraryAdditionalJars
+ }
+ override lazy val toolsWS = new WrapperStep(scalapConfig::partestConfig::Nil)
+
+
+
+ /*
+ * Defining here the creation of the binaries for quick and pack
+ */
+ private lazy val quickBinClasspath = libraryOutput::actorsOutput::dbcOutput::swingOutput::compilerOutput::scalapOutput::forkJoinJar::fjbgJar::msilJar::jlineJar::Nil
+ private lazy val packBinClasspath = Nil
+ lazy val binQuick = tools(layerOutput / "bin", quickBinClasspath).dependsOn(finishLayer)
+ lazy val binPack = tools(packingDestination / "bin", packBinClasspath).dependsOn(pack)
+
+
+ }
+
+
+ /**
+ * Definition of what is specific to the strap layer
+ */
+ class StrapLayer(info:ProjectInfo, previous:BasicLayer) extends BasicLayer(info,versionNumber,Some(previous)) {
+
+ lazy val instantiationCompilerJar = previous.compilerOutput
+ lazy val instantiationLibraryJar = previous.libraryOutput
+
+ override lazy val libraryWS = new WrapperStep(libraryConfig::actorsConfig::dbcConfig::swingConfig::Nil) with WrapperPackaging{
+ def jarName = libraryJarName
+ def packagingDestination = packingDestination
+ }
+
+ override lazy val toolsWS= new WrapperStep(scalapConfig::partestConfig::Nil)
+
+ }
+}
diff --git a/project/build/ScalaTools.scala b/project/build/ScalaTools.scala
new file mode 100644
index 0000000000..a182498467
--- /dev/null
+++ b/project/build/ScalaTools.scala
@@ -0,0 +1,179 @@
+import java.io.{FileInputStream, File, InputStream, FileWriter}
+import sbt._
+import scala.io._
+
+/**
+ * Create the scala binaries
+ * Based on scala.tools.ant.ScalaTool
+ * @author Grégory Moix (for the sbt adaptation)
+ */
+trait ScalaTools{
+ self:BasicLayer =>
+
+ lazy val templatesLocation = compilerConfig.srcDir/ "scala" / "tools" / "ant" / "templates"
+ lazy val unixTemplate = templatesLocation / "tool-unix.tmpl"
+ lazy val winTemplate = templatesLocation / "tool-windows.tmpl"
+
+
+ // XXX encoding and generalize
+ private def getResourceAsCharStream(resource: Path): Stream[Char] = {
+ val stream = new FileInputStream(resource.asFile)
+ def streamReader():Stream[Char]= stream.read match{
+ case -1 => Stream.empty
+ case value => Stream.cons(value.asInstanceOf[Char], streamReader())
+
+ }
+ if (stream == null) {
+ log.debug("Stream was null")
+ Stream.empty
+ }
+
+ //else Stream continually stream.read() takeWhile (_ != -1) map (_.asInstanceOf[Char]) // Does not work in scala 2.7.7
+ else streamReader
+ }
+
+
+ // Converts a variable like @SCALA_HOME@ to ${SCALA_HOME} when pre = "${" and post = "}"
+ private def transposeVariableMarkup(text: String, pre: String, post: String) : String = {
+ val chars = Source.fromString(text)
+ val builder = new StringBuilder()
+
+ while (chars.hasNext) {
+ val char = chars.next
+ if (char == '@') {
+ var char = chars.next
+ val token = new StringBuilder()
+ while (chars.hasNext && char != '@') {
+ token.append(char)
+ char = chars.next
+ }
+ if (token.toString == "")
+ builder.append('@')
+ else
+ builder.append(pre + token.toString + post)
+ } else builder.append(char)
+ }
+ builder.toString
+ }
+
+ private def readAndPatchResource(resource: Path, tokens: Map[String, String]): String = {
+ val chars = getResourceAsCharStream(resource).elements
+ val builder = new StringBuilder()
+
+ while (chars.hasNext) {
+ val char = chars.next
+ if (char == '@') {
+ var char = chars.next
+ val token = new StringBuilder()
+ while (chars.hasNext && char != '@') {
+ token.append(char)
+ char = chars.next
+ }
+ if (tokens.contains(token.toString))
+ builder.append(tokens(token.toString))
+ else if (token.toString == "")
+ builder.append('@')
+ else
+ builder.append("@" + token.toString + "@")
+ } else builder.append(char)
+ }
+ builder.toString
+ }
+
+ private def writeFile(file: File, content: String, makeExecutable:Boolean):Option[String] =
+ if (file.exists() && !file.canWrite())
+ Some("File " + file + " is not writable")
+ else {
+ val writer = new FileWriter(file, false)
+ writer.write(content)
+ writer.close()
+ file.setExecutable(makeExecutable)
+ None
+ }
+
+ /** Gets the value of the classpath attribute in a Scala-friendly form.
+ * @return The class path as a list of files. */
+ private def getUnixclasspath(classpath:List[String]): String =
+ transposeVariableMarkup(classpath.mkString("", ":", "").replace('\\', '/'), "${", "}")
+
+ /** Gets the value of the classpath attribute in a Scala-friendly form.
+ * @return The class path as a list of files. */
+ private def getWinclasspath(classpath:List[String]): String =
+ transposeVariableMarkup(classpath.mkString("", ";", "").replace('/', '\\'), "%", "%")
+
+ /** Performs the tool creation of a tool with for a given os
+ * @param file
+ * @param mainClas
+ * @param properties
+ * @param javaFlags
+ * @param toolFlags
+ * @param classPath
+ * @param template
+ * @param classpathFormater
+ */
+ private def tool(template:Path,classpathFormater: List[String]=>String, file:Path,mainClass:String,
+ properties:String,javaFlags:String,toolFlags:String,classPath:List[Path],makeExecutable:Boolean):Option[String] = {
+ val patches = Map (
+ ("class", mainClass),
+ ("properties", properties),
+ ("javaflags", javaFlags),
+ ("toolflags", toolFlags),
+ ("classpath", classpathFormater(classPath.map(_.absolutePath)))
+ )
+
+ val result = readAndPatchResource(template,patches)
+ writeFile(file.asFile,result,makeExecutable)
+
+ }
+ private def generateTool(config:ToolConfiguration):Option[String] =
+ generateTool(config.toolName,config.destination,config.mainClass,config.properties,config.javaFlags,config.toolFlags,config.classPath)
+
+ private def generateTool(toolName:String,destination:Path,mainClass:String, properties:String,javaFlags:String,toolFlags:String,classPath:List[Path]):Option[String] ={
+ val unixFile = destination / toolName
+ val winFile = destination /(toolName + ".bat")
+ tool(unixTemplate,getUnixclasspath,unixFile,mainClass, properties,javaFlags,toolFlags,classPath,true) orElse
+ tool(winTemplate,getWinclasspath,winFile,mainClass, properties,javaFlags,toolFlags,classPath,false)
+ }
+
+
+ /*============================================================================*\
+ ** Definition of the different tools **
+ \*============================================================================*/
+ private val defaultJavaFlags = "-Xmx256M -Xms32M"
+
+ /**
+ * A class that holds the different parameters of a tool
+ */
+ class ToolConfiguration(val toolName:String, val destination:Path, val mainClass:String, val properties:String, val javaFlags:String,val toolFlags:String,val classPath:List[Path])
+
+ /**
+ * Generate all tools
+ * @param destination Root folder where all the binaries will be written
+ * @param classpath Should be specified when you want to use a specific classpath, could be Nil if you want
+ * to make the bin use what is in the lib folder of the distribution.
+ */
+ def tools(destination:Path,classpath:List[Path]) = task{
+ val scala = new ToolConfiguration("scala", destination, "scala.tools.nsc.MainGenericRunner", "",defaultJavaFlags, "", classpath)
+ val scalac = new ToolConfiguration("scalac", destination, "scala.tools.nsc.Main", "",defaultJavaFlags, "", classpath)
+ val scaladoc = new ToolConfiguration("scaladoc",destination,"scala.tools.nsc.ScalaDoc", "",defaultJavaFlags,"", classpath)
+ val fsc = new ToolConfiguration("fsc", destination,"scala.tools.nsc.CompileClient", "",defaultJavaFlags, "", classpath)
+ val scalap = new ToolConfiguration("scalap",destination, "scala.tools.scalap.Main", "",defaultJavaFlags, "", classpath)
+
+
+ val toolList = scala ::scalac::scaladoc::fsc::scalap::Nil
+
+ def process(list:List[ToolConfiguration]):Option[String] = list match{
+ case x::xs => {
+ log.debug("Generating "+x.toolName+" bin")
+ generateTool(x) orElse process(xs)
+ }
+ case Nil => None
+
+ }
+ FileUtilities.createDirectory(destination,log)
+ process(toolList)
+
+ }
+}
+
+
diff --git a/project/build/Scaladoc.scala b/project/build/Scaladoc.scala
new file mode 100644
index 0000000000..d96fd4e3ae
--- /dev/null
+++ b/project/build/Scaladoc.scala
@@ -0,0 +1,51 @@
+import sbt._
+import xsbt.AnalyzingCompiler
+
+trait Scaladoc{
+ self:BasicLayer with Packer =>
+
+ lazy val documentationDestination = outputRootPath / "scaladoc"
+ lazy val libraryDocumentationDestination = documentationDestination / "library"
+ lazy val compilerDocumentationDestination = documentationDestination / "compiler"
+ lazy val libraryDoc= {
+ val reflect = librarySrcDir / "scala" / "reflect"
+ val runtime = librarySrcDir / "scala" / "runtime"
+
+ ((librarySrcDir +++ actorsSrcDir +++ swingSrcDir)**("*.scala")---
+ reflect / "Code.scala" ---
+ reflect / "Manifest.scala" ---
+ reflect / "Print.scala" ---
+ reflect / "Symbol.scala" ---
+ reflect / "Tree.scala" ---
+ reflect / "Type.scala" ---
+ reflect / "TypedCode.scala" ---
+ runtime /"ScalaRunTime.scala" ---
+ runtime / "StreamCons.scala" ---
+ runtime / "StringAdd.scala" ---
+ runtime * ("*$.scala") ---
+ runtime *("*Array.scala")
+ )
+
+ }
+ lazy val compilerDoc = {
+ compilerSrcDir **("*.scala")
+ }
+ lazy val classpath ={
+ (antJar +++ jlineJar +++ msilJar +++ fjbgJar +++ forkJoinJar +++ outputLibraryJar +++ outputCompilerJar +++ outputPartestJar +++ outputScalapJar ).get
+
+ }
+ lazy val scaladoc = task{
+ val externalSbt = new ExternalTaskRunner(projectRoot,this.name,generateScaladoc.name,log)
+ externalSbt.runTask
+ }.dependsOn(pack)
+
+ lazy val generateScaladoc=task{
+ instanceScope[Option[String]]{ scala =>
+ lazy val compiler = new AnalyzingCompiler(scala,componentManager,xsbt.ClasspathOptions.manual,log)
+ val docGenerator = new sbt.Scaladoc(50,compiler)
+ docGenerator("Scala "+ versionNumber+" API", libraryDoc.get, classpath, libraryDocumentationDestination, Seq(), log) orElse
+ docGenerator("Scala Compiler"+ versionNumber+" API", compilerDoc.get, classpath, compilerDocumentationDestination, Seq(), log)
+ }
+ }
+
+}