diff options
author | Antonio Cunei <antonio.cunei@epfl.ch> | 2011-09-16 15:11:55 +0000 |
---|---|---|
committer | Antonio Cunei <antonio.cunei@epfl.ch> | 2011-09-16 15:11:55 +0000 |
commit | 7752f84c2d78fc1d480a06f41bd52d64a35d5900 (patch) | |
tree | 5fd2ed28d7dff71da1bc699d2782bc27908cd730 | |
parent | 0379f091f517ede2e37ae5957eb914f59ad24636 (diff) | |
download | scala-7752f84c2d78fc1d480a06f41bd52d64a35d5900.tar.gz scala-7752f84c2d78fc1d480a06f41bd52d64a35d5900.tar.bz2 scala-7752f84c2d78fc1d480a06f41bd52d64a35d5900.zip |
Backport of r25661 and r25664.
3 files changed, 56 insertions, 9 deletions
diff --git a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala index 8c1b2b6d33..7b84901604 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)) @@ -315,7 +317,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 ece336d1f9..c12d5e1622 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 || !settings.YpresentationStrict.value) + 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 @@ -888,6 +927,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 { diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 51401304b7..19b9c3c737 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -155,6 +155,7 @@ trait ScalaSettings extends AbsScalaSettings with StandardScalaSettings { */ val YpresentationVerbose = BooleanSetting("-Ypresentation-verbose", "Print information about presentation compiler tasks.") val YpresentationDebug = BooleanSetting("-Ypresentation-debug", "Enable debugging output for the presentation compiler.") + val YpresentationStrict = BooleanSetting("-Ypresentation-strict", "Do not report type errors in sources with syntax errors.") val YpresentationLog = StringSetting("-Ypresentation-log", "file", "Log presentation compiler events into file", "") val YpresentationReplay = StringSetting("-Ypresentation-replay", "file", "Replay presentation compiler events from file", "") |