diff options
author | Paul Phillips <paulp@improving.org> | 2012-11-01 13:01:59 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-11-02 00:08:34 -0700 |
commit | 77a45858777554c6e1fb7b9583359a6a492ec066 (patch) | |
tree | 619dd3849b1d0b4d3e91ef1cb6bce819e9cf5767 /src/compiler | |
parent | 14704da1b854e04d8e8de81eb7741757f33a2d13 (diff) | |
download | scala-77a45858777554c6e1fb7b9583359a6a492ec066.tar.gz scala-77a45858777554c6e1fb7b9583359a6a492ec066.tar.bz2 scala-77a45858777554c6e1fb7b9583359a6a492ec066.zip |
The improvements made possible by the scope changes.
Diffstat (limited to 'src/compiler')
4 files changed, 25 insertions, 47 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 42589874fe..e69b4bee94 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -562,7 +562,7 @@ abstract class ClassfileParser { 0 until in.nextChar foreach (_ => parseMethod()) val needsConstructor = ( !sawPrivateConstructor - && instanceScope.lookup(nme.CONSTRUCTOR) == NoSymbol + && !(instanceScope containsName nme.CONSTRUCTOR) && (sflags & INTERFACE) == 0 ) if (needsConstructor) diff --git a/src/compiler/scala/tools/nsc/transform/Flatten.scala b/src/compiler/scala/tools/nsc/transform/Flatten.scala index e2913bea0d..672a11ec30 100644 --- a/src/compiler/scala/tools/nsc/transform/Flatten.scala +++ b/src/compiler/scala/tools/nsc/transform/Flatten.scala @@ -18,18 +18,14 @@ abstract class Flatten extends InfoTransform { /** the following two members override abstract members in Transform */ val phaseName: String = "flatten" - /** Updates the owning scope with the given symbol; returns the old symbol. + /** Updates the owning scope with the given symbol, unlinking any others. */ - private def replaceSymbolInCurrentScope(sym: Symbol): Symbol = exitingFlatten { + private def replaceSymbolInCurrentScope(sym: Symbol): Unit = exitingFlatten { val scope = sym.owner.info.decls - val old = scope lookup sym.name andAlso scope.unlink + val old = (scope lookupUnshadowedEntries sym.name).toList + old foreach (scope unlink _) scope enter sym - - if (old eq NoSymbol) - log(s"lifted ${sym.fullLocationString}") - else - log(s"lifted ${sym.fullLocationString} after unlinking existing $old from scope.") - + log(s"lifted ${sym.fullLocationString}" + ( if (old.isEmpty) "" else " after unlinking $old from scope." )) old } diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 92e2bc186e..f2409ea482 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -758,15 +758,12 @@ trait Contexts { self: Analyzer => def lookupSymbol(name: Name, qualifies: Symbol => Boolean): NameLookup = { var lookupError: NameLookup = null // set to non-null if a definite error is encountered var inaccessible: NameLookup = null // records inaccessible symbol for error reporting in case none is found - var defEntry: ScopeEntry = null // the scope entry of defSym, if defined in a local scope var defSym: Symbol = NoSymbol // the directly found symbol + var symbolDepth: Int = -1 // the depth of the directly found symbol var pre: Type = NoPrefix // the prefix type of defSym, if a class member var cx: Context = this var needsQualifier = false // working around package object overloading bug - def defEntrySymbol = if (defEntry eq null) NoSymbol else defEntry.sym - def localScopeDepth = if (defEntry eq null) 0 else cx.scope.nestingLevel - defEntry.owner.nestingLevel - def finish(qual: Tree, sym: Symbol): NameLookup = ( if (lookupError ne null) lookupError else sym match { @@ -789,23 +786,6 @@ trait Contexts { self: Analyzer => def lookupInPrefix(name: Name) = pre member name filter qualifies def accessibleInPrefix(s: Symbol) = isAccessible(s, pre, superAccess = false) - def correctForPackageObject(sym: Symbol): Symbol = { - if (sym.isTerm && isInPackageObject(sym, pre.typeSymbol)) { - val sym1 = lookupInPrefix(sym.name) - if ((sym1 eq NoSymbol) || (sym eq sym1)) sym else { - needsQualifier = true - log(s""" - | !!! Overloaded package object member resolved incorrectly. - | prefix: $pre - | Discarded: ${sym.defString} - | Using: ${sym1.defString} - """.stripMargin) - sym1 - } - } - else sym - } - def searchPrefix = { cx = cx.enclClass val found0 = lookupInPrefix(name) @@ -817,22 +797,24 @@ trait Contexts { self: Analyzer => } // cx.scope eq null arises during FixInvalidSyms in Duplicators while (defSym == NoSymbol && (cx ne NoContext) && (cx.scope ne null)) { - pre = cx.enclClass.prefix - // !!! FIXME. This call to lookupEntry is at the root of all the - // bad behavior with overloading in package objects. lookupEntry - // just takes the first symbol it finds in scope, ignoring the rest. - // When a selection on a package object arrives here, the first - // overload is always chosen. "correctForPackageObject" exists to - // undo that decision. Obviously it would be better not to do it in - // the first place; however other things seem to be tied to obtaining - // that ScopeEntry, specifically calculating the nesting depth. - defEntry = cx.scope lookupEntry name - defSym = defEntrySymbol filter qualifies map correctForPackageObject orElse searchPrefix - if (!defSym.exists) - cx = cx.outer + val entries = (cx.scope lookupUnshadowedEntries name filter (e => qualifies(e.sym))).toList + + pre = cx.enclClass.prefix + symbolDepth = if (entries.isEmpty) cx.depth else (cx.depth - cx.scope.nestingLevel) + entries.head.depth + defSym = entries match { + case Nil => searchPrefix + case hd :: Nil => hd.sym + case alts => logResult(s"!!! lookup overloaded")(cx.owner.newOverloaded(pre, entries map (_.sym))) + } + + if (defSym.exists) // we have a winner: record the symbol depth + symbolDepth = ( + if (entries.isEmpty) cx.depth + else (cx.depth - cx.scope.nestingLevel) + entries.head.depth + ) + else cx = cx.outer // push further outward } - val symbolDepth = cx.depth - localScopeDepth var impSym: Symbol = NoSymbol var imports = Context.this.imports // impSym != NoSymbol => it is imported from imports.head def imp1 = imports.head diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 99b927af66..d8d021f64d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -381,8 +381,8 @@ trait Namers extends MethodSynthesis { if (sym eq NoSymbol) return val ctx = if (context.owner.isPackageObjectClass) context.outer else context - val module = if (sym.isModule) sym else ctx.scope lookup tree.name.toTermName - val clazz = if (sym.isClass) sym else ctx.scope lookup tree.name.toTypeName + val module = if (sym.isModule) sym else ctx.scope lookupModule tree.name + val clazz = if (sym.isClass) sym else ctx.scope lookupClass tree.name val fails = ( module.isModule && clazz.isClass |