summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/interactive/Global.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2011-01-04 17:05:37 +0000
committerMartin Odersky <odersky@gmail.com>2011-01-04 17:05:37 +0000
commitf0f0dfd9a326f949ab72786e61596cfa361069ae (patch)
tree17ab7ac993ef6ad975981eed6f6cb850eec095de /src/compiler/scala/tools/nsc/interactive/Global.scala
parent5c5657c29922fa2ac9eec763176fc2eda5c7b436 (diff)
downloadscala-f0f0dfd9a326f949ab72786e61596cfa361069ae.tar.gz
scala-f0f0dfd9a326f949ab72786e61596cfa361069ae.tar.bz2
scala-f0f0dfd9a326f949ab72786e61596cfa361069ae.zip
Towards a replay framework for the presentation...
Towards a replay framework for the presentation compiler
Diffstat (limited to 'src/compiler/scala/tools/nsc/interactive/Global.scala')
-rw-r--r--src/compiler/scala/tools/nsc/interactive/Global.scala84
1 files changed, 59 insertions, 25 deletions
diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala
index e106ad1f9d..9c14f80a9e 100644
--- a/src/compiler/scala/tools/nsc/interactive/Global.scala
+++ b/src/compiler/scala/tools/nsc/interactive/Global.scala
@@ -1,17 +1,19 @@
package scala.tools.nsc
package interactive
-import java.io.{ PrintWriter, StringWriter }
+import java.io.{ PrintWriter, StringWriter, FileReader, FileWriter }
import scala.collection.mutable
import mutable.{LinkedHashMap, SynchronizedMap,LinkedHashSet, SynchronizedSet}
import scala.concurrent.SyncVar
import scala.util.control.ControlThrowable
import scala.tools.nsc.io.AbstractFile
-import scala.tools.nsc.util.{SourceFile, Position, RangePosition, NoPosition, WorkScheduler}
+import scala.tools.nsc.util.{SourceFile, Position, RangePosition, NoPosition, WorkScheduler, LogReplay, Logger, Replayer, NullLogger}
import scala.tools.nsc.reporters._
import scala.tools.nsc.symtab._
import scala.tools.nsc.ast._
+import scala.tools.nsc.io.JSON._
+import scala.tools.nsc.util.Pickler._
/** The main class of the presentation compiler in an interactive environment such as an IDE
*/
@@ -20,7 +22,8 @@ class Global(settings: Settings, reporter: Reporter)
with CompilerControl
with RangePositions
with ContextTrees
- with RichCompilationUnits {
+ with RichCompilationUnits
+ with Picklers {
self =>
import definitions._
@@ -28,6 +31,18 @@ self =>
val debugIDE: Boolean = settings.YpresentationDebug.value
val verboseIDE: Boolean = settings.YpresentationVerbose.value
+ private def replayName = settings.YpresentationReplay.value
+ private def logName = settings.YpresentationLog.value
+
+ lazy val log =
+ if (replayName != "") new Replayer(new FileReader(replayName))
+ else if (logName != "") new Logger(new FileWriter(logName))
+ else NullLogger
+
+// import log.logreplay
+
+ def logreplay[T](label: String, x: T): T = x
+
/** Print msg only when debugIDE is true. */
@inline final def debugLog(msg: => String) =
if (debugIDE) println(msg)
@@ -82,7 +97,7 @@ self =>
*/
override def signalDone(context: Context, old: Tree, result: Tree) {
def integrateNew() {
- // Don't think this is needed anymore, let's see if we can remove
+ // still needed?
context.unit.body = new TreeReplacer(old, result) transform context.unit.body
}
if (activeLocks == 0) { // can we try to avoid that condition (?)
@@ -165,6 +180,9 @@ self =>
// ----------------- Polling ---------------------------------------
+ var moreWorkAtNode: Int = -1
+ var nodesSeen = 0
+
/** Called from runner thread and signalDone:
* Poll for interrupts and execute them immediately.
* Then, poll for exceptions and execute them.
@@ -182,28 +200,46 @@ self =>
pollForWork()
case _ =>
}
- if (pendingResponse.isCancelled)
- throw CancelException
- scheduler.pollThrowable() match {
- case Some(ex @ FreshRunReq) =>
- newTyperRun()
- minRunId = currentRunId
- if (outOfDate) throw ex
- else outOfDate = true
- case Some(ex: Throwable) => throw ex
- case _ =>
+
+ def nodeWithWork(): Option[Int] = {
+ nodesSeen += 1
+ if (scheduler.moreWork || pendingResponse.isCancelled) Some(nodesSeen) else None
}
- scheduler.nextWorkItem() match {
- case Some(action) =>
- try {
- debugLog("picked up work item: "+action)
- action()
- debugLog("done with work item: "+action)
- } finally {
- debugLog("quitting work item: "+action)
- }
+
+ logreplay("atnode", nodeWithWork()) match {
+ case Some(id) =>
+ assert(id >= nodesSeen)
+ moreWorkAtNode = id
case None =>
}
+
+ if (nodesSeen == moreWorkAtNode) {
+
+ if (logreplay("cancelled", pendingResponse.isCancelled)) {
+ throw CancelException
+ }
+
+ logreplay("exception thrown", scheduler.pollThrowable()) match {
+ case Some(ex @ FreshRunReq) =>
+ newTyperRun()
+ minRunId = currentRunId
+ if (outOfDate) throw ex
+ else outOfDate = true
+ case Some(ex: Throwable) => throw ex
+ case _ =>
+ }
+ logreplay("workitem", scheduler.nextWorkItem()) match {
+ case Some(action) =>
+ try {
+ debugLog("picked up work item: "+action)
+ action()
+ debugLog("done with work item: "+action)
+ } finally {
+ debugLog("quitting work item: "+action)
+ }
+ case None =>
+ }
+ }
}
def debugInfo(source : SourceFile, start : Int, length : Int): String = {
@@ -291,13 +327,11 @@ self =>
// remove any files in first that are no longer maintained by presentation compiler (i.e. closed)
allSources = allSources filter (s => unitOfFile contains (s.file))
- informIDE("Parsing %d files.".format(allSources.size))
for (s <- allSources) {
val unit = unitOf(s)
if (unit.status == NotLoaded) parse(unit)
}
- informIDE("Typechecking %d files.".format(allSources.size))
for (s <- allSources) {
val unit = unitOf(s)
if (!unit.isUpToDate) typeCheck(unit)