summaryrefslogtreecommitdiff
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
parent14704da1b854e04d8e8de81eb7741757f33a2d13 (diff)
downloadscala-77a45858777554c6e1fb7b9583359a6a492ec066.tar.gz
scala-77a45858777554c6e1fb7b9583359a6a492ec066.tar.bz2
scala-77a45858777554c6e1fb7b9583359a6a492ec066.zip
The improvements made possible by the scope changes.
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Flatten.scala14
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala52
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala4
-rw-r--r--test/files/neg/dbldef.check4
5 files changed, 26 insertions, 50 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
diff --git a/test/files/neg/dbldef.check b/test/files/neg/dbldef.check
index 3ee63475e4..b896c4cdcf 100644
--- a/test/files/neg/dbldef.check
+++ b/test/files/neg/dbldef.check
@@ -6,9 +6,7 @@ dbldef.scala:1: error: type mismatch;
required: Int
case class test0(x: Int, x: Float)
^
-dbldef.scala:1: error: type mismatch;
- found : Float
- required: Int
+dbldef.scala:1: error: in class test0, multiple overloaded alternatives of x define default arguments
case class test0(x: Int, x: Float)
^
three errors found