diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Symbols.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala | 44 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/Mixin.scala | 2 | ||||
-rw-r--r-- | test/files/pos/bug704.scala | 27 | ||||
-rw-r--r-- | test/files/run/implicits.check | 2 | ||||
-rwxr-xr-x | test/files/run/implicits.scala | 25 |
6 files changed, 74 insertions, 28 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index 2bc085b07a..a6ab145e65 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -789,7 +789,7 @@ trait Symbols requires SymbolTable { * Do the same for any accessed symbols or setters/getters */ def expandName(base: Symbol): unit = - if (this != NoSymbol && !hasFlag(EXPANDEDNAME)) { + if (this.isTerm && this != NoSymbol && !hasFlag(EXPANDEDNAME)) { setFlag(EXPANDEDNAME) if (hasFlag(ACCESSOR)) { accessed.expandName(base) diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index 128ac3275b..cc47db0773 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -64,34 +64,42 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter */ def transformInfo(sym: Symbol, tp: Type): Type = tp match { case MethodType(formals, restpe) => - if (sym.owner.isTrait && ((sym hasFlag SUPERACCESSOR) || sym.isModule)) // 5 + if (sym.owner.isTrait && ((sym hasFlag SUPERACCESSOR) || sym.isModule)) { // 5 + Console.println("make not private: "+sym+" "+sym.owner) sym.makeNotPrivate(sym.owner) + Console.println("made not private: "+sym) + } if (sym.owner.isTrait && (sym hasFlag PROTECTED)) sym setFlag notPROTECTED // 6 if (sym.isClassConstructor && isInner(sym.owner)) // 1 MethodType(sym.owner.outerClass.thisType :: formals, restpe) else tp - case ClassInfoType(parents, decls, clazz) if (isInner(clazz) && !(clazz hasFlag INTERFACE)) => - val decls1 = newScope(decls.toList) - val outerAcc = clazz.newMethod(clazz.pos, nme.OUTER) // 3 - outerAcc.expandName(clazz) - val restpe = if (clazz.isTrait) clazz.outerClass.tpe else clazz.outerClass.thisType - decls1 enter ( - clazz.newOuterAccessor(clazz.pos) - setInfo MethodType(List(), restpe)) + case ClassInfoType(parents, decls, clazz) => + var decls1 = decls + if (isInner(clazz) && !(clazz hasFlag INTERFACE)) { + decls1 = newScope(decls.toList) + val outerAcc = clazz.newMethod(clazz.pos, nme.OUTER) // 3 + outerAcc.expandName(clazz) + val restpe = if (clazz.isTrait) clazz.outerClass.tpe else clazz.outerClass.thisType + decls1 enter ( + clazz.newOuterAccessor(clazz.pos) + setInfo MethodType(List(), restpe)) + if (!clazz.isTrait) // 2 + //todo: avoid outer field if superclass has same outer value? + decls1 enter ( + clazz.newValue(clazz.pos, nme.getterToLocal(nme.OUTER)) + setFlag (PROTECTED | PARAMACCESSOR) + setInfo clazz.outerClass.thisType) + } if (!parents.isEmpty) { for (val mc <- clazz.mixinClasses) { val mixinOuterAcc: Symbol = atPhase(phase.next)(outerAccessor(mc)) - if (mixinOuterAcc != NoSymbol) + if (mixinOuterAcc != NoSymbol) { + if (decls1 eq decls) decls1 = newScope(decls.toList) decls1 enter (mixinOuterAcc.cloneSymbol(clazz) resetFlag DEFERRED) + } } } - if (!clazz.isTrait) // 2 - //todo: avoid outer field if superclass has same outer value? - decls1 enter ( - clazz.newValue(clazz.pos, nme.getterToLocal(nme.OUTER)) - setFlag (PROTECTED | PARAMACCESSOR) - setInfo clazz.outerClass.thisType) - ClassInfoType(parents, decls1, clazz) + if (decls1 eq decls) tp else ClassInfoType(parents, decls1, clazz) case PolyType(tparams, restp) => val restp1 = transformInfo(sym, restp) if (restp eq restp1) tp else PolyType(tparams, restp1) @@ -212,7 +220,7 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter */ def mixinOuterAccessorDef(mixinClass: Symbol): Tree = { val outerAcc = outerAccessor(mixinClass).overridingSymbol(currentClass) - if (outerAcc == NoSymbol) Console.println("cc "+currentClass+":"+currentClass.info.decls)//debug + if (outerAcc == NoSymbol) Console.println("cc "+currentClass+":"+currentClass.info.decls+" at "+phase)//debug assert(outerAcc != NoSymbol) val path = gen.mkAttributedQualifier(currentClass.thisType.baseType(mixinClass).prefix) val rhs = ExplicitOuterTransformer.this.transform(path) diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index 98ee4c001d..540ea6e687 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -472,7 +472,9 @@ abstract class Mixin extends InfoTransform { if (sym.isSetter) Assign(accessedRef, Ident(vparams.head)) else accessedRef}) } else if (sym.isModule && !(sym hasFlag LIFTED | BRIDGE)) { // add modules + Console.println("add module "+sym+sym.hasFlag(EXPANDEDNAME)) val vdef = gen.mkModuleVarDef(sym) + Console.println("add module "+sym+sym.hasFlag(EXPANDEDNAME)+":"+vdef.symbol.tpe) addDef(position(sym), vdef) addDef(position(sym), gen.mkModuleAccessDef(sym, vdef.symbol)) } else if (!sym.isMethod) { diff --git a/test/files/pos/bug704.scala b/test/files/pos/bug704.scala index aea8292f2d..a05e0a51e7 100644 --- a/test/files/pos/bug704.scala +++ b/test/files/pos/bug704.scala @@ -1,14 +1,23 @@ trait D { - private val x = 1 + private val x = "xxxx should appear twice" private object xxxx { Console.println(x) } + def get_xxxx: AnyRef = xxxx } -object Go extends D { - def main(args : Array[String]) : Unit = {}; -} -trait D2 { - val x = 1 - object yyyy { Console.println(x) } + +trait E extends D { + def f(): unit = { + val y = "yyyy should appear twice" + object yyyy { + val x1 = get_xxxx + Console.println(y) + } + yyyy + } } -object Go2 extends D2 { - def main(args : Array[String]) : Unit = {}; +class C extends E {} +object Go extends D { + def main(args : Array[String]) { + new C().f() + new C().f() + } } diff --git a/test/files/run/implicits.check b/test/files/run/implicits.check new file mode 100644 index 0000000000..010571589c --- /dev/null +++ b/test/files/run/implicits.check @@ -0,0 +1,2 @@ +OK +[2] diff --git a/test/files/run/implicits.scala b/test/files/run/implicits.scala new file mode 100755 index 0000000000..c45badc49f --- /dev/null +++ b/test/files/run/implicits.scala @@ -0,0 +1,25 @@ +object A { + object B { + implicit def int2string(x: int) = "["+x.toString+"]" + } +} + +class C(x: String) { + + class Inner { + } + + object Inner { + val s: String = x + implicit def Inner2String(x: Inner): String = s + } +} + +object Test extends Application { + import A.B._ + val c = new C("OK") + val i = new c.Inner + val s: String = i + Console.println(s) + Console.println(2: String) +} |