summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorGilles Dubochet <gilles.dubochet@epfl.ch>2008-02-29 14:31:10 +0000
committerGilles Dubochet <gilles.dubochet@epfl.ch>2008-02-29 14:31:10 +0000
commit941b8cc5604b2cbc15c8de55fa84fc62146408a4 (patch)
treedac4d1014ce460f23b1ad108357399868984f6ae /src/compiler
parent50d638aa63b1c7ec8c1b9fad4cd62880f87cd781 (diff)
downloadscala-941b8cc5604b2cbc15c8de55fa84fc62146408a4.tar.gz
scala-941b8cc5604b2cbc15c8de55fa84fc62146408a4.tar.bz2
scala-941b8cc5604b2cbc15c8de55fa84fc62146408a4.zip
First step towards a faster commit build.
1. Added new Ant tasks to build the compiler in a memory-efficient way. 2. Modified Partest to make it more extensible and added an Ant task to run it. 3. Created a SuperSABBUS build file (beta) using these new tasks.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/ant/Same.scala170
-rw-r--r--src/compiler/scala/tools/ant/antlib.xml4
-rw-r--r--src/compiler/scala/tools/ant/sabbus/Break.scala26
-rw-r--r--src/compiler/scala/tools/ant/sabbus/CompilationFailure.scala11
-rw-r--r--src/compiler/scala/tools/ant/sabbus/Compiler.scala46
-rw-r--r--src/compiler/scala/tools/ant/sabbus/CompilerSettings.scala90
-rw-r--r--src/compiler/scala/tools/ant/sabbus/CompilerTest.scala47
-rw-r--r--src/compiler/scala/tools/ant/sabbus/Compilers.scala45
-rw-r--r--src/compiler/scala/tools/ant/sabbus/ForeignCompiler.scala49
-rw-r--r--src/compiler/scala/tools/ant/sabbus/Make.scala94
-rw-r--r--src/compiler/scala/tools/ant/sabbus/Use.scala69
-rw-r--r--src/compiler/scala/tools/ant/sabbus/antlib.xml8
12 files changed, 659 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/ant/Same.scala b/src/compiler/scala/tools/ant/Same.scala
new file mode 100644
index 0000000000..3f67531452
--- /dev/null
+++ b/src/compiler/scala/tools/ant/Same.scala
@@ -0,0 +1,170 @@
+/* __ *\
+** ________ ___ / / ___ Scala Ant Tasks **
+** / __/ __// _ | / / / _ | (c) 2005-2007, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id: ScalaTool.scala 11911 2007-06-05 15:57:59Z odersky $
+
+package scala.tools.ant
+
+import java.io.{File, FileInputStream}
+
+import org.apache.tools.ant.{BuildException, Project}
+import org.apache.tools.ant.taskdefs.MatchingTask
+import org.apache.tools.ant.util.FileUtils
+import org.apache.tools.ant.util.{FileNameMapper, IdentityMapper}
+
+import org.apache.tools.ant.types.Mapper
+
+/** <p>
+ * An Ant task that, for a set of files, tests them for byte-to-byte
+ * equality with one or more other files.
+ * This task supports the following parameters as attributes:
+ * </p><ul>
+ * <li>dir</li>
+ * <li>todir</li>
+ * <li>resultproperty (a property to be set when all tested files pairs are equal, if not set, the task will fail instead),</li>
+ * <li>failing (whether to stop if all files are not equal).</li></ul>
+ * <p>It also support the following nested elements:</p><ul>
+ * <li>mapper (a mapper from original files to test files).</li></ul>
+ * <p>This task itself defines a fileset that represents the set of original files.</p>
+ *
+ * @author Gilles Dubochet
+ * @version 1.0 */
+class Same extends MatchingTask {
+
+ /** The unique Ant file utilities instance to use in this task. */
+ private val fileUtils = FileUtils.newFileUtils()
+
+/*============================================================================*\
+** Ant user-properties **
+\*============================================================================*/
+
+ private var origin: Option[File] = None
+ private var destination: Option[File] = None
+
+ private var resultProperty: Option[String] = None
+ private var failing: Boolean = false
+
+ private var mapperElement: Option[Mapper] = None
+
+/*============================================================================*\
+** Properties setters **
+\*============================================================================*/
+
+ def setDir(input: File) =
+ origin = Some(input)
+
+ def setTodir(input: File) =
+ destination = Some(input)
+
+ def setResultproperty(input: String) =
+ resultProperty = Some(input)
+
+ def setFailondifferent(input: Boolean) =
+ failing = input
+
+ def createMapper(): Mapper =
+ if (mapperElement.isEmpty) {
+ val mapper = new Mapper(getProject)
+ mapperElement = Some(mapper)
+ mapper
+ }
+ else throw new BuildException("Cannot define more than one mapper", getLocation)
+
+ def add(fileNameMapper: FileNameMapper) =
+ createMapper().add(fileNameMapper)
+
+/*============================================================================*\
+** Properties getters **
+\*============================================================================*/
+
+ private def getMapper: FileNameMapper = mapperElement match {
+ case None =>
+ new IdentityMapper()
+ case Some(me) =>
+ me.getImplementation
+ }
+
+/*============================================================================*\
+** Support methods **
+\*============================================================================*/
+
+ private var allEqualNow = true
+
+ /** Tests if all mandatory attributes are set and valid. */
+ private def validateAttributes = {
+ if (origin.isEmpty) error("Mandatory attribute 'dir' is not set.")
+ if (destination.isEmpty) error("Mandatory attribute 'todir' is not set.")
+ }
+
+ private def reportDiff(f1: File, f2: File) = {
+ allEqualNow = false
+ log("File '" + f1 + "' is different from correspondant.")
+ }
+
+ private def reportMissing(f1: File) = {
+ allEqualNow = false
+ log("File '" + f1 + "' has no correspondant.")
+ }
+
+/*============================================================================*\
+** The big execute method **
+\*============================================================================*/
+
+ override def execute() = {
+ validateAttributes
+ val mapper = getMapper
+ allEqualNow = true
+ val originNames: Array[String] = getDirectoryScanner(origin.get).getIncludedFiles
+ val bufferSize = 1024
+ val originBuffer = new Array[Byte](bufferSize)
+ val destBuffer = new Array[Byte](bufferSize)
+ for (
+ originName: String <- originNames;
+ destName: String <- mapper.mapFileName(originName.toString)
+ ) {
+ //println("originName="+originName)
+ //println("destName ="+destName)
+ var equalNow = true
+ val originFile = new File(origin.get, originName)
+ val destFile = new File(destination.get, destName)
+ if (originFile.canRead && destFile.canRead) {
+ val originStream = new FileInputStream(originFile)
+ val destStream = new FileInputStream(destFile)
+ var originRemaining = originStream.read(originBuffer)
+ var destRemaining = destStream.read(destBuffer)
+ while (originRemaining > 0 && equalNow) {
+ if (originRemaining == destRemaining)
+ for (idx <- 0 until originRemaining)
+ equalNow = equalNow && (originBuffer(idx) == destBuffer(idx))
+ else
+ equalNow = false
+ originRemaining = originStream.read(originBuffer)
+ destRemaining = destStream.read(destBuffer)
+ }
+ if (destRemaining > 0)
+ equalNow = false
+ if (!equalNow)
+ reportDiff(originFile, destFile)
+ originStream.close
+ destStream.close
+ }
+ else reportMissing(originFile)
+ }
+ if (!allEqualNow)
+ if (failing)
+ error("There were differences between '" + origin.get + "' and '" + destination.get + "'")
+ else
+ log("There were differences between '" + origin.get + "' and '" + destination.get + "'")
+ else {
+ if (!resultProperty.isEmpty)
+ getProject.setProperty(resultProperty.get, "yes")
+ log("All files in '" + origin.get + "' and '" + destination.get + "' are equal", Project.MSG_VERBOSE)
+ }
+ }
+
+}
diff --git a/src/compiler/scala/tools/ant/antlib.xml b/src/compiler/scala/tools/ant/antlib.xml
index 2f8565e896..347ad2319d 100644
--- a/src/compiler/scala/tools/ant/antlib.xml
+++ b/src/compiler/scala/tools/ant/antlib.xml
@@ -11,6 +11,10 @@
classname="scala.tools.ant.ScalaBazaar"/>
<taskdef name="scaladoc"
classname="scala.tools.ant.Scaladoc"/>
+ <taskdef name="scalatool"
+ classname="scala.tools.ant.ScalaTool"/>
+ <taskdef name="same"
+ classname="scala.tools.ant.Same"/>
<!--<taskdef name="scalatest"
classname="scala.tools.ant.ScalaDoc"/>-->
</antlib>
diff --git a/src/compiler/scala/tools/ant/sabbus/Break.scala b/src/compiler/scala/tools/ant/sabbus/Break.scala
new file mode 100644
index 0000000000..f1d9029b1d
--- /dev/null
+++ b/src/compiler/scala/tools/ant/sabbus/Break.scala
@@ -0,0 +1,26 @@
+/* __ *\
+** ________ ___ / / ___ Scala Ant Tasks **
+** / __/ __// _ | / / / _ | (c) 2005-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.tools.ant.sabbus
+
+import org.apache.tools.ant.Task
+
+class Break extends Task {
+
+ def setId(input: String): Unit = {
+ id = Some(input)
+ }
+
+ private var id: Option[String] = None
+
+ override def execute: Unit = {
+ if (id.isEmpty) error("Attribute 'id' is not set")
+ Compilers.break(id.get)
+ }
+
+}
diff --git a/src/compiler/scala/tools/ant/sabbus/CompilationFailure.scala b/src/compiler/scala/tools/ant/sabbus/CompilationFailure.scala
new file mode 100644
index 0000000000..fc1fa05557
--- /dev/null
+++ b/src/compiler/scala/tools/ant/sabbus/CompilationFailure.scala
@@ -0,0 +1,11 @@
+/* __ *\
+** ________ ___ / / ___ Scala Ant Tasks **
+** / __/ __// _ | / / / _ | (c) 2005-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.tools.ant.sabbus
+
+case class CompilationFailure(message: String, cause: Exception) extends Exception(message, cause)
diff --git a/src/compiler/scala/tools/ant/sabbus/Compiler.scala b/src/compiler/scala/tools/ant/sabbus/Compiler.scala
new file mode 100644
index 0000000000..61f4fedafe
--- /dev/null
+++ b/src/compiler/scala/tools/ant/sabbus/Compiler.scala
@@ -0,0 +1,46 @@
+/* __ *\
+** ________ ___ / / ___ Scala Ant Tasks **
+** / __/ __// _ | / / / _ | (c) 2005-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.tools.ant.sabbus
+
+import java.io.File
+import java.net.URL
+import java.lang.reflect.InvocationTargetException
+
+class Compiler(classpath: Array[URL], val settings: CompilerSettings) {
+
+ private lazy val classLoader: ClassLoader =
+ new java.net.URLClassLoader(classpath, null)
+
+ private lazy val foreignCompilerName: String =
+ "scala.tools.ant.sabbus.ForeignCompiler"
+ private lazy val foreignCompiler: AnyRef =
+ classLoader.loadClass(foreignCompilerName).newInstance.asInstanceOf[AnyRef]
+
+ foreignInvoke("args_$eq", Array(classOf[String]), Array(settings.toArgs))
+
+ private def foreignInvoke(method: String, types: Array[Class[T] forSome { type T }] , args: Array[AnyRef]) =
+ try {
+ foreignCompiler.getClass.getMethod(method, types).invoke(foreignCompiler, args)
+ }
+ catch {
+ case e: InvocationTargetException => throw e.getCause
+ }
+
+ def compile(files: Array[File]): (Int, Int) = //(errors, warnings)
+ try {
+ val result =
+ foreignInvoke("compile", Array(classOf[Array[File]]), Array(files)).asInstanceOf[Int]
+ (result >> 16, result & 0x00FF)
+ }
+ catch {
+ case ex: Exception =>
+ throw CompilationFailure(ex.getMessage, ex)
+ }
+
+}
diff --git a/src/compiler/scala/tools/ant/sabbus/CompilerSettings.scala b/src/compiler/scala/tools/ant/sabbus/CompilerSettings.scala
new file mode 100644
index 0000000000..16db6ac6e0
--- /dev/null
+++ b/src/compiler/scala/tools/ant/sabbus/CompilerSettings.scala
@@ -0,0 +1,90 @@
+/* __ *\
+** ________ ___ / / ___ Scala Ant Tasks **
+** / __/ __// _ | / / / _ | (c) 2005-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.tools.ant.sabbus
+
+import java.io.File
+
+import org.apache.tools.ant.types.{Path, Reference}
+
+class CompilerSettings {
+
+ private var gBf: Option[String] = None
+ def g = gBf.get
+ def g_=(s: String): this.type = { gBf = Some(s); this }
+
+ private var uncheckedBf: Boolean = false
+ def unchecked = uncheckedBf
+ def unchecked_=(b: Boolean): this.type = { uncheckedBf = b; this }
+
+ private var classpathBf: Option[Path] = None
+ def classpath = classpathBf.get
+ def classpath_=(p: Path): this.type = { classpathBf = Some(p); this }
+
+ private var sourcepathBf: Option[Path] = None
+ def sourcepath = sourcepathBf.get
+ def sourcepath_=(p: Path): this.type = { sourcepathBf = Some(p); this }
+
+ private var bootclasspathBf: Option[Path] = None
+ def bootclasspath = bootclasspathBf.get
+ def bootclasspath_=(p: Path): this.type = { bootclasspathBf = Some(p); this }
+
+ private var extdirsBf: Option[Path] = None
+ def extdirs = extdirsBf.get
+ def extdirs_=(p: Path): this.type = { extdirsBf = Some(p); this }
+
+ private var dBf: Option[File] = None
+ def d = dBf.get
+ def d_=(f: File): this.type = { dBf = Some(f); this }
+
+ private var encodingBf: Option[String] = None
+ def encoding = encodingBf.get
+ def encoding_=(s: String): this.type = { encodingBf = Some(s); this }
+
+ private var targetBf: Option[String] = None
+ def target = targetBf.get
+ def target_=(s: String): this.type = { targetBf = Some(s); this }
+
+ private var optimiseBf: Boolean = false
+ def optimise = optimiseBf
+ def optimise_=(b: Boolean): Unit = { optimiseBf = b }
+
+ private var moreBf: Option[String] = None
+ def more = moreBf.get
+ def more_=(s: String): this.type = { moreBf = Some(s); this }
+
+ def toArgs: String = ("" +
+ (if (!gBf.isEmpty) "-g:" + g + " " else "") +
+ (if (uncheckedBf) "-unchecked " else "") +
+ (if (!classpathBf.isEmpty) "-classpath " + classpath + " " else "") +
+ (if (!sourcepathBf.isEmpty) "-sourcepath " + sourcepath + " " else "") +
+ (if (!bootclasspathBf.isEmpty) "-bootclasspath " + bootclasspath + " " else "") +
+ (if (!extdirsBf.isEmpty) "-extdirs " + extdirs + " " else "") +
+ (if (!dBf.isEmpty) "-d " + d + " " else "") +
+ (if (!encodingBf.isEmpty) "-encoding " + encoding + " " else "") +
+ (if (!targetBf.isEmpty) "-target:" + target + " " else "") +
+ (if (optimiseBf) "-optimise " else "") +
+ (if (!moreBf.isEmpty) more else "")
+ )
+
+ override def equals(that: Any): Boolean = that match {
+ case cs: CompilerSettings =>
+ this.gBf == cs.gBf &&
+ this.uncheckedBf == cs.uncheckedBf &&
+ this.classpathBf == cs.classpathBf &&
+ this.sourcepathBf == cs.sourcepathBf &&
+ this.bootclasspathBf == cs.bootclasspathBf &&
+ this.extdirsBf == cs.extdirsBf &&
+ this.dBf == cs.dBf &&
+ this.encodingBf == cs.encodingBf &&
+ this.targetBf == cs.targetBf &&
+ this.optimiseBf == cs.optimiseBf &&
+ this.moreBf == cs.moreBf
+ }
+
+}
diff --git a/src/compiler/scala/tools/ant/sabbus/CompilerTest.scala b/src/compiler/scala/tools/ant/sabbus/CompilerTest.scala
new file mode 100644
index 0000000000..b165f50b87
--- /dev/null
+++ b/src/compiler/scala/tools/ant/sabbus/CompilerTest.scala
@@ -0,0 +1,47 @@
+/* __ *\
+** ________ ___ / / ___ Scala Ant Tasks **
+** / __/ __// _ | / / / _ | (c) 2005-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.tools.ant.sabbus
+
+import java.io.File
+import java.net.URL
+
+object CompilerTest {
+
+ def main(args: Array[String]): Unit = {
+
+ implicit def fileToURL(file: File): URL = file.toURL
+
+ val scalalib = new File("/Developer/Scala/latest/lib")
+ val sabbus = new File("/Users/Dubochet/Documents/Eclipse/FaSabbus")
+
+ val classpath: Array[URL] = Array (
+ new File(scalalib, "scala-library.jar"),
+ new File(scalalib, "scala-compiler.jar"),
+ new File(sabbus, "bin")
+ )
+
+ val settings = new CompilerSettings
+ settings.d = new File("/Users/Dubochet/Documents/Eclipse/FaSabbus/bin_sabbus")
+ val compiler = new Compiler(classpath, settings)
+
+ val files: Array[File] = Array (
+ new File(sabbus, "src/scala/tools/ant/sabbus/CompilationFailure.scala"),
+ new File(sabbus, "src/scala/tools/ant/sabbus/Compiler.scala"),
+ new File(sabbus, "src/scala/tools/ant/sabbus/CompilerTest.scala"),
+ new File(sabbus, "src/scala/tools/ant/sabbus/ForeignCompiler.scala")
+ )
+
+ if (compiler.compile(files)._1 == 0)
+ println("Everything a-okey, sir!")
+ else
+ println("We had some issues, sir!")
+
+ }
+
+}
diff --git a/src/compiler/scala/tools/ant/sabbus/Compilers.scala b/src/compiler/scala/tools/ant/sabbus/Compilers.scala
new file mode 100644
index 0000000000..76b8876a26
--- /dev/null
+++ b/src/compiler/scala/tools/ant/sabbus/Compilers.scala
@@ -0,0 +1,45 @@
+/* __ *\
+** ________ ___ / / ___ Scala Ant Tasks **
+** / __/ __// _ | / / / _ | (c) 2005-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.tools.ant.sabbus
+
+import java.net.URL
+
+object Compilers extends collection.Map[String, Compiler] {
+
+ val debug = false
+
+ private val container = new collection.mutable.HashMap[String, Compiler]
+
+ def elements = container.elements
+
+ def get(id: String) = container.get(id)
+
+ def size = container.size
+
+ def make(id: String, classpath: Array[URL], settings: CompilerSettings): Compiler = {
+ val runtime = Runtime.getRuntime
+ if (debug) println("Making compiler " + id)
+ if (debug) println(" memory before: " + (runtime.freeMemory/1048576.).formatted("%10.2f") + " MB")
+ val comp = new Compiler(classpath, settings)
+ container += Pair(id, comp)
+ if (debug) println(" memory after: " + (runtime.freeMemory/1048576.).formatted("%10.2f") + " MB")
+ comp
+ }
+
+ def break(id: String): Null = {
+ val runtime = Runtime.getRuntime
+ if (debug) println("Breaking compiler " + id)
+ if (debug) println(" memory before: " + (runtime.freeMemory/1048576.).formatted("%10.2f") + " MB")
+ container -= id
+ System.gc
+ if (debug) println(" memory after: " + (runtime.freeMemory/1048576.).formatted("%10.2f") + " MB")
+ null
+ }
+
+}
diff --git a/src/compiler/scala/tools/ant/sabbus/ForeignCompiler.scala b/src/compiler/scala/tools/ant/sabbus/ForeignCompiler.scala
new file mode 100644
index 0000000000..c82bcc8d76
--- /dev/null
+++ b/src/compiler/scala/tools/ant/sabbus/ForeignCompiler.scala
@@ -0,0 +1,49 @@
+/* __ *\
+** ________ ___ / / ___ Scala Ant Tasks **
+** / __/ __// _ | / / / _ | (c) 2005-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.tools.ant.sabbus
+
+import java.io.File
+
+import scala.tools.nsc._
+import scala.tools.nsc.reporters.ConsoleReporter
+
+class ForeignCompiler {
+
+ private var argsBuffer: String = null
+ def args: String = argsBuffer
+ def args_=(a: String): Unit = {
+ if (args != null) throw new Error("Argument must be set only once")
+ argsBuffer = a
+ nsc
+ }
+
+ private val error: (String => Nothing) = { msg => throw new Exception(msg) }
+
+ private def settings = new Settings(error)
+
+ private lazy val reporter = new ConsoleReporter(settings)
+
+ private lazy val nsc: Global = {
+ try {
+ val command = new CompilerCommand(List.fromString(args, ' '), settings, error, false)
+ new Global(command.settings, reporter)
+ }
+ catch {
+ case ex @ FatalError(msg) =>
+ throw new Exception(msg, ex)
+ }
+ }
+
+ def compile(files: Array[File]): Int = {
+ val command = new CompilerCommand(files.toList.map(_.toString), settings, error, true)
+ (new nsc.Run) compile command.files
+ reporter.ERROR.count << 16 | reporter.WARNING.count
+ }
+
+}
diff --git a/src/compiler/scala/tools/ant/sabbus/Make.scala b/src/compiler/scala/tools/ant/sabbus/Make.scala
new file mode 100644
index 0000000000..1908ab89b8
--- /dev/null
+++ b/src/compiler/scala/tools/ant/sabbus/Make.scala
@@ -0,0 +1,94 @@
+/* __ *\
+** ________ ___ / / ___ Scala Ant Tasks **
+** / __/ __// _ | / / / _ | (c) 2005-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.tools.ant.sabbus
+
+import java.net.URL
+import java.io.File
+import org.apache.tools.ant.Task
+import org.apache.tools.ant.types.{Path, Reference}
+
+class Make extends Task {
+
+ def setId(input: String): Unit = {
+ id = Some(input)
+ }
+
+ def setParams(input: String): Unit = {
+ params = params match {
+ case None => Some(input)
+ case Some(ps) => Some(ps + " " + input)
+ }
+ }
+
+ def setCompilationPath(input: Path): Unit = {
+ if (compilationPath.isEmpty) compilationPath = Some(input)
+ else compilationPath.get.append(input)
+ }
+
+ def createCompilationPath: Path = {
+ if (compilationPath.isEmpty) compilationPath = Some(new Path(getProject()))
+ compilationPath.get.createPath()
+ }
+
+ def setCompilationPathRef(input: Reference): Unit = {
+ createCompilationPath.setRefid(input)
+ }
+
+ def setSrcPath(input: Path): Unit = {
+ if (sourcePath.isEmpty) sourcePath = Some(input)
+ else sourcePath.get.append(input)
+ }
+
+ def createSrcPath: Path = {
+ if (sourcePath.isEmpty) sourcePath = Some(new Path(getProject()))
+ sourcePath.get.createPath()
+ }
+
+ def setSrcPathRef(input: Reference): Unit = {
+ createSrcPath.setRefid(input)
+ }
+
+ def setCompilerPath(input: Path): Unit = {
+ if (compilerPath.isEmpty) compilerPath = Some(input)
+ else compilerPath.get.append(input)
+ }
+
+ def createCompilerPath: Path = {
+ if (compilerPath.isEmpty) compilerPath = Some(new Path(getProject()))
+ compilerPath.get.createPath()
+ }
+
+ def setCompilerPathRef(input: Reference): Unit = {
+ createCompilerPath.setRefid(input)
+ }
+
+ def setDestdir(input: File): Unit = {
+ destinationDir = Some(input)
+ }
+
+ private var id: Option[String] = None
+ private var params: Option[String] = None
+ private var compilationPath: Option[Path] = None
+ private var sourcePath: Option[Path] = None
+ private var compilerPath: Option[Path] = None
+ private var destinationDir: Option[File] = None
+
+ override def execute: Unit = {
+ if (id.isEmpty) error("Mandatory attribute 'id' is not set.")
+ if (compilerPath.isEmpty) error("Mandatory attribute 'compilerpath' is not set.")
+ if (destinationDir.isEmpty) error("Mandatory attribute 'destdir' is not set.")
+ val settings = new CompilerSettings
+ if (!destinationDir.isEmpty) settings.d = destinationDir.get
+ if (!compilationPath.isEmpty) settings.classpath = compilationPath.get
+ if (!sourcePath.isEmpty) settings.sourcepath = sourcePath.get
+ if (!params.isEmpty) settings.more = params.get
+ Compilers.make(id.get, (compilerPath.get.list.map{ path => new File(path).toURL }), settings)
+ }
+
+}
diff --git a/src/compiler/scala/tools/ant/sabbus/Use.scala b/src/compiler/scala/tools/ant/sabbus/Use.scala
new file mode 100644
index 0000000000..748e36f999
--- /dev/null
+++ b/src/compiler/scala/tools/ant/sabbus/Use.scala
@@ -0,0 +1,69 @@
+/* __ *\
+** ________ ___ / / ___ Scala Ant Tasks **
+** / __/ __// _ | / / / _ | (c) 2005-2008, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.tools.ant.sabbus
+
+import java.io.File
+
+import org.apache.tools.ant.taskdefs.MatchingTask
+import org.apache.tools.ant.types.{Path, Reference}
+import org.apache.tools.ant.util.{GlobPatternMapper, SourceFileScanner}
+
+class Use extends MatchingTask {
+
+ def setId(input: String): Unit = {
+ id = Some(input)
+ }
+
+ def setSrcdir(input: File) {
+ sourceDir = Some(input)
+ }
+
+ def setFailOnError(input: Boolean): Unit = {
+ failOnError = input
+ }
+
+ private var id: Option[String] = None
+ private var sourceDir: Option[File] = None
+ private var failOnError: Boolean = true
+
+ override def execute(): Unit = {
+ if (id.isEmpty) error("Mandatory attribute 'id' is not set.")
+ if (sourceDir.isEmpty) error("Mandatory attribute 'srcdir' is not set.")
+ val compiler = Compilers(id.get)
+ val mapper = new GlobPatternMapper()
+ mapper.setTo("*.class")
+ mapper.setFrom("*.scala")
+ val includedFiles: Array[File] =
+ new SourceFileScanner(this).restrict(
+ getDirectoryScanner(sourceDir.get).getIncludedFiles,
+ sourceDir.get,
+ compiler.settings.d,
+ mapper
+ ) map (new File(sourceDir.get, _))
+ if (includedFiles.size > 0)
+ try {
+ log("Compiling " + includedFiles.size + " file" + (if (includedFiles.size > 1) "s" else "") + " to " + compiler.settings.d.getAbsolutePath)
+ //for (f <- includedFiles) log(" " + f.getAbsolutePath)
+ //log("Attributes are " + compiler.settings.toArgs)
+ val (errors, warnings) = compiler.compile(includedFiles)
+ if (errors > 0)
+ error("Compilation failed with " + errors + " error" + (if (errors > 1) "s" else "") + ".")
+ else if (warnings > 0)
+ log("Compilation suceeded with " + warnings + " warning" + (if (warnings > 1) "s" else "") + ".")
+ }
+ catch {
+ case CompilationFailure(msg, ex) =>
+ ex.printStackTrace
+ val errorMsg =
+ "Compilation failed because of an internal compiler error (" + msg + "); see the error output for details."
+ if (failOnError) error(errorMsg) else log(errorMsg)
+ }
+ }
+
+}
diff --git a/src/compiler/scala/tools/ant/sabbus/antlib.xml b/src/compiler/scala/tools/ant/sabbus/antlib.xml
new file mode 100644
index 0000000000..3388ee00f4
--- /dev/null
+++ b/src/compiler/scala/tools/ant/sabbus/antlib.xml
@@ -0,0 +1,8 @@
+<antlib>
+ <taskdef name="sabmake"
+ classname="scala.tools.ant.sabbus.Make"/>
+ <taskdef name="sabuse"
+ classname="scala.tools.ant.sabbus.Use"/>
+ <taskdef name="sabbreak"
+ classname="scala.tools.ant.sabbus.Break"/>
+</antlib> \ No newline at end of file