summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormichelou <michelou@epfl.ch>2011-11-27 11:39:54 +0000
committermichelou <michelou@epfl.ch>2011-11-27 11:39:54 +0000
commit37201dd3cd6da6ca47f651a5b346a7706ae1e561 (patch)
tree0d1581939e649b63ce9bf6233d33bcae618b955c
parentafc755916f7e67f1f2c899972de8801b1ef62543 (diff)
downloadscala-37201dd3cd6da6ca47f651a5b346a7706ae1e561.tar.gz
scala-37201dd3cd6da6ca47f651a5b346a7706ae1e561.tar.bz2
scala-37201dd3cd6da6ca47f651a5b346a7706ae1e561.zip
attempt to fix reopened SI-5196
-rw-r--r--src/compiler/scala/tools/ant/FastScalac.scala81
-rw-r--r--src/compiler/scala/tools/ant/Scalac.scala17
2 files changed, 73 insertions, 25 deletions
diff --git a/src/compiler/scala/tools/ant/FastScalac.scala b/src/compiler/scala/tools/ant/FastScalac.scala
index 96d242ae07..19a1526e67 100644
--- a/src/compiler/scala/tools/ant/FastScalac.scala
+++ b/src/compiler/scala/tools/ant/FastScalac.scala
@@ -8,10 +8,14 @@
package scala.tools.ant
-import org.apache.tools.ant.Project
+import org.apache.tools.ant.{AntClassLoader, Project}
+import org.apache.tools.ant.taskdefs.Java
+import org.apache.tools.ant.types.Path
import scala.tools.nsc.Settings
+import scala.tools.nsc.io.File
import scala.tools.nsc.settings.FscSettings
+import scala.tools.nsc.util.ScalaClassLoader
/** An Ant task to compile with the fast Scala compiler (`fsc`).
*
@@ -92,12 +96,6 @@ class FastScalac extends Scalac {
s.preferIPv4.value = useIPv4
if (!idleMinutes.isEmpty) s.idleMins.value = idleMinutes.get
- val prefixSettings =
- List(
- /*scalac*/
- s.jvmargs, s.defines
- ) flatMap (_.value)
-
val stringSettings =
List(
/*scalac*/
@@ -111,7 +109,7 @@ class FastScalac extends Scalac {
List(
/*scalac*/
s.debuginfo, s.target
- ) map (x => "%s:%s".format(x.name, x.value))
+ ) filter (x => x.value != x.default) map (x => "%s:%s".format(x.name, x.value))
val booleanSettings =
List(
@@ -134,20 +132,61 @@ class FastScalac extends Scalac {
else List("%s:%s".format(s.name, s.value.mkString(",")))
}
- val cmdOptions =
- prefixSettings ::: stringSettings ::: choiceSettings ::: booleanSettings ::: intSettings ::: phaseSetting
-
- val args = (cmdOptions ::: (sourceFiles map (_.toString))).toArray
- log("FastScalac args="+args.mkString(" "), Project.MSG_DEBUG)
- try {
- if (!scala.tools.nsc.CompileClient.process(args) && failonerror)
- buildError("Compile failed; see the compiler error output for details.")
+ val fscOptions =
+ stringSettings ::: choiceSettings ::: booleanSettings ::: intSettings ::: phaseSetting
+
+ val java = new Java(this)
+ java setFork true
+ // use same default memory options as in fsc script
+ java.createJvmarg() setValue "-Xmx256M"
+ java.createJvmarg() setValue "-Xms32M"
+ val scalacPath: Path = {
+ val path = new Path(getProject)
+ if (compilerPath.isDefined) path add compilerPath.get
+ else getClass.getClassLoader match {
+ case cl: AntClassLoader =>
+ path add new Path(getProject, cl.getClasspath)
+ case _ =>
+ buildError("Compilation failed because of an internal compiler error;"+
+ " see the error output for details.")
+ }
+ path
}
- catch {
- case ex: Throwable =>
- ex.printStackTrace()
- val msg = if (ex.getMessage == null) "no error message provided" else ex.getMessage
- buildError("Compile failed because of an internal compiler error (" + msg + "); see the error output for details.")
+ java.createJvmarg() setValue ("-Xbootclasspath/a:"+scalacPath)
+ s.jvmargs.value foreach (java.createJvmarg() setValue _)
+
+ val scalaHome: String = try {
+ val url = ScalaClassLoader.originOfClass(classOf[FastScalac]).get
+ File(url.getFile).jfile.getParentFile.getParentFile getAbsolutePath
+ } catch {
+ case _ =>
+ buildError("Compilation failed because of an internal compiler error;"+
+ " couldn't determine value for -Dscala.home=<value>")
}
+ java.createJvmarg() setValue "-Dscala.usejavacp=true"
+ java.createJvmarg() setValue ("-Dscala.home="+scalaHome)
+ s.defines.value foreach (java.createJvmarg() setValue _)
+
+ java setClassname "scala.tools.nsc.MainGenericRunner"
+ java.createArg() setValue "scala.tools.nsc.CompileClient"
+
+ // Encode scalac/javac args for use in a file to be read back via "@file.txt"
+ def encodeScalacArgsFile(t: Traversable[String]) = t map { s =>
+ if(s.find(c => c <= ' ' || "\"'\\".contains(c)).isDefined)
+ "\"" + s.flatMap(c => (if(c == '"' || c == '\\') "\\" else "") + c ) + "\""
+ else s
+ } mkString "\n"
+
+ // dump the arguments to a file and do "java @file"
+ val tempArgFile = File.makeTemp("fastscalac")
+ val tokens = fscOptions ++ (sourceFiles map (_.getPath))
+ tempArgFile writeAll encodeScalacArgsFile(tokens)
+
+ val paths = List(Some(tempArgFile.toAbsolute.path), argfile).flatten map (_.toString)
+ val res = execWithArgFiles(java, paths)
+
+ if (failonerror && res != 0)
+ buildError("Compilation failed because of an internal compiler error;"+
+ " see the error output for details.")
}
}
diff --git a/src/compiler/scala/tools/ant/Scalac.scala b/src/compiler/scala/tools/ant/Scalac.scala
index 72330615cc..7aff4e3e8e 100644
--- a/src/compiler/scala/tools/ant/Scalac.scala
+++ b/src/compiler/scala/tools/ant/Scalac.scala
@@ -36,6 +36,7 @@ import scala.tools.nsc.reporters.{Reporter, ConsoleReporter}
* - `bootclasspathref`,
* - `extdirs`,
* - `extdirsref`,
+ * - `argfile`,
* - `dependencyfile`,
* - `encoding`,
* - `target`,
@@ -126,8 +127,9 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
/** The external extensions path to use for this compilation. */
protected var extdirs: Option[Path] = None
+ protected var argfile: Option[File] = None
/** The dependency tracking file. */
- protected var dependencyfile: Option[String] = None
+ protected var dependencyfile: Option[File] = None
/** The character encoding of the files to compile. */
protected var encoding: Option[String] = None
@@ -229,7 +231,7 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
}
/** Sets the `compilerPath` attribute. Used by [[http://ant.apache.org Ant]].
* @param input The value of `compilerPath`. */
- def setCompilerPath(input : Path) {
+ def setCompilerPath(input: Path) {
compilerPath = setOrAppend(compilerPath, input)
}
@@ -299,9 +301,15 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
def setExtdirsref(input: Reference) =
createExtdirs().setRefid(input)
+ /** Sets the `argfile` attribute. Used by [[http://ant.apache.org Ant]].
+ * @param input The value of `argfile`. */
+ def setArgfile(input: File) {
+ argfile = Some(input)
+ }
+
/** Sets the `dependencyfile` attribute. Used by [[http://ant.apache.org Ant]].
* @param input The value of `dependencyfile`. */
- def setDependencyfile(input: String) {
+ def setDependencyfile(input: File) {
dependencyfile = Some(input)
}
@@ -584,7 +592,8 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
if (!bootclasspath.isEmpty)
settings.bootclasspath.value = asString(getBootclasspath)
if (!extdirs.isEmpty) settings.extdirs.value = asString(getExtdirs)
- if (!dependencyfile.isEmpty) settings.dependencyfile.value = dependencyfile.get
+ if (!dependencyfile.isEmpty)
+ settings.dependencyfile.value = asString(dependencyfile.get)
if (!encoding.isEmpty) settings.encoding.value = encoding.get
if (!backend.isEmpty) settings.target.value = backend.get
if (!logging.isEmpty && logging.get == "verbose")