summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/CompileServer.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2006-06-06 12:10:18 +0000
committerMartin Odersky <odersky@gmail.com>2006-06-06 12:10:18 +0000
commit3be616edcfa5beaa3fd8fc632f25b340c578bbdc (patch)
treeb43fbb2280a0b3876aa679e2e816537734af9e60 /src/compiler/scala/tools/nsc/CompileServer.scala
parent31adfc6cf4b34273a4283765dd1f865670bf9c10 (diff)
downloadscala-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-xsrc/compiler/scala/tools/nsc/CompileServer.scala159
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)
+ }
+}