1.1 --- a/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Mon Sep 06 12:55:09 2010 -0700 1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Tue Sep 07 17:31:54 2010 +0100 1.3 @@ -283,12 +283,13 @@ 1.4 ListBuffer<JCTree> bridges) { 1.5 if (sym.kind == MTH && 1.6 sym.name != names.init && 1.7 - (sym.flags() & (PRIVATE | SYNTHETIC | STATIC)) == 0 && 1.8 + (sym.flags() & (PRIVATE | STATIC)) == 0 && 1.9 + (sym.flags() & (SYNTHETIC | OVERRIDE_BRIDGE)) != SYNTHETIC && 1.10 sym.isMemberOf(origin, types)) 1.11 { 1.12 MethodSymbol meth = (MethodSymbol)sym; 1.13 MethodSymbol bridge = meth.binaryImplementation(origin, types); 1.14 - MethodSymbol impl = meth.implementation(origin, types, true); 1.15 + MethodSymbol impl = meth.implementation(origin, types, true, overrideBridgeFilter); 1.16 if (bridge == null || 1.17 bridge == meth || 1.18 (impl != null && !bridge.owner.isSubClass(impl.owner, types))) { 1.19 @@ -304,7 +305,7 @@ 1.20 // reflection design error. 1.21 addBridge(pos, meth, impl, origin, false, bridges); 1.22 } 1.23 - } else if ((bridge.flags() & SYNTHETIC) != 0) { 1.24 + } else if ((bridge.flags() & (SYNTHETIC | OVERRIDE_BRIDGE)) == SYNTHETIC) { 1.25 MethodSymbol other = overridden.get(bridge); 1.26 if (other != null && other != meth) { 1.27 if (impl == null || !impl.overrides(other, origin, types, true)) { 1.28 @@ -327,6 +328,11 @@ 1.29 } 1.30 } 1.31 // where 1.32 + Filter<Symbol> overrideBridgeFilter = new Filter<Symbol>() { 1.33 + public boolean accepts(Symbol s) { 1.34 + return (s.flags() & (SYNTHETIC | OVERRIDE_BRIDGE)) != SYNTHETIC; 1.35 + } 1.36 + }; 1.37 /** 1.38 * @param method The symbol for which a bridge might have to be added 1.39 * @param impl The implementation of method 1.40 @@ -754,6 +760,90 @@ 1.41 return types.erasure(t); 1.42 } 1.43 1.44 + private boolean boundsRestricted(ClassSymbol c) { 1.45 + Type st = types.supertype(c.type); 1.46 + if (st.isParameterized()) { 1.47 + List<Type> actuals = st.allparams(); 1.48 + List<Type> formals = st.tsym.type.allparams(); 1.49 + while (!actuals.isEmpty() && !formals.isEmpty()) { 1.50 + Type actual = actuals.head; 1.51 + Type formal = formals.head; 1.52 + 1.53 + if (!types.isSameType(types.erasure(actual), 1.54 + types.erasure(formal))) 1.55 + return true; 1.56 + 1.57 + actuals = actuals.tail; 1.58 + formals = formals.tail; 1.59 + } 1.60 + } 1.61 + return false; 1.62 + } 1.63 + 1.64 + private List<JCTree> addOverrideBridgesIfNeeded(DiagnosticPosition pos, 1.65 + final ClassSymbol c) { 1.66 + ListBuffer<JCTree> buf = ListBuffer.lb(); 1.67 + if (c.isInterface() || !boundsRestricted(c)) 1.68 + return buf.toList(); 1.69 + Type t = types.supertype(c.type); 1.70 + Scope s = t.tsym.members(); 1.71 + if (s.elems != null) { 1.72 + for (Symbol sym : s.getElements(new NeedsOverridBridgeFilter(c))) { 1.73 + 1.74 + MethodSymbol m = (MethodSymbol)sym; 1.75 + MethodSymbol member = (MethodSymbol)m.asMemberOf(c.type, types); 1.76 + MethodSymbol impl = m.implementation(c, types, false); 1.77 + 1.78 + if ((impl == null || impl.owner != c) && 1.79 + !types.isSameType(member.erasure(types), m.erasure(types))) { 1.80 + addOverrideBridges(pos, m, member, c, buf); 1.81 + } 1.82 + } 1.83 + } 1.84 + return buf.toList(); 1.85 + } 1.86 + // where 1.87 + class NeedsOverridBridgeFilter implements Filter<Symbol> { 1.88 + 1.89 + ClassSymbol c; 1.90 + 1.91 + NeedsOverridBridgeFilter(ClassSymbol c) { 1.92 + this.c = c; 1.93 + } 1.94 + public boolean accepts(Symbol s) { 1.95 + return s.kind == MTH && 1.96 + !s.isConstructor() && 1.97 + s.isInheritedIn(c, types) && 1.98 + (s.flags() & FINAL) == 0 && 1.99 + (s.flags() & (SYNTHETIC | OVERRIDE_BRIDGE)) != SYNTHETIC; 1.100 + } 1.101 + } 1.102 + 1.103 + private void addOverrideBridges(DiagnosticPosition pos, 1.104 + MethodSymbol impl, 1.105 + MethodSymbol member, 1.106 + ClassSymbol c, 1.107 + ListBuffer<JCTree> bridges) { 1.108 + Type implErasure = impl.erasure(types); 1.109 + long flags = (impl.flags() & AccessFlags) | SYNTHETIC | BRIDGE | OVERRIDE_BRIDGE; 1.110 + member = new MethodSymbol(flags, member.name, member.type, c); 1.111 + JCMethodDecl md = make.MethodDef(member, null); 1.112 + JCExpression receiver = make.Super(types.supertype(c.type).tsym.erasure(types), c); 1.113 + Type calltype = erasure(impl.type.getReturnType()); 1.114 + JCExpression call = 1.115 + make.Apply(null, 1.116 + make.Select(receiver, impl).setType(calltype), 1.117 + translateArgs(make.Idents(md.params), 1.118 + implErasure.getParameterTypes(), null)) 1.119 + .setType(calltype); 1.120 + JCStatement stat = (member.getReturnType().tag == VOID) 1.121 + ? make.Exec(call) 1.122 + : make.Return(coerce(call, member.erasure(types).getReturnType())); 1.123 + md.body = make.Block(0, List.of(stat)); 1.124 + c.members().enter(member); 1.125 + bridges.append(md); 1.126 + } 1.127 + 1.128 /************************************************************************** 1.129 * main method 1.130 *************************************************************************/ 1.131 @@ -786,6 +876,7 @@ 1.132 make.at(tree.pos); 1.133 if (addBridges) { 1.134 ListBuffer<JCTree> bridges = new ListBuffer<JCTree>(); 1.135 + bridges.appendList(addOverrideBridgesIfNeeded(tree, c)); 1.136 if ((tree.sym.flags() & INTERFACE) == 0) 1.137 addBridges(tree.pos(), tree.sym, bridges); 1.138 tree.defs = bridges.toList().prependList(tree.defs);