src/share/classes/com/sun/tools/javac/comp/TransTypes.java

changeset 673
7ae4016c5938
parent 609
13354e1abba7
child 730
20659c8c917d
     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);

mercurial