diff options
author | Paul Phillips <paulp@improving.org> | 2010-02-16 19:57:44 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2010-02-16 19:57:44 +0000 |
commit | cc698e70af0500d103e60ada46eecca1af8f24b1 (patch) | |
tree | 4dd7783d708976856cdfcaa921d2214a3d4b5555 | |
parent | 5e993b77ec12d139f43889a6f8194c8ff804a448 (diff) | |
download | scala-cc698e70af0500d103e60ada46eecca1af8f24b1.tar.gz scala-cc698e70af0500d103e60ada46eecca1af8f24b1.tar.bz2 scala-cc698e70af0500d103e60ada46eecca1af8f24b1.zip |
Some prestidigitation improving the repl startu...
Some prestidigitation improving the repl startup time. The prompt is
quicker than the eye! No review.
-rw-r--r-- | src/compiler/scala/tools/nsc/Interpreter.scala | 52 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/InterpreterLoop.scala | 8 | ||||
-rw-r--r-- | src/library/scala/concurrent/DelayedLazyVal.scala | 10 |
3 files changed, 53 insertions, 17 deletions
diff --git a/src/compiler/scala/tools/nsc/Interpreter.scala b/src/compiler/scala/tools/nsc/Interpreter.scala index d467fc397b..650edc5ed3 100644 --- a/src/compiler/scala/tools/nsc/Interpreter.scala +++ b/src/compiler/scala/tools/nsc/Interpreter.scala @@ -96,14 +96,37 @@ class Interpreter(val settings: Settings, out: PrintWriter) { * on the future. */ private val _compiler: Global = newCompiler(settings, reporter) - private var _isInitialized: () => Boolean = scala.concurrent.ops.future { - new _compiler.Run() + private def _initialize(): Boolean = { + val source = """ + | // this is assembled to force the loading of approximately the + | // classes which will be loaded on the first expression anyway. + | class $repl_$init { + | val x = "abc".reverse.length + (5 max 5) + | val nl = if (x.toString contains '\n') "\n" else "" + | scala.runtime.ScalaRunTime.stringOf(nl) + | } + |""".stripMargin + + val run = new _compiler.Run() + run compileSources List(new BatchSourceFile("<init>", source)) + if (settings.debug.value) { + out println "Repl compiler initialized." + out.flush() + } true } + // set up initialization future + private var _isInitialized: () => Unit = () => false + def initialize() { + if (!_isInitialized()) + _isInitialized = scala.concurrent.ops future _initialize() + } + /** the public, go through the future compiler */ lazy val compiler: Global = { - _isInitialized() // blocks until it is + _isInitialized() // blocks until it is + _compiler } @@ -516,6 +539,12 @@ class Interpreter(val settings: Settings, out: PrintWriter) { def compileString(code: String): Boolean = compileSources(new BatchSourceFile("<script>", code)) + def compileAndSaveRun(label: String, code: String) = { + val run = new compiler.Run() + run.compileSources(List(new BatchSourceFile(label, code))) + run + } + /** Build a request from the user. <code>trees</code> is <code>line</code> * after being parsed. */ @@ -870,19 +899,12 @@ class Interpreter(val settings: Settings, out: PrintWriter) { code println postamble } - lazy val objRun = { - val x = new compiler.Run() - // compile the object containing the user's code - x.compileSources(List(new BatchSourceFile("<console>", objectSourceCode))) - x - } + // compile the object containing the user's code + lazy val objRun = compileAndSaveRun("<console>", objectSourceCode) + + // compile the result-extraction object + lazy val extractionObjectRun = compileAndSaveRun("<console>", resultObjectSourceCode) - lazy val extractionObjectRun = { - val x = new compiler.Run() - // compile the result-extraction object - x.compileSources(List(new BatchSourceFile("<console>", resultObjectSourceCode))) - x - } lazy val loadedResultObject = loadByName(resultObjectName) def extractionValue(): Option[AnyRef] = { diff --git a/src/compiler/scala/tools/nsc/InterpreterLoop.scala b/src/compiler/scala/tools/nsc/InterpreterLoop.scala index b2fc7772c6..7060c14ea2 100644 --- a/src/compiler/scala/tools/nsc/InterpreterLoop.scala +++ b/src/compiler/scala/tools/nsc/InterpreterLoop.scala @@ -12,6 +12,7 @@ import java.io.IOException import scala.tools.nsc.{ InterpreterResults => IR } import scala.annotation.tailrec import scala.collection.mutable.ListBuffer +import scala.concurrent.ops import interpreter._ import io.{ File, Process } @@ -242,6 +243,13 @@ class InterpreterLoop(in0: Option[BufferedReader], out: PrintWriter) { case _ => true } + // this is about the illusion of snappiness. We call initialize() + // which spins off a separate thread, then print the prompt and try + // our best to look ready. Ideally the user will spend a + // couple seconds saying "wow, it starts so fast!" and by the time + // they type a command the compiler is ready to roll. + interpreter.initialize() + while (processLine(readOneLine)) { } } diff --git a/src/library/scala/concurrent/DelayedLazyVal.scala b/src/library/scala/concurrent/DelayedLazyVal.scala index 092800cb10..7c5d43e70c 100644 --- a/src/library/scala/concurrent/DelayedLazyVal.scala +++ b/src/library/scala/concurrent/DelayedLazyVal.scala @@ -27,9 +27,15 @@ import ops.future * @version 2.8 */ class DelayedLazyVal[T](f: () => T, body: => Unit) { - @volatile private[this] var isDone = false + @volatile private[this] var _isDone = false private[this] lazy val complete = f() + /** Whether the computation is complete. + * + * @return true if the computation is complete. + */ + def isDone = _isDone + /** The current result of f(), or the final result if complete. * * @return the current value @@ -38,6 +44,6 @@ class DelayedLazyVal[T](f: () => T, body: => Unit) { future { body - isDone = true + _isDone = true } } |