langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
changeset 8242 3873b4aaf4a8
parent 8238 15ff254ff5c2
child 8427 703181b01773
equal deleted inserted replaced
8241:4161b56e0d20 8242:3873b4aaf4a8
  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.