diff options
author | paltherr <paltherr@epfl.ch> | 2003-09-12 20:53:28 +0000 |
---|---|---|
committer | paltherr <paltherr@epfl.ch> | 2003-09-12 20:53:28 +0000 |
commit | 6e784092689e55e768aee020ba6269c38f2b0188 (patch) | |
tree | 5a0208ff1b5f6f54005ccbeacde4e7a010cf21f5 /sources | |
parent | 8c482d22ebf6c86a436b767422890473f8959aae (diff) | |
download | scala-6e784092689e55e768aee020ba6269c38f2b0188.tar.gz scala-6e784092689e55e768aee020ba6269c38f2b0188.tar.bz2 scala-6e784092689e55e768aee020ba6269c38f2b0188.zip |
- Added creation of bridge methods for abstract...
- Added creation of bridge methods for abstract methods from
superinterfaces.
Diffstat (limited to 'sources')
-rw-r--r-- | sources/scalac/transformer/Erasure.java | 77 |
1 files changed, 63 insertions, 14 deletions
diff --git a/sources/scalac/transformer/Erasure.java b/sources/scalac/transformer/Erasure.java index 7f62094608..a55d08d400 100644 --- a/sources/scalac/transformer/Erasure.java +++ b/sources/scalac/transformer/Erasure.java @@ -234,7 +234,7 @@ public class Erasure extends Transformer implements Modifiers { /** Add bridge which Java-overrides `sym1' and which forwards to `sym' */ - public void addBridge(Symbol sym, Symbol sym1) { + public void addBridge(Symbol owner, Symbol sym, Symbol sym1) { Type bridgeType = sym1.type().erasure(); // create bridge symbol and add to bridgeSyms(sym) @@ -250,10 +250,11 @@ public class Erasure extends Transformer implements Modifiers { bridgeSym.flags &= ~JAVA; bridgesOfSym = bridgesOfSym.incl(bridgeSym); bridgeSyms.put(sym, bridgesOfSym); + bridgeSym.setOwner(owner); // check that there is no overloaded symbol with same erasure as bridge // todo: why only check for overloaded? - Symbol overSym = sym.owner().members().lookup(sym.name); + Symbol overSym = owner.members().lookup(sym.name); switch (overSym.type()) { case OverloadedType(Symbol[] alts, Type[] alttypes): for (int i = 0; i < alts.length; i++) { @@ -295,26 +296,51 @@ public class Erasure extends Transformer implements Modifiers { } public void addBridges(Symbol sym) { - Symbol c = sym.owner(); + Symbol c = sym.owner(); if (c.isClass() && !c.isInterface()) { + //global.nextPhase(); System.out.println("!!! " + Debug.show(sym) + " : " + sym.type().erasure() + " @ " + Debug.show(c)); global.prevPhase(); Type[] basetypes = c.parents(); + for (int i = 0; i < basetypes.length; i++) { + addBridges(basetypes[i], sym); + } + } + } - //global.nextPhase(); System.out.println("!!! " + Debug.show(sym) + " : " + sym.type().erasure()); global.prevPhase(); + public void addBridges(Type basetype, Symbol sym) { + Symbol sym1 = sym.overriddenSymbol(basetype); + //global.nextPhase(); System.out.println("!!! " + Debug.show(sym) + " @ " + basetype + " -> " + Debug.show(sym1) + (sym1.kind == Kinds.NONE ? "" : " : " + sym1.type().erasure() + " => " + (isSameAs(sym1.type().erasure(), sym.type().erasure()) ? "ok" : "ADD BRIDGE"))); global.prevPhase(); - for (int i = 0; i < basetypes.length; i++) { - Symbol sym1 = sym.overriddenSymbol(basetypes[i]); + if (sym1.kind != Kinds.NONE && + !isSameAs(sym1.type().erasure(), sym.type().erasure())) { + //System.out.println("!!! " + Debug.show(sym) + " adding bridge for " + Debug.show(sym1)); + addBridge(sym.owner(), sym, sym1); + } + } - //global.nextPhase(); System.out.println("!!! " + Debug.show(sym) + " @ " + basetypes[i] + " -> " + Debug.show(sym1) + (sym1.kind == Kinds.NONE ? "" : " : " + sym1.type().erasure() + " => " + (isSameAs(sym1.type().erasure(), sym.type().erasure()) ? "ok" : "ADD BRIDGE"))); global.prevPhase(); + public void addInterfaceBridges(Symbol c, Symbol sym) { + assert c.isClass() && !c.isInterface(): Debug.show(c); + //global.nextPhase(); System.out.println("!!! " + Debug.show(sym) + " : " + sym.type().erasure() + " @ " + Debug.show(c)); global.prevPhase(); + Symbol member = sym; - if (sym1.kind != Kinds.NONE && - !isSameAs(sym1.type().erasure(), sym.type().erasure())) { + // !!! create a clone to make overriddenSymbol return the right symbol + Symbol clone = sym.cloneSymbol(); + clone.setOwner(c); + clone.setType(c.thisType().memberType(sym)); - //System.out.println("!!! " + Debug.show(sym) + " adding bridge for " + Debug.show(sym1)); + sym = clone; + //global.nextPhase(); System.out.println("!!! " + Debug.show(sym) + " : " + sym.type().erasure() + " @ " + Debug.show(c)); global.prevPhase(); + + Type basetype = c.thisType(); + Symbol sym1 = sym.overriddenSymbol(basetype); + sym = member; + //global.nextPhase(); System.out.println("!!! " + Debug.show(sym) + " @ " + basetype + " -> " + Debug.show(sym1) + (sym1.kind == Kinds.NONE ? "" : " : " + sym1.type().erasure() + " => " + (isSameAs(sym1.type().erasure(), sym.type().erasure()) ? "ok" : "ADD BRIDGE"))); global.prevPhase(); + + if (sym1.kind != Kinds.NONE && + !isSameAs(sym1.type().erasure(), sym.type().erasure())) { + //System.out.println("!!! " + Debug.show(sym) + " adding bridge for " + Debug.show(sym1)); + addBridge(c, sym1, member); + } - addBridge(sym, sym1); - } - } - } } ////////////////////////////////////////////////////////////////////////////////// @@ -566,6 +592,7 @@ public class Erasure extends Transformer implements Modifiers { bridgeSyms = new HashMap(); Tree[] bases1 = transform(templ.parents); TreeList body1 = new TreeList(transform(templ.body)); + if (!clazz.isInterface()) addInterfaceBridges(clazz); body1.append(bridges); if (bridges.length() > 0) { Type info = clazz.nextInfo(); @@ -589,6 +616,28 @@ public class Erasure extends Transformer implements Modifiers { .setType(templ.type.erasure()); } + // !!! This is just rapid fix. Needs to be reviewed. + private void addInterfaceBridges(Symbol owner) { + Type[] parents = owner.info().parents(); + for (int i = 1; i < parents.length; i++) + addInterfaceBridgesRec(owner, parents[i].symbol()); + } + private void addInterfaceBridgesRec(Symbol owner, Symbol interfase) { + addInterfaceBridgesAux(owner, interfase.nextInfo().members()); + Type[] parents = interfase.parents(); + for (int i = 0; i < parents.length; i++) { + Symbol clasz = parents[i].symbol(); + if (clasz.isInterface()) addInterfaceBridgesRec(owner, clasz); + } + } + private void addInterfaceBridgesAux(Symbol owner, Scope symbols) { + for (Scope.SymbolIterator i = symbols.iterator(true); i.hasNext();) { + Symbol member = i.next(); + if (!member.isTerm() || !member.isDeferred()) continue; + addInterfaceBridges(owner, member); + } + } + /** Transform without keeping the previous transform's contract. */ Tree transformLhs(Tree tree) { |