fixed #1364 (overeriding vals in traits)

git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@16740 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
odersky 2008-12-10 14:37:15 +00:00
parent b0350e1cad
commit b38a24eef4
2 changed files with 33 additions and 11 deletions

View File

@ -139,8 +139,9 @@ abstract class Mixin extends InfoTransform {
member setFlag MIXEDIN
}
def needsExpandedSetterName(field: Symbol) =
settings.Xexperimental.value && !field.hasFlag(LAZY | MUTABLE)
def needsExpandedSetterName(field: Symbol) =
!(field hasFlag LAZY) &&
(if (field.isMethod) (field hasFlag STABLE) else !(field hasFlag MUTABLE))
/** Add getters and setters for all non-module fields of an implementation
* class to its interface unless they are already present. This is done
@ -157,19 +158,26 @@ abstract class Mixin extends InfoTransform {
/** Create a new getter. Getters are never private or local. They are
* always accessors and deferred. */
def newGetter(field: Symbol): Symbol =
def newGetter(field: Symbol): Symbol = {
//println("creating new getter for "+field+field.locationString+(field hasFlag MUTABLE))
clazz.newMethod(field.pos, nme.getterName(field.name))
.setFlag(field.flags & ~(PRIVATE | LOCAL) | ACCESSOR | lateDEFERRED)
.setFlag(field.flags & ~(PRIVATE | LOCAL) | ACCESSOR | lateDEFERRED |
(if (field hasFlag MUTABLE) 0 else STABLE))
.setInfo(MethodType(List(), field.info))
}
/** Create a new setter. Setters are never private or local. They are
* always accessors and deferred. */
def newSetter(field: Symbol): Symbol = {
//println("creating new setter for "+field+field.locationString+(field hasFlag MUTABLE))
val setterName = nme.getterToSetter(nme.getterName(field.name))
val setter = clazz.newMethod(field.pos, setterName)
.setFlag(field.flags & ~(PRIVATE | LOCAL) | ACCESSOR | lateDEFERRED)
.setInfo(MethodType(List(field.info), UnitClass.tpe))
if (needsExpandedSetterName(field)) setter.name = clazz.expandedSetterName(setter.name)
if (needsExpandedSetterName(field)) {
//println("creating expanded setter from "+field)
setter.name = clazz.expandedSetterName(setter.name)
}
setter
}
@ -793,7 +801,7 @@ abstract class Mixin extends InfoTransform {
}
if (sym.isSetter) {
val isOverriddenSetter =
settings.Xexperimental.value && nme.isTraitSetterName(sym.name) && {
nme.isTraitSetterName(sym.name) && {
sym.allOverriddenSymbols match {
case other :: _ =>
isOverriddenAccessor(other.getter(other.owner), clazz.info.baseClasses)
@ -960,10 +968,14 @@ abstract class Mixin extends InfoTransform {
// assign to fields in some implementation class via an abstract
// setter in the interface.
localTyper.typed {
// println(lhs.symbol)
// println(lhs.symbol.owner.info.decls)
// println(needsExpandedSetterName(lhs.symbol))
// util.trace("generating tree: ") {
/*
println(lhs.symbol)
println(lhs.symbol.owner.info.decls)
println(needsExpandedSetterName(lhs.symbol))
println(toInterface(lhs.symbol.owner.tpe).typeSymbol)
println(toInterface(lhs.symbol.owner.tpe).typeSymbol.info.decls)
util.trace("generating tree: ") {
*/
atPos(tree.pos) {
Apply(
Select(
@ -973,7 +985,8 @@ abstract class Mixin extends InfoTransform {
needsExpandedSetterName(lhs.symbol))) setPos lhs.pos,
List(rhs))
}
} //}
// }
}
case _ =>
tree
}

View File

@ -0,0 +1,9 @@
object Test extends Application {
trait Happy { val status = "happy" }
trait Sad { val status = "sad" }
def go1 = (new AnyRef with Happy with Sad { override val status = "happysad" }).status
def go2 = (new AnyRef with Happy with Sad { val blurp = "happysad" ; override val status = blurp }).status
def go3 = (new AnyRef with Happy with Sad { override val status = blurp ; val blurp = "happysad" }).status
}