summaryrefslogtreecommitdiff
path: root/src/compiler/scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2011-03-14 11:43:13 +0000
committerMartin Odersky <odersky@gmail.com>2011-03-14 11:43:13 +0000
commit13c59adf9fbff0e99ffa9f8e30f5dc05e0c1ee4d (patch)
tree17de4b40b057cf9ac6cc11e42a652a711928e9ae /src/compiler/scala
parent1f3c58a818feb7c2887ceebb079ce992aa677c0d (diff)
downloadscala-13c59adf9fbff0e99ffa9f8e30f5dc05e0c1ee4d.tar.gz
scala-13c59adf9fbff0e99ffa9f8e30f5dc05e0c1ee4d.tar.bz2
scala-13c59adf9fbff0e99ffa9f8e30f5dc05e0c1ee4d.zip
Changed Super to fix #4300
Diffstat (limited to 'src/compiler/scala')
-rw-r--r--src/compiler/scala/tools/nsc/ast/NodePrinters.scala3
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala4
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreePrinters.scala8
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala16
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala6
-rw-r--r--src/compiler/scala/tools/nsc/interactive/Global.scala3
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala30
-rw-r--r--src/compiler/scala/tools/nsc/transform/Reifiers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Duplicators.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala73
14 files changed, 94 insertions, 67 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
index 72d1895796..ca4ccd4f35 100644
--- a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
+++ b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
@@ -196,7 +196,8 @@ abstract class NodePrinters {
traverse(qualifier, level + 1, true)
printcln(" \"" + selector + "\")")
case Super(qual, mix) =>
- printcln("Super(\"" + qual + "\", \"" + mix + "\")" + nodeinfo2(tree))
+ println("Super(\"" + mix + "\")" + nodeinfo(tree))
+ traverse(qual, level + 1, true)
case Template(parents, self, body) =>
println("Template(" + nodeinfo(tree))
println(" " + parents.map(p =>
diff --git a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
index 2e51f03f4c..8fd0017b81 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
@@ -345,7 +345,7 @@ abstract class TreeBrowsers {
("Apply", EMPTY)
case Super(qualif, mix) =>
- ("Super", qualif.toString() + ", mix: " + mix.toString())
+ ("Super", "mix: " + mix.toString())
case This(qualifier) =>
("This", qualifier)
@@ -486,7 +486,7 @@ abstract class TreeBrowsers {
List(qual) ::: args
case Super(qualif, mix) =>
- Nil
+ List(qualif)
case This(qualif) =>
Nil
diff --git a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
index 033034451b..b8c3e12ee6 100644
--- a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala
@@ -341,12 +341,18 @@ trait TreePrinters { trees: SymbolTable =>
print("<apply-dynamic>("); print(qual); print("#"); print(tree.symbol.nameString)
printRow(vargs, ", (", ", ", "))")
- case Super(qual, mix) =>
+ case Super(This(qual), mix) =>
if (!qual.isEmpty || tree.symbol != NoSymbol) print(symName(tree, qual) + ".")
print("super")
if (!mix.isEmpty)
print("[" + mix + "]")
+ case Super(qual, mix) =>
+ print(qual)
+ print(".super")
+ if (!mix.isEmpty)
+ print("[" + mix + "]")
+
case This(qual) =>
if (!qual.isEmpty) print(symName(tree, qual) + ".")
print("this")
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index f7c56db113..cf612ad7a0 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -256,7 +256,7 @@ trait Trees extends reflect.generic.Trees { self: SymbolTable =>
if (vparamss1.isEmpty || !vparamss1.head.isEmpty && vparamss1.head.head.mods.isImplicit)
vparamss1 = List() :: vparamss1;
val superRef: Tree = atPos(superPos) {
- Select(Super(tpnme.EMPTY, tpnme.EMPTY), nme.CONSTRUCTOR)
+ Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR)
}
val superCall = (superRef /: argss) (Apply)
List(
@@ -289,7 +289,7 @@ trait Trees extends reflect.generic.Trees { self: SymbolTable =>
(superRef /: argss) (Apply)
}
- def Super(sym: Symbol, mix: Name): Tree = Super(sym.name.toTypeName, mix.toTypeName) setSymbol sym
+ def Super(sym: Symbol, mix: TypeName): Tree = Super(This(sym), mix)
def This(sym: Symbol): Tree = This(sym.name.toTypeName) setSymbol sym
@@ -388,7 +388,7 @@ trait Trees extends reflect.generic.Trees { self: SymbolTable =>
def TypeApply(tree: Tree, fun: Tree, args: List[Tree]): TypeApply
def Apply(tree: Tree, fun: Tree, args: List[Tree]): Apply
def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]): ApplyDynamic
- def Super(tree: Tree, qual: Name, mix: Name): Super
+ def Super(tree: Tree, qual: Tree, mix: TypeName): Super
def This(tree: Tree, qual: Name): This
def Select(tree: Tree, qualifier: Tree, selector: Name): Select
def Ident(tree: Tree, name: Name): Ident
@@ -470,8 +470,8 @@ trait Trees extends reflect.generic.Trees { self: SymbolTable =>
}).copyAttrs(tree)
def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]) =
new ApplyDynamic(qual, args).copyAttrs(tree)
- def Super(tree: Tree, qual: Name, mix: Name) =
- new Super(qual.toTypeName, mix.toTypeName).copyAttrs(tree)
+ def Super(tree: Tree, qual: Tree, mix: TypeName) =
+ new Super(qual, mix).copyAttrs(tree)
def This(tree: Tree, qual: Name) =
new This(qual.toTypeName).copyAttrs(tree)
def Select(tree: Tree, qualifier: Tree, selector: Name) =
@@ -656,7 +656,7 @@ trait Trees extends reflect.generic.Trees { self: SymbolTable =>
if (qual0 == qual) && (args0 == args) => t
case _ => treeCopy.ApplyDynamic(tree, qual, args)
}
- def Super(tree: Tree, qual: Name, mix: Name) = tree match {
+ def Super(tree: Tree, qual: Tree, mix: TypeName) = tree match {
case t @ Super(qual0, mix0)
if (qual0 == qual) && (mix0 == mix) => t
case _ => treeCopy.Super(tree, qual, mix)
@@ -824,7 +824,7 @@ trait Trees extends reflect.generic.Trees { self: SymbolTable =>
case ApplyDynamic(qual, args) =>
treeCopy.ApplyDynamic(tree, transform(qual), transformTrees(args))
case Super(qual, mix) =>
- treeCopy.Super(tree, qual, mix)
+ treeCopy.Super(tree, transform(qual), mix)
case This(qual) =>
treeCopy.This(tree, qual)
case Select(qualifier, selector) =>
@@ -901,6 +901,8 @@ trait Trees extends reflect.generic.Trees { self: SymbolTable =>
traverseTrees(ts)
case TypeTreeWithDeferredRefCheck() => // TODO: should we traverse the wrapped tree?
// (and rewrap the result? how to update the deferred check? would need to store wrapped tree instead of returning it from check)
+ case Super(qual, _) =>
+ traverse(qual) // !!! remove when Super is done
case _ => super.traverse(tree)
}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index ed92afe5de..cc515d957a 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -376,7 +376,7 @@ self =>
Nil,
List(Nil),
TypeTree(),
- Block(List(Apply(Select(Super(tpnme.EMPTY, tpnme.EMPTY), nme.CONSTRUCTOR), Nil)), Literal(Constant(())))
+ Block(List(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), Nil)), Literal(Constant(())))
)
// def main
@@ -995,7 +995,7 @@ self =>
}
} else if (in.token == SUPER) {
in.nextToken()
- t = atPos(start) { Super(tpnme.EMPTY, mixinQualifierOpt()) }
+ t = atPos(start) { Super(This(tpnme.EMPTY), mixinQualifierOpt()) }
accept(DOT)
t = selector(t)
if (in.token == DOT) t = selectors(t, typeOK, in.skipToken())
@@ -1015,7 +1015,7 @@ self =>
t = selectors(t, typeOK, accept(DOT))
} else if (in.token == SUPER) {
in.nextToken()
- t = atPos(start) { Super(name.toTypeName, mixinQualifierOpt()) }
+ t = atPos(start) { Super(This(name.toTypeName), mixinQualifierOpt()) }
accept(DOT)
t = selector(t)
if (in.token == DOT) t = selectors(t, typeOK, in.skipToken())
diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala
index 11ad5d9ce3..3fad69821f 100644
--- a/src/compiler/scala/tools/nsc/interactive/Global.scala
+++ b/src/compiler/scala/tools/nsc/interactive/Global.scala
@@ -629,7 +629,7 @@ class Global(settings: Settings, reporter: Reporter)
val newsym = pre.decl(sym.name) filter { alt =>
sym.isType || {
try {
- val tp1 = pre.memberType(alt) onTypeError NoType
+ val tp1 = adaptToNewRunMap(pre.memberType(alt) onTypeError NoType)
val tp2 = adaptToNewRunMap(sym.tpe)
matchesType(tp1, tp2, false)
} catch {
@@ -645,6 +645,7 @@ class Global(settings: Settings, reporter: Reporter)
debugLog("link not found "+sym+" "+source+" "+pre)
NoPosition
} else if (newsym.isOverloaded) {
+ settings.uniqid.value = true
debugLog("link ambiguous "+sym+" "+source+" "+pre+" "+newsym.alternatives)
NoPosition
} else {
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
index 8f560b772f..b57f89c020 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
@@ -358,7 +358,7 @@ abstract class Pickler extends SubComponent {
putTrees(args)
case Super(qual, mix) =>
- putEntry(qual:Name)
+ putTree(qual)
putEntry(mix:Name)
case This(qual) =>
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index 01f90ec236..48742f4fcd 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -548,11 +548,25 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
/** Replace a super reference by this or the self parameter, depending
* on whether we are in an implementation class or not.
- * Leave all other trees unchanged */
- private def transformSuper(qual: Tree) =
- if (!qual.isInstanceOf[Super]) qual
- else if (currentOwner.enclClass.isImplClass) selfRef(qual.pos)
- else gen.mkAttributedThis(currentOwner.enclClass)
+ * Leave all other trees unchanged.
+ */
+ private def transformSuper(tree: Tree) = tree match {
+ case Super(qual, _) =>
+ transformThis(qual)
+ case _ =>
+ tree
+ }
+
+ /** Replace a this reference to the current implementation class by the self
+ * parameter. Leave all other trees unchanged.
+ */
+ private def transformThis(tree: Tree) = tree match {
+ case This(_) if tree.symbol.isImplClass =>
+ assert(tree.symbol == currentOwner.enclClass)
+ selfRef(tree.pos)
+ case _ =>
+ tree
+ }
/** Create a static reference to given symbol <code>sym</code> of the
* form <code>M.sym</code> where M is the symbol's implementation module.
@@ -1178,10 +1192,8 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
tree
}
- case This(_) if tree.symbol.isImplClass =>
- // change `this' in implementation modules to references to the self parameter
- assert(tree.symbol == currentOwner.enclClass)
- selfRef(tree.pos)
+ case This(_) =>
+ transformThis(tree)
case Select(Super(_, _), name) =>
tree
diff --git a/src/compiler/scala/tools/nsc/transform/Reifiers.scala b/src/compiler/scala/tools/nsc/transform/Reifiers.scala
index e0ee4d3af8..6b0d441ad9 100644
--- a/src/compiler/scala/tools/nsc/transform/Reifiers.scala
+++ b/src/compiler/scala/tools/nsc/transform/Reifiers.scala
@@ -305,7 +305,7 @@ trait Reifiers {
val rrhs = reify(rhs)
reflect.DefDef(rsym, rparss, rret, rrhs)
- case sp @ Super(qual: Name, mix: Name) =>
+ case sp @ Super(qual, mix) =>
val rsym = reify(sp.symbol)
reflect.Super(rsym)
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index 6673560b89..42ccae9a76 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -1396,7 +1396,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
if (symbol.isConstructor) {
val t = atOwner(symbol) {
- val superRef: Tree = Select(Super(tpnme.EMPTY, tpnme.EMPTY), nme.CONSTRUCTOR)
+ val superRef: Tree = Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR)
forwardCtorCall(tree.pos, superRef, vparamss, symbol.owner)
}
if (symbol.isPrimaryConstructor) localTyper typed {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
index cb03c61b50..286310cad0 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
@@ -276,12 +276,12 @@ abstract class Duplicators extends Analyzer {
val tree1 = super.typed(tree, mode, pt)
// log("plain this typed to: " + tree1)
tree1
-
+/* no longer needed, because Super now contains a This(...)
case Super(qual, mix) if (oldClassOwner ne null) && (tree.symbol == oldClassOwner) =>
val tree1 = Super(qual, mix)
log("changed " + tree + " to " + tree1)
super.typed(atPos(tree.pos)(tree1))
-
+*/
case Match(scrut, cases) =>
val scrut1 = typed(scrut, EXPRmode | BYVALmode, WildcardType)
val scrutTpe = scrut1.tpe.widen
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index b578759c85..cd845ab9e5 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -757,7 +757,7 @@ trait Namers { self: Analyzer =>
// add apply and unapply methods to companion objects of case classes,
// unless they exist already; here, "clazz" is the module class
if (clazz.isModuleClass) {
- Namers.this.caseClassOfModuleClass get clazz map { cdefRef =>
+ Namers.this.caseClassOfModuleClass get clazz foreach { cdefRef =>
val cdef = cdefRef()
addApplyUnapply(cdef, templateNamer)
caseClassOfModuleClass -= clazz
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index 929eb0c4f3..83d72fc3a0 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -190,10 +190,12 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
mayNeedProtectedAccessor(sel, args, false)
case sel @ Select(qual @ This(_), name) =>
+ // direct calls to aliases of param accessors to the superclass in order to avoid
+ // duplicating fields.
if (sym.isParamAccessor && sym.alias != NoSymbol) {
val result = localTyper.typed {
Select(
- Super(qual.symbol, tpnme.EMPTY/*qual.symbol.info.parents.head.symbol.name*/) setPos qual.pos,
+ Super(qual, tpnme.EMPTY/*qual.symbol.info.parents.head.symbol.name*/) setPos qual.pos,
sym.alias) setPos tree.pos
}
if (settings.debug.value)
@@ -202,7 +204,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
}
else mayNeedProtectedAccessor(sel, List(EmptyTree), false)
- case Select(sup @ Super(_, mix), name) =>
+ case Select(Super(_, mix), name) =>
if (sym.isValue && !sym.isMethod || sym.hasAccessorFlag) {
unit.error(tree.pos, "super may be not be used on "+
(if (sym.hasAccessorFlag) sym.accessed else sym))
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index cf28ea24fe..c0158a09c1 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -3378,41 +3378,44 @@ trait Typers extends Modes {
def qualifyingClassSym(qual: Name): Symbol =
if (tree.symbol != NoSymbol) tree.symbol else qualifyingClass(tree, qual, false)
- def typedSuper(qual: Name, mix: Name) = {
- val clazz = qualifyingClassSym(qual)
- if (clazz == NoSymbol) setError(tree)
- else {
- def findMixinSuper(site: Type): Type = {
- val ps = site.parents filter (_.typeSymbol.name == mix)
- if (ps.isEmpty) {
- if (settings.debug.value)
- Console.println(site.parents map (_.typeSymbol.name))//debug
- if (phase.erasedTypes && context.enclClass.owner.isImplClass) {
- // the reference to super class got lost during erasure
- restrictionError(tree.pos, unit, "traits may not select fields or methods from to super[C] where C is a class")
- } else {
- error(tree.pos, mix+" does not name a parent class of "+clazz)
- }
- ErrorType
- } else if (!ps.tail.isEmpty) {
- error(tree.pos, "ambiguous parent class qualifier")
- ErrorType
+ def typedSuper(qual: Tree, mix: TypeName) = {
+ val qual1 = typed(qual)
+ val clazz = qual1.symbol
+
+ def findMixinSuper(site: Type): Type = {
+ var ps = site.parents filter (_.typeSymbol.name == mix)
+ if (ps.isEmpty)
+ ps = site.parents filter (_.typeSymbol.toInterface.name == mix)
+ if (ps.isEmpty) {
+ if (settings.debug.value)
+ Console.println(site.parents map (_.typeSymbol.name))//debug
+ if (phase.erasedTypes && context.enclClass.owner.isImplClass) {
+ // the reference to super class got lost during erasure
+ restrictionError(tree.pos, unit, "traits may not select fields or methods from super[C] where C is a class")
} else {
- ps.head
+ error(tree.pos, mix+" does not name a parent class of "+clazz)
}
+ ErrorType
+ } else if (!ps.tail.isEmpty) {
+ error(tree.pos, "ambiguous parent class qualifier")
+ ErrorType
+ } else {
+ ps.head
}
- val owntype =
- if (mix.isEmpty) {
- if ((mode & SUPERCONSTRmode) != 0)
- if (clazz.info.parents.isEmpty) AnyRefClass.tpe // can happen due to cyclic references ==> #1036
- else clazz.info.parents.head
- else intersectionType(clazz.info.parents)
- } else {
- findMixinSuper(clazz.info)
- }
- tree setSymbol clazz setType SuperType(clazz.thisType, owntype)
}
- }
+
+ val owntype =
+ if (mix.isEmpty) {
+ if ((mode & SUPERCONSTRmode) != 0)
+ if (clazz.info.parents.isEmpty) AnyRefClass.tpe // can happen due to cyclic references ==> #1036
+ else clazz.info.parents.head
+ else intersectionType(clazz.info.parents)
+ } else {
+ findMixinSuper(clazz.info)
+ }
+
+ treeCopy.Super(tree, qual1, mix) setType SuperType(clazz.thisType, owntype)
+ }
def typedThis(qual: Name) = {
val clazz = qualifyingClassSym(qual)
@@ -3609,11 +3612,11 @@ trait Typers extends Modes {
}
else {
cx = cx.enclClass
- defSym = pre.member(name) filter (
- sym => qualifies(sym) && context.isAccessible(sym, pre, false))
+ val foundSym = pre.member(name) filter qualifies
+ defSym = foundSym filter (context.isAccessible(_, pre, false))
if (defSym == NoSymbol) {
- if (inaccessibleSym eq NoSymbol) {
- inaccessibleSym = pre.member(name) filter qualifies
+ if ((foundSym ne NoSymbol) && (inaccessibleSym eq NoSymbol)) {
+ inaccessibleSym = foundSym
inaccessibleExplanation = analyzer.lastAccessCheckDetails
}
cx = cx.outer