summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-11-01 13:01:59 -0700
committerPaul Phillips <paulp@improving.org>2012-11-02 00:08:34 -0700
commit77a45858777554c6e1fb7b9583359a6a492ec066 (patch)
tree619dd3849b1d0b4d3e91ef1cb6bce819e9cf5767 /src/compiler/scala/tools/nsc/typechecker/Contexts.scala
parent14704da1b854e04d8e8de81eb7741757f33a2d13 (diff)
downloadscala-77a45858777554c6e1fb7b9583359a6a492ec066.tar.gz
scala-77a45858777554c6e1fb7b9583359a6a492ec066.tar.bz2
scala-77a45858777554c6e1fb7b9583359a6a492ec066.zip
The improvements made possible by the scope changes.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Contexts.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala52
1 files changed, 17 insertions, 35 deletions
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