summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2010-10-25 13:26:35 +0000
committerMartin Odersky <odersky@gmail.com>2010-10-25 13:26:35 +0000
commit5c322510b185e7ee50ec6f75057369c427b9724b (patch)
tree4d9a8ba65fac59172673cfdce4d0d288e2e94aad
parentbaf9c6f3803d64b7d03fa9193871a85cd29c00b8 (diff)
downloadscala-5c322510b185e7ee50ec6f75057369c427b9724b.tar.gz
scala-5c322510b185e7ee50ec6f75057369c427b9724b.tar.bz2
scala-5c322510b185e7ee50ec6f75057369c427b9724b.zip
Now short-circuits reload work items that are s...
Now short-circuits reload work items that are superseded by later ones.
-rw-r--r--src/compiler/scala/tools/nsc/interactive/CompilerControl.scala50
-rw-r--r--src/compiler/scala/tools/nsc/util/WorkScheduler.scala3
2 files changed, 32 insertions, 21 deletions
diff --git a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
index 5258849b8c..87eace3a24 100644
--- a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
+++ b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
@@ -13,6 +13,11 @@ trait CompilerControl { self: Global =>
abstract class WorkItem extends (() => Unit)
+ case class ReloadItem(sources: List[SourceFile], response: Response[Unit]) extends WorkItem {
+ def apply() = reload(sources, response)
+ override def toString = "reload "+sources
+ }
+
/** Info given for every member found by completion
*/
abstract class Member {
@@ -89,54 +94,57 @@ trait CompilerControl { self: Global =>
}
/** Make sure a set of compilation units is loaded and parsed.
- * Return () to syncvar `result` on completion.
+ * Return () to syncvar `response` on completion.
*/
- def askReload(sources: List[SourceFile], result: Response[Unit]) =
- scheduler postWorkItem new WorkItem {
- def apply() = reload(sources, result)
- override def toString = "reload "+sources
+ def askReload(sources: List[SourceFile], response: Response[Unit]) = {
+ val superseeded = scheduler.dequeueAll {
+ case ri: ReloadItem if ri.sources == sources => Some(ri)
+ case _ => None
}
+ superseeded foreach (_.response.set())
+ scheduler postWorkItem new ReloadItem(sources, response)
+ }
- /** Set sync var `result` to the smallest fully attributed tree that encloses position `pos`.
+ /** Set sync var `response` to the smallest fully attributed tree that encloses position `pos`.
*/
- def askTypeAt(pos: Position, result: Response[Tree]) =
+ def askTypeAt(pos: Position, response: Response[Tree]) =
scheduler postWorkItem new WorkItem {
- def apply() = self.getTypedTreeAt(pos, result)
+ def apply() = self.getTypedTreeAt(pos, response)
override def toString = "typeat "+pos.source+" "+pos.show
}
- /** Set sync var `result` to the fully attributed & typechecked tree contained in `source`.
+ /** Set sync var `response` to the fully attributed & typechecked tree contained in `source`.
*/
- def askType(source: SourceFile, forceReload: Boolean, result: Response[Tree]) =
+ def askType(source: SourceFile, forceReload: Boolean, response: Response[Tree]) =
scheduler postWorkItem new WorkItem {
- def apply() = self.getTypedTree(source, forceReload, result)
+ def apply() = self.getTypedTree(source, forceReload, response)
override def toString = "typecheck"
}
- /** Set sync var `result` to the last fully attributed & typechecked tree produced from `source`.
- * If no such tree exists yet, do a normal askType(source, false, result)
+ /** Set sync var `response` to the last fully attributed & typechecked tree produced from `source`.
+ * If no such tree exists yet, do a normal askType(source, false, response)
*/
- def askLastType(source: SourceFile, result: Response[Tree]) =
+ def askLastType(source: SourceFile, response: Response[Tree]) =
scheduler postWorkItem new WorkItem {
- def apply() = self.getLastTypedTree(source, result)
+ def apply() = self.getLastTypedTree(source, response)
override def toString = "reconcile"
}
- /** Set sync var `result' to list of members that are visible
+ /** Set sync var `response' to list of members that are visible
* as members of the tree enclosing `pos`, possibly reachable by an implicit.
*/
- def askTypeCompletion(pos: Position, result: Response[List[Member]]) =
+ def askTypeCompletion(pos: Position, response: Response[List[Member]]) =
scheduler postWorkItem new WorkItem {
- def apply() = self.getTypeCompletion(pos, result)
+ def apply() = self.getTypeCompletion(pos, response)
override def toString = "type completion "+pos.source+" "+pos.show
}
- /** Set sync var `result' to list of members that are visible
+ /** Set sync var `response' to list of members that are visible
* as members of the scope enclosing `pos`.
*/
- def askScopeCompletion(pos: Position, result: Response[List[Member]]) =
+ def askScopeCompletion(pos: Position, response: Response[List[Member]]) =
scheduler postWorkItem new WorkItem {
- def apply() = self.getScopeCompletion(pos, result)
+ def apply() = self.getScopeCompletion(pos, response)
override def toString = "scope completion "+pos.source+" "+pos.show
}
diff --git a/src/compiler/scala/tools/nsc/util/WorkScheduler.scala b/src/compiler/scala/tools/nsc/util/WorkScheduler.scala
index f520aec8bc..509efca8e5 100644
--- a/src/compiler/scala/tools/nsc/util/WorkScheduler.scala
+++ b/src/compiler/scala/tools/nsc/util/WorkScheduler.scala
@@ -26,6 +26,9 @@ class WorkScheduler {
if (todo.isEmpty) None else Some(todo.dequeue())
}
+ def dequeueAll[T](f: Action => Option[T]): Seq[T] =
+ todo.dequeueAll(a => f(a).isDefined).map(a => f(a).get)
+
/** Called from server: return optional exception posted by client
* Reset to no exception.
*/