/** Return the first method in t2 that conflicts with a method from t1. */ private Symbol firstDirectIncompatibility(Type t1, Type t2, Type site) { for (Scope.Entry e1 = t1.tsym.members().elems; e1 != null; e1 = e1.sibling) { Symbol s1 = e1.sym; Type st1 = null; if (s1.kind != MTH || !s1.isInheritedIn(site.tsym, types)) continue; Symbol impl = ((MethodSymbol)s1).implementation(site.tsym, types, false); if (impl != null && (impl.flags() & ABSTRACT) == 0) continue; for (Scope.Entry e2 = t2.tsym.members().lookup(s1.name); e2.scope != null; e2 = e2.next()) { Symbol s2 = e2.sym; if (s1 == s2) continue; if (s2.kind != MTH || !s2.isInheritedIn(site.tsym, types)) continue; if (st1 == null) st1 = types.memberType(t1, s1); Type st2 = types.memberType(t2, s2); if (types.overrideEquivalent(st1, st2)) { List<Type> tvars1 = st1.getTypeArguments(); List<Type> tvars2 = st2.getTypeArguments(); Type rt1 = st1.getReturnType(); Type rt2 = types.subst(st2.getReturnType(), tvars2, tvars1); boolean compat = types.isSameType(rt1, rt2) || rt1.tag >= CLASS && rt2.tag >= CLASS && (types.covariantReturnType(rt1, rt2, Warner.noWarnings) || types.covariantReturnType(rt2, rt1, Warner.noWarnings)); if (!compat) return s2; } } } return null; }
/** Check that all methods which implement some * method in `ic' conform to the method they implement. */ void checkImplementations(JCClassDecl tree, ClassSymbol ic) { ClassSymbol origin = tree.sym; for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) { ClassSymbol lc = (ClassSymbol)l.head.tsym; if ((allowGenerics || origin != lc) && (lc.flags() & ABSTRACT) != 0) { for (Scope.Entry e=lc.members().elems; e != null; e=e.sibling) { if (e.sym.kind == MTH && (e.sym.flags() & (STATIC|ABSTRACT)) == ABSTRACT) { MethodSymbol absmeth = (MethodSymbol)e.sym; MethodSymbol implmeth = absmeth.implementation(origin, types, false); if (implmeth != null && implmeth != absmeth && (implmeth.owner.flags() & INTERFACE) == (origin.flags() & INTERFACE)) { // don't check if implmeth is in a class, yet // origin is an interface. This case arises only // if implmeth is declared in Object. The reason is // that interfaces really don't inherit from // Object it's just that the compiler represents // things that way. checkOverride(tree, implmeth, absmeth, origin); } } } } } }
/** Return the first method in t2 that conflicts with a method from t1. */ private Symbol firstDirectIncompatibility(Type t1, Type t2, Type site) { for (Scope.Entry e1 = t1.tsym.members().elems; e1 != null; e1 = e1.sibling) { Symbol s1 = e1.sym; Type st1 = null; if (s1.kind != MTH || !s1.isInheritedIn(site.tsym, types)) continue; Symbol impl = ((MethodSymbol)s1).implementation(site.tsym, types, false); if (impl != null && (impl.flags() & ABSTRACT) == 0) continue; for (Scope.Entry e2 = t2.tsym.members().lookup(s1.name); e2.scope != null; e2 = e2.next()) { Symbol s2 = e2.sym; if (s1 == s2) continue; if (s2.kind != MTH || !s2.isInheritedIn(site.tsym, types)) continue; if (st1 == null) st1 = types.memberType(t1, s1); Type st2 = types.memberType(t2, s2); if (types.overrideEquivalent(st1, st2)) { List<Type> tvars1 = st1.getTypeArguments(); List<Type> tvars2 = st2.getTypeArguments(); Type rt1 = st1.getReturnType(); Type rt2 = types.subst(st2.getReturnType(), tvars2, tvars1); boolean compat = types.isSameType(rt1, rt2) || rt1.tag >= CLASS && rt2.tag >= CLASS && (types.covariantReturnType(rt1, rt2, Warner.noWarnings) || types.covariantReturnType(rt2, rt1, Warner.noWarnings)); if (!compat) return s2; } } } return null; }
/** Check that all methods which implement some * method in `ic' conform to the method they implement. */ void checkImplementations(JCTree tree, ClassSymbol origin, ClassSymbol ic) { for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) { ClassSymbol lc = (ClassSymbol)l.head.tsym; if ((allowGenerics || origin != lc) && (lc.flags() & ABSTRACT) != 0) { for (Scope.Entry e=lc.members().elems; e != null; e=e.sibling) { if (e.sym.kind == MTH && (e.sym.flags() & (STATIC|ABSTRACT)) == ABSTRACT) { MethodSymbol absmeth = (MethodSymbol)e.sym; MethodSymbol implmeth = absmeth.implementation(origin, types, false); if (implmeth != null && implmeth != absmeth && (implmeth.owner.flags() & INTERFACE) == (origin.flags() & INTERFACE)) { // don't check if implmeth is in a class, yet // origin is an interface. This case arises only // if implmeth is declared in Object. The reason is // that interfaces really don't inherit from // Object it's just that the compiler represents // things that way. checkOverride(tree, implmeth, absmeth, origin); } } } } } }
/** Check that all methods which implement some * method in `ic' conform to the method they implement. */ void checkImplementations(JCClassDecl tree, ClassSymbol ic) { ClassSymbol origin = tree.sym; for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) { ClassSymbol lc = (ClassSymbol)l.head.tsym; if ((allowGenerics || origin != lc) && (lc.flags() & ABSTRACT) != 0) { for (Scope.Entry e=lc.members().elems; e != null; e=e.sibling) { if (e.sym.kind == MTH && (e.sym.flags() & (STATIC|ABSTRACT)) == ABSTRACT) { MethodSymbol absmeth = (MethodSymbol)e.sym; MethodSymbol implmeth = absmeth.implementation(origin, types, false); if (implmeth != null && implmeth != absmeth && (implmeth.owner.flags() & INTERFACE) == (origin.flags() & INTERFACE)) { // don't check if implmeth is in a class, yet // origin is an interface. This case arises only // if implmeth is declared in Object. The reason is // that interfaces really don't inherit from // Object it's just that the compiler represents // things that way. checkOverride(tree, implmeth, absmeth, origin); } } } } } }
/** Check that all methods which implement some * method in `ic' conform to the method they implement. */ void checkImplementations(JCTree tree, ClassSymbol origin, ClassSymbol ic) { for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) { ClassSymbol lc = (ClassSymbol)l.head.tsym; if ((allowGenerics || origin != lc) && (lc.flags() & ABSTRACT) != 0) { for (Scope.Entry e=lc.members().elems; e != null; e=e.sibling) { if (e.sym.kind == MTH && (e.sym.flags() & (STATIC|ABSTRACT)) == ABSTRACT) { MethodSymbol absmeth = (MethodSymbol)e.sym; MethodSymbol implmeth = absmeth.implementation(origin, types, false); if (implmeth != null && implmeth != absmeth && (implmeth.owner.flags() & INTERFACE) == (origin.flags() & INTERFACE)) { // don't check if implmeth is in a class, yet // origin is an interface. This case arises only // if implmeth is declared in Object. The reason is // that interfaces really don't inherit from // Object it's just that the compiler represents // things that way. checkOverride(tree, implmeth, absmeth, origin); } } } } } }
/** The implementation of this (abstract) symbol in class origin; * null if none exists. Synthetic methods are not considered * as possible implementations. */ public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) { for (Type t = origin.type; t.tag == CLASS; t = types.supertype(t)) { TypeSymbol c = t.tsym; for (Scope.Entry e = c.members().lookup(name); e.scope != null; e = e.next()) { if (e.sym.kind == MTH) { MethodSymbol m = (MethodSymbol) e.sym; if (m.overrides(this, origin, types, checkResult) && (m.flags() & SYNTHETIC) == 0) return m; } } } // if origin is derived from a raw type, we might have missed // an implementation because we do not know enough about instantiations. // in this case continue with the supertype as origin. if (types.isDerivedRaw(origin.type)) return implementation(types.supertype(origin.type).tsym, types, checkResult); else return null; }
/** The implementation of this (abstract) symbol in class origin; * null if none exists. Synthetic methods are not considered * as possible implementations. */ public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) { for (Type t = origin.type; t.tag == CLASS; t = types.supertype(t)) { TypeSymbol c = t.tsym; for (Scope.Entry e = c.members().lookup(name); e.scope != null; e = e.next()) { if (e.sym.kind == MTH) { MethodSymbol m = (MethodSymbol) e.sym; if (m.overrides(this, origin, types, checkResult) && (m.flags() & SYNTHETIC) == 0) return m; } } } // if origin is derived from a raw type, we might have missed // an implementation because we do not know enough about instantiations. // in this case continue with the supertype as origin. if (types.isDerivedRaw(origin.type)) return implementation(types.supertype(origin.type).tsym, types, checkResult); else return null; }
private List<JCTree> addOverrideBridgesIfNeeded(DiagnosticPosition pos, final ClassSymbol c) { ListBuffer<JCTree> buf = new ListBuffer<>(); if (c.isInterface() || !boundsRestricted(c)) return buf.toList(); Type t = types.supertype(c.type); Scope s = t.tsym.members(); if (s.elems != null) { for (Symbol sym : s.getElements(new NeedsOverridBridgeFilter(c))) { MethodSymbol m = (MethodSymbol)sym; MethodSymbol member = (MethodSymbol)m.asMemberOf(c.type, types); MethodSymbol impl = m.implementation(c, types, false); if ((impl == null || impl.owner != c) && !types.isSameType(member.erasure(types), m.erasure(types))) { addOverrideBridges(pos, m, member, c, buf); } } } return buf.toList(); } // where
private boolean isDeprecatedOverrideIgnorable(MethodSymbol m, ClassSymbol origin) { // If the method, m, is defined in an interface, then ignore the issue if the method // is only inherited via a supertype and also implemented in the supertype, // because in that case, we will rediscover the issue when examining the method // in the supertype. // If the method, m, is not defined in an interface, then the only time we need to // address the issue is when the method is the supertype implemementation: any other // case, we will have dealt with when examining the supertype classes ClassSymbol mc = m.enclClass(); Type st = types.supertype(origin.type); if (!st.hasTag(CLASS)) return true; MethodSymbol stimpl = m.implementation((ClassSymbol)st.tsym, types, false); if (mc != null && ((mc.flags() & INTERFACE) != 0)) { List<Type> intfs = types.interfaces(origin.type); return (intfs.contains(mc.type) ? false : (stimpl != null)); } else return (stimpl != m); }
private boolean isDeprecatedOverrideIgnorable(MethodSymbol m, ClassSymbol origin) { // If the method, m, is defined in an interface, then ignore the issue if the method // is only inherited via a supertype and also implemented in the supertype, // because in that case, we will rediscover the issue when examining the method // in the supertype. // If the method, m, is not defined in an interface, then the only time we need to // address the issue is when the method is the supertype implemementation: any other // case, we will have dealt with when examining the supertype classes ClassSymbol mc = m.enclClass(); Type st = types.supertype(origin.type); if (!st.hasTag(CLASS)) return true; MethodSymbol stimpl = m.implementation((ClassSymbol)st.tsym, types, false); if (mc != null && ((mc.flags() & INTERFACE) != 0)) { List<Type> intfs = types.interfaces(origin.type); return (intfs.contains(mc.type) ? false : (stimpl != null)); } else return (stimpl != m); }
private boolean isDeprecatedOverrideIgnorable(MethodSymbol m, ClassSymbol origin) { // If the method, m, is defined in an interface, then ignore the issue if the method // is only inherited via a supertype and also implemented in the supertype, // because in that case, we will rediscover the issue when examining the method // in the supertype. // If the method, m, is not defined in an interface, then the only time we need to // address the issue is when the method is the supertype implemementation: any other // case, we will have dealt with when examining the supertype classes ClassSymbol mc = m.enclClass(); Type st = types.supertype(origin.type); if (st.tag != CLASS) return true; MethodSymbol stimpl = m.implementation((ClassSymbol)st.tsym, types, false); if (mc != null && ((mc.flags() & INTERFACE) != 0)) { List<Type> intfs = types.interfaces(origin.type); return (intfs.contains(mc.type) ? false : (stimpl != null)); } else return (stimpl != m); }
private boolean isDeprecatedOverrideIgnorable(MethodSymbol m, ClassSymbol origin) { // If the method, m, is defined in an interface, then ignore the issue if the method // is only inherited via a supertype and also implemented in the supertype, // because in that case, we will rediscover the issue when examining the method // in the supertype. // If the method, m, is not defined in an interface, then the only time we need to // address the issue is when the method is the supertype implemementation: any other // case, we will have dealt with when examining the supertype classes ClassSymbol mc = m.enclClass(); Type st = types.supertype(origin.type); if (st.tag != CLASS) return true; MethodSymbol stimpl = m.implementation((ClassSymbol)st.tsym, types, false); if (mc != null && ((mc.flags() & INTERFACE) != 0)) { List<Type> intfs = types.interfaces(origin.type); return (intfs.contains(mc.type) ? false : (stimpl != null)); } else return (stimpl != m); }
private List<JCTree> addOverrideBridgesIfNeeded(DiagnosticPosition pos, final ClassSymbol c) { ListBuffer<JCTree> buf = new ListBuffer<>(); if (c.isInterface() || !boundsRestricted(c)) return buf.toList(); Type t = types.supertype(c.type); Scope s = t.tsym.members(); if (s.elems != null) { for (Symbol sym : s.getElements(new NeedsOverridBridgeFilter(c))) { MethodSymbol m = (MethodSymbol)sym; MethodSymbol member = (MethodSymbol)m.asMemberOf(c.type, types); MethodSymbol impl = m.implementation(c, types, false); if ((impl == null || impl.owner != c) && !types.isSameType(member.erasure(types), m.erasure(types))) { addOverrideBridges(pos, m, member, c, buf); } } } return buf.toList(); } // where
private boolean notOverriddenIn(Type site, Symbol sym) { if (sym.kind != MTH || sym.isConstructor() || sym.isStatic()) return true; else { Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true); return (s2 == null || s2 == sym || sym.owner == s2.owner || !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym))); } } //where
public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter) { MethodSymbol res = types.implementation(this, origin, checkResult, implFilter); if (res != null) return res; // if origin is derived from a raw type, we might have missed // an implementation because we do not know enough about instantiations. // in this case continue with the supertype as origin. if (types.isDerivedRaw(origin.type) && !origin.isInterface()) return implementation(types.supertype(origin.type).tsym, types, checkResult); else return null; }
/** The implementation of this (abstract) symbol in class origin; * null if none exists. Synthetic methods are not considered * as possible implementations. */ public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) { return implementation(origin, types, checkResult, implementation_filter); } // where
private boolean notOverriddenIn(Type site, Symbol sym) { if (sym.kind != MTH || sym.isConstructor() || sym.isStatic()) return true; else { Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true); return (s2 == null || s2 == sym || sym.owner == s2.owner || !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym))); } } //where
public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter) { MethodSymbol res = types.implementation(this, origin, checkResult, implFilter); if (res != null) return res; // if origin is derived from a raw type, we might have missed // an implementation because we do not know enough about instantiations. // in this case continue with the supertype as origin. if (types.isDerivedRaw(origin.type) && !origin.isInterface()) return implementation(types.supertype(origin.type).tsym, types, checkResult); else return null; }
/** The implementation of this (abstract) symbol in class origin; * null if none exists. Synthetic methods are not considered * as possible implementations. */ public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) { return implementation(origin, types, checkResult, implementation_filter); } // where