diff options
-rw-r--r-- | sources/scalac/backend/jvm/GenJVM.java | 27 | ||||
-rw-r--r-- | sources/scalac/symtab/Definitions.java | 2 | ||||
-rw-r--r-- | sources/scalac/transformer/AddInterfacesPhase.java | 62 |
3 files changed, 46 insertions, 45 deletions
diff --git a/sources/scalac/backend/jvm/GenJVM.java b/sources/scalac/backend/jvm/GenJVM.java index fe04e952a4..9c18e219fc 100644 --- a/sources/scalac/backend/jvm/GenJVM.java +++ b/sources/scalac/backend/jvm/GenJVM.java @@ -1205,29 +1205,22 @@ class GenJVM { String javaName = javaName(cSym); scalac.symtab.Type[] baseTps = cSym.info().parents(); + assert baseTps.length > 0 : Debug.show(cSym); + int offset; String superClassName; - String[] interfaceNames; if (cSym.isInterface()) { + offset = baseTps[0].isSameAs(defs.ANY_TYPE) ? 1 : 0; superClassName = JAVA_LANG_OBJECT; - if (baseTps.length == 1 && baseTps[0] == defs.ANY_TYPE) - interfaceNames = EMPTY_STRING_ARRAY; - else { - interfaceNames = new String[baseTps.length]; - for (int i = 0; i < baseTps.length; ++i) { - Symbol baseSym = baseTps[i].symbol(); - assert baseSym.isInterface() : cSym + " implements " + baseSym; - interfaceNames[i] = javaName(baseSym); - } - } } else { + offset = 1; superClassName = javaName(baseTps[0].symbol()); - interfaceNames = new String[Math.max(0, baseTps.length - 1)]; - for (int i = 1; i < baseTps.length; ++i) { - Symbol baseSym = baseTps[i].symbol(); - assert baseSym.isInterface() : cSym + " implements " + baseSym; - interfaceNames[i-1] = javaName(baseSym); - } + } + String[] interfaceNames = new String[baseTps.length - offset]; + for (int i = offset; i < baseTps.length; ++i) { + Symbol baseSym = baseTps[i].symbol(); + assert baseSym.isInterface() : cSym + " implements " + baseSym; + interfaceNames[i - offset] = javaName(baseSym); } ClassGen cGen = new ClassGen(javaName, diff --git a/sources/scalac/symtab/Definitions.java b/sources/scalac/symtab/Definitions.java index 10c0198e00..04d7a65c46 100644 --- a/sources/scalac/symtab/Definitions.java +++ b/sources/scalac/symtab/Definitions.java @@ -221,7 +221,7 @@ public class Definitions { Kinds.ALIAS, Position.NOPOS, Names.AnyRef.toTypeName(), SCALA_CLASS, Modifiers.JAVA) .setInfo(JAVA_OBJECT_TYPE); - ANYREF_TYPE = ANYREF_CLASS.typeConstructor(); + ANYREF_TYPE = ANYREF_CLASS.typeConstructor().unalias(); SCALA.members().enter(ANYREF_CLASS); // the scala.OBJECT class diff --git a/sources/scalac/transformer/AddInterfacesPhase.java b/sources/scalac/transformer/AddInterfacesPhase.java index 6bf1a8fe40..5d85bf317e 100644 --- a/sources/scalac/transformer/AddInterfacesPhase.java +++ b/sources/scalac/transformer/AddInterfacesPhase.java @@ -46,7 +46,18 @@ public class AddInterfacesPhase extends PhaseDescriptor { // an interface. All its value arguments have to be // removed. return removeValueParams(tp); - } else if (sym.isClass() && !sym.isPackage()) { + } else if (sym.isClass() && !sym.isJava()) { + Definitions definitions = Global.instance.definitions; + Type[] oldParents = tp.parents(); + assert oldParents.length > 0 : Debug.show(sym); + for (int i = 1; i < oldParents.length; ++i) { + Symbol oldSym = oldParents[i].symbol(); + assert !oldSym.isJava() || oldSym.isInterface() : + Debug.show(sym) + " <: " + Debug.show(oldSym); + } + + Type[] newParents; + Scope newMembers; if (needInterface(sym)) { // Before this phase, the symbol is a class, but after // it will be an interface. Its type has to be changed @@ -61,7 +72,7 @@ public class AddInterfacesPhase extends PhaseDescriptor { Scope.SymbolIterator oldMembersIt = new Scope.UnloadIterator(tp.members().iterator()); - Scope newMembers = new Scope(); + newMembers = new Scope(); while (oldMembersIt.hasNext()) { Symbol member = oldMembersIt.next(); @@ -77,44 +88,37 @@ public class AddInterfacesPhase extends PhaseDescriptor { newMembers.enterOrOverload(member); } - LinkedList/*<Type>*/ newParentsLst = new LinkedList(); - Type[] oldParents = tp.parents(); - for (int i = 0; i < oldParents.length; ++i) { - if (! oldParents[i].symbol().isJava()) - newParentsLst.addLast(oldParents[i]); - } - Type[] newParents; - if (newParentsLst.size() == oldParents.length) + Symbol oldSym = oldParents[0].symbol(); + if (oldSym.isJava() && !oldSym.isInterface() && + oldSym != definitions.ANY_CLASS && + oldSym != definitions.ANYREF_CLASS) + { + newParents = new Type[oldParents.length]; + newParents[0] = definitions.ANYREF_TYPE; + for (int i = 1; i < oldParents.length; ++i) + newParents[i] = oldParents[i]; + } else { newParents = oldParents; - else - newParents = (Type[]) - newParentsLst.toArray(new Type[newParentsLst.size()]); - return Type.compoundType(newParents, newMembers, sym); + } } else { // The symbol is the one of a class which doesn't need // an interface. We need to fix its parents to use // class symbols instead of interface symbols. - LinkedList/*<Type>*/ newParentsLst = new LinkedList(); - Type[] oldParents = tp.parents(); + newMembers = tp.members(); + newParents = new Type[oldParents.length]; for (int i = 0; i < oldParents.length; ++i) { switch (oldParents[i]) { case TypeRef(Type pre, Symbol oldSym, Type[] args): - if (needInterface(oldSym)) { - newParentsLst.addLast( - Type.typeRef( - pre, getClassSymbol(oldSym), args)); - } - else - newParentsLst.addLast(oldParents[i]); + newParents[i] = !needInterface(oldSym) ? oldParents[i]: + Type.typeRef(pre, getClassSymbol(oldSym), args); break; default: throw Debug.abort("illegal case", oldParents[i]); } } - Type[] newParents = (Type[]) - newParentsLst.toArray(new Type[newParentsLst.size()]); - return Type.compoundType(newParents, tp.members(), sym); } + + return Type.compoundType(newParents, newMembers, sym); } else return tp; } @@ -179,7 +183,11 @@ public class AddInterfacesPhase extends PhaseDescriptor { : Debug.toString(classSym) + " is not a class (kind " + classSym.kind + ")"; return !(classSym.isJava() || classSym.isModuleClass() - || hasInterfaceSymbol(classSym)); + || hasInterfaceSymbol(classSym) + || classSym == Global.instance.definitions.ANY_CLASS + || classSym == Global.instance.definitions.ANYREF_CLASS + || classSym == Global.instance.definitions.ALL_CLASS + || classSym == Global.instance.definitions.ALLREF_CLASS); } protected final static String CLASS_SUFFIX = "$class"; |