--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Mon Feb 07 18:09:46 2011 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Mon Feb 07 18:10:13 2011 +0000
@@ -1679,7 +1679,7 @@
"(" + types.memberType(t2, s2).getParameterTypes() + ")");
return s2;
}
- } else if (!checkNameClash((ClassSymbol)site.tsym, s1, s2)) {
+ } else if (checkNameClash((ClassSymbol)site.tsym, s1, s2)) {
log.error(pos,
"name.clash.same.erasure.no.override",
s1, s1.location(),
@@ -1761,18 +1761,10 @@
}
private boolean checkNameClash(ClassSymbol origin, Symbol s1, Symbol s2) {
- if (s1.kind == MTH &&
- s1.isInheritedIn(origin, types) &&
- (s1.flags() & SYNTHETIC) == 0 &&
- !s2.isConstructor()) {
- Type er1 = s2.erasure(types);
- Type er2 = s1.erasure(types);
- if (types.isSameTypes(er1.getParameterTypes(),
- er2.getParameterTypes())) {
- return false;
- }
- }
- return true;
+ ClashFilter cf = new ClashFilter(origin.type);
+ return (cf.accepts(s1) &&
+ cf.accepts(s2) &&
+ types.hasSameArgs(s1.erasure(types), s2.erasure(types)));
}
@@ -2111,52 +2103,82 @@
* @param site The class whose methods are checked.
* @param sym The method symbol to be checked.
*/
- void checkClashes(DiagnosticPosition pos, Type site, Symbol sym) {
- List<Type> supertypes = types.closure(site);
- for (List<Type> l = supertypes; l.nonEmpty(); l = l.tail) {
- for (List<Type> m = supertypes; m.nonEmpty(); m = m.tail) {
- checkClashes(pos, l.head, m.head, site, sym);
+ void checkOverrideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
+ ClashFilter cf = new ClashFilter(site);
+ //for each method m1 that is a member of 'site'...
+ for (Scope.Entry e1 = types.membersClosure(site).lookup(sym.name, cf) ;
+ e1.scope != null ; e1 = e1.next(cf)) {
+ //...find another method m2 that is overridden (directly or indirectly)
+ //by method 'sym' in 'site'
+ for (Scope.Entry e2 = types.membersClosure(site).lookup(sym.name, cf) ;
+ e2.scope != null ; e2 = e2.next(cf)) {
+ if (e1.sym == e2.sym || !sym.overrides(e2.sym, site.tsym, types, false)) continue;
+ //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
+ //a member of 'site') and (ii) m1 has the same erasure as m2, issue an error
+ if (!types.isSubSignature(sym.type, types.memberType(site, e1.sym)) &&
+ types.hasSameArgs(e1.sym.erasure(types), e2.sym.erasure(types))) {
+ sym.flags_field |= CLASH;
+ String key = e2.sym == sym ?
+ "name.clash.same.erasure.no.override" :
+ "name.clash.same.erasure.no.override.1";
+ log.error(pos,
+ key,
+ sym, sym.location(),
+ e1.sym, e1.sym.location(),
+ e2.sym, e2.sym.location());
+ return;
+ }
}
}
}
- /** Reports an error whenever 'sym' seen as a member of type 't1' clashes with
- * some unrelated method defined in 't2'.
+ /** Check that all static methods accessible from 'site' are
+ * mutually compatible (JLS 8.4.8).
+ *
+ * @param pos Position to be used for error reporting.
+ * @param site The class whose methods are checked.
+ * @param sym The method symbol to be checked.
*/
- private void checkClashes(DiagnosticPosition pos, Type t1, Type t2, Type site, Symbol s1) {
+ void checkHideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
ClashFilter cf = new ClashFilter(site);
- s1 = ((MethodSymbol)s1).implementedIn(t1.tsym, types);
- if (s1 == null) return;
- Type st1 = types.memberType(site, s1);
- for (Scope.Entry e2 = t2.tsym.members().lookup(s1.name, cf); e2.scope != null; e2 = e2.next(cf)) {
- Symbol s2 = e2.sym;
- if (s1 == s2) continue;
- Type st2 = types.memberType(site, s2);
- if (!types.overrideEquivalent(st1, st2) &&
- !checkNameClash((ClassSymbol)site.tsym, s1, s2)) {
+ //for each method m1 that is a member of 'site'...
+ for (Scope.Entry e = types.membersClosure(site).lookup(sym.name, cf) ;
+ e.scope != null ; e = e.next(cf)) {
+ //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
+ //a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error
+ if (!types.isSubSignature(sym.type, types.memberType(site, e.sym)) &&
+ types.hasSameArgs(e.sym.erasure(types), sym.erasure(types))) {
log.error(pos,
- "name.clash.same.erasure.no.override",
- s1, s1.location(),
- s2, s2.location());
- }
- }
- }
- //where
- private class ClashFilter implements Filter<Symbol> {
+ "name.clash.same.erasure.no.hide",
+ sym, sym.location(),
+ e.sym, e.sym.location());
+ return;
+ }
+ }
+ }
- Type site;
+ //where
+ private class ClashFilter implements Filter<Symbol> {
+
+ Type site;
- ClashFilter(Type site) {
- this.site = site;
- }
+ ClashFilter(Type site) {
+ this.site = site;
+ }
+
+ boolean shouldSkip(Symbol s) {
+ return (s.flags() & CLASH) != 0 &&
+ s.owner == site.tsym;
+ }
- public boolean accepts(Symbol s) {
- return s.kind == MTH &&
- (s.flags() & (SYNTHETIC | CLASH)) == 0 &&
- s.isInheritedIn(site.tsym, types) &&
- !s.isConstructor();
- }
- }
+ public boolean accepts(Symbol s) {
+ return s.kind == MTH &&
+ (s.flags() & SYNTHETIC) == 0 &&
+ !shouldSkip(s) &&
+ s.isInheritedIn(site.tsym, types) &&
+ !s.isConstructor();
+ }
+ }
/** Report a conflict between a user symbol and a synthetic symbol.
*/
@@ -2638,10 +2660,10 @@
if (sym.owner.name == names.any) return false;
for (Scope.Entry e = s.lookup(sym.name); e.scope == s; e = e.next()) {
if (sym != e.sym &&
- (e.sym.flags() & CLASH) == 0 &&
- sym.kind == e.sym.kind &&
- sym.name != names.error &&
- (sym.kind != MTH || types.hasSameArgs(types.erasure(sym.type), types.erasure(e.sym.type)))) {
+ (e.sym.flags() & CLASH) == 0 &&
+ sym.kind == e.sym.kind &&
+ sym.name != names.error &&
+ (sym.kind != MTH || types.hasSameArgs(types.erasure(sym.type), types.erasure(e.sym.type)))) {
if ((sym.flags() & VARARGS) != (e.sym.flags() & VARARGS)) {
varargsDuplicateError(pos, sym, e.sym);
return true;
@@ -2667,13 +2689,13 @@
return types.hasSameArgs(mt1.asMethodType(), mt2.asMethodType());
}
- /** Report duplicate declaration error.
- */
- void duplicateErasureError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) {
- if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) {
- log.error(pos, "name.clash.same.erasure", sym1, sym2);
- }
+ /** Report duplicate declaration error.
+ */
+ void duplicateErasureError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) {
+ if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) {
+ log.error(pos, "name.clash.same.erasure", sym1, sym2);
}
+ }
/** Check that single-type import is not already imported or top-level defined,
* but make an exception for two single-type imports which denote the same type.