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

changeset 858
96d4226bdd60
parent 854
03cf47d4de15
child 877
351027202f60
equal deleted inserted replaced
857:3aa269645199 858:96d4226bdd60
1677 log.error(pos, "types.incompatible.diff.ret", 1677 log.error(pos, "types.incompatible.diff.ret",
1678 t1, t2, s2.name + 1678 t1, t2, s2.name +
1679 "(" + types.memberType(t2, s2).getParameterTypes() + ")"); 1679 "(" + types.memberType(t2, s2).getParameterTypes() + ")");
1680 return s2; 1680 return s2;
1681 } 1681 }
1682 } else if (!checkNameClash((ClassSymbol)site.tsym, s1, s2)) { 1682 } else if (checkNameClash((ClassSymbol)site.tsym, s1, s2)) {
1683 log.error(pos, 1683 log.error(pos,
1684 "name.clash.same.erasure.no.override", 1684 "name.clash.same.erasure.no.override",
1685 s1, s1.location(), 1685 s1, s1.location(),
1686 s2, s2.location()); 1686 s2, s2.location());
1687 return s2; 1687 return s2;
1759 e = e.next(); 1759 e = e.next();
1760 } 1760 }
1761 } 1761 }
1762 1762
1763 private boolean checkNameClash(ClassSymbol origin, Symbol s1, Symbol s2) { 1763 private boolean checkNameClash(ClassSymbol origin, Symbol s1, Symbol s2) {
1764 if (s1.kind == MTH && 1764 ClashFilter cf = new ClashFilter(origin.type);
1765 s1.isInheritedIn(origin, types) && 1765 return (cf.accepts(s1) &&
1766 (s1.flags() & SYNTHETIC) == 0 && 1766 cf.accepts(s2) &&
1767 !s2.isConstructor()) { 1767 types.hasSameArgs(s1.erasure(types), s2.erasure(types)));
1768 Type er1 = s2.erasure(types);
1769 Type er2 = s1.erasure(types);
1770 if (types.isSameTypes(er1.getParameterTypes(),
1771 er2.getParameterTypes())) {
1772 return false;
1773 }
1774 }
1775 return true;
1776 } 1768 }
1777 1769
1778 1770
1779 /** Check that all abstract members of given class have definitions. 1771 /** Check that all abstract members of given class have definitions.
1780 * @param pos Position to be used for error reporting. 1772 * @param pos Position to be used for error reporting.
2109 * 2101 *
2110 * @param pos Position to be used for error reporting. 2102 * @param pos Position to be used for error reporting.
2111 * @param site The class whose methods are checked. 2103 * @param site The class whose methods are checked.
2112 * @param sym The method symbol to be checked. 2104 * @param sym The method symbol to be checked.
2113 */ 2105 */
2114 void checkClashes(DiagnosticPosition pos, Type site, Symbol sym) { 2106 void checkOverrideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
2115 List<Type> supertypes = types.closure(site); 2107 ClashFilter cf = new ClashFilter(site);
2116 for (List<Type> l = supertypes; l.nonEmpty(); l = l.tail) { 2108 //for each method m1 that is a member of 'site'...
2117 for (List<Type> m = supertypes; m.nonEmpty(); m = m.tail) { 2109 for (Scope.Entry e1 = types.membersClosure(site).lookup(sym.name, cf) ;
2118 checkClashes(pos, l.head, m.head, site, sym); 2110 e1.scope != null ; e1 = e1.next(cf)) {
2119 } 2111 //...find another method m2 that is overridden (directly or indirectly)
2120 } 2112 //by method 'sym' in 'site'
2121 } 2113 for (Scope.Entry e2 = types.membersClosure(site).lookup(sym.name, cf) ;
2122 2114 e2.scope != null ; e2 = e2.next(cf)) {
2123 /** Reports an error whenever 'sym' seen as a member of type 't1' clashes with 2115 if (e1.sym == e2.sym || !sym.overrides(e2.sym, site.tsym, types, false)) continue;
2124 * some unrelated method defined in 't2'. 2116 //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
2125 */ 2117 //a member of 'site') and (ii) m1 has the same erasure as m2, issue an error
2126 private void checkClashes(DiagnosticPosition pos, Type t1, Type t2, Type site, Symbol s1) { 2118 if (!types.isSubSignature(sym.type, types.memberType(site, e1.sym)) &&
2119 types.hasSameArgs(e1.sym.erasure(types), e2.sym.erasure(types))) {
2120 sym.flags_field |= CLASH;
2121 String key = e2.sym == sym ?
2122 "name.clash.same.erasure.no.override" :
2123 "name.clash.same.erasure.no.override.1";
2124 log.error(pos,
2125 key,
2126 sym, sym.location(),
2127 e1.sym, e1.sym.location(),
2128 e2.sym, e2.sym.location());
2129 return;
2130 }
2131 }
2132 }
2133 }
2134
2135 /** Check that all static methods accessible from 'site' are
2136 * mutually compatible (JLS 8.4.8).
2137 *
2138 * @param pos Position to be used for error reporting.
2139 * @param site The class whose methods are checked.
2140 * @param sym The method symbol to be checked.
2141 */
2142 void checkHideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
2127 ClashFilter cf = new ClashFilter(site); 2143 ClashFilter cf = new ClashFilter(site);
2128 s1 = ((MethodSymbol)s1).implementedIn(t1.tsym, types); 2144 //for each method m1 that is a member of 'site'...
2129 if (s1 == null) return; 2145 for (Scope.Entry e = types.membersClosure(site).lookup(sym.name, cf) ;
2130 Type st1 = types.memberType(site, s1); 2146 e.scope != null ; e = e.next(cf)) {
2131 for (Scope.Entry e2 = t2.tsym.members().lookup(s1.name, cf); e2.scope != null; e2 = e2.next(cf)) { 2147 //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
2132 Symbol s2 = e2.sym; 2148 //a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error
2133 if (s1 == s2) continue; 2149 if (!types.isSubSignature(sym.type, types.memberType(site, e.sym)) &&
2134 Type st2 = types.memberType(site, s2); 2150 types.hasSameArgs(e.sym.erasure(types), sym.erasure(types))) {
2135 if (!types.overrideEquivalent(st1, st2) &&
2136 !checkNameClash((ClassSymbol)site.tsym, s1, s2)) {
2137 log.error(pos, 2151 log.error(pos,
2138 "name.clash.same.erasure.no.override", 2152 "name.clash.same.erasure.no.hide",
2139 s1, s1.location(), 2153 sym, sym.location(),
2140 s2, s2.location()); 2154 e.sym, e.sym.location());
2141 } 2155 return;
2142 } 2156 }
2143 } 2157 }
2144 //where 2158 }
2145 private class ClashFilter implements Filter<Symbol> { 2159
2146 2160 //where
2147 Type site; 2161 private class ClashFilter implements Filter<Symbol> {
2148 2162
2149 ClashFilter(Type site) { 2163 Type site;
2150 this.site = site; 2164
2151 } 2165 ClashFilter(Type site) {
2152 2166 this.site = site;
2153 public boolean accepts(Symbol s) { 2167 }
2154 return s.kind == MTH && 2168
2155 (s.flags() & (SYNTHETIC | CLASH)) == 0 && 2169 boolean shouldSkip(Symbol s) {
2156 s.isInheritedIn(site.tsym, types) && 2170 return (s.flags() & CLASH) != 0 &&
2157 !s.isConstructor(); 2171 s.owner == site.tsym;
2158 } 2172 }
2159 } 2173
2174 public boolean accepts(Symbol s) {
2175 return s.kind == MTH &&
2176 (s.flags() & SYNTHETIC) == 0 &&
2177 !shouldSkip(s) &&
2178 s.isInheritedIn(site.tsym, types) &&
2179 !s.isConstructor();
2180 }
2181 }
2160 2182
2161 /** Report a conflict between a user symbol and a synthetic symbol. 2183 /** Report a conflict between a user symbol and a synthetic symbol.
2162 */ 2184 */
2163 private void syntheticError(DiagnosticPosition pos, Symbol sym) { 2185 private void syntheticError(DiagnosticPosition pos, Symbol sym) {
2164 if (!sym.type.isErroneous()) { 2186 if (!sym.type.isErroneous()) {
2636 if (sym.type.isErroneous()) 2658 if (sym.type.isErroneous())
2637 return true; 2659 return true;
2638 if (sym.owner.name == names.any) return false; 2660 if (sym.owner.name == names.any) return false;
2639 for (Scope.Entry e = s.lookup(sym.name); e.scope == s; e = e.next()) { 2661 for (Scope.Entry e = s.lookup(sym.name); e.scope == s; e = e.next()) {
2640 if (sym != e.sym && 2662 if (sym != e.sym &&
2641 (e.sym.flags() & CLASH) == 0 && 2663 (e.sym.flags() & CLASH) == 0 &&
2642 sym.kind == e.sym.kind && 2664 sym.kind == e.sym.kind &&
2643 sym.name != names.error && 2665 sym.name != names.error &&
2644 (sym.kind != MTH || types.hasSameArgs(types.erasure(sym.type), types.erasure(e.sym.type)))) { 2666 (sym.kind != MTH || types.hasSameArgs(types.erasure(sym.type), types.erasure(e.sym.type)))) {
2645 if ((sym.flags() & VARARGS) != (e.sym.flags() & VARARGS)) { 2667 if ((sym.flags() & VARARGS) != (e.sym.flags() & VARARGS)) {
2646 varargsDuplicateError(pos, sym, e.sym); 2668 varargsDuplicateError(pos, sym, e.sym);
2647 return true; 2669 return true;
2648 } else if (sym.kind == MTH && !hasSameSignature(sym.type, e.sym.type)) { 2670 } else if (sym.kind == MTH && !hasSameSignature(sym.type, e.sym.type)) {
2649 duplicateErasureError(pos, sym, e.sym); 2671 duplicateErasureError(pos, sym, e.sym);
2665 mt2 = types.subst(fa2, fa2.tvars, fa1.tvars); 2687 mt2 = types.subst(fa2, fa2.tvars, fa1.tvars);
2666 } 2688 }
2667 return types.hasSameArgs(mt1.asMethodType(), mt2.asMethodType()); 2689 return types.hasSameArgs(mt1.asMethodType(), mt2.asMethodType());
2668 } 2690 }
2669 2691
2670 /** Report duplicate declaration error. 2692 /** Report duplicate declaration error.
2671 */ 2693 */
2672 void duplicateErasureError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) { 2694 void duplicateErasureError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) {
2673 if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) { 2695 if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) {
2674 log.error(pos, "name.clash.same.erasure", sym1, sym2); 2696 log.error(pos, "name.clash.same.erasure", sym1, sym2);
2675 } 2697 }
2676 } 2698 }
2677 2699
2678 /** Check that single-type import is not already imported or top-level defined, 2700 /** Check that single-type import is not already imported or top-level defined,
2679 * but make an exception for two single-type imports which denote the same type. 2701 * but make an exception for two single-type imports which denote the same type.
2680 * @param pos Position for error reporting. 2702 * @param pos Position for error reporting.
2681 * @param sym The symbol. 2703 * @param sym The symbol.

mercurial