summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools
diff options
context:
space:
mode:
authorLex Spoon <lex@lexspoon.org>2007-06-14 21:47:37 +0000
committerLex Spoon <lex@lexspoon.org>2007-06-14 21:47:37 +0000
commit960ce31287f826fa82aea226d9e03eac3821d767 (patch)
tree93b92a82332c57cad1386ea8c18357008f222f3f /src/compiler/scala/tools
parent9128040ab12ea8c187fbcf471e703fcc81f0dc28 (diff)
downloadscala-960ce31287f826fa82aea226d9e03eac3821d767.tar.gz
scala-960ce31287f826fa82aea226d9e03eac3821d767.tar.bz2
scala-960ce31287f826fa82aea226d9e03eac3821d767.zip
Refactored ScriptRunner and the offline compila...
Refactored ScriptRunner and the offline compilation classes so that they can be subclassed effectively.
Diffstat (limited to 'src/compiler/scala/tools')
-rw-r--r--src/compiler/scala/tools/nsc/CompileClient.scala25
-rw-r--r--src/compiler/scala/tools/nsc/CompileServer.scala59
-rw-r--r--src/compiler/scala/tools/nsc/CompileSocket.scala31
-rw-r--r--src/compiler/scala/tools/nsc/CompilerCommand.scala2
-rw-r--r--src/compiler/scala/tools/nsc/OfflineCompilerCommand.scala28
-rw-r--r--src/compiler/scala/tools/nsc/ScriptRunner.scala26
6 files changed, 117 insertions, 54 deletions
diff --git a/src/compiler/scala/tools/nsc/CompileClient.scala b/src/compiler/scala/tools/nsc/CompileClient.scala
index 8454f522df..f58ce1c087 100644
--- a/src/compiler/scala/tools/nsc/CompileClient.scala
+++ b/src/compiler/scala/tools/nsc/CompileClient.scala
@@ -10,10 +10,12 @@ import java.io.{BufferedReader, File, InputStreamReader, PrintWriter}
import scala.tools.util.StringOps
-/** The main class for NSC, a compiler for the programming
- * language Scala.
+/** The client part of the fsc offline compiler. Instead of compiling
+ * things itself, it send requests to a CompileServer.
*/
-object CompileClient {
+class StandardCompileClient {
+ def compileSocket: CompileSocket = CompileSocket // todo: should be lazy val
+
val versionMsg = "Fast Scala Compiler " +
Properties.versionString + " -- " +
Properties.copyrightString
@@ -34,13 +36,15 @@ object CompileClient {
pathsList.map(absFileName).mkString("", sep, "")
}
- private def normalize(args: Array[String]): (String, String) = {
+ val fileEnding = ".scala"
+
+ protected def normalize(args: Array[String]): (String, String) = {
var i = 0
val vmArgs = new StringBuilder
var serverAdr = ""
while (i < args.length) {
val arg = args(i)
- if (arg endsWith ".scala") {
+ if (arg endsWith fileEnding) {
args(i) = absFileName(arg)
} else if (arg startsWith "-J") {
//see http://java.sun.com/j2se/1.5.0/docs/tooldocs/solaris/javac.html#J
@@ -89,20 +93,20 @@ object CompileClient {
Console.println("[Server arguments: " + args.mkString("", " ", "]"))
Console.println("[VM arguments: " + vmArgs + "]")
}
- val socket = if (serverAdr == "") CompileSocket.getOrCreateSocket(vmArgs, !shutdown)
- else CompileSocket.getSocket(serverAdr)
+ val socket = if (serverAdr == "") compileSocket.getOrCreateSocket(vmArgs, !shutdown)
+ else compileSocket.getSocket(serverAdr)
if (shutdown && (socket==null)) {
Console.println("[No compilation server running.]")
return 0
}
val out = new PrintWriter(socket.getOutputStream(), true)
val in = new BufferedReader(new InputStreamReader(socket.getInputStream()))
- out.println(CompileSocket.getPassword(socket.getPort()))
+ out.println(compileSocket.getPassword(socket.getPort()))
out.println(args.mkString("", "\0", ""))
var sawerror = false
var fromServer = in.readLine()
while (fromServer ne null) {
- if (CompileSocket.errorPattern.matcher(fromServer).matches)
+ if (compileSocket.errorPattern.matcher(fromServer).matches)
sawerror = true
Console.println(fromServer)
fromServer = in.readLine()
@@ -119,3 +123,6 @@ object CompileClient {
exit(status)
}
}
+
+
+object CompileClient extends StandardCompileClient
diff --git a/src/compiler/scala/tools/nsc/CompileServer.scala b/src/compiler/scala/tools/nsc/CompileServer.scala
index 8b8609a38b..3fcdd5d991 100644
--- a/src/compiler/scala/tools/nsc/CompileServer.scala
+++ b/src/compiler/scala/tools/nsc/CompileServer.scala
@@ -15,13 +15,16 @@ import scala.tools.nsc.reporters.{Reporter, ConsoleReporter}
import scala.tools.nsc.util.FakePos //Position
import scala.tools.util.SocketServer
-/** The main class for NSC, a compiler for the programming
- * language Scala.
+/**
+ * The server part of the fsc offline compiler. It awaits compilation
+ * commands and executes them. It caches a compiler instance so
+ * that it can respond more quickly.
*
* @author Martin Odersky
* @version 1.0
*/
-object CompileServer extends SocketServer {
+class StandardCompileServer extends SocketServer {
+ def compileSocket: CompileSocket = CompileSocket // todo: make this a lazy val
val versionMsg = "Fast Scala compiler " +
Properties.versionString + " -- " +
@@ -52,7 +55,7 @@ object CompileServer extends SocketServer {
private def spawnWatchDog(): Unit = spawn {
while (true) {
Thread.sleep(10000)
- if (!CompileSocket.portFile(port).exists() && !inSession) {
+ if (!compileSocket.portFile(port).exists() && !inSession) {
progress = false
spawn {
Thread.sleep(10000)
@@ -67,12 +70,28 @@ object CompileServer extends SocketServer {
var reporter: ConsoleReporter = _
+
+ /** Create a new compiler instance */
+ def newGlobal(settings: Settings, reporter: Reporter) =
+ new Global(settings, reporter) {
+ override def inform(msg: String) = out.println(msg)
+ }
+
+
+ protected def newOfflineCompilerCommand(
+ arguments: List[String],
+ settings: Settings,
+ error: String => Unit,
+ interactive: Boolean)
+ = new OfflineCompilerCommand(arguments, settings, error, interactive)
+
def session() {
System.out.println("New session" +
", total memory = "+ runtime.totalMemory() +
", max memory = " + runtime.maxMemory() +
", free memory = " + runtime.freeMemory)
- val password = CompileSocket.getPassword(port)
+ System.out.flush()
+ val password = compileSocket.getPassword(port)
val guessedPassword = in.readLine()
val input = in.readLine()
if ((input ne null) && password == guessedPassword) {
@@ -81,12 +100,12 @@ object CompileServer extends SocketServer {
progress = true
val args = input.split("\0").toList
if (args contains "-shutdown") {
- out.println("[Scala compile server exited]")
+ out.println("[Compile server exited]")
shutDown = true
return
}
if (args contains "-reset") {
- out.println("[Scala compile server was reset]")
+ out.println("[Compile server was reset]")
compiler = null
return
}
@@ -94,16 +113,7 @@ object CompileServer extends SocketServer {
reporter.error(/*new Position*/ FakePos("fsc"),
msg + "\n fsc -help gives more information")
}
- val command = new CompilerCommand(args, new Settings(error), 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")
- }
+ val command = newOfflineCompilerCommand(args, new Settings(error), error, false)
reporter = new ConsoleReporter(command.settings, in, out) {
// disable prompts, so that compile server cannot block
@@ -125,10 +135,8 @@ object CompileServer extends SocketServer {
compiler.reporter = reporter
} else {
if (args contains "-verbose")
- out.println("[Starting new Scala compile server instance]")
- compiler = new Global(command.settings, reporter) {
- override def inform(msg: String) = out.println(msg)
- }
+ out.println("[Starting new compile server instance]")
+ compiler = newGlobal(command.settings, reporter)
}
val c = compiler
val run = new c.Run
@@ -156,7 +164,7 @@ object CompileServer extends SocketServer {
}
/** A directory holding redirected output */
- private val redirectDir = new File(CompileSocket.tmpDir, "output-redirects")
+ private val redirectDir = new File(compileSocket.tmpDir, "output-redirects")
redirectDir.mkdirs
private def redirect(setter: PrintStream => Unit, filename: String) {
@@ -173,9 +181,12 @@ object CompileServer extends SocketServer {
System.err.println("...starting server on socket "+port+"...")
System.err.flush()
spawnWatchDog()
- CompileSocket.setPort(port)
+ compileSocket.setPort(port)
run()
- CompileSocket.deletePort(port)
+ compileSocket.deletePort(port)
exit(0)
}
}
+
+
+object CompileServer extends StandardCompileServer
diff --git a/src/compiler/scala/tools/nsc/CompileSocket.scala b/src/compiler/scala/tools/nsc/CompileSocket.scala
index ec63ed5be8..85c2e273f4 100644
--- a/src/compiler/scala/tools/nsc/CompileSocket.scala
+++ b/src/compiler/scala/tools/nsc/CompileSocket.scala
@@ -13,28 +13,32 @@ import java.io.{BufferedReader, FileReader}
import java.util.regex.Pattern
import java.net._
-object CompileSocket {
+/** This class manages sockets for the fsc offline compiler. */
+class CompileSocket {
+ protected def compileClient: StandardCompileClient = CompileClient //todo: lazy val
/** The prefix of the port identification file, which is followed
* by the port number.
*/
- private val dirName = "scalac-compile-server-port"
+ protected def dirName = "scalac-compile-server-port" //todo: lazy val
- /** The vm-part of the command to start a new scala compile server */
- private val vmCommand =
+ protected def cmdName = Properties.cmdName //todo: lazy val
+
+ /** The vm part of the command to start a new scala compile server */
+ protected val vmCommand =
Properties.scalaHome match {
case null =>
- Properties.cmdName
+ cmdName
case dirname =>
- val trial = new File(new File(dirname, "bin"), Properties.cmdName)
+ val trial = new File(new File(dirname, "bin"), cmdName)
if (trial.canRead)
trial.getPath
else
- Properties.cmdName
+ cmdName
}
/** The class name of the scala compile server */
- private val serverClass = "scala.tools.nsc.CompileServer"
+ protected val serverClass = "scala.tools.nsc.CompileServer"
/** A regular expression for checking compiler output for errors */
val errorRegex = ".*errors? found.*"
@@ -42,15 +46,15 @@ object CompileSocket {
/** A Pattern object for checking compiler output for errors */
val errorPattern = Pattern.compile(errorRegex)
- private def error(msg: String) = System.err.println(msg)
+ protected def error(msg: String) = System.err.println(msg)
- private def fatal(msg: String) = {
+ protected def fatal(msg: String) = {
error(msg)
exit(1)
}
- private def info(msg: String) =
- if (CompileClient.verbose) System.out.println(msg)
+ protected def info(msg: String) =
+ if (compileClient.verbose) System.out.println(msg)
/** A temporary directory to use */
val tmpDir = {
@@ -256,3 +260,6 @@ object CompileSocket {
result
}
}
+
+
+object CompileSocket extends CompileSocket
diff --git a/src/compiler/scala/tools/nsc/CompilerCommand.scala b/src/compiler/scala/tools/nsc/CompilerCommand.scala
index 22acb56a6b..0907b589d3 100644
--- a/src/compiler/scala/tools/nsc/CompilerCommand.scala
+++ b/src/compiler/scala/tools/nsc/CompilerCommand.scala
@@ -20,7 +20,7 @@ class CompilerCommand(arguments: List[String], val settings: Settings,
val cmdName = "scalac"
/** The file extension of files that the compiler can process */
- val fileEnding = ".scala"
+ def fileEnding = ".scala" //todo: lazy val
private val helpSyntaxColumnWidth: Int =
Iterable.max(settings.allSettings map (_.helpSyntax.length))
diff --git a/src/compiler/scala/tools/nsc/OfflineCompilerCommand.scala b/src/compiler/scala/tools/nsc/OfflineCompilerCommand.scala
new file mode 100644
index 0000000000..6a132fc116
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/OfflineCompilerCommand.scala
@@ -0,0 +1,28 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2007 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id$
+
+package scala.tools.nsc
+
+/** A compiler command for the offline compiler.
+ *
+ * @author Martin Odersky and Lex Spoon
+ */
+class OfflineCompilerCommand(
+ arguments: List[String],
+ settings: Settings,
+ error: String => Unit,
+ interactive: Boolean)
+extends CompilerCommand(arguments, new Settings(error), 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")
+}
diff --git a/src/compiler/scala/tools/nsc/ScriptRunner.scala b/src/compiler/scala/tools/nsc/ScriptRunner.scala
index 435d178e4d..5ce1a64d4d 100644
--- a/src/compiler/scala/tools/nsc/ScriptRunner.scala
+++ b/src/compiler/scala/tools/nsc/ScriptRunner.scala
@@ -13,7 +13,7 @@ import java.net.URL
import java.util.jar.{JarEntry, JarOutputStream}
import scala.tools.nsc.io.PlainFile
-import scala.tools.nsc.reporters.ConsoleReporter
+import scala.tools.nsc.reporters.{Reporter,ConsoleReporter}
import scala.tools.nsc.util.{CompoundSourceFile, SourceFile, SourceFileFragment}
/** An object that runs Scala code in script files.
@@ -42,7 +42,11 @@ import scala.tools.nsc.util.{CompoundSourceFile, SourceFile, SourceFileFragment}
* @todo It would be better if error output went to stderr instead
* of stdout...
*/
-object ScriptRunner {
+class ScriptRunner {
+ protected def compileClient: StandardCompileClient = CompileClient //todo: lazy val
+ protected def compileSocket: CompileSocket = CompileSocket //todo: make lazy val
+
+
/** Default name to use for the wrapped script */
val defaultScriptMain = "Main"
@@ -194,14 +198,14 @@ object ScriptRunner {
settings: GenericRunnerSettings,
scriptFileIn: String): Boolean =
{
- val scriptFile = CompileClient.absFileName(scriptFileIn)
+ val scriptFile = compileClient.absFileName(scriptFileIn)
for (setting:settings.StringSetting <- List(
settings.classpath,
settings.sourcepath,
settings.bootclasspath,
settings.extdirs,
settings.outdir))
- setting.value = CompileClient.absFileNames(setting.value)
+ setting.value = compileClient.absFileNames(setting.value)
val compSettingNames =
(new Settings(error)).allSettings.map(_.name)
@@ -218,11 +222,11 @@ object ScriptRunner {
(coreCompArgs :::
List("-script", scriptMain(settings), scriptFile))
- val socket = CompileSocket.getOrCreateSocket("")
+ val socket = compileSocket.getOrCreateSocket("")
val out = new PrintWriter(socket.getOutputStream(), true)
val in = new BufferedReader(new InputStreamReader(socket.getInputStream()))
- out.println(CompileSocket.getPassword(socket.getPort))
+ out.println(compileSocket.getPassword(socket.getPort))
out.println(compArgs.mkString("", "\0", ""))
var compok = true
@@ -230,7 +234,7 @@ object ScriptRunner {
var fromServer = in.readLine()
while (fromServer ne null) {
Console.println(fromServer)
- if (CompileSocket.errorPattern.matcher(fromServer).matches)
+ if (compileSocket.errorPattern.matcher(fromServer).matches)
compok = false
fromServer = in.readLine()
@@ -242,6 +246,9 @@ object ScriptRunner {
compok
}
+ protected def newGlobal(settings: Settings, reporter: Reporter) =
+ new Global(settings, reporter)
+
/** Compile a script and then run the specified closure with
* a classpath for the compiled script.
*/
@@ -265,7 +272,7 @@ object ScriptRunner {
if (settings.nocompdaemon.value) {
val reporter = new ConsoleReporter(settings)
- val compiler = new Global(settings, reporter)
+ val compiler = newGlobal(settings, reporter)
val cr = new compiler.Run
val wrapped =
wrappedScript(
@@ -370,3 +377,6 @@ object ScriptRunner {
})
}
}
+
+
+object ScriptRunner extends ScriptRunner