diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/interactive/CompilerControl.scala | 9 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/interactive/Global.scala | 55 |
2 files changed, 55 insertions, 9 deletions
diff --git a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala index 63793fa21a..f37f45298e 100644 --- a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala +++ b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala @@ -167,7 +167,9 @@ trait CompilerControl { self: Global => def askScopeCompletion(pos: Position, response: Response[List[Member]]) = postWorkItem(new AskScopeCompletionItem(pos, response)) - /** Asks to do unit corresponding to given source file on present and subsequent type checking passes */ + /** Asks to do unit corresponding to given source file on present and subsequent type checking passes. + * If the file is in the 'crashedFiles' ignore list it is removed and typechecked normally. + */ def askToDoFirst(source: SourceFile) = postWorkItem(new AskToDoFirstItem(source)) @@ -330,7 +332,10 @@ trait CompilerControl { self: Global => } class AskToDoFirstItem(val source: SourceFile) extends WorkItem { - def apply() = moveToFront(List(source)) + def apply() = { + moveToFront(List(source)) + enableIgnoredFile(source.file) + } override def toString = "dofirst "+source def raiseMissing() = () diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala index 78169941c8..a0913bd75d 100644 --- a/src/compiler/scala/tools/nsc/interactive/Global.scala +++ b/src/compiler/scala/tools/nsc/interactive/Global.scala @@ -48,7 +48,6 @@ class Global(settings: Settings, reporter: Reporter, projectName: String = "") else NullLogger import log.logreplay - debugLog("interactive compiler from 20 Feb") debugLog("logger: " + log.getClass + " writing to " + (new java.io.File(logName)).getAbsolutePath) debugLog("classpath: "+classPath) @@ -161,6 +160,25 @@ class Global(settings: Settings, reporter: Reporter, projectName: String = "") */ protected var allSources: List[SourceFile] = List() + private var lastException: Option[Throwable] = None + + /** A list of files that crashed the compiler. They will be ignored during background + * compilation until they are removed from this list. + */ + private var ignoredFiles: Set[AbstractFile] = Set() + + /** Flush the buffer of sources that are ignored during background compilation. */ + def clearIgnoredFiles() { + ignoredFiles = Set() + } + + /** Remove a crashed file from the ignore buffer. Background compilation will take it into account + * and errors will be reported against it. */ + def enableIgnoredFile(file: AbstractFile) { + ignoredFiles -= file + debugLog("Removed crashed file %s. Still in the ignored buffer: %s".format(file, ignoredFiles)) + } + /** The currently active typer run */ private var currentTyperRun: TyperRun = _ newTyperRun() @@ -440,12 +458,33 @@ class Global(settings: Settings, reporter: Reporter, projectName: String = "") } // ensure all loaded units are typechecked - for (s <- allSources; unit <- getUnit(s)) { - if (!unit.isUpToDate) typeCheck(unit) - else debugLog("already up to date: "+unit) - for (r <- waitLoadedTypeResponses(unit.source)) - r set unit.body - serviceParsedEntered() + for (s <- allSources; if !ignoredFiles(s.file); unit <- getUnit(s)) { + try { + if (!unit.isUpToDate) + if (unit.problems.isEmpty) + typeCheck(unit) + else debugLog("%s has syntax errors. Skipped typechecking".format(unit)) + else debugLog("already up to date: "+unit) + for (r <- waitLoadedTypeResponses(unit.source)) + r set unit.body + serviceParsedEntered() + } catch { + case ex: FreshRunReq => throw ex // propagate a new run request + + case ex => + println("[%s]: exception during background compile: ".format(unit.source) + ex) + ex.printStackTrace() + for (r <- waitLoadedTypeResponses(unit.source)) { + r.raise(ex) + } + serviceParsedEntered() + + lastException = Some(ex) + ignoredFiles += unit.source.file + println("[%s] marking unit as crashed (crashedFiles: %s)".format(unit, ignoredFiles)) + + reporter.error(unit.body.pos, "Presentation compiler crashed while type checking this file: %s".format(ex.toString())) + } } // clean out stale waiting responses @@ -890,6 +929,8 @@ class Global(settings: Settings, reporter: Reporter, projectName: String = "") if (unit.isUpToDate) { debugLog("already typed"); response set unit.body + } else if (ignoredFiles(source.file)) { + response.raise(lastException.getOrElse(CancelException)) } else if (onSameThread) { getTypedTree(source, forceReload = false, response) } else { |