summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/interactive/CompilerControl.scala13
-rw-r--r--src/compiler/scala/tools/nsc/interactive/Global.scala14
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala14
4 files changed, 33 insertions, 14 deletions
diff --git a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
index 32a780104d..9d29b781c1 100644
--- a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
+++ b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
@@ -51,7 +51,14 @@ trait CompilerControl { self: Global =>
*/
def getUnitOf(s: SourceFile): Option[RichCompilationUnit] = getUnit(s)
- /** The compilation unit corresponding to a source file
+ /** Run operation `op` on a compilation unit assocuated with given `source`.
+ * If source has a loaded compilation unit, this one is passed to `op`.
+ * Otherwise a new compilation unit is created, but not added to the set of loaded units.
+ */
+ def onUnitOf[T](source: SourceFile)(op: RichCompilationUnit => T): T =
+ op(unitOfFile.getOrElse(source.file, new RichCompilationUnit(source)))
+
+ /** The compilation unit corresponding to a source file
* if it does not yet exist create a new one atomically
* Note: We want to get roid of this operation as it messes compiler invariants.
*/
@@ -193,6 +200,10 @@ trait CompilerControl { self: Global =>
/** Returns parse tree for source `source`. No symbols are entered. Syntax errors are reported.
*/
def askParse(source: SourceFile, response: Response[Tree]) = respond(response) {
+ parseTree(source)
+ }
+
+ def parseTree(source: SourceFile): Tree = ask { () =>
getUnit(source) match {
case Some(unit) if unit.status >= JustParsed =>
unit.body
diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala
index fdce4f8cbf..8fc23c68f0 100644
--- a/src/compiler/scala/tools/nsc/interactive/Global.scala
+++ b/src/compiler/scala/tools/nsc/interactive/Global.scala
@@ -83,9 +83,6 @@ self =>
protected[interactive] def getOrCreateUnitOf(source: SourceFile): RichCompilationUnit =
unitOfFile.getOrElse(source.file, { println("precondition violated: "+source+" is not loaded"); new Exception().printStackTrace(); new RichCompilationUnit(source) })
- protected [interactive] def onUnitOf[T](source: SourceFile)(op: RichCompilationUnit => T): T =
- op(unitOfFile.getOrElse(source.file, new RichCompilationUnit(source)))
-
/** Work through toBeRemoved list to remove any units.
* Then return optionlly unit associated with given source.
*/
@@ -139,10 +136,7 @@ self =>
if (context.unit == null)
context.unit.body = new TreeReplacer(old, result) transform context.unit.body
}
- @inline def isUnlocked(sym: Symbol) = (sym.rawflags & LOCKED) == 0
- @tailrec def noLocks(sym: Symbol): Boolean = sym == NoSymbol || isUnlocked(sym) && noLocks(sym.owner)
- def noImportLocks: Boolean = context.imports forall (imp => isUnlocked(imp.tree.symbol))
- if (interruptsEnabled && noLocks(context.owner) && noImportLocks) {
+ if (interruptsEnabled && analyzer.lockedCount == 0) {
if (context.unit != null &&
result.pos.isOpaqueRange &&
(result.pos includes context.unit.targetPos)) {
@@ -711,8 +705,10 @@ self =>
addTypeMember(sym, pre, true, NoSymbol)
members.values.toList #:: {
val applicableViews: List[SearchResult] =
- new ImplicitSearch(tree, functionType(List(ownerTpe), AnyClass.tpe), isView = true, context.makeImplicit(reportAmbiguousErrors = false))
- .allImplicits
+ if (ownerTpe.isErroneous) List()
+ else new ImplicitSearch(
+ tree, functionType(List(ownerTpe), AnyClass.tpe), isView = true,
+ context.makeImplicit(reportAmbiguousErrors = false)).allImplicits
for (view <- applicableViews) {
val vtree = viewApply(view)
val vpre = stabilizedType(vtree)
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
index 320f581031..32a1caef85 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
@@ -62,8 +62,10 @@ abstract class SymbolLoaders {
def enterClassAndModule(root: Symbol, name: String, completer: SymbolLoader) {
val clazz = enterClass(root, name, completer)
val module = enterModule(root, name, completer)
- assert(clazz.companionModule == module || clazz.isAnonymousClass, module)
- assert(module.companionClass == clazz, clazz)
+ if (!clazz.isAnonymousClass) {
+ assert(clazz.companionModule == module, module)
+ assert(module.companionClass == clazz, clazz)
+ }
}
/** In batch mode: Enter class and module with given `name` into scope of `root`
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 1f750dd727..3553ac5d99 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -1347,9 +1347,16 @@ trait Namers { self: Analyzer =>
val tree: Tree
}
+ var lockedCount = 0
+
def mkTypeCompleter(t: Tree)(c: Symbol => Unit) = new TypeCompleter {
val tree = t
- override def complete(sym: Symbol) = c(sym)
+ override def complete(sym: Symbol) = try {
+ lockedCount += 1
+ c(sym)
+ } finally {
+ lockedCount -= 1
+ }
}
/** A class representing a lazy type with known type parameters.
@@ -1357,10 +1364,13 @@ trait Namers { self: Analyzer =>
class PolyTypeCompleter(tparams: List[Tree], restp: TypeCompleter, owner: Tree, ownerSym: Symbol, ctx: Context) extends TypeCompleter {
override val typeParams: List[Symbol]= tparams map (_.symbol) //@M
override val tree = restp.tree
- override def complete(sym: Symbol) {
+ override def complete(sym: Symbol) = try {
+ lockedCount += 1
if(ownerSym.isAbstractType) //@M an abstract type's type parameters are entered -- TODO: change to isTypeMember ?
newNamer(ctx.makeNewScope(owner, ownerSym)).enterSyms(tparams) //@M
restp.complete(sym)
+ } finally {
+ lockedCount -= 1
}
}