diff options
author | Martin Odersky <odersky@gmail.com> | 2011-03-25 13:33:49 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2011-03-25 13:33:49 +0000 |
commit | 73c16ef14f366e883acc09011a3837b7ddf60956 (patch) | |
tree | b5b9b3e3e58907d5dc412a4f1e4cf35d57986eab /src/compiler | |
parent | bc08f3bfa1f136c1014e5c4d870832d5c5bc9b85 (diff) | |
download | scala-73c16ef14f366e883acc09011a3837b7ddf60956.tar.gz scala-73c16ef14f366e883acc09011a3837b7ddf60956.tar.bz2 scala-73c16ef14f366e883acc09011a3837b7ddf60956.zip |
Merged revisions 24578-24579 via svnmerge from
https://lampsvn.epfl.ch/svn-repos/scala/scala/trunk
........
r24578 | odersky | 2011-03-25 11:15:29 +0100 (Fri, 25 Mar 2011) | 1 line
All compiler control methods now do something sensible when called
from presentation compiler thread itself. ........ r24579 | odersky |
2011-03-25 11:17:35 +0100 (Fri, 25 Mar 2011) | 1 line
Fixed error in previous commit
........
Diffstat (limited to 'src/compiler')
3 files changed, 34 insertions, 31 deletions
diff --git a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala index 2ced0788c1..51ee6bf5fb 100644 --- a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala +++ b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala @@ -107,6 +107,8 @@ trait CompilerControl { self: Global => scheduler.postWorkItem(item) } + private def onCompilerThread = Thread.currentThread == compileRunner + /** Makes sure a set of compilation units is loaded and parsed. * Returns () to syncvar `response` on completions. * Afterwards a new background compiler run is started with @@ -130,13 +132,8 @@ trait CompilerControl { self: Global => /** Sets sync var `response` to the fully attributed & typechecked tree contained in `source`. * @pre `source` needs to be loaded. */ - def askType(source: SourceFile, forceReload: Boolean, response: Response[Tree]) = { - if (debugIDE) { - println("ask type called") - new Exception().printStackTrace() - } + def askType(source: SourceFile, forceReload: Boolean, response: Response[Tree]) = postWorkItem(new AskTypeItem(source, forceReload, response)) - } /** Sets sync var `response` to the position of the definition of the given link in * the given sourcefile. @@ -179,7 +176,7 @@ trait CompilerControl { self: Global => * the a NoSuchUnitError is raised in the response. */ def askLoadedTyped(source: SourceFile, response: Response[Tree]) = - postWorkItem(new AskLoadedTypedItem(source, response)) + postWorkItem(new AskLoadedTypedItem(source, response, onCompilerThread)) /** If source if not yet loaded, get an outline view with askParseEntered. * If source is loaded, wait for it to be typechecked. @@ -200,7 +197,7 @@ trait CompilerControl { self: Global => * @param response The response. */ def askParsedEntered(source: SourceFile, keepLoaded: Boolean, response: Response[Tree]) = - postWorkItem(new AskParsedEnteredItem(source, keepLoaded, response)) + postWorkItem(new AskParsedEnteredItem(source, keepLoaded, response, onCompilerThread)) /** Cancels current compiler run and start a fresh one where everything will be re-typechecked * (but not re-loaded). @@ -228,7 +225,7 @@ trait CompilerControl { self: Global => } /** Asks for a computation to be done quickly on the presentation compiler thread */ - def ask[A](op: () => A): A = scheduler doQuickly op + def ask[A](op: () => A): A = if (onCompilerThread) op() else scheduler doQuickly op /** Info given for every member found by completion */ @@ -293,13 +290,13 @@ trait CompilerControl { self: Global => override def toString = "linkpos "+sym+" in "+source } - class AskLoadedTypedItem(val source: SourceFile, response: Response[Tree]) extends WorkItem { - def apply() = self.waitLoadedTyped(source, response) + class AskLoadedTypedItem(val source: SourceFile, response: Response[Tree], val onSameThread: Boolean) extends WorkItem { + def apply() = self.waitLoadedTyped(source, response, onSameThread) override def toString = "wait loaded & typed "+source } - class AskParsedEnteredItem(val source: SourceFile, val keepLoaded: Boolean, response: Response[Tree]) extends WorkItem { - def apply() = self.getParsedEntered(source, keepLoaded, response) + class AskParsedEnteredItem(val source: SourceFile, val keepLoaded: Boolean, response: Response[Tree], val onSameThread: Boolean) extends WorkItem { + def apply() = self.getParsedEntered(source, keepLoaded, response, onSameThread) override def toString = "getParsedEntered "+source+", keepLoaded = "+keepLoaded } } diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala index 95aec8b0a2..2e76a6378e 100644 --- a/src/compiler/scala/tools/nsc/interactive/Global.scala +++ b/src/compiler/scala/tools/nsc/interactive/Global.scala @@ -849,31 +849,37 @@ class Global(settings: Settings, reporter: Reporter) } /** Implements CompilerControl.askLoadedTyped */ - protected def waitLoadedTyped(source: SourceFile, response: Response[Tree]) { + protected def waitLoadedTyped(source: SourceFile, response: Response[Tree], onSameThread: Boolean) { getUnit(source) match { - case Some(unit) => - if (unit.isUpToDate) { debugLog("already typed"); response set unit.body } - else { debugLog("wait for later"); outOfDate = true; waitLoadedTypeResponses(source) += response } - case None => + case Some(unit) if unit.isUpToDate => + debugLog("already typed"); + response set unit.body + case Some(_) if !onSameThread => + debugLog("wait for later") + outOfDate = true + waitLoadedTypeResponses(source) += response + case _ => debugLog("load unit and type") try reloadSources(List(source)) - finally waitLoadedTyped(source, response) + finally waitLoadedTyped(source, response, onSameThread) } } /** Implements CompilerControl.askParsedEntered */ - protected def getParsedEntered(source: SourceFile, keepLoaded: Boolean, response: Response[Tree]) { + protected def getParsedEntered(source: SourceFile, keepLoaded: Boolean, response: Response[Tree], onSameThread: Boolean) { getUnit(source) match { case Some(unit) => getParsedEnteredNow(source, response) case None => - if (keepLoaded) - try reloadSources(List(source)) - finally getParsedEnteredNow(source, response) - else if (outOfDate) - getParsedEnteredResponses(source) += response - else - getParsedEnteredNow(source, response) + try { + if (keepLoaded || outOfDate && onSameThread) + reloadSources(List(source)) + } finally { + if (keepLoaded || !outOfDate || onSameThread) + getParsedEnteredNow(source, response) + else + getParsedEnteredResponses(source) += response + } } } diff --git a/src/compiler/scala/tools/nsc/interactive/Picklers.scala b/src/compiler/scala/tools/nsc/interactive/Picklers.scala index 250f648250..4591cf2522 100644 --- a/src/compiler/scala/tools/nsc/interactive/Picklers.scala +++ b/src/compiler/scala/tools/nsc/interactive/Picklers.scala @@ -159,13 +159,13 @@ trait Picklers { self: Global => .asClass (classOf[AskLinkPosItem]) implicit def askLoadedTypedItem: CondPickler[AskLoadedTypedItem] = - pkl[SourceFile] - .wrapped { new AskLoadedTypedItem(_, new Response) } { _.source } + (pkl[SourceFile] ~ pkl[Boolean]) + .wrapped { case source ~ onSameThread => new AskLoadedTypedItem(source, new Response, onSameThread) } { w => w.source ~ w.onSameThread } .asClass (classOf[AskLoadedTypedItem]) implicit def askParsedEnteredItem: CondPickler[AskParsedEnteredItem] = - (pkl[SourceFile] ~ pkl[Boolean]) - .wrapped { case source ~ keepLoaded => new AskParsedEnteredItem(source, keepLoaded, new Response) } { w => w.source ~ w.keepLoaded } + (pkl[SourceFile] ~ pkl[Boolean] ~ pkl[Boolean]) + .wrapped { case source ~ keepLoaded ~ onSameThread => new AskParsedEnteredItem(source, keepLoaded, new Response, onSameThread) } { w => w.source ~ w.keepLoaded ~ w.onSameThread } .asClass (classOf[AskParsedEnteredItem]) implicit def emptyAction: CondPickler[EmptyAction] = |