diff options
author | Martin Odersky <odersky@gmail.com> | 2006-06-06 12:10:18 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2006-06-06 12:10:18 +0000 |
commit | 3be616edcfa5beaa3fd8fc632f25b340c578bbdc (patch) | |
tree | b43fbb2280a0b3876aa679e2e816537734af9e60 /src/compiler/scala/tools/nsc/CompileServer.scala | |
parent | 31adfc6cf4b34273a4283765dd1f865670bf9c10 (diff) | |
download | scala-3be616edcfa5beaa3fd8fc632f25b340c578bbdc.tar.gz scala-3be616edcfa5beaa3fd8fc632f25b340c578bbdc.tar.bz2 scala-3be616edcfa5beaa3fd8fc632f25b340c578bbdc.zip |
added scala compile server
Diffstat (limited to 'src/compiler/scala/tools/nsc/CompileServer.scala')
-rwxr-xr-x | src/compiler/scala/tools/nsc/CompileServer.scala | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/CompileServer.scala b/src/compiler/scala/tools/nsc/CompileServer.scala new file mode 100755 index 0000000000..3f058d7392 --- /dev/null +++ b/src/compiler/scala/tools/nsc/CompileServer.scala @@ -0,0 +1,159 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2006 LAMP/EPFL + * @author Martin Odersky + */ +// $Id: Main.scala 7679 2006-06-02 14:36:18 +0000 (Fri, 02 Jun 2006) odersky $ +package scala.tools.nsc + +import scala.tools.util.{SocketServer, StringOps} +import scala.tools.nsc.util.Position +import scala.tools.nsc.reporters.{Reporter, ConsoleReporter} +import scala.tools.nsc.doc.DocGenerator +import scala.concurrent.Process.spawn +import java.io._ + +/** The main class for NSC, a compiler for the programming + * language Scala. + */ +object CompileServer extends SocketServer { + + val PRODUCT: String = + System.getProperty("scala.tool.name", "scalac") + val VERSION: String = + System.getProperty("scala.tool.version", "unknown version") + val COPYRIGHT: String = + System.getProperty("scala.copyright", "(c) 2002-2006 LAMP/EPFL") + val versionMsg = PRODUCT + " " + VERSION + " -- " + COPYRIGHT + + val MaxCharge = 0.8 + + var compiler: Global = null + var shutDown: boolean = false + + private def settingsAreCompatible(s1: Settings, s2: Settings) = + s1.encoding.value == s2.encoding.value && + s1.classpath.value == s2.classpath.value && + s1.sourcepath.value == s2.sourcepath.value && + s1.outdir.value == s2.outdir.value && + s1.bootclasspath.value == s2.bootclasspath.value && + s1.extdirs.value == s2.extdirs.value + + private def exit(code: int): Nothing = { + System.err.close() + System.out.close() + Predef.exit(code) + } + + private def spawnWatchDog(): unit = spawn { + try { + while (true) { + Thread.sleep(10000) + if (!CompileSocket.portFile(port).exists()) { + System.err.println("port file no longer exists; exiting") + exit(1) + } + } + } catch { + case ex: Throwable => + ex.printStackTrace() + System.err.println("exiting") + exit(1) + } + } + + private val runtime = Runtime.getRuntime() + + def session(): unit = { + System.out.println("New session, total memory = "+runtime.totalMemory()+ + ", max memory = "+runtime.maxMemory()+ + ", free memory = "+runtime.freeMemory) + val input = in.readLine() + if (input != null) { + val args = StringOps.words(input) + if (args contains "-shutdown") { + out.println("[Scala compile server exited]") + shutDown = true + return + } + if (args contains "-reset") { + out.println("[Scala compile server was reset]") + compiler = null + } + val reporter = new ConsoleReporter(in, out) { + // disable prompts, so that compile server cannot block + override def displayPrompt = {} + } + def error(msg: String): unit = + reporter.error(new Position(PRODUCT), + msg + "\n " + PRODUCT + " -help gives more information") + val command = new CompilerCommand(args, error, false) { + override val cmdName = "fsc" + settings.disable(settings.prompt) + settings.disable(settings.resident) + new settings.BooleanSetting("-reset", "Reset compile server caches") + new settings.BooleanSetting("-shutdown", "Shutdown compile server") + new settings.StringSetting("-server", "hostname:portnumber", + "Specify compile server socket", "") + new settings.BooleanSetting("-J<flag>", "Pass <flag> directly to runtime system") + } + + reporter.prompt = command.settings.prompt.value; + if (command.settings.version.value) + reporter.info(null, versionMsg, true) + else if (command.settings.help.value) + reporter.info(null, command.usageMsg, true) + else if (command.files.isEmpty) + reporter.info(null, command.usageMsg, true) + else { + try {scala.tools.nsc.CompileServer + if (compiler != null && settingsAreCompatible(command.settings, compiler.settings)) { + compiler.settings = command.settings + compiler.reporter = reporter + } else { + if (args exists ("-verbose" ==)) + out.println("[Starting new Scala compile server instance]") + compiler = new Global(command.settings, reporter) { + override def inform(msg: String) = out.println(msg) + } + } + val c = compiler + val run = new c.Run + run compile command.files + } catch { + case ex @ FatalError(msg) => + if (command.settings.debug.value) + 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 + } + reporter.printSummary() + runtime.gc() + if ((runtime.totalMemory() - runtime.freeMemory()).toDouble / + runtime.maxMemory().toDouble > MaxCharge) compiler = null + } + } + } + + def redirect(setter: PrintStream => unit, filename: String): unit = + setter( + new PrintStream( + new BufferedOutputStream( + new FileOutputStream( + new File(System.getProperty("java.io.tmpdir"), filename))))) + + def main(args: Array[String]): unit = { + redirect(System.setOut, "scala-compile-server-out.log") + redirect(System.setErr, "scala-compile-server-err.log") + System.err.println("...starting server on socket "+port+"...") + System.err.flush() + spawnWatchDog() + CompileSocket.setPort(port) + run() + CompileSocket.deletePort(port) + exit(0) + } +} |