summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/CompileServer.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-02-08 08:47:29 +0000
committerPaul Phillips <paulp@improving.org>2011-02-08 08:47:29 +0000
commit3467ad57e4c2b56cdd02ce0c75af4716b5631a10 (patch)
treeaf5d632276e79a449e9971e94c25bec0c1fc73e4 /src/compiler/scala/tools/nsc/CompileServer.scala
parentc89ea6e3ae82d9b6bacda25dceb74a958d2fa4f6 (diff)
downloadscala-3467ad57e4c2b56cdd02ce0c75af4716b5631a10.tar.gz
scala-3467ad57e4c2b56cdd02ce0c75af4716b5631a10.tar.bz2
scala-3467ad57e4c2b56cdd02ce0c75af4716b5631a10.zip
Working on fsc.
for me anyway, with this commit scripts will occasionally reuse a compiler instance, instead of never. Since any tests I write will fail on platforms which aren't mine, there are no tests. I might have to start a platform-specific testing area to break some ice around these huge untested zones. No review.
Diffstat (limited to 'src/compiler/scala/tools/nsc/CompileServer.scala')
-rw-r--r--src/compiler/scala/tools/nsc/CompileServer.scala96
1 files changed, 59 insertions, 37 deletions
diff --git a/src/compiler/scala/tools/nsc/CompileServer.scala b/src/compiler/scala/tools/nsc/CompileServer.scala
index 5296432519..e33545d3c9 100644
--- a/src/compiler/scala/tools/nsc/CompileServer.scala
+++ b/src/compiler/scala/tools/nsc/CompileServer.scala
@@ -6,11 +6,10 @@
package scala.tools.nsc
import java.io.{ BufferedOutputStream, FileOutputStream, PrintStream, File => JFile }
-import io.File
-
import scala.tools.nsc.reporters.{Reporter, ConsoleReporter}
import scala.tools.nsc.util.FakePos //Position
import scala.tools.util.SocketServer
+import settings.FscSettings
/**
* The server part of the fsc offline compiler. It awaits compilation
@@ -29,9 +28,9 @@ class StandardCompileServer extends SocketServer {
val MaxCharge = 0.8
- var shutDown: Boolean = false
-
private var compiler: Global = null
+ var reporter: ConsoleReporter = _
+ var shutdown = false
private def exit(code: Int): Nothing = {
System.err.close()
@@ -42,8 +41,6 @@ class StandardCompileServer extends SocketServer {
private val runtime = Runtime.getRuntime()
import runtime.{ totalMemory, freeMemory, maxMemory }
- var reporter: ConsoleReporter = _
-
/** Create a new compiler instance */
def newGlobal(settings: Settings, reporter: Reporter) =
new Global(settings, reporter) {
@@ -69,11 +66,29 @@ class StandardCompileServer extends SocketServer {
protected def newOfflineCompilerCommand(arguments: List[String], settings: Settings) =
new OfflineCompilerCommand(arguments, settings)
+ /** Problematically, Settings are only considered equal if every setting
+ * is exactly equal. In fsc this immediately breaks down because the randomly
+ * chosen temporary outdirs differ between client and server. Among other
+ * things. Long term we could use a meaningful equality; short term I'm just
+ * ignoring options which I can see causing a new compiler instance every time
+ * and which do not interestingly influence compilation products.
+ */
+ def unequalSettings(s1: Settings, s2: Settings): Set[Settings#Setting] = {
+ val ignoreSettings = Set("-d", "-encoding", "-verbose")
+ def trim (s: Settings): Set[Settings#Setting] = (
+ s.userSetSettings.toSet[Settings#Setting] filterNot (ss => ignoreSettings exists (ss respondsTo _))
+ )
+ val ss1 = trim(s1)
+ val ss2 = trim(s2)
+
+ (ss1 union ss2) -- (ss1 intersect ss2)
+ }
+
def session() {
printMemoryStats()
- val password = compileSocket getPassword port
+ val password = compileSocket getPassword port
val guessedPassword = in.readLine()
- val input = in.readLine()
+ val input = in.readLine()
def fscError(msg: String): Unit = out println (
FakePos("fsc"),
@@ -83,13 +98,17 @@ class StandardCompileServer extends SocketServer {
return
val args = input.split("\0", -1).toList
- val command = newOfflineCompilerCommand(args, new Settings(fscError))
-
- if (command.fscShutdown.value) {
- shutDown = true
+ val settings = new FscSettings(fscError)
+ def logVerbose(msg: String) =
+ if (settings.verbose.value)
+ out println msg
+
+ val command = newOfflineCompilerCommand(args, settings)
+ if (settings.shutdown.value) {
+ shutdown = true
return out.println("[Compile server exited]")
}
- if (command.fscReset.value) {
+ if (settings.reset.value) {
compiler = null
return out.println("[Compile server was reset]")
}
@@ -98,45 +117,48 @@ class StandardCompileServer extends SocketServer {
// disable prompts, so that compile server cannot block
override def displayPrompt = ()
}
+ def isCompilerReusable: Boolean = {
+ if (compiler == null) {
+ logVerbose("[Creating compiler instance for compile server.]")
+ return false
+ }
+ val unequal = unequalSettings(command.settings, compiler.settings)
+ if (unequal.nonEmpty) {
+ logVerbose("[Replacing compiler with new instance because settings are unequal.]")
+ logVerbose("[Asymmetric settings: " + unequal.mkString(", ") + "]")
+ }
+ unequal.isEmpty
+ }
if (command.shouldStopWithInfo)
reporter.info(null, command.getInfoMessage(newGlobal(command.settings, reporter)), true)
else if (command.files.isEmpty)
reporter.info(null, command.usageMsg, true)
else {
- try {
- if (compiler != null && command.settings == compiler.settings) {
- compiler.settings = command.settings
- compiler.reporter = reporter
- }
- else {
- if (command.verbose) {
- val reason = if (compiler == null) "compiler is null" else "settings not equal"
- out.println("[Starting new compile server instance because %s]".format(reason))
- }
- compiler = newGlobal(command.settings, reporter)
- }
- val c = compiler
- val run = new c.Run()
- run compile command.files
+ if (isCompilerReusable) {
+ compiler.settings = command.settings
+ compiler.reporter = reporter
}
+ else {
+ compiler = newGlobal(command.settings, reporter)
+ }
+ val c = compiler
+ val run = new c.Run()
+ try run compile command.files
catch {
case ex @ FatalError(msg) =>
- if (command.debug)
- ex.printStackTrace(out)
-
reporter.error(null, "fatal error: " + msg)
compiler = null
- case ex: Throwable =>
- ex.printStackTrace(out);
- reporter.error(null, "fatal error (server aborted): " + ex.getMessage())
- shutDown = true
+ case ex =>
+ shutdown = true
+ throw ex
}
}
-
reporter.printSummary()
- if (isMemoryFullEnough)
+ if (isMemoryFullEnough) {
+ logVerbose("Nulling out compiler due to memory utilization.")
compiler = null
+ }
}
}