Save This Page
Home » openjdk-7 » com.sun.tools » javac » comp » [javadoc | source]
    1   /*
    2    * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package com.sun.tools.javac.comp;
   27   
   28   import java.util;
   29   import java.util.Set;
   30   
   31   import com.sun.tools.javac.code;
   32   import com.sun.tools.javac.jvm;
   33   import com.sun.tools.javac.tree;
   34   import com.sun.tools.javac.util;
   35   import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
   36   import com.sun.tools.javac.util.List;
   37   
   38   import com.sun.tools.javac.tree.JCTree;
   39   import com.sun.tools.javac.code.Lint;
   40   import com.sun.tools.javac.code.Lint.LintCategory;
   41   import com.sun.tools.javac.code.Type;
   42   import com.sun.tools.javac.code.Symbol;
   43   
   44   import static com.sun.tools.javac.code.Flags.*;
   45   import static com.sun.tools.javac.code.Kinds.*;
   46   import static com.sun.tools.javac.code.TypeTags.*;
   47   
   48   import static com.sun.tools.javac.main.OptionName.*;
   49   
   50   /** Type checking helper class for the attribution phase.
   51    *
   52    *  <p><b>This is NOT part of any supported API.
   53    *  If you write code that depends on this, you do so at your own risk.
   54    *  This code and its internal interfaces are subject to change or
   55    *  deletion without notice.</b>
   56    */
   57   public class Check {
   58       protected static final Context.Key<Check> checkKey =
   59           new Context.Key<Check>();
   60   
   61       private final Names names;
   62       private final Log log;
   63       private final Symtab syms;
   64       private final Enter enter;
   65       private final Infer infer;
   66       private final Types types;
   67       private final JCDiagnostic.Factory diags;
   68       private final boolean skipAnnotations;
   69       private boolean warnOnSyntheticConflicts;
   70       private boolean suppressAbortOnBadClassFile;
   71       private boolean enableSunApiLintControl;
   72       private final TreeInfo treeinfo;
   73   
   74       // The set of lint options currently in effect. It is initialized
   75       // from the context, and then is set/reset as needed by Attr as it
   76       // visits all the various parts of the trees during attribution.
   77       private Lint lint;
   78   
   79       // The method being analyzed in Attr - it is set/reset as needed by
   80       // Attr as it visits new method declarations.
   81       private MethodSymbol method;
   82   
   83       public static Check instance(Context context) {
   84           Check instance = context.get(checkKey);
   85           if (instance == null)
   86               instance = new Check(context);
   87           return instance;
   88       }
   89   
   90       protected Check(Context context) {
   91           context.put(checkKey, this);
   92   
   93           names = Names.instance(context);
   94           log = Log.instance(context);
   95           syms = Symtab.instance(context);
   96           enter = Enter.instance(context);
   97           infer = Infer.instance(context);
   98           this.types = Types.instance(context);
   99           diags = JCDiagnostic.Factory.instance(context);
  100           Options options = Options.instance(context);
  101           lint = Lint.instance(context);
  102           treeinfo = TreeInfo.instance(context);
  103   
  104           Source source = Source.instance(context);
  105           allowGenerics = source.allowGenerics();
  106           allowAnnotations = source.allowAnnotations();
  107           allowCovariantReturns = source.allowCovariantReturns();
  108           allowSimplifiedVarargs = source.allowSimplifiedVarargs();
  109           complexInference = options.isSet(COMPLEXINFERENCE);
  110           skipAnnotations = options.isSet("skipAnnotations");
  111           warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts");
  112           suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile");
  113           enableSunApiLintControl = options.isSet("enableSunApiLintControl");
  114   
  115           Target target = Target.instance(context);
  116           syntheticNameChar = target.syntheticNameChar();
  117   
  118           boolean verboseDeprecated = lint.isEnabled(LintCategory.DEPRECATION);
  119           boolean verboseUnchecked = lint.isEnabled(LintCategory.UNCHECKED);
  120           boolean verboseSunApi = lint.isEnabled(LintCategory.SUNAPI);
  121           boolean enforceMandatoryWarnings = source.enforceMandatoryWarnings();
  122   
  123           deprecationHandler = new MandatoryWarningHandler(log, verboseDeprecated,
  124                   enforceMandatoryWarnings, "deprecated", LintCategory.DEPRECATION);
  125           uncheckedHandler = new MandatoryWarningHandler(log, verboseUnchecked,
  126                   enforceMandatoryWarnings, "unchecked", LintCategory.UNCHECKED);
  127           sunApiHandler = new MandatoryWarningHandler(log, verboseSunApi,
  128                   enforceMandatoryWarnings, "sunapi", null);
  129   
  130           deferredLintHandler = DeferredLintHandler.immediateHandler;
  131       }
  132   
  133       /** Switch: generics enabled?
  134        */
  135       boolean allowGenerics;
  136   
  137       /** Switch: annotations enabled?
  138        */
  139       boolean allowAnnotations;
  140   
  141       /** Switch: covariant returns enabled?
  142        */
  143       boolean allowCovariantReturns;
  144   
  145       /** Switch: simplified varargs enabled?
  146        */
  147       boolean allowSimplifiedVarargs;
  148   
  149       /** Switch: -complexinference option set?
  150        */
  151       boolean complexInference;
  152   
  153       /** Character for synthetic names
  154        */
  155       char syntheticNameChar;
  156   
  157       /** A table mapping flat names of all compiled classes in this run to their
  158        *  symbols; maintained from outside.
  159        */
  160       public Map<Name,ClassSymbol> compiled = new HashMap<Name, ClassSymbol>();
  161   
  162       /** A handler for messages about deprecated usage.
  163        */
  164       private MandatoryWarningHandler deprecationHandler;
  165   
  166       /** A handler for messages about unchecked or unsafe usage.
  167        */
  168       private MandatoryWarningHandler uncheckedHandler;
  169   
  170       /** A handler for messages about using proprietary API.
  171        */
  172       private MandatoryWarningHandler sunApiHandler;
  173   
  174       /** A handler for deferred lint warnings.
  175        */
  176       private DeferredLintHandler deferredLintHandler;
  177   
  178   /* *************************************************************************
  179    * Errors and Warnings
  180    **************************************************************************/
  181   
  182       Lint setLint(Lint newLint) {
  183           Lint prev = lint;
  184           lint = newLint;
  185           return prev;
  186       }
  187   
  188       DeferredLintHandler setDeferredLintHandler(DeferredLintHandler newDeferredLintHandler) {
  189           DeferredLintHandler prev = deferredLintHandler;
  190           deferredLintHandler = newDeferredLintHandler;
  191           return prev;
  192       }
  193   
  194       MethodSymbol setMethod(MethodSymbol newMethod) {
  195           MethodSymbol prev = method;
  196           method = newMethod;
  197           return prev;
  198       }
  199   
  200       /** Warn about deprecated symbol.
  201        *  @param pos        Position to be used for error reporting.
  202        *  @param sym        The deprecated symbol.
  203        */
  204       void warnDeprecated(DiagnosticPosition pos, Symbol sym) {
  205           if (!lint.isSuppressed(LintCategory.DEPRECATION))
  206               deprecationHandler.report(pos, "has.been.deprecated", sym, sym.location());
  207       }
  208   
  209       /** Warn about unchecked operation.
  210        *  @param pos        Position to be used for error reporting.
  211        *  @param msg        A string describing the problem.
  212        */
  213       public void warnUnchecked(DiagnosticPosition pos, String msg, Object... args) {
  214           if (!lint.isSuppressed(LintCategory.UNCHECKED))
  215               uncheckedHandler.report(pos, msg, args);
  216       }
  217   
  218       /** Warn about unsafe vararg method decl.
  219        *  @param pos        Position to be used for error reporting.
  220        *  @param sym        The deprecated symbol.
  221        */
  222       void warnUnsafeVararg(DiagnosticPosition pos, String key, Object... args) {
  223           if (lint.isEnabled(LintCategory.VARARGS) && allowSimplifiedVarargs)
  224               log.warning(LintCategory.VARARGS, pos, key, args);
  225       }
  226   
  227       /** Warn about using proprietary API.
  228        *  @param pos        Position to be used for error reporting.
  229        *  @param msg        A string describing the problem.
  230        */
  231       public void warnSunApi(DiagnosticPosition pos, String msg, Object... args) {
  232           if (!lint.isSuppressed(LintCategory.SUNAPI))
  233               sunApiHandler.report(pos, msg, args);
  234       }
  235   
  236       public void warnStatic(DiagnosticPosition pos, String msg, Object... args) {
  237           if (lint.isEnabled(LintCategory.STATIC))
  238               log.warning(LintCategory.STATIC, pos, msg, args);
  239       }
  240   
  241       /**
  242        * Report any deferred diagnostics.
  243        */
  244       public void reportDeferredDiagnostics() {
  245           deprecationHandler.reportDeferredDiagnostic();
  246           uncheckedHandler.reportDeferredDiagnostic();
  247           sunApiHandler.reportDeferredDiagnostic();
  248       }
  249   
  250   
  251       /** Report a failure to complete a class.
  252        *  @param pos        Position to be used for error reporting.
  253        *  @param ex         The failure to report.
  254        */
  255       public Type completionError(DiagnosticPosition pos, CompletionFailure ex) {
  256           log.error(pos, "cant.access", ex.sym, ex.getDetailValue());
  257           if (ex instanceof ClassReader.BadClassFile
  258                   && !suppressAbortOnBadClassFile) throw new Abort();
  259           else return syms.errType;
  260       }
  261   
  262       /** Report a type error.
  263        *  @param pos        Position to be used for error reporting.
  264        *  @param problem    A string describing the error.
  265        *  @param found      The type that was found.
  266        *  @param req        The type that was required.
  267        */
  268       Type typeError(DiagnosticPosition pos, Object problem, Type found, Type req) {
  269           log.error(pos, "prob.found.req",
  270                     problem, found, req);
  271           return types.createErrorType(found);
  272       }
  273   
  274       Type typeError(DiagnosticPosition pos, String problem, Type found, Type req, Object explanation) {
  275           log.error(pos, "prob.found.req.1", problem, found, req, explanation);
  276           return types.createErrorType(found);
  277       }
  278   
  279       /** Report an error that wrong type tag was found.
  280        *  @param pos        Position to be used for error reporting.
  281        *  @param required   An internationalized string describing the type tag
  282        *                    required.
  283        *  @param found      The type that was found.
  284        */
  285       Type typeTagError(DiagnosticPosition pos, Object required, Object found) {
  286           // this error used to be raised by the parser,
  287           // but has been delayed to this point:
  288           if (found instanceof Type && ((Type)found).tag == VOID) {
  289               log.error(pos, "illegal.start.of.type");
  290               return syms.errType;
  291           }
  292           log.error(pos, "type.found.req", found, required);
  293           return types.createErrorType(found instanceof Type ? (Type)found : syms.errType);
  294       }
  295   
  296       /** Report an error that symbol cannot be referenced before super
  297        *  has been called.
  298        *  @param pos        Position to be used for error reporting.
  299        *  @param sym        The referenced symbol.
  300        */
  301       void earlyRefError(DiagnosticPosition pos, Symbol sym) {
  302           log.error(pos, "cant.ref.before.ctor.called", sym);
  303       }
  304   
  305       /** Report duplicate declaration error.
  306        */
  307       void duplicateError(DiagnosticPosition pos, Symbol sym) {
  308           if (!sym.type.isErroneous()) {
  309               log.error(pos, "already.defined", sym, sym.location());
  310           }
  311       }
  312   
  313       /** Report array/varargs duplicate declaration
  314        */
  315       void varargsDuplicateError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) {
  316           if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) {
  317               log.error(pos, "array.and.varargs", sym1, sym2, sym2.location());
  318           }
  319       }
  320   
  321   /* ************************************************************************
  322    * duplicate declaration checking
  323    *************************************************************************/
  324   
  325       /** Check that variable does not hide variable with same name in
  326        *  immediately enclosing local scope.
  327        *  @param pos           Position for error reporting.
  328        *  @param v             The symbol.
  329        *  @param s             The scope.
  330        */
  331       void checkTransparentVar(DiagnosticPosition pos, VarSymbol v, Scope s) {
  332           if (s.next != null) {
  333               for (Scope.Entry e = s.next.lookup(v.name);
  334                    e.scope != null && e.sym.owner == v.owner;
  335                    e = e.next()) {
  336                   if (e.sym.kind == VAR &&
  337                       (e.sym.owner.kind & (VAR | MTH)) != 0 &&
  338                       v.name != names.error) {
  339                       duplicateError(pos, e.sym);
  340                       return;
  341                   }
  342               }
  343           }
  344       }
  345   
  346       /** Check that a class or interface does not hide a class or
  347        *  interface with same name in immediately enclosing local scope.
  348        *  @param pos           Position for error reporting.
  349        *  @param c             The symbol.
  350        *  @param s             The scope.
  351        */
  352       void checkTransparentClass(DiagnosticPosition pos, ClassSymbol c, Scope s) {
  353           if (s.next != null) {
  354               for (Scope.Entry e = s.next.lookup(c.name);
  355                    e.scope != null && e.sym.owner == c.owner;
  356                    e = e.next()) {
  357                   if (e.sym.kind == TYP && e.sym.type.tag != TYPEVAR &&
  358                       (e.sym.owner.kind & (VAR | MTH)) != 0 &&
  359                       c.name != names.error) {
  360                       duplicateError(pos, e.sym);
  361                       return;
  362                   }
  363               }
  364           }
  365       }
  366   
  367       /** Check that class does not have the same name as one of
  368        *  its enclosing classes, or as a class defined in its enclosing scope.
  369        *  return true if class is unique in its enclosing scope.
  370        *  @param pos           Position for error reporting.
  371        *  @param name          The class name.
  372        *  @param s             The enclosing scope.
  373        */
  374       boolean checkUniqueClassName(DiagnosticPosition pos, Name name, Scope s) {
  375           for (Scope.Entry e = s.lookup(name); e.scope == s; e = e.next()) {
  376               if (e.sym.kind == TYP && e.sym.name != names.error) {
  377                   duplicateError(pos, e.sym);
  378                   return false;
  379               }
  380           }
  381           for (Symbol sym = s.owner; sym != null; sym = sym.owner) {
  382               if (sym.kind == TYP && sym.name == name && sym.name != names.error) {
  383                   duplicateError(pos, sym);
  384                   return true;
  385               }
  386           }
  387           return true;
  388       }
  389   
  390   /* *************************************************************************
  391    * Class name generation
  392    **************************************************************************/
  393   
  394       /** Return name of local class.
  395        *  This is of the form    <enclClass> $ n <classname>
  396        *  where
  397        *    enclClass is the flat name of the enclosing class,
  398        *    classname is the simple name of the local class
  399        */
  400       Name localClassName(ClassSymbol c) {
  401           for (int i=1; ; i++) {
  402               Name flatname = names.
  403                   fromString("" + c.owner.enclClass().flatname +
  404                              syntheticNameChar + i +
  405                              c.name);
  406               if (compiled.get(flatname) == null) return flatname;
  407           }
  408       }
  409   
  410   /* *************************************************************************
  411    * Type Checking
  412    **************************************************************************/
  413   
  414       /** Check that a given type is assignable to a given proto-type.
  415        *  If it is, return the type, otherwise return errType.
  416        *  @param pos        Position to be used for error reporting.
  417        *  @param found      The type that was found.
  418        *  @param req        The type that was required.
  419        */
  420       Type checkType(DiagnosticPosition pos, Type found, Type req) {
  421           return checkType(pos, found, req, "incompatible.types");
  422       }
  423   
  424       Type checkType(DiagnosticPosition pos, Type found, Type req, String errKey) {
  425           if (req.tag == ERROR)
  426               return req;
  427           if (found.tag == FORALL)
  428               return instantiatePoly(pos, (ForAll)found, req, convertWarner(pos, found, req));
  429           if (req.tag == NONE)
  430               return found;
  431           if (types.isAssignable(found, req, convertWarner(pos, found, req)))
  432               return found;
  433           if (found.tag <= DOUBLE && req.tag <= DOUBLE)
  434               return typeError(pos, diags.fragment("possible.loss.of.precision"), found, req);
  435           if (found.isSuperBound()) {
  436               log.error(pos, "assignment.from.super-bound", found);
  437               return types.createErrorType(found);
  438           }
  439           if (req.isExtendsBound()) {
  440               log.error(pos, "assignment.to.extends-bound", req);
  441               return types.createErrorType(found);
  442           }
  443           return typeError(pos, diags.fragment(errKey), found, req);
  444       }
  445   
  446       /** Instantiate polymorphic type to some prototype, unless
  447        *  prototype is `anyPoly' in which case polymorphic type
  448        *  is returned unchanged.
  449        */
  450       Type instantiatePoly(DiagnosticPosition pos, ForAll t, Type pt, Warner warn) throws Infer.NoInstanceException {
  451           if (pt == Infer.anyPoly && complexInference) {
  452               return t;
  453           } else if (pt == Infer.anyPoly || pt.tag == NONE) {
  454               Type newpt = t.qtype.tag <= VOID ? t.qtype : syms.objectType;
  455               return instantiatePoly(pos, t, newpt, warn);
  456           } else if (pt.tag == ERROR) {
  457               return pt;
  458           } else {
  459               try {
  460                   return infer.instantiateExpr(t, pt, warn);
  461               } catch (Infer.NoInstanceException ex) {
  462                   if (ex.isAmbiguous) {
  463                       JCDiagnostic d = ex.getDiagnostic();
  464                       log.error(pos,
  465                                 "undetermined.type" + (d!=null ? ".1" : ""),
  466                                 t, d);
  467                       return types.createErrorType(pt);
  468                   } else {
  469                       JCDiagnostic d = ex.getDiagnostic();
  470                       return typeError(pos,
  471                                        diags.fragment("incompatible.types" + (d!=null ? ".1" : ""), d),
  472                                        t, pt);
  473                   }
  474               } catch (Infer.InvalidInstanceException ex) {
  475                   JCDiagnostic d = ex.getDiagnostic();
  476                   log.error(pos, "invalid.inferred.types", t.tvars, d);
  477                   return types.createErrorType(pt);
  478               }
  479           }
  480       }
  481   
  482       /** Check that a given type can be cast to a given target type.
  483        *  Return the result of the cast.
  484        *  @param pos        Position to be used for error reporting.
  485        *  @param found      The type that is being cast.
  486        *  @param req        The target type of the cast.
  487        */
  488       Type checkCastable(DiagnosticPosition pos, Type found, Type req) {
  489           if (found.tag == FORALL) {
  490               instantiatePoly(pos, (ForAll) found, req, castWarner(pos, found, req));
  491               return req;
  492           } else if (types.isCastable(found, req, castWarner(pos, found, req))) {
  493               return req;
  494           } else {
  495               return typeError(pos,
  496                                diags.fragment("inconvertible.types"),
  497                                found, req);
  498           }
  499       }
  500   //where
  501           /** Is type a type variable, or a (possibly multi-dimensional) array of
  502            *  type variables?
  503            */
  504           boolean isTypeVar(Type t) {
  505               return t.tag == TYPEVAR || t.tag == ARRAY && isTypeVar(types.elemtype(t));
  506           }
  507   
  508       /** Check that a type is within some bounds.
  509        *
  510        *  Used in TypeApply to verify that, e.g., X in V<X> is a valid
  511        *  type argument.
  512        *  @param pos           Position to be used for error reporting.
  513        *  @param a             The type that should be bounded by bs.
  514        *  @param bs            The bound.
  515        */
  516       private boolean checkExtends(Type a, TypeVar bs) {
  517            if (a.isUnbound()) {
  518                return true;
  519            } else if (a.tag != WILDCARD) {
  520                a = types.upperBound(a);
  521                return types.isSubtype(a, bs.bound);
  522            } else if (a.isExtendsBound()) {
  523                return types.isCastable(bs.getUpperBound(), types.upperBound(a), Warner.noWarnings);
  524            } else if (a.isSuperBound()) {
  525                return !types.notSoftSubtype(types.lowerBound(a), bs.getUpperBound());
  526            }
  527            return true;
  528        }
  529   
  530       /** Check that type is different from 'void'.
  531        *  @param pos           Position to be used for error reporting.
  532        *  @param t             The type to be checked.
  533        */
  534       Type checkNonVoid(DiagnosticPosition pos, Type t) {
  535           if (t.tag == VOID) {
  536               log.error(pos, "void.not.allowed.here");
  537               return types.createErrorType(t);
  538           } else {
  539               return t;
  540           }
  541       }
  542   
  543       /** Check that type is a class or interface type.
  544        *  @param pos           Position to be used for error reporting.
  545        *  @param t             The type to be checked.
  546        */
  547       Type checkClassType(DiagnosticPosition pos, Type t) {
  548           if (t.tag != CLASS && t.tag != ERROR)
  549               return typeTagError(pos,
  550                                   diags.fragment("type.req.class"),
  551                                   (t.tag == TYPEVAR)
  552                                   ? diags.fragment("type.parameter", t)
  553                                   : t);
  554           else
  555               return t;
  556       }
  557   
  558       /** Check that type is a class or interface type.
  559        *  @param pos           Position to be used for error reporting.
  560        *  @param t             The type to be checked.
  561        *  @param noBounds    True if type bounds are illegal here.
  562        */
  563       Type checkClassType(DiagnosticPosition pos, Type t, boolean noBounds) {
  564           t = checkClassType(pos, t);
  565           if (noBounds && t.isParameterized()) {
  566               List<Type> args = t.getTypeArguments();
  567               while (args.nonEmpty()) {
  568                   if (args.head.tag == WILDCARD)
  569                       return typeTagError(pos,
  570                                           diags.fragment("type.req.exact"),
  571                                           args.head);
  572                   args = args.tail;
  573               }
  574           }
  575           return t;
  576       }
  577   
  578       /** Check that type is a reifiable class, interface or array type.
  579        *  @param pos           Position to be used for error reporting.
  580        *  @param t             The type to be checked.
  581        */
  582       Type checkReifiableReferenceType(DiagnosticPosition pos, Type t) {
  583           if (t.tag != CLASS && t.tag != ARRAY && t.tag != ERROR) {
  584               return typeTagError(pos,
  585                                   diags.fragment("type.req.class.array"),
  586                                   t);
  587           } else if (!types.isReifiable(t)) {
  588               log.error(pos, "illegal.generic.type.for.instof");
  589               return types.createErrorType(t);
  590           } else {
  591               return t;
  592           }
  593       }
  594   
  595       /** Check that type is a reference type, i.e. a class, interface or array type
  596        *  or a type variable.
  597        *  @param pos           Position to be used for error reporting.
  598        *  @param t             The type to be checked.
  599        */
  600       Type checkRefType(DiagnosticPosition pos, Type t) {
  601           switch (t.tag) {
  602           case CLASS:
  603           case ARRAY:
  604           case TYPEVAR:
  605           case WILDCARD:
  606           case ERROR:
  607               return t;
  608           default:
  609               return typeTagError(pos,
  610                                   diags.fragment("type.req.ref"),
  611                                   t);
  612           }
  613       }
  614   
  615       /** Check that each type is a reference type, i.e. a class, interface or array type
  616        *  or a type variable.
  617        *  @param trees         Original trees, used for error reporting.
  618        *  @param types         The types to be checked.
  619        */
  620       List<Type> checkRefTypes(List<JCExpression> trees, List<Type> types) {
  621           List<JCExpression> tl = trees;
  622           for (List<Type> l = types; l.nonEmpty(); l = l.tail) {
  623               l.head = checkRefType(tl.head.pos(), l.head);
  624               tl = tl.tail;
  625           }
  626           return types;
  627       }
  628   
  629       /** Check that type is a null or reference type.
  630        *  @param pos           Position to be used for error reporting.
  631        *  @param t             The type to be checked.
  632        */
  633       Type checkNullOrRefType(DiagnosticPosition pos, Type t) {
  634           switch (t.tag) {
  635           case CLASS:
  636           case ARRAY:
  637           case TYPEVAR:
  638           case WILDCARD:
  639           case BOT:
  640           case ERROR:
  641               return t;
  642           default:
  643               return typeTagError(pos,
  644                                   diags.fragment("type.req.ref"),
  645                                   t);
  646           }
  647       }
  648   
  649       /** Check that flag set does not contain elements of two conflicting sets. s
  650        *  Return true if it doesn't.
  651        *  @param pos           Position to be used for error reporting.
  652        *  @param flags         The set of flags to be checked.
  653        *  @param set1          Conflicting flags set #1.
  654        *  @param set2          Conflicting flags set #2.
  655        */
  656       boolean checkDisjoint(DiagnosticPosition pos, long flags, long set1, long set2) {
  657           if ((flags & set1) != 0 && (flags & set2) != 0) {
  658               log.error(pos,
  659                         "illegal.combination.of.modifiers",
  660                         asFlagSet(TreeInfo.firstFlag(flags & set1)),
  661                         asFlagSet(TreeInfo.firstFlag(flags & set2)));
  662               return false;
  663           } else
  664               return true;
  665       }
  666   
  667       /** Check that usage of diamond operator is correct (i.e. diamond should not
  668        * be used with non-generic classes or in anonymous class creation expressions)
  669        */
  670       Type checkDiamond(JCNewClass tree, Type t) {
  671           if (!TreeInfo.isDiamond(tree) ||
  672                   t.isErroneous()) {
  673               return checkClassType(tree.clazz.pos(), t, true);
  674           } else if (tree.def != null) {
  675               log.error(tree.clazz.pos(),
  676                       "cant.apply.diamond.1",
  677                       t, diags.fragment("diamond.and.anon.class", t));
  678               return types.createErrorType(t);
  679           } else if (t.tsym.type.getTypeArguments().isEmpty()) {
  680               log.error(tree.clazz.pos(),
  681                   "cant.apply.diamond.1",
  682                   t, diags.fragment("diamond.non.generic", t));
  683               return types.createErrorType(t);
  684           } else if (tree.typeargs != null &&
  685                   tree.typeargs.nonEmpty()) {
  686               log.error(tree.clazz.pos(),
  687                   "cant.apply.diamond.1",
  688                   t, diags.fragment("diamond.and.explicit.params", t));
  689               return types.createErrorType(t);
  690           } else {
  691               return t;
  692           }
  693       }
  694   
  695       void checkVarargsMethodDecl(Env<AttrContext> env, JCMethodDecl tree) {
  696           MethodSymbol m = tree.sym;
  697           if (!allowSimplifiedVarargs) return;
  698           boolean hasTrustMeAnno = m.attribute(syms.trustMeType.tsym) != null;
  699           Type varargElemType = null;
  700           if (m.isVarArgs()) {
  701               varargElemType = types.elemtype(tree.params.last().type);
  702           }
  703           if (hasTrustMeAnno && !isTrustMeAllowedOnMethod(m)) {
  704               if (varargElemType != null) {
  705                   log.error(tree,
  706                           "varargs.invalid.trustme.anno",
  707                           syms.trustMeType.tsym,
  708                           diags.fragment("varargs.trustme.on.virtual.varargs", m));
  709               } else {
  710                   log.error(tree,
  711                               "varargs.invalid.trustme.anno",
  712                               syms.trustMeType.tsym,
  713                               diags.fragment("varargs.trustme.on.non.varargs.meth", m));
  714               }
  715           } else if (hasTrustMeAnno && varargElemType != null &&
  716                               types.isReifiable(varargElemType)) {
  717               warnUnsafeVararg(tree,
  718                               "varargs.redundant.trustme.anno",
  719                               syms.trustMeType.tsym,
  720                               diags.fragment("varargs.trustme.on.reifiable.varargs", varargElemType));
  721           }
  722           else if (!hasTrustMeAnno && varargElemType != null &&
  723                   !types.isReifiable(varargElemType)) {
  724               warnUnchecked(tree.params.head.pos(), "unchecked.varargs.non.reifiable.type", varargElemType);
  725           }
  726       }
  727       //where
  728           private boolean isTrustMeAllowedOnMethod(Symbol s) {
  729               return (s.flags() & VARARGS) != 0 &&
  730                   (s.isConstructor() ||
  731                       (s.flags() & (STATIC | FINAL)) != 0);
  732           }
  733   
  734       /**
  735        * Check that vararg method call is sound
  736        * @param pos Position to be used for error reporting.
  737        * @param argtypes Actual arguments supplied to vararg method.
  738        */
  739       void checkVararg(DiagnosticPosition pos, List<Type> argtypes, Symbol msym) {
  740           Type argtype = argtypes.last();
  741           if (!types.isReifiable(argtype) &&
  742                   (!allowSimplifiedVarargs ||
  743                   msym.attribute(syms.trustMeType.tsym) == null ||
  744                   !isTrustMeAllowedOnMethod(msym))) {
  745               warnUnchecked(pos,
  746                                 "unchecked.generic.array.creation",
  747                                 argtype);
  748           }
  749       }
  750   
  751       /**
  752        * Check that type 't' is a valid instantiation of a generic class
  753        * (see JLS 4.5)
  754        *
  755        * @param t class type to be checked
  756        * @return true if 't' is well-formed
  757        */
  758       public boolean checkValidGenericType(Type t) {
  759           return firstIncompatibleTypeArg(t) == null;
  760       }
  761       //WHERE
  762           private Type firstIncompatibleTypeArg(Type type) {
  763               List<Type> formals = type.tsym.type.allparams();
  764               List<Type> actuals = type.allparams();
  765               List<Type> args = type.getTypeArguments();
  766               List<Type> forms = type.tsym.type.getTypeArguments();
  767               ListBuffer<Type> tvars_buf = new ListBuffer<Type>();
  768   
  769               // For matching pairs of actual argument types `a' and
  770               // formal type parameters with declared bound `b' ...
  771               while (args.nonEmpty() && forms.nonEmpty()) {
  772                   // exact type arguments needs to know their
  773                   // bounds (for upper and lower bound
  774                   // calculations).  So we create new TypeVars with
  775                   // bounds substed with actuals.
  776                   tvars_buf.append(types.substBound(((TypeVar)forms.head),
  777                                                     formals,
  778                                                     actuals));
  779                   args = args.tail;
  780                   forms = forms.tail;
  781               }
  782   
  783               args = type.getTypeArguments();
  784               List<Type> tvars_cap = types.substBounds(formals,
  785                                         formals,
  786                                         types.capture(type).allparams());
  787               while (args.nonEmpty() && tvars_cap.nonEmpty()) {
  788                   // Let the actual arguments know their bound
  789                   args.head.withTypeVar((TypeVar)tvars_cap.head);
  790                   args = args.tail;
  791                   tvars_cap = tvars_cap.tail;
  792               }
  793   
  794               args = type.getTypeArguments();
  795               List<Type> tvars = tvars_buf.toList();
  796   
  797               while (args.nonEmpty() && tvars.nonEmpty()) {
  798                   Type actual = types.subst(args.head,
  799                       type.tsym.type.getTypeArguments(),
  800                       tvars_buf.toList());
  801                   if (!isTypeArgErroneous(actual) &&
  802                           !tvars.head.getUpperBound().isErroneous() &&
  803                           !checkExtends(actual, (TypeVar)tvars.head)) {
  804                       return args.head;
  805                   }
  806                   args = args.tail;
  807                   tvars = tvars.tail;
  808               }
  809   
  810               args = type.getTypeArguments();
  811               tvars = tvars_buf.toList();
  812   
  813               for (Type arg : types.capture(type).getTypeArguments()) {
  814                   if (arg.tag == TYPEVAR &&
  815                           arg.getUpperBound().isErroneous() &&
  816                           !tvars.head.getUpperBound().isErroneous() &&
  817                           !isTypeArgErroneous(args.head)) {
  818                       return args.head;
  819                   }
  820                   tvars = tvars.tail;
  821                   args = args.tail;
  822               }
  823   
  824               return null;
  825           }
  826           //where
  827           boolean isTypeArgErroneous(Type t) {
  828               return isTypeArgErroneous.visit(t);
  829           }
  830   
  831           Types.UnaryVisitor<Boolean> isTypeArgErroneous = new Types.UnaryVisitor<Boolean>() {
  832               public Boolean visitType(Type t, Void s) {
  833                   return t.isErroneous();
  834               }
  835               @Override
  836               public Boolean visitTypeVar(TypeVar t, Void s) {
  837                   return visit(t.getUpperBound());
  838               }
  839               @Override
  840               public Boolean visitCapturedType(CapturedType t, Void s) {
  841                   return visit(t.getUpperBound()) ||
  842                           visit(t.getLowerBound());
  843               }
  844               @Override
  845               public Boolean visitWildcardType(WildcardType t, Void s) {
  846                   return visit(t.type);
  847               }
  848           };
  849   
  850       /** Check that given modifiers are legal for given symbol and
  851        *  return modifiers together with any implicit modififiers for that symbol.
  852        *  Warning: we can't use flags() here since this method
  853        *  is called during class enter, when flags() would cause a premature
  854        *  completion.
  855        *  @param pos           Position to be used for error reporting.
  856        *  @param flags         The set of modifiers given in a definition.
  857        *  @param sym           The defined symbol.
  858        */
  859       long checkFlags(DiagnosticPosition pos, long flags, Symbol sym, JCTree tree) {
  860           long mask;
  861           long implicit = 0;
  862           switch (sym.kind) {
  863           case VAR:
  864               if (sym.owner.kind != TYP)
  865                   mask = LocalVarFlags;
  866               else if ((sym.owner.flags_field & INTERFACE) != 0)
  867                   mask = implicit = InterfaceVarFlags;
  868               else
  869                   mask = VarFlags;
  870               break;
  871           case MTH:
  872               if (sym.name == names.init) {
  873                   if ((sym.owner.flags_field & ENUM) != 0) {
  874                       // enum constructors cannot be declared public or
  875                       // protected and must be implicitly or explicitly
  876                       // private
  877                       implicit = PRIVATE;
  878                       mask = PRIVATE;
  879                   } else
  880                       mask = ConstructorFlags;
  881               }  else if ((sym.owner.flags_field & INTERFACE) != 0)
  882                   mask = implicit = InterfaceMethodFlags;
  883               else {
  884                   mask = MethodFlags;
  885               }
  886               // Imply STRICTFP if owner has STRICTFP set.
  887               if (((flags|implicit) & Flags.ABSTRACT) == 0)
  888                 implicit |= sym.owner.flags_field & STRICTFP;
  889               break;
  890           case TYP:
  891               if (sym.isLocal()) {
  892                   mask = LocalClassFlags;
  893                   if (sym.name.isEmpty()) { // Anonymous class
  894                       // Anonymous classes in static methods are themselves static;
  895                       // that's why we admit STATIC here.
  896                       mask |= STATIC;
  897                       // JLS: Anonymous classes are final.
  898                       implicit |= FINAL;
  899                   }
  900                   if ((sym.owner.flags_field & STATIC) == 0 &&
  901                       (flags & ENUM) != 0)
  902                       log.error(pos, "enums.must.be.static");
  903               } else if (sym.owner.kind == TYP) {
  904                   mask = MemberClassFlags;
  905                   if (sym.owner.owner.kind == PCK ||
  906                       (sym.owner.flags_field & STATIC) != 0)
  907                       mask |= STATIC;
  908                   else if ((flags & ENUM) != 0)
  909                       log.error(pos, "enums.must.be.static");
  910                   // Nested interfaces and enums are always STATIC (Spec ???)
  911                   if ((flags & (INTERFACE | ENUM)) != 0 ) implicit = STATIC;
  912               } else {
  913                   mask = ClassFlags;
  914               }
  915               // Interfaces are always ABSTRACT
  916               if ((flags & INTERFACE) != 0) implicit |= ABSTRACT;
  917   
  918               if ((flags & ENUM) != 0) {
  919                   // enums can't be declared abstract or final
  920                   mask &= ~(ABSTRACT | FINAL);
  921                   implicit |= implicitEnumFinalFlag(tree);
  922               }
  923               // Imply STRICTFP if owner has STRICTFP set.
  924               implicit |= sym.owner.flags_field & STRICTFP;
  925               break;
  926           default:
  927               throw new AssertionError();
  928           }
  929           long illegal = flags & StandardFlags & ~mask;
  930           if (illegal != 0) {
  931               if ((illegal & INTERFACE) != 0) {
  932                   log.error(pos, "intf.not.allowed.here");
  933                   mask |= INTERFACE;
  934               }
  935               else {
  936                   log.error(pos,
  937                             "mod.not.allowed.here", asFlagSet(illegal));
  938               }
  939           }
  940           else if ((sym.kind == TYP ||
  941                     // ISSUE: Disallowing abstract&private is no longer appropriate
  942                     // in the presence of inner classes. Should it be deleted here?
  943                     checkDisjoint(pos, flags,
  944                                   ABSTRACT,
  945                                   PRIVATE | STATIC))
  946                    &&
  947                    checkDisjoint(pos, flags,
  948                                  ABSTRACT | INTERFACE,
  949                                  FINAL | NATIVE | SYNCHRONIZED)
  950                    &&
  951                    checkDisjoint(pos, flags,
  952                                  PUBLIC,
  953                                  PRIVATE | PROTECTED)
  954                    &&
  955                    checkDisjoint(pos, flags,
  956                                  PRIVATE,
  957                                  PUBLIC | PROTECTED)
  958                    &&
  959                    checkDisjoint(pos, flags,
  960                                  FINAL,
  961                                  VOLATILE)
  962                    &&
  963                    (sym.kind == TYP ||
  964                     checkDisjoint(pos, flags,
  965                                   ABSTRACT | NATIVE,
  966                                   STRICTFP))) {
  967               // skip
  968           }
  969           return flags & (mask | ~StandardFlags) | implicit;
  970       }
  971   
  972   
  973       /** Determine if this enum should be implicitly final.
  974        *
  975        *  If the enum has no specialized enum contants, it is final.
  976        *
  977        *  If the enum does have specialized enum contants, it is
  978        *  <i>not</i> final.
  979        */
  980       private long implicitEnumFinalFlag(JCTree tree) {
  981           if (tree.getTag() != JCTree.CLASSDEF) return 0;
  982           class SpecialTreeVisitor extends JCTree.Visitor {
  983               boolean specialized;
  984               SpecialTreeVisitor() {
  985                   this.specialized = false;
  986               };
  987   
  988               @Override
  989               public void visitTree(JCTree tree) { /* no-op */ }
  990   
  991               @Override
  992               public void visitVarDef(JCVariableDecl tree) {
  993                   if ((tree.mods.flags & ENUM) != 0) {
  994                       if (tree.init instanceof JCNewClass &&
  995                           ((JCNewClass) tree.init).def != null) {
  996                           specialized = true;
  997                       }
  998                   }
  999               }
 1000           }
 1001   
 1002           SpecialTreeVisitor sts = new SpecialTreeVisitor();
 1003           JCClassDecl cdef = (JCClassDecl) tree;
 1004           for (JCTree defs: cdef.defs) {
 1005               defs.accept(sts);
 1006               if (sts.specialized) return 0;
 1007           }
 1008           return FINAL;
 1009       }
 1010   
 1011   /* *************************************************************************
 1012    * Type Validation
 1013    **************************************************************************/
 1014   
 1015       /** Validate a type expression. That is,
 1016        *  check that all type arguments of a parametric type are within
 1017        *  their bounds. This must be done in a second phase after type attributon
 1018        *  since a class might have a subclass as type parameter bound. E.g:
 1019        *
 1020        *  class B<A extends C> { ... }
 1021        *  class C extends B<C> { ... }
 1022        *
 1023        *  and we can't make sure that the bound is already attributed because
 1024        *  of possible cycles.
 1025        *
 1026        * Visitor method: Validate a type expression, if it is not null, catching
 1027        *  and reporting any completion failures.
 1028        */
 1029       void validate(JCTree tree, Env<AttrContext> env) {
 1030           validate(tree, env, true);
 1031       }
 1032       void validate(JCTree tree, Env<AttrContext> env, boolean checkRaw) {
 1033           new Validator(env).validateTree(tree, checkRaw, true);
 1034       }
 1035   
 1036       /** Visitor method: Validate a list of type expressions.
 1037        */
 1038       void validate(List<? extends JCTree> trees, Env<AttrContext> env) {
 1039           for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail)
 1040               validate(l.head, env);
 1041       }
 1042   
 1043       /** A visitor class for type validation.
 1044        */
 1045       class Validator extends JCTree.Visitor {
 1046   
 1047           boolean isOuter;
 1048           Env<AttrContext> env;
 1049   
 1050           Validator(Env<AttrContext> env) {
 1051               this.env = env;
 1052           }
 1053   
 1054           @Override
 1055           public void visitTypeArray(JCArrayTypeTree tree) {
 1056               tree.elemtype.accept(this);
 1057           }
 1058   
 1059           @Override
 1060           public void visitTypeApply(JCTypeApply tree) {
 1061               if (tree.type.tag == CLASS) {
 1062                   List<JCExpression> args = tree.arguments;
 1063                   List<Type> forms = tree.type.tsym.type.getTypeArguments();
 1064   
 1065                   Type incompatibleArg = firstIncompatibleTypeArg(tree.type);
 1066                   if (incompatibleArg != null) {
 1067                       for (JCTree arg : tree.arguments) {
 1068                           if (arg.type == incompatibleArg) {
 1069                               log.error(arg, "not.within.bounds", incompatibleArg, forms.head);
 1070                           }
 1071                           forms = forms.tail;
 1072                        }
 1073                    }
 1074   
 1075                   forms = tree.type.tsym.type.getTypeArguments();
 1076   
 1077                   boolean is_java_lang_Class = tree.type.tsym.flatName() == names.java_lang_Class;
 1078   
 1079                   // For matching pairs of actual argument types `a' and
 1080                   // formal type parameters with declared bound `b' ...
 1081                   while (args.nonEmpty() && forms.nonEmpty()) {
 1082                       validateTree(args.head,
 1083                               !(isOuter && is_java_lang_Class),
 1084                               false);
 1085                       args = args.tail;
 1086                       forms = forms.tail;
 1087                   }
 1088   
 1089                   // Check that this type is either fully parameterized, or
 1090                   // not parameterized at all.
 1091                   if (tree.type.getEnclosingType().isRaw())
 1092                       log.error(tree.pos(), "improperly.formed.type.inner.raw.param");
 1093                   if (tree.clazz.getTag() == JCTree.SELECT)
 1094                       visitSelectInternal((JCFieldAccess)tree.clazz);
 1095               }
 1096           }
 1097   
 1098           @Override
 1099           public void visitTypeParameter(JCTypeParameter tree) {
 1100               validateTrees(tree.bounds, true, isOuter);
 1101               checkClassBounds(tree.pos(), tree.type);
 1102           }
 1103   
 1104           @Override
 1105           public void visitWildcard(JCWildcard tree) {
 1106               if (tree.inner != null)
 1107                   validateTree(tree.inner, true, isOuter);
 1108           }
 1109   
 1110           @Override
 1111           public void visitSelect(JCFieldAccess tree) {
 1112               if (tree.type.tag == CLASS) {
 1113                   visitSelectInternal(tree);
 1114   
 1115                   // Check that this type is either fully parameterized, or
 1116                   // not parameterized at all.
 1117                   if (tree.selected.type.isParameterized() && tree.type.tsym.type.getTypeArguments().nonEmpty())
 1118                       log.error(tree.pos(), "improperly.formed.type.param.missing");
 1119               }
 1120           }
 1121   
 1122           public void visitSelectInternal(JCFieldAccess tree) {
 1123               if (tree.type.tsym.isStatic() &&
 1124                   tree.selected.type.isParameterized()) {
 1125                   // The enclosing type is not a class, so we are
 1126                   // looking at a static member type.  However, the
 1127                   // qualifying expression is parameterized.
 1128                   log.error(tree.pos(), "cant.select.static.class.from.param.type");
 1129               } else {
 1130                   // otherwise validate the rest of the expression
 1131                   tree.selected.accept(this);
 1132               }
 1133           }
 1134   
 1135           /** Default visitor method: do nothing.
 1136            */
 1137           @Override
 1138           public void visitTree(JCTree tree) {
 1139           }
 1140   
 1141           public void validateTree(JCTree tree, boolean checkRaw, boolean isOuter) {
 1142               try {
 1143                   if (tree != null) {
 1144                       this.isOuter = isOuter;
 1145                       tree.accept(this);
 1146                       if (checkRaw)
 1147                           checkRaw(tree, env);
 1148                   }
 1149               } catch (CompletionFailure ex) {
 1150                   completionError(tree.pos(), ex);
 1151               }
 1152           }
 1153   
 1154           public void validateTrees(List<? extends JCTree> trees, boolean checkRaw, boolean isOuter) {
 1155               for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail)
 1156                   validateTree(l.head, checkRaw, isOuter);
 1157           }
 1158   
 1159           void checkRaw(JCTree tree, Env<AttrContext> env) {
 1160               if (lint.isEnabled(LintCategory.RAW) &&
 1161                   tree.type.tag == CLASS &&
 1162                   !TreeInfo.isDiamond(tree) &&
 1163                   !env.enclClass.name.isEmpty() &&  //anonymous or intersection
 1164                   tree.type.isRaw()) {
 1165                   log.warning(LintCategory.RAW,
 1166                           tree.pos(), "raw.class.use", tree.type, tree.type.tsym.type);
 1167               }
 1168           }
 1169       }
 1170   
 1171   /* *************************************************************************
 1172    * Exception checking
 1173    **************************************************************************/
 1174   
 1175       /* The following methods treat classes as sets that contain
 1176        * the class itself and all their subclasses
 1177        */
 1178   
 1179       /** Is given type a subtype of some of the types in given list?
 1180        */
 1181       boolean subset(Type t, List<Type> ts) {
 1182           for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
 1183               if (types.isSubtype(t, l.head)) return true;
 1184           return false;
 1185       }
 1186   
 1187       /** Is given type a subtype or supertype of
 1188        *  some of the types in given list?
 1189        */
 1190       boolean intersects(Type t, List<Type> ts) {
 1191           for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
 1192               if (types.isSubtype(t, l.head) || types.isSubtype(l.head, t)) return true;
 1193           return false;
 1194       }
 1195   
 1196       /** Add type set to given type list, unless it is a subclass of some class
 1197        *  in the list.
 1198        */
 1199       List<Type> incl(Type t, List<Type> ts) {
 1200           return subset(t, ts) ? ts : excl(t, ts).prepend(t);
 1201       }
 1202   
 1203       /** Remove type set from type set list.
 1204        */
 1205       List<Type> excl(Type t, List<Type> ts) {
 1206           if (ts.isEmpty()) {
 1207               return ts;
 1208           } else {
 1209               List<Type> ts1 = excl(t, ts.tail);
 1210               if (types.isSubtype(ts.head, t)) return ts1;
 1211               else if (ts1 == ts.tail) return ts;
 1212               else return ts1.prepend(ts.head);
 1213           }
 1214       }
 1215   
 1216       /** Form the union of two type set lists.
 1217        */
 1218       List<Type> union(List<Type> ts1, List<Type> ts2) {
 1219           List<Type> ts = ts1;
 1220           for (List<Type> l = ts2; l.nonEmpty(); l = l.tail)
 1221               ts = incl(l.head, ts);
 1222           return ts;
 1223       }
 1224   
 1225       /** Form the difference of two type lists.
 1226        */
 1227       List<Type> diff(List<Type> ts1, List<Type> ts2) {
 1228           List<Type> ts = ts1;
 1229           for (List<Type> l = ts2; l.nonEmpty(); l = l.tail)
 1230               ts = excl(l.head, ts);
 1231           return ts;
 1232       }
 1233   
 1234       /** Form the intersection of two type lists.
 1235        */
 1236       public List<Type> intersect(List<Type> ts1, List<Type> ts2) {
 1237           List<Type> ts = List.nil();
 1238           for (List<Type> l = ts1; l.nonEmpty(); l = l.tail)
 1239               if (subset(l.head, ts2)) ts = incl(l.head, ts);
 1240           for (List<Type> l = ts2; l.nonEmpty(); l = l.tail)
 1241               if (subset(l.head, ts1)) ts = incl(l.head, ts);
 1242           return ts;
 1243       }
 1244   
 1245       /** Is exc an exception symbol that need not be declared?
 1246        */
 1247       boolean isUnchecked(ClassSymbol exc) {
 1248           return
 1249               exc.kind == ERR ||
 1250               exc.isSubClass(syms.errorType.tsym, types) ||
 1251               exc.isSubClass(syms.runtimeExceptionType.tsym, types);
 1252       }
 1253   
 1254       /** Is exc an exception type that need not be declared?
 1255        */
 1256       boolean isUnchecked(Type exc) {
 1257           return
 1258               (exc.tag == TYPEVAR) ? isUnchecked(types.supertype(exc)) :
 1259               (exc.tag == CLASS) ? isUnchecked((ClassSymbol)exc.tsym) :
 1260               exc.tag == BOT;
 1261       }
 1262   
 1263       /** Same, but handling completion failures.
 1264        */
 1265       boolean isUnchecked(DiagnosticPosition pos, Type exc) {
 1266           try {
 1267               return isUnchecked(exc);
 1268           } catch (CompletionFailure ex) {
 1269               completionError(pos, ex);
 1270               return true;
 1271           }
 1272       }
 1273   
 1274       /** Is exc handled by given exception list?
 1275        */
 1276       boolean isHandled(Type exc, List<Type> handled) {
 1277           return isUnchecked(exc) || subset(exc, handled);
 1278       }
 1279   
 1280       /** Return all exceptions in thrown list that are not in handled list.
 1281        *  @param thrown     The list of thrown exceptions.
 1282        *  @param handled    The list of handled exceptions.
 1283        */
 1284       List<Type> unhandled(List<Type> thrown, List<Type> handled) {
 1285           List<Type> unhandled = List.nil();
 1286           for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
 1287               if (!isHandled(l.head, handled)) unhandled = unhandled.prepend(l.head);
 1288           return unhandled;
 1289       }
 1290   
 1291   /* *************************************************************************
 1292    * Overriding/Implementation checking
 1293    **************************************************************************/
 1294   
 1295       /** The level of access protection given by a flag set,
 1296        *  where PRIVATE is highest and PUBLIC is lowest.
 1297        */
 1298       static int protection(long flags) {
 1299           switch ((short)(flags & AccessFlags)) {
 1300           case PRIVATE: return 3;
 1301           case PROTECTED: return 1;
 1302           default:
 1303           case PUBLIC: return 0;
 1304           case 0: return 2;
 1305           }
 1306       }
 1307   
 1308       /** A customized "cannot override" error message.
 1309        *  @param m      The overriding method.
 1310        *  @param other  The overridden method.
 1311        *  @return       An internationalized string.
 1312        */
 1313       Object cannotOverride(MethodSymbol m, MethodSymbol other) {
 1314           String key;
 1315           if ((other.owner.flags() & INTERFACE) == 0)
 1316               key = "cant.override";
 1317           else if ((m.owner.flags() & INTERFACE) == 0)
 1318               key = "cant.implement";
 1319           else
 1320               key = "clashes.with";
 1321           return diags.fragment(key, m, m.location(), other, other.location());
 1322       }
 1323   
 1324       /** A customized "override" warning message.
 1325        *  @param m      The overriding method.
 1326        *  @param other  The overridden method.
 1327        *  @return       An internationalized string.
 1328        */
 1329       Object uncheckedOverrides(MethodSymbol m, MethodSymbol other) {
 1330           String key;
 1331           if ((other.owner.flags() & INTERFACE) == 0)
 1332               key = "unchecked.override";
 1333           else if ((m.owner.flags() & INTERFACE) == 0)
 1334               key = "unchecked.implement";
 1335           else
 1336               key = "unchecked.clash.with";
 1337           return diags.fragment(key, m, m.location(), other, other.location());
 1338       }
 1339   
 1340       /** A customized "override" warning message.
 1341        *  @param m      The overriding method.
 1342        *  @param other  The overridden method.
 1343        *  @return       An internationalized string.
 1344        */
 1345       Object varargsOverrides(MethodSymbol m, MethodSymbol other) {
 1346           String key;
 1347           if ((other.owner.flags() & INTERFACE) == 0)
 1348               key = "varargs.override";
 1349           else  if ((m.owner.flags() & INTERFACE) == 0)
 1350               key = "varargs.implement";
 1351           else
 1352               key = "varargs.clash.with";
 1353           return diags.fragment(key, m, m.location(), other, other.location());
 1354       }
 1355   
 1356       /** Check that this method conforms with overridden method 'other'.
 1357        *  where `origin' is the class where checking started.
 1358        *  Complications:
 1359        *  (1) Do not check overriding of synthetic methods
 1360        *      (reason: they might be final).
 1361        *      todo: check whether this is still necessary.
 1362        *  (2) Admit the case where an interface proxy throws fewer exceptions
 1363        *      than the method it implements. Augment the proxy methods with the
 1364        *      undeclared exceptions in this case.
 1365        *  (3) When generics are enabled, admit the case where an interface proxy
 1366        *      has a result type
 1367        *      extended by the result type of the method it implements.
 1368        *      Change the proxies result type to the smaller type in this case.
 1369        *
 1370        *  @param tree         The tree from which positions
 1371        *                      are extracted for errors.
 1372        *  @param m            The overriding method.
 1373        *  @param other        The overridden method.
 1374        *  @param origin       The class of which the overriding method
 1375        *                      is a member.
 1376        */
 1377       void checkOverride(JCTree tree,
 1378                          MethodSymbol m,
 1379                          MethodSymbol other,
 1380                          ClassSymbol origin) {
 1381           // Don't check overriding of synthetic methods or by bridge methods.
 1382           if ((m.flags() & (SYNTHETIC|BRIDGE)) != 0 || (other.flags() & SYNTHETIC) != 0) {
 1383               return;
 1384           }
 1385   
 1386           // Error if static method overrides instance method (JLS 8.4.6.2).
 1387           if ((m.flags() & STATIC) != 0 &&
 1388                      (other.flags() & STATIC) == 0) {
 1389               log.error(TreeInfo.diagnosticPositionFor(m, tree), "override.static",
 1390                         cannotOverride(m, other));
 1391               return;
 1392           }
 1393   
 1394           // Error if instance method overrides static or final
 1395           // method (JLS 8.4.6.1).
 1396           if ((other.flags() & FINAL) != 0 ||
 1397                    (m.flags() & STATIC) == 0 &&
 1398                    (other.flags() & STATIC) != 0) {
 1399               log.error(TreeInfo.diagnosticPositionFor(m, tree), "override.meth",
 1400                         cannotOverride(m, other),
 1401                         asFlagSet(other.flags() & (FINAL | STATIC)));
 1402               return;
 1403           }
 1404   
 1405           if ((m.owner.flags() & ANNOTATION) != 0) {
 1406               // handled in validateAnnotationMethod
 1407               return;
 1408           }
 1409   
 1410           // Error if overriding method has weaker access (JLS 8.4.6.3).
 1411           if ((origin.flags() & INTERFACE) == 0 &&
 1412                    protection(m.flags()) > protection(other.flags())) {
 1413               log.error(TreeInfo.diagnosticPositionFor(m, tree), "override.weaker.access",
 1414                         cannotOverride(m, other),
 1415                         other.flags() == 0 ?
 1416                             Flag.PACKAGE :
 1417                             asFlagSet(other.flags() & AccessFlags));
 1418               return;
 1419           }
 1420   
 1421           Type mt = types.memberType(origin.type, m);
 1422           Type ot = types.memberType(origin.type, other);
 1423           // Error if overriding result type is different
 1424           // (or, in the case of generics mode, not a subtype) of
 1425           // overridden result type. We have to rename any type parameters
 1426           // before comparing types.
 1427           List<Type> mtvars = mt.getTypeArguments();
 1428           List<Type> otvars = ot.getTypeArguments();
 1429           Type mtres = mt.getReturnType();
 1430           Type otres = types.subst(ot.getReturnType(), otvars, mtvars);
 1431   
 1432           overrideWarner.clear();
 1433           boolean resultTypesOK =
 1434               types.returnTypeSubstitutable(mt, ot, otres, overrideWarner);
 1435           if (!resultTypesOK) {
 1436               if (!allowCovariantReturns &&
 1437                   m.owner != origin &&
 1438                   m.owner.isSubClass(other.owner, types)) {
 1439                   // allow limited interoperability with covariant returns
 1440               } else {
 1441                   log.error(TreeInfo.diagnosticPositionFor(m, tree),
 1442                             "override.incompatible.ret",
 1443                             cannotOverride(m, other),
 1444                             mtres, otres);
 1445                   return;
 1446               }
 1447           } else if (overrideWarner.hasNonSilentLint(LintCategory.UNCHECKED)) {
 1448               warnUnchecked(TreeInfo.diagnosticPositionFor(m, tree),
 1449                       "override.unchecked.ret",
 1450                       uncheckedOverrides(m, other),
 1451                       mtres, otres);
 1452           }
 1453   
 1454           // Error if overriding method throws an exception not reported
 1455           // by overridden method.
 1456           List<Type> otthrown = types.subst(ot.getThrownTypes(), otvars, mtvars);
 1457           List<Type> unhandledErased = unhandled(mt.getThrownTypes(), types.erasure(otthrown));
 1458           List<Type> unhandledUnerased = unhandled(mt.getThrownTypes(), otthrown);
 1459           if (unhandledErased.nonEmpty()) {
 1460               log.error(TreeInfo.diagnosticPositionFor(m, tree),
 1461                         "override.meth.doesnt.throw",
 1462                         cannotOverride(m, other),
 1463                         unhandledUnerased.head);
 1464               return;
 1465           }
 1466           else if (unhandledUnerased.nonEmpty()) {
 1467               warnUnchecked(TreeInfo.diagnosticPositionFor(m, tree),
 1468                             "override.unchecked.thrown",
 1469                            cannotOverride(m, other),
 1470                            unhandledUnerased.head);
 1471               return;
 1472           }
 1473   
 1474           // Optional warning if varargs don't agree
 1475           if ((((m.flags() ^ other.flags()) & Flags.VARARGS) != 0)
 1476               && lint.isEnabled(LintCategory.OVERRIDES)) {
 1477               log.warning(TreeInfo.diagnosticPositionFor(m, tree),
 1478                           ((m.flags() & Flags.VARARGS) != 0)
 1479                           ? "override.varargs.missing"
 1480                           : "override.varargs.extra",
 1481                           varargsOverrides(m, other));
 1482           }
 1483   
 1484           // Warn if instance method overrides bridge method (compiler spec ??)
 1485           if ((other.flags() & BRIDGE) != 0) {
 1486               log.warning(TreeInfo.diagnosticPositionFor(m, tree), "override.bridge",
 1487                           uncheckedOverrides(m, other));
 1488           }
 1489   
 1490           // Warn if a deprecated method overridden by a non-deprecated one.
 1491           if (!isDeprecatedOverrideIgnorable(other, origin)) {
 1492               checkDeprecated(TreeInfo.diagnosticPositionFor(m, tree), m, other);
 1493           }
 1494       }
 1495       // where
 1496           private boolean isDeprecatedOverrideIgnorable(MethodSymbol m, ClassSymbol origin) {
 1497               // If the method, m, is defined in an interface, then ignore the issue if the method
 1498               // is only inherited via a supertype and also implemented in the supertype,
 1499               // because in that case, we will rediscover the issue when examining the method
 1500               // in the supertype.
 1501               // If the method, m, is not defined in an interface, then the only time we need to
 1502               // address the issue is when the method is the supertype implemementation: any other
 1503               // case, we will have dealt with when examining the supertype classes
 1504               ClassSymbol mc = m.enclClass();
 1505               Type st = types.supertype(origin.type);
 1506               if (st.tag != CLASS)
 1507                   return true;
 1508               MethodSymbol stimpl = m.implementation((ClassSymbol)st.tsym, types, false);
 1509   
 1510               if (mc != null && ((mc.flags() & INTERFACE) != 0)) {
 1511                   List<Type> intfs = types.interfaces(origin.type);
 1512                   return (intfs.contains(mc.type) ? false : (stimpl != null));
 1513               }
 1514               else
 1515                   return (stimpl != m);
 1516           }
 1517   
 1518   
 1519       // used to check if there were any unchecked conversions
 1520       Warner overrideWarner = new Warner();
 1521   
 1522       /** Check that a class does not inherit two concrete methods
 1523        *  with the same signature.
 1524        *  @param pos          Position to be used for error reporting.
 1525        *  @param site         The class type to be checked.
 1526        */
 1527       public void checkCompatibleConcretes(DiagnosticPosition pos, Type site) {
 1528           Type sup = types.supertype(site);
 1529           if (sup.tag != CLASS) return;
 1530   
 1531           for (Type t1 = sup;
 1532                t1.tsym.type.isParameterized();
 1533                t1 = types.supertype(t1)) {
 1534               for (Scope.Entry e1 = t1.tsym.members().elems;
 1535                    e1 != null;
 1536                    e1 = e1.sibling) {
 1537                   Symbol s1 = e1.sym;
 1538                   if (s1.kind != MTH ||
 1539                       (s1.flags() & (STATIC|SYNTHETIC|BRIDGE)) != 0 ||
 1540                       !s1.isInheritedIn(site.tsym, types) ||
 1541                       ((MethodSymbol)s1).implementation(site.tsym,
 1542                                                         types,
 1543                                                         true) != s1)
 1544                       continue;
 1545                   Type st1 = types.memberType(t1, s1);
 1546                   int s1ArgsLength = st1.getParameterTypes().length();
 1547                   if (st1 == s1.type) continue;
 1548   
 1549                   for (Type t2 = sup;
 1550                        t2.tag == CLASS;
 1551                        t2 = types.supertype(t2)) {
 1552                       for (Scope.Entry e2 = t2.tsym.members().lookup(s1.name);
 1553                            e2.scope != null;
 1554                            e2 = e2.next()) {
 1555                           Symbol s2 = e2.sym;
 1556                           if (s2 == s1 ||
 1557                               s2.kind != MTH ||
 1558                               (s2.flags() & (STATIC|SYNTHETIC|BRIDGE)) != 0 ||
 1559                               s2.type.getParameterTypes().length() != s1ArgsLength ||
 1560                               !s2.isInheritedIn(site.tsym, types) ||
 1561                               ((MethodSymbol)s2).implementation(site.tsym,
 1562                                                                 types,
 1563                                                                 true) != s2)
 1564                               continue;
 1565                           Type st2 = types.memberType(t2, s2);
 1566                           if (types.overrideEquivalent(st1, st2))
 1567                               log.error(pos, "concrete.inheritance.conflict",
 1568                                         s1, t1, s2, t2, sup);
 1569                       }
 1570                   }
 1571               }
 1572           }
 1573       }
 1574   
 1575       /** Check that classes (or interfaces) do not each define an abstract
 1576        *  method with same name and arguments but incompatible return types.
 1577        *  @param pos          Position to be used for error reporting.
 1578        *  @param t1           The first argument type.
 1579        *  @param t2           The second argument type.
 1580        */
 1581       public boolean checkCompatibleAbstracts(DiagnosticPosition pos,
 1582                                               Type t1,
 1583                                               Type t2) {
 1584           return checkCompatibleAbstracts(pos, t1, t2,
 1585                                           types.makeCompoundType(t1, t2));
 1586       }
 1587   
 1588       public boolean checkCompatibleAbstracts(DiagnosticPosition pos,
 1589                                               Type t1,
 1590                                               Type t2,
 1591                                               Type site) {
 1592           return firstIncompatibility(pos, t1, t2, site) == null;
 1593       }
 1594   
 1595       /** Return the first method which is defined with same args
 1596        *  but different return types in two given interfaces, or null if none
 1597        *  exists.
 1598        *  @param t1     The first type.
 1599        *  @param t2     The second type.
 1600        *  @param site   The most derived type.
 1601        *  @returns symbol from t2 that conflicts with one in t1.
 1602        */
 1603       private Symbol firstIncompatibility(DiagnosticPosition pos, Type t1, Type t2, Type site) {
 1604           Map<TypeSymbol,Type> interfaces1 = new HashMap<TypeSymbol,Type>();
 1605           closure(t1, interfaces1);
 1606           Map<TypeSymbol,Type> interfaces2;
 1607           if (t1 == t2)
 1608               interfaces2 = interfaces1;
 1609           else
 1610               closure(t2, interfaces1, interfaces2 = new HashMap<TypeSymbol,Type>());
 1611   
 1612           for (Type t3 : interfaces1.values()) {
 1613               for (Type t4 : interfaces2.values()) {
 1614                   Symbol s = firstDirectIncompatibility(pos, t3, t4, site);
 1615                   if (s != null) return s;
 1616               }
 1617           }
 1618           return null;
 1619       }
 1620   
 1621       /** Compute all the supertypes of t, indexed by type symbol. */
 1622       private void closure(Type t, Map<TypeSymbol,Type> typeMap) {
 1623           if (t.tag != CLASS) return;
 1624           if (typeMap.put(t.tsym, t) == null) {
 1625               closure(types.supertype(t), typeMap);
 1626               for (Type i : types.interfaces(t))
 1627                   closure(i, typeMap);
 1628           }
 1629       }
 1630   
 1631       /** Compute all the supertypes of t, indexed by type symbol (except thise in typesSkip). */
 1632       private void closure(Type t, Map<TypeSymbol,Type> typesSkip, Map<TypeSymbol,Type> typeMap) {
 1633           if (t.tag != CLASS) return;
 1634           if (typesSkip.get(t.tsym) != null) return;
 1635           if (typeMap.put(t.tsym, t) == null) {
 1636               closure(types.supertype(t), typesSkip, typeMap);
 1637               for (Type i : types.interfaces(t))
 1638                   closure(i, typesSkip, typeMap);
 1639           }
 1640       }
 1641   
 1642       /** Return the first method in t2 that conflicts with a method from t1. */
 1643       private Symbol firstDirectIncompatibility(DiagnosticPosition pos, Type t1, Type t2, Type site) {
 1644           for (Scope.Entry e1 = t1.tsym.members().elems; e1 != null; e1 = e1.sibling) {
 1645               Symbol s1 = e1.sym;
 1646               Type st1 = null;
 1647               if (s1.kind != MTH || !s1.isInheritedIn(site.tsym, types)) continue;
 1648               Symbol impl = ((MethodSymbol)s1).implementation(site.tsym, types, false);
 1649               if (impl != null && (impl.flags() & ABSTRACT) == 0) continue;
 1650               for (Scope.Entry e2 = t2.tsym.members().lookup(s1.name); e2.scope != null; e2 = e2.next()) {
 1651                   Symbol s2 = e2.sym;
 1652                   if (s1 == s2) continue;
 1653                   if (s2.kind != MTH || !s2.isInheritedIn(site.tsym, types)) continue;
 1654                   if (st1 == null) st1 = types.memberType(t1, s1);
 1655                   Type st2 = types.memberType(t2, s2);
 1656                   if (types.overrideEquivalent(st1, st2)) {
 1657                       List<Type> tvars1 = st1.getTypeArguments();
 1658                       List<Type> tvars2 = st2.getTypeArguments();
 1659                       Type rt1 = st1.getReturnType();
 1660                       Type rt2 = types.subst(st2.getReturnType(), tvars2, tvars1);
 1661                       boolean compat =
 1662                           types.isSameType(rt1, rt2) ||
 1663                           rt1.tag >= CLASS && rt2.tag >= CLASS &&
 1664                           (types.covariantReturnType(rt1, rt2, Warner.noWarnings) ||
 1665                            types.covariantReturnType(rt2, rt1, Warner.noWarnings)) ||
 1666                            checkCommonOverriderIn(s1,s2,site);
 1667                       if (!compat) {
 1668                           log.error(pos, "types.incompatible.diff.ret",
 1669                               t1, t2, s2.name +
 1670                               "(" + types.memberType(t2, s2).getParameterTypes() + ")");
 1671                           return s2;
 1672                       }
 1673                   } else if (checkNameClash((ClassSymbol)site.tsym, s1, s2) &&
 1674                           !checkCommonOverriderIn(s1, s2, site)) {
 1675                       log.error(pos,
 1676                               "name.clash.same.erasure.no.override",
 1677                               s1, s1.location(),
 1678                               s2, s2.location());
 1679                       return s2;
 1680                   }
 1681               }
 1682           }
 1683           return null;
 1684       }
 1685       //WHERE
 1686       boolean checkCommonOverriderIn(Symbol s1, Symbol s2, Type site) {
 1687           Map<TypeSymbol,Type> supertypes = new HashMap<TypeSymbol,Type>();
 1688           Type st1 = types.memberType(site, s1);
 1689           Type st2 = types.memberType(site, s2);
 1690           closure(site, supertypes);
 1691           for (Type t : supertypes.values()) {
 1692               for (Scope.Entry e = t.tsym.members().lookup(s1.name); e.scope != null; e = e.next()) {
 1693                   Symbol s3 = e.sym;
 1694                   if (s3 == s1 || s3 == s2 || s3.kind != MTH || (s3.flags() & (BRIDGE|SYNTHETIC)) != 0) continue;
 1695                   Type st3 = types.memberType(site,s3);
 1696                   if (types.overrideEquivalent(st3, st1) && types.overrideEquivalent(st3, st2)) {
 1697                       if (s3.owner == site.tsym) {
 1698                           return true;
 1699                       }
 1700                       List<Type> tvars1 = st1.getTypeArguments();
 1701                       List<Type> tvars2 = st2.getTypeArguments();
 1702                       List<Type> tvars3 = st3.getTypeArguments();
 1703                       Type rt1 = st1.getReturnType();
 1704                       Type rt2 = st2.getReturnType();
 1705                       Type rt13 = types.subst(st3.getReturnType(), tvars3, tvars1);
 1706                       Type rt23 = types.subst(st3.getReturnType(), tvars3, tvars2);
 1707                       boolean compat =
 1708                           rt13.tag >= CLASS && rt23.tag >= CLASS &&
 1709                           (types.covariantReturnType(rt13, rt1, Warner.noWarnings) &&
 1710                            types.covariantReturnType(rt23, rt2, Warner.noWarnings));
 1711                       if (compat)
 1712                           return true;
 1713                   }
 1714               }
 1715           }
 1716           return false;
 1717       }
 1718   
 1719       /** Check that a given method conforms with any method it overrides.
 1720        *  @param tree         The tree from which positions are extracted
 1721        *                      for errors.
 1722        *  @param m            The overriding method.
 1723        */
 1724       void checkOverride(JCTree tree, MethodSymbol m) {
 1725           ClassSymbol origin = (ClassSymbol)m.owner;
 1726           if ((origin.flags() & ENUM) != 0 && names.finalize.equals(m.name))
 1727               if (m.overrides(syms.enumFinalFinalize, origin, types, false)) {
 1728                   log.error(tree.pos(), "enum.no.finalize");
 1729                   return;
 1730               }
 1731           for (Type t = origin.type; t.tag == CLASS;
 1732                t = types.supertype(t)) {
 1733               if (t != origin.type) {
 1734                   checkOverride(tree, t, origin, m);
 1735               }
 1736               for (Type t2 : types.interfaces(t)) {
 1737                   checkOverride(tree, t2, origin, m);
 1738               }
 1739           }
 1740       }
 1741   
 1742       void checkOverride(JCTree tree, Type site, ClassSymbol origin, MethodSymbol m) {
 1743           TypeSymbol c = site.tsym;
 1744           Scope.Entry e = c.members().lookup(m.name);
 1745           while (e.scope != null) {
 1746               if (m.overrides(e.sym, origin, types, false)) {
 1747                   if ((e.sym.flags() & ABSTRACT) == 0) {
 1748                       checkOverride(tree, m, (MethodSymbol)e.sym, origin);
 1749                   }
 1750               }
 1751               e = e.next();
 1752           }
 1753       }
 1754   
 1755       private boolean checkNameClash(ClassSymbol origin, Symbol s1, Symbol s2) {
 1756           ClashFilter cf = new ClashFilter(origin.type);
 1757           return (cf.accepts(s1) &&
 1758                   cf.accepts(s2) &&
 1759                   types.hasSameArgs(s1.erasure(types), s2.erasure(types)));
 1760       }
 1761   
 1762   
 1763       /** Check that all abstract members of given class have definitions.
 1764        *  @param pos          Position to be used for error reporting.
 1765        *  @param c            The class.
 1766        */
 1767       void checkAllDefined(DiagnosticPosition pos, ClassSymbol c) {
 1768           try {
 1769               MethodSymbol undef = firstUndef(c, c);
 1770               if (undef != null) {
 1771                   if ((c.flags() & ENUM) != 0 &&
 1772                       types.supertype(c.type).tsym == syms.enumSym &&
 1773                       (c.flags() & FINAL) == 0) {
 1774                       // add the ABSTRACT flag to an enum
 1775                       c.flags_field |= ABSTRACT;
 1776                   } else {
 1777                       MethodSymbol undef1 =
 1778                           new MethodSymbol(undef.flags(), undef.name,
 1779                                            types.memberType(c.type, undef), undef.owner);
 1780                       log.error(pos, "does.not.override.abstract",
 1781                                 c, undef1, undef1.location());
 1782                   }
 1783               }
 1784           } catch (CompletionFailure ex) {
 1785               completionError(pos, ex);
 1786           }
 1787       }
 1788   //where
 1789           /** Return first abstract member of class `c' that is not defined
 1790            *  in `impl', null if there is none.
 1791            */
 1792           private MethodSymbol firstUndef(ClassSymbol impl, ClassSymbol c) {
 1793               MethodSymbol undef = null;
 1794               // Do not bother to search in classes that are not abstract,
 1795               // since they cannot have abstract members.
 1796               if (c == impl || (c.flags() & (ABSTRACT | INTERFACE)) != 0) {
 1797                   Scope s = c.members();
 1798                   for (Scope.Entry e = s.elems;
 1799                        undef == null && e != null;
 1800                        e = e.sibling) {
 1801                       if (e.sym.kind == MTH &&
 1802                           (e.sym.flags() & (ABSTRACT|IPROXY)) == ABSTRACT) {
 1803                           MethodSymbol absmeth = (MethodSymbol)e.sym;
 1804                           MethodSymbol implmeth = absmeth.implementation(impl, types, true);
 1805                           if (implmeth == null || implmeth == absmeth)
 1806                               undef = absmeth;
 1807                       }
 1808                   }
 1809                   if (undef == null) {
 1810                       Type st = types.supertype(c.type);
 1811                       if (st.tag == CLASS)
 1812                           undef = firstUndef(impl, (ClassSymbol)st.tsym);
 1813                   }
 1814                   for (List<Type> l = types.interfaces(c.type);
 1815                        undef == null && l.nonEmpty();
 1816                        l = l.tail) {
 1817                       undef = firstUndef(impl, (ClassSymbol)l.head.tsym);
 1818                   }
 1819               }
 1820               return undef;
 1821           }
 1822   
 1823       void checkNonCyclicDecl(JCClassDecl tree) {
 1824           CycleChecker cc = new CycleChecker();
 1825           cc.scan(tree);
 1826           if (!cc.errorFound && !cc.partialCheck) {
 1827               tree.sym.flags_field |= ACYCLIC;
 1828           }
 1829       }
 1830   
 1831       class CycleChecker extends TreeScanner {
 1832   
 1833           List<Symbol> seenClasses = List.nil();
 1834           boolean errorFound = false;
 1835           boolean partialCheck = false;
 1836   
 1837           private void checkSymbol(DiagnosticPosition pos, Symbol sym) {
 1838               if (sym != null && sym.kind == TYP) {
 1839                   Env<AttrContext> classEnv = enter.getEnv((TypeSymbol)sym);
 1840                   if (classEnv != null) {
 1841                       DiagnosticSource prevSource = log.currentSource();
 1842                       try {
 1843                           log.useSource(classEnv.toplevel.sourcefile);
 1844                           scan(classEnv.tree);
 1845                       }
 1846                       finally {
 1847                           log.useSource(prevSource.getFile());
 1848                       }
 1849                   } else if (sym.kind == TYP) {
 1850                       checkClass(pos, sym, List.<JCTree>nil());
 1851                   }
 1852               } else {
 1853                   //not completed yet
 1854                   partialCheck = true;
 1855               }
 1856           }
 1857   
 1858           @Override
 1859           public void visitSelect(JCFieldAccess tree) {
 1860               super.visitSelect(tree);
 1861               checkSymbol(tree.pos(), tree.sym);
 1862           }
 1863   
 1864           @Override
 1865           public void visitIdent(JCIdent tree) {
 1866               checkSymbol(tree.pos(), tree.sym);
 1867           }
 1868   
 1869           @Override
 1870           public void visitTypeApply(JCTypeApply tree) {
 1871               scan(tree.clazz);
 1872           }
 1873   
 1874           @Override
 1875           public void visitTypeArray(JCArrayTypeTree tree) {
 1876               scan(tree.elemtype);
 1877           }
 1878   
 1879           @Override
 1880           public void visitClassDef(JCClassDecl tree) {
 1881               List<JCTree> supertypes = List.nil();
 1882               if (tree.getExtendsClause() != null) {
 1883                   supertypes = supertypes.prepend(tree.getExtendsClause());
 1884               }
 1885               if (tree.getImplementsClause() != null) {
 1886                   for (JCTree intf : tree.getImplementsClause()) {
 1887                       supertypes = supertypes.prepend(intf);
 1888                   }
 1889               }
 1890               checkClass(tree.pos(), tree.sym, supertypes);
 1891           }
 1892   
 1893           void checkClass(DiagnosticPosition pos, Symbol c, List<JCTree> supertypes) {
 1894               if ((c.flags_field & ACYCLIC) != 0)
 1895                   return;
 1896               if (seenClasses.contains(c)) {
 1897                   errorFound = true;
 1898                   noteCyclic(pos, (ClassSymbol)c);
 1899               } else if (!c.type.isErroneous()) {
 1900                   try {
 1901                       seenClasses = seenClasses.prepend(c);
 1902                       if (c.type.tag == CLASS) {
 1903                           if (supertypes.nonEmpty()) {
 1904                               scan(supertypes);
 1905                           }
 1906                           else {
 1907                               ClassType ct = (ClassType)c.type;
 1908                               if (ct.supertype_field == null ||
 1909                                       ct.interfaces_field == null) {
 1910                                   //not completed yet
 1911                                   partialCheck = true;
 1912                                   return;
 1913                               }
 1914                               checkSymbol(pos, ct.supertype_field.tsym);
 1915                               for (Type intf : ct.interfaces_field) {
 1916                                   checkSymbol(pos, intf.tsym);
 1917                               }
 1918                           }
 1919                           if (c.owner.kind == TYP) {
 1920                               checkSymbol(pos, c.owner);
 1921                           }
 1922                       }
 1923                   } finally {
 1924                       seenClasses = seenClasses.tail;
 1925                   }
 1926               }
 1927           }
 1928       }
 1929   
 1930       /** Check for cyclic references. Issue an error if the
 1931        *  symbol of the type referred to has a LOCKED flag set.
 1932        *
 1933        *  @param pos      Position to be used for error reporting.
 1934        *  @param t        The type referred to.
 1935        */
 1936       void checkNonCyclic(DiagnosticPosition pos, Type t) {
 1937           checkNonCyclicInternal(pos, t);
 1938       }
 1939   
 1940   
 1941       void checkNonCyclic(DiagnosticPosition pos, TypeVar t) {
 1942           checkNonCyclic1(pos, t, List.<TypeVar>nil());
 1943       }
 1944   
 1945       private void checkNonCyclic1(DiagnosticPosition pos, Type t, List<TypeVar> seen) {
 1946           final TypeVar tv;
 1947           if  (t.tag == TYPEVAR && (t.tsym.flags() & UNATTRIBUTED) != 0)
 1948               return;
 1949           if (seen.contains(t)) {
 1950               tv = (TypeVar)t;
 1951               tv.bound = types.createErrorType(t);
 1952               log.error(pos, "cyclic.inheritance", t);
 1953           } else if (t.tag == TYPEVAR) {
 1954               tv = (TypeVar)t;
 1955               seen = seen.prepend(tv);
 1956               for (Type b : types.getBounds(tv))
 1957                   checkNonCyclic1(pos, b, seen);
 1958           }
 1959       }
 1960   
 1961       /** Check for cyclic references. Issue an error if the
 1962        *  symbol of the type referred to has a LOCKED flag set.
 1963        *
 1964        *  @param pos      Position to be used for error reporting.
 1965        *  @param t        The type referred to.
 1966        *  @returns        True if the check completed on all attributed classes
 1967        */
 1968       private boolean checkNonCyclicInternal(DiagnosticPosition pos, Type t) {
 1969           boolean complete = true; // was the check complete?
 1970           //- System.err.println("checkNonCyclicInternal("+t+");");//DEBUG
 1971           Symbol c = t.tsym;
 1972           if ((c.flags_field & ACYCLIC) != 0) return true;
 1973   
 1974           if ((c.flags_field & LOCKED) != 0) {
 1975               noteCyclic(pos, (ClassSymbol)c);
 1976           } else if (!c.type.isErroneous()) {
 1977               try {
 1978                   c.flags_field |= LOCKED;
 1979                   if (c.type.tag == CLASS) {
 1980                       ClassType clazz = (ClassType)c.type;
 1981                       if (clazz.interfaces_field != null)
 1982                           for (List<Type> l=clazz.interfaces_field; l.nonEmpty(); l=l.tail)
 1983                               complete &= checkNonCyclicInternal(pos, l.head);
 1984                       if (clazz.supertype_field != null) {
 1985                           Type st = clazz.supertype_field;
 1986                           if (st != null && st.tag == CLASS)
 1987                               complete &= checkNonCyclicInternal(pos, st);
 1988                       }
 1989                       if (c.owner.kind == TYP)
 1990                           complete &= checkNonCyclicInternal(pos, c.owner.type);
 1991                   }
 1992               } finally {
 1993                   c.flags_field &= ~LOCKED;
 1994               }
 1995           }
 1996           if (complete)
 1997               complete = ((c.flags_field & UNATTRIBUTED) == 0) && c.completer == null;
 1998           if (complete) c.flags_field |= ACYCLIC;
 1999           return complete;
 2000       }
 2001   
 2002       /** Note that we found an inheritance cycle. */
 2003       private void noteCyclic(DiagnosticPosition pos, ClassSymbol c) {
 2004           log.error(pos, "cyclic.inheritance", c);
 2005           for (List<Type> l=types.interfaces(c.type); l.nonEmpty(); l=l.tail)
 2006               l.head = types.createErrorType((ClassSymbol)l.head.tsym, Type.noType);
 2007           Type st = types.supertype(c.type);
 2008           if (st.tag == CLASS)
 2009               ((ClassType)c.type).supertype_field = types.createErrorType((ClassSymbol)st.tsym, Type.noType);
 2010           c.type = types.createErrorType(c, c.type);
 2011           c.flags_field |= ACYCLIC;
 2012       }
 2013   
 2014       /** Check that all methods which implement some
 2015        *  method conform to the method they implement.
 2016        *  @param tree         The class definition whose members are checked.
 2017        */
 2018       void checkImplementations(JCClassDecl tree) {
 2019           checkImplementations(tree, tree.sym);
 2020       }
 2021   //where
 2022           /** Check that all methods which implement some
 2023            *  method in `ic' conform to the method they implement.
 2024            */
 2025           void checkImplementations(JCClassDecl tree, ClassSymbol ic) {
 2026               ClassSymbol origin = tree.sym;
 2027               for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) {
 2028                   ClassSymbol lc = (ClassSymbol)l.head.tsym;
 2029                   if ((allowGenerics || origin != lc) && (lc.flags() & ABSTRACT) != 0) {
 2030                       for (Scope.Entry e=lc.members().elems; e != null; e=e.sibling) {
 2031                           if (e.sym.kind == MTH &&
 2032                               (e.sym.flags() & (STATIC|ABSTRACT)) == ABSTRACT) {
 2033                               MethodSymbol absmeth = (MethodSymbol)e.sym;
 2034                               MethodSymbol implmeth = absmeth.implementation(origin, types, false);
 2035                               if (implmeth != null && implmeth != absmeth &&
 2036                                   (implmeth.owner.flags() & INTERFACE) ==
 2037                                   (origin.flags() & INTERFACE)) {
 2038                                   // don't check if implmeth is in a class, yet
 2039                                   // origin is an interface. This case arises only
 2040                                   // if implmeth is declared in Object. The reason is
 2041                                   // that interfaces really don't inherit from
 2042                                   // Object it's just that the compiler represents
 2043                                   // things that way.
 2044                                   checkOverride(tree, implmeth, absmeth, origin);
 2045                               }
 2046                           }
 2047                       }
 2048                   }
 2049               }
 2050           }
 2051   
 2052       /** Check that all abstract methods implemented by a class are
 2053        *  mutually compatible.
 2054        *  @param pos          Position to be used for error reporting.
 2055        *  @param c            The class whose interfaces are checked.
 2056        */
 2057       void checkCompatibleSupertypes(DiagnosticPosition pos, Type c) {
 2058           List<Type> supertypes = types.interfaces(c);
 2059           Type supertype = types.supertype(c);
 2060           if (supertype.tag == CLASS &&
 2061               (supertype.tsym.flags() & ABSTRACT) != 0)
 2062               supertypes = supertypes.prepend(supertype);
 2063           for (List<Type> l = supertypes; l.nonEmpty(); l = l.tail) {
 2064               if (allowGenerics && !l.head.getTypeArguments().isEmpty() &&
 2065                   !checkCompatibleAbstracts(pos, l.head, l.head, c))
 2066                   return;
 2067               for (List<Type> m = supertypes; m != l; m = m.tail)
 2068                   if (!checkCompatibleAbstracts(pos, l.head, m.head, c))
 2069                       return;
 2070           }
 2071           checkCompatibleConcretes(pos, c);
 2072       }
 2073   
 2074       void checkConflicts(DiagnosticPosition pos, Symbol sym, TypeSymbol c) {
 2075           for (Type ct = c.type; ct != Type.noType ; ct = types.supertype(ct)) {
 2076               for (Scope.Entry e = ct.tsym.members().lookup(sym.name); e.scope == ct.tsym.members(); e = e.next()) {
 2077                   // VM allows methods and variables with differing types
 2078                   if (sym.kind == e.sym.kind &&
 2079                       types.isSameType(types.erasure(sym.type), types.erasure(e.sym.type)) &&
 2080                       sym != e.sym &&
 2081                       (sym.flags() & Flags.SYNTHETIC) != (e.sym.flags() & Flags.SYNTHETIC) &&
 2082                       (sym.flags() & IPROXY) == 0 && (e.sym.flags() & IPROXY) == 0 &&
 2083                       (sym.flags() & BRIDGE) == 0 && (e.sym.flags() & BRIDGE) == 0) {
 2084                       syntheticError(pos, (e.sym.flags() & SYNTHETIC) == 0 ? e.sym : sym);
 2085                       return;
 2086                   }
 2087               }
 2088           }
 2089       }
 2090   
 2091       /** Check that all non-override equivalent methods accessible from 'site'
 2092        *  are mutually compatible (JLS 8.4.8/9.4.1).
 2093        *
 2094        *  @param pos  Position to be used for error reporting.
 2095        *  @param site The class whose methods are checked.
 2096        *  @param sym  The method symbol to be checked.
 2097        */
 2098       void checkOverrideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
 2099            ClashFilter cf = new ClashFilter(site);
 2100            //for each method m1 that is a member of 'site'...
 2101            for (Symbol s1 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) {
 2102               //...find another method m2 that is overridden (directly or indirectly)
 2103               //by method 'sym' in 'site'
 2104               for (Symbol s2 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) {
 2105                   if (s1 == s2 || !sym.overrides(s2, site.tsym, types, false)) continue;
 2106                   //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
 2107                   //a member of 'site') and (ii) m1 has the same erasure as m2, issue an error
 2108                   if (!types.isSubSignature(sym.type, types.memberType(site, s1), false) &&
 2109                           types.hasSameArgs(s1.erasure(types), s2.erasure(types))) {
 2110                       sym.flags_field |= CLASH;
 2111                       String key = s2 == sym ?
 2112                               "name.clash.same.erasure.no.override" :
 2113                               "name.clash.same.erasure.no.override.1";
 2114                       log.error(pos,
 2115                               key,
 2116                               sym, sym.location(),
 2117                               s1, s1.location(),
 2118                               s2, s2.location());
 2119                       return;
 2120                   }
 2121               }
 2122           }
 2123       }
 2124   
 2125   
 2126   
 2127       /** Check that all static methods accessible from 'site' are
 2128        *  mutually compatible (JLS 8.4.8).
 2129        *
 2130        *  @param pos  Position to be used for error reporting.
 2131        *  @param site The class whose methods are checked.
 2132        *  @param sym  The method symbol to be checked.
 2133        */
 2134       void checkHideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
 2135           ClashFilter cf = new ClashFilter(site);
 2136           //for each method m1 that is a member of 'site'...
 2137           for (Symbol s : types.membersClosure(site, true).getElementsByName(sym.name, cf)) {
 2138               //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
 2139               //a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error
 2140               if (!types.isSubSignature(sym.type, types.memberType(site, s), false) &&
 2141                       types.hasSameArgs(s.erasure(types), sym.erasure(types))) {
 2142                   log.error(pos,
 2143                           "name.clash.same.erasure.no.hide",
 2144                           sym, sym.location(),
 2145                           s, s.location());
 2146                   return;
 2147                }
 2148            }
 2149        }
 2150   
 2151        //where
 2152        private class ClashFilter implements Filter<Symbol> {
 2153   
 2154            Type site;
 2155   
 2156            ClashFilter(Type site) {
 2157                this.site = site;
 2158            }
 2159   
 2160            boolean shouldSkip(Symbol s) {
 2161                return (s.flags() & CLASH) != 0 &&
 2162                   s.owner == site.tsym;
 2163            }
 2164   
 2165            public boolean accepts(Symbol s) {
 2166                return s.kind == MTH &&
 2167                        (s.flags() & SYNTHETIC) == 0 &&
 2168                        !shouldSkip(s) &&
 2169                        s.isInheritedIn(site.tsym, types) &&
 2170                        !s.isConstructor();
 2171            }
 2172        }
 2173   
 2174       /** Report a conflict between a user symbol and a synthetic symbol.
 2175        */
 2176       private void syntheticError(DiagnosticPosition pos, Symbol sym) {
 2177           if (!sym.type.isErroneous()) {
 2178               if (warnOnSyntheticConflicts) {
 2179                   log.warning(pos, "synthetic.name.conflict", sym, sym.location());
 2180               }
 2181               else {
 2182                   log.error(pos, "synthetic.name.conflict", sym, sym.location());
 2183               }
 2184           }
 2185       }
 2186   
 2187       /** Check that class c does not implement directly or indirectly
 2188        *  the same parameterized interface with two different argument lists.
 2189        *  @param pos          Position to be used for error reporting.
 2190        *  @param type         The type whose interfaces are checked.
 2191        */
 2192       void checkClassBounds(DiagnosticPosition pos, Type type) {
 2193           checkClassBounds(pos, new HashMap<TypeSymbol,Type>(), type);
 2194       }
 2195   //where
 2196           /** Enter all interfaces of type `type' into the hash table `seensofar'
 2197            *  with their class symbol as key and their type as value. Make
 2198            *  sure no class is entered with two different types.
 2199            */
 2200           void checkClassBounds(DiagnosticPosition pos,
 2201                                 Map<TypeSymbol,Type> seensofar,
 2202                                 Type type) {
 2203               if (type.isErroneous()) return;
 2204               for (List<Type> l = types.interfaces(type); l.nonEmpty(); l = l.tail) {
 2205                   Type it = l.head;
 2206                   Type oldit = seensofar.put(it.tsym, it);
 2207                   if (oldit != null) {
 2208                       List<Type> oldparams = oldit.allparams();
 2209                       List<Type> newparams = it.allparams();
 2210                       if (!types.containsTypeEquivalent(oldparams, newparams))
 2211                           log.error(pos, "cant.inherit.diff.arg",
 2212                                     it.tsym, Type.toString(oldparams),
 2213                                     Type.toString(newparams));
 2214                   }
 2215                   checkClassBounds(pos, seensofar, it);
 2216               }
 2217               Type st = types.supertype(type);
 2218               if (st != null) checkClassBounds(pos, seensofar, st);
 2219           }
 2220   
 2221       /** Enter interface into into set.
 2222        *  If it existed already, issue a "repeated interface" error.
 2223        */
 2224       void checkNotRepeated(DiagnosticPosition pos, Type it, Set<Type> its) {
 2225           if (its.contains(it))
 2226               log.error(pos, "repeated.interface");
 2227           else {
 2228               its.add(it);
 2229           }
 2230       }
 2231   
 2232   /* *************************************************************************
 2233    * Check annotations
 2234    **************************************************************************/
 2235   
 2236       /**
 2237        * Recursively validate annotations values
 2238        */
 2239       void validateAnnotationTree(JCTree tree) {
 2240           class AnnotationValidator extends TreeScanner {
 2241               @Override
 2242               public void visitAnnotation(JCAnnotation tree) {
 2243                   if (!tree.type.isErroneous()) {
 2244                       super.visitAnnotation(tree);
 2245                       validateAnnotation(tree);
 2246                   }
 2247               }
 2248           }
 2249           tree.accept(new AnnotationValidator());
 2250       }
 2251   
 2252       /** Annotation types are restricted to primitives, String, an
 2253        *  enum, an annotation, Class, Class<?>, Class<? extends
 2254        *  Anything>, arrays of the preceding.
 2255        */
 2256       void validateAnnotationType(JCTree restype) {
 2257           // restype may be null if an error occurred, so don't bother validating it
 2258           if (restype != null) {
 2259               validateAnnotationType(restype.pos(), restype.type);
 2260           }
 2261       }
 2262   
 2263       void validateAnnotationType(DiagnosticPosition pos, Type type) {
 2264           if (type.isPrimitive()) return;
 2265           if (types.isSameType(type, syms.stringType)) return;
 2266           if ((type.tsym.flags() & Flags.ENUM) != 0) return;
 2267           if ((type.tsym.flags() & Flags.ANNOTATION) != 0) return;
 2268           if (types.lowerBound(type).tsym == syms.classType.tsym) return;
 2269           if (types.isArray(type) && !types.isArray(types.elemtype(type))) {
 2270               validateAnnotationType(pos, types.elemtype(type));
 2271               return;
 2272           }
 2273           log.error(pos, "invalid.annotation.member.type");
 2274       }
 2275   
 2276       /**
 2277        * "It is also a compile-time error if any method declared in an
 2278        * annotation type has a signature that is override-equivalent to
 2279        * that of any public or protected method declared in class Object
 2280        * or in the interface annotation.Annotation."
 2281        *
 2282        * @jls 9.6 Annotation Types
 2283        */
 2284       void validateAnnotationMethod(DiagnosticPosition pos, MethodSymbol m) {
 2285           for (Type sup = syms.annotationType; sup.tag == CLASS; sup = types.supertype(sup)) {
 2286               Scope s = sup.tsym.members();
 2287               for (Scope.Entry e = s.lookup(m.name); e.scope != null; e = e.next()) {
 2288                   if (e.sym.kind == MTH &&
 2289                       (e.sym.flags() & (PUBLIC | PROTECTED)) != 0 &&
 2290                       types.overrideEquivalent(m.type, e.sym.type))
 2291                       log.error(pos, "intf.annotation.member.clash", e.sym, sup);
 2292               }
 2293           }
 2294       }
 2295   
 2296       /** Check the annotations of a symbol.
 2297        */
 2298       public void validateAnnotations(List<JCAnnotation> annotations, Symbol s) {
 2299           if (skipAnnotations) return;
 2300           for (JCAnnotation a : annotations)
 2301               validateAnnotation(a, s);
 2302       }
 2303   
 2304       /** Check an annotation of a symbol.
 2305        */
 2306       public void validateAnnotation(JCAnnotation a, Symbol s) {
 2307           validateAnnotationTree(a);
 2308   
 2309           if (!annotationApplicable(a, s))
 2310               log.error(a.pos(), "annotation.type.not.applicable");
 2311   
 2312           if (a.annotationType.type.tsym == syms.overrideType.tsym) {
 2313               if (!isOverrider(s))
 2314                   log.error(a.pos(), "method.does.not.override.superclass");
 2315           }
 2316       }
 2317   
 2318       /** Is s a method symbol that overrides a method in a superclass? */
 2319       boolean isOverrider(Symbol s) {
 2320           if (s.kind != MTH || s.isStatic())
 2321               return false;
 2322           MethodSymbol m = (MethodSymbol)s;
 2323           TypeSymbol owner = (TypeSymbol)m.owner;
 2324           for (Type sup : types.closure(owner.type)) {
 2325               if (sup == owner.type)
 2326                   continue; // skip "this"
 2327               Scope scope = sup.tsym.members();
 2328               for (Scope.Entry e = scope.lookup(m.name); e.scope != null; e = e.next()) {
 2329                   if (!e.sym.isStatic() && m.overrides(e.sym, owner, types, true))
 2330                       return true;
 2331               }
 2332           }
 2333           return false;
 2334       }
 2335   
 2336       /** Is the annotation applicable to the symbol? */
 2337       boolean annotationApplicable(JCAnnotation a, Symbol s) {
 2338           Attribute.Compound atTarget =
 2339               a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym);
 2340           if (atTarget == null) return true;
 2341           Attribute atValue = atTarget.member(names.value);
 2342           if (!(atValue instanceof Attribute.Array)) return true; // error recovery
 2343           Attribute.Array arr = (Attribute.Array) atValue;
 2344           for (Attribute app : arr.values) {
 2345               if (!(app instanceof Attribute.Enum)) return true; // recovery
 2346               Attribute.Enum e = (Attribute.Enum) app;
 2347               if (e.value.name == names.TYPE)
 2348                   { if (s.kind == TYP) return true; }
 2349               else if (e.value.name == names.FIELD)
 2350                   { if (s.kind == VAR && s.owner.kind != MTH) return true; }
 2351               else if (e.value.name == names.METHOD)
 2352                   { if (s.kind == MTH && !s.isConstructor()) return true; }
 2353               else if (e.value.name == names.PARAMETER)
 2354                   { if (s.kind == VAR &&
 2355                         s.owner.kind == MTH &&
 2356                         (s.flags() & PARAMETER) != 0)
 2357                       return true;
 2358                   }
 2359               else if (e.value.name == names.CONSTRUCTOR)
 2360                   { if (s.kind == MTH && s.isConstructor()) return true; }
 2361               else if (e.value.name == names.LOCAL_VARIABLE)
 2362                   { if (s.kind == VAR && s.owner.kind == MTH &&
 2363                         (s.flags() & PARAMETER) == 0)
 2364                       return true;
 2365                   }
 2366               else if (e.value.name == names.ANNOTATION_TYPE)
 2367                   { if (s.kind == TYP && (s.flags() & ANNOTATION) != 0)
 2368                       return true;
 2369                   }
 2370               else if (e.value.name == names.PACKAGE)
 2371                   { if (s.kind == PCK) return true; }
 2372               else if (e.value.name == names.TYPE_USE)
 2373                   { if (s.kind == TYP ||
 2374                         s.kind == VAR ||
 2375                         (s.kind == MTH && !s.isConstructor() &&
 2376                          s.type.getReturnType().tag != VOID))
 2377                       return true;
 2378                   }
 2379               else
 2380                   return true; // recovery
 2381           }
 2382           return false;
 2383       }
 2384   
 2385       /** Check an annotation value.
 2386        */
 2387       public void validateAnnotation(JCAnnotation a) {
 2388           // collect an inventory of the members (sorted alphabetically)
 2389           Set<MethodSymbol> members = new TreeSet<MethodSymbol>(new Comparator<Symbol>() {
 2390               public int compare(Symbol t, Symbol t1) {
 2391                   return t.name.compareTo(t1.name);
 2392               }
 2393           });
 2394           for (Scope.Entry e = a.annotationType.type.tsym.members().elems;
 2395                e != null;
 2396                e = e.sibling)
 2397               if (e.sym.kind == MTH)
 2398                   members.add((MethodSymbol) e.sym);
 2399   
 2400           // count them off as they're annotated
 2401           for (JCTree arg : a.args) {
 2402               if (arg.getTag() != JCTree.ASSIGN) continue; // recovery
 2403               JCAssign assign = (JCAssign) arg;
 2404               Symbol m = TreeInfo.symbol(assign.lhs);
 2405               if (m == null || m.type.isErroneous()) continue;
 2406               if (!members.remove(m))
 2407                   log.error(assign.lhs.pos(), "duplicate.annotation.member.value",
 2408                             m.name, a.type);
 2409           }
 2410   
 2411           // all the remaining ones better have default values
 2412           ListBuffer<Name> missingDefaults = ListBuffer.lb();
 2413           for (MethodSymbol m : members) {
 2414               if (m.defaultValue == null && !m.type.isErroneous()) {
 2415                   missingDefaults.append(m.name);
 2416               }
 2417           }
 2418           if (missingDefaults.nonEmpty()) {
 2419               String key = (missingDefaults.size() > 1)
 2420                       ? "annotation.missing.default.value.1"
 2421                       : "annotation.missing.default.value";
 2422               log.error(a.pos(), key, a.type, missingDefaults);
 2423           }
 2424   
 2425           // special case: java.lang.annotation.Target must not have
 2426           // repeated values in its value member
 2427           if (a.annotationType.type.tsym != syms.annotationTargetType.tsym ||
 2428               a.args.tail == null)
 2429               return;
 2430   
 2431           if (a.args.head.getTag() != JCTree.ASSIGN) return; // error recovery
 2432           JCAssign assign = (JCAssign) a.args.head;
 2433           Symbol m = TreeInfo.symbol(assign.lhs);
 2434           if (m.name != names.value) return;
 2435           JCTree rhs = assign.rhs;
 2436           if (rhs.getTag() != JCTree.NEWARRAY) return;
 2437           JCNewArray na = (JCNewArray) rhs;
 2438           Set<Symbol> targets = new HashSet<Symbol>();
 2439           for (JCTree elem : na.elems) {
 2440               if (!targets.add(TreeInfo.symbol(elem))) {
 2441                   log.error(elem.pos(), "repeated.annotation.target");
 2442               }
 2443           }
 2444       }
 2445   
 2446       void checkDeprecatedAnnotation(DiagnosticPosition pos, Symbol s) {
 2447           if (allowAnnotations &&
 2448               lint.isEnabled(LintCategory.DEP_ANN) &&
 2449               (s.flags() & DEPRECATED) != 0 &&
 2450               !syms.deprecatedType.isErroneous() &&
 2451               s.attribute(syms.deprecatedType.tsym) == null) {
 2452               log.warning(LintCategory.DEP_ANN,
 2453                       pos, "missing.deprecated.annotation");
 2454           }
 2455       }
 2456   
 2457       void checkDeprecated(final DiagnosticPosition pos, final Symbol other, final Symbol s) {
 2458           if ((s.flags() & DEPRECATED) != 0 &&
 2459                   (other.flags() & DEPRECATED) == 0 &&
 2460                   s.outermostClass() != other.outermostClass()) {
 2461               deferredLintHandler.report(new DeferredLintHandler.LintLogger() {
 2462                   @Override
 2463                   public void report() {
 2464                       warnDeprecated(pos, s);
 2465                   }
 2466               });
 2467           };
 2468       }
 2469   
 2470       void checkSunAPI(final DiagnosticPosition pos, final Symbol s) {
 2471           if ((s.flags() & PROPRIETARY) != 0) {
 2472               deferredLintHandler.report(new DeferredLintHandler.LintLogger() {
 2473                   public void report() {
 2474                       if (enableSunApiLintControl)
 2475                         warnSunApi(pos, "sun.proprietary", s);
 2476                       else
 2477                         log.strictWarning(pos, "sun.proprietary", s);
 2478                   }
 2479               });
 2480           }
 2481       }
 2482   
 2483   /* *************************************************************************
 2484    * Check for recursive annotation elements.
 2485    **************************************************************************/
 2486   
 2487       /** Check for cycles in the graph of annotation elements.
 2488        */
 2489       void checkNonCyclicElements(JCClassDecl tree) {
 2490           if ((tree.sym.flags_field & ANNOTATION) == 0) return;
 2491           Assert.check((tree.sym.flags_field & LOCKED) == 0);
 2492           try {
 2493               tree.sym.flags_field |= LOCKED;
 2494               for (JCTree def : tree.defs) {
 2495                   if (def.getTag() != JCTree.METHODDEF) continue;
 2496                   JCMethodDecl meth = (JCMethodDecl)def;
 2497                   checkAnnotationResType(meth.pos(), meth.restype.type);
 2498               }
 2499           } finally {
 2500               tree.sym.flags_field &= ~LOCKED;
 2501               tree.sym.flags_field |= ACYCLIC_ANN;
 2502           }
 2503       }
 2504   
 2505       void checkNonCyclicElementsInternal(DiagnosticPosition pos, TypeSymbol tsym) {
 2506           if ((tsym.flags_field & ACYCLIC_ANN) != 0)
 2507               return;
 2508           if ((tsym.flags_field & LOCKED) != 0) {
 2509               log.error(pos, "cyclic.annotation.element");
 2510               return;
 2511           }
 2512           try {
 2513               tsym.flags_field |= LOCKED;
 2514               for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) {
 2515                   Symbol s = e.sym;
 2516                   if (s.kind != Kinds.MTH)
 2517                       continue;
 2518                   checkAnnotationResType(pos, ((MethodSymbol)s).type.getReturnType());
 2519               }
 2520           } finally {
 2521               tsym.flags_field &= ~LOCKED;
 2522               tsym.flags_field |= ACYCLIC_ANN;
 2523           }
 2524       }
 2525   
 2526       void checkAnnotationResType(DiagnosticPosition pos, Type type) {
 2527           switch (type.tag) {
 2528           case TypeTags.CLASS:
 2529               if ((type.tsym.flags() & ANNOTATION) != 0)
 2530                   checkNonCyclicElementsInternal(pos, type.tsym);
 2531               break;
 2532           case TypeTags.ARRAY:
 2533               checkAnnotationResType(pos, types.elemtype(type));
 2534               break;
 2535           default:
 2536               break; // int etc
 2537           }
 2538       }
 2539   
 2540   /* *************************************************************************
 2541    * Check for cycles in the constructor call graph.
 2542    **************************************************************************/
 2543   
 2544       /** Check for cycles in the graph of constructors calling other
 2545        *  constructors.
 2546        */
 2547       void checkCyclicConstructors(JCClassDecl tree) {
 2548           Map<Symbol,Symbol> callMap = new HashMap<Symbol, Symbol>();
 2549   
 2550           // enter each constructor this-call into the map
 2551           for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
 2552               JCMethodInvocation app = TreeInfo.firstConstructorCall(l.head);
 2553               if (app == null) continue;
 2554               JCMethodDecl meth = (JCMethodDecl) l.head;
 2555               if (TreeInfo.name(app.meth) == names._this) {
 2556                   callMap.put(meth.sym, TreeInfo.symbol(app.meth));
 2557               } else {
 2558                   meth.sym.flags_field |= ACYCLIC;
 2559               }
 2560           }
 2561   
 2562           // Check for cycles in the map
 2563           Symbol[] ctors = new Symbol[0];
 2564           ctors = callMap.keySet().toArray(ctors);
 2565           for (Symbol caller : ctors) {
 2566               checkCyclicConstructor(tree, caller, callMap);
 2567           }
 2568       }
 2569   
 2570       /** Look in the map to see if the given constructor is part of a
 2571        *  call cycle.
 2572        */
 2573       private void checkCyclicConstructor(JCClassDecl tree, Symbol ctor,
 2574                                           Map<Symbol,Symbol> callMap) {
 2575           if (ctor != null && (ctor.flags_field & ACYCLIC) == 0) {
 2576               if ((ctor.flags_field & LOCKED) != 0) {
 2577                   log.error(TreeInfo.diagnosticPositionFor(ctor, tree),
 2578                             "recursive.ctor.invocation");
 2579               } else {
 2580                   ctor.flags_field |= LOCKED;
 2581                   checkCyclicConstructor(tree, callMap.remove(ctor), callMap);
 2582                   ctor.flags_field &= ~LOCKED;
 2583               }
 2584               ctor.flags_field |= ACYCLIC;
 2585           }
 2586       }
 2587   
 2588   /* *************************************************************************
 2589    * Miscellaneous
 2590    **************************************************************************/
 2591   
 2592       /**
 2593        * Return the opcode of the operator but emit an error if it is an
 2594        * error.
 2595        * @param pos        position for error reporting.
 2596        * @param operator   an operator
 2597        * @param tag        a tree tag
 2598        * @param left       type of left hand side
 2599        * @param right      type of right hand side
 2600        */
 2601       int checkOperator(DiagnosticPosition pos,
 2602                          OperatorSymbol operator,
 2603                          int tag,
 2604                          Type left,
 2605                          Type right) {
 2606           if (operator.opcode == ByteCodes.error) {
 2607               log.error(pos,
 2608                         "operator.cant.be.applied.1",
 2609                         treeinfo.operatorName(tag),
 2610                         left, right);
 2611           }
 2612           return operator.opcode;
 2613       }
 2614   
 2615   
 2616       /**
 2617        *  Check for division by integer constant zero
 2618        *  @param pos           Position for error reporting.
 2619        *  @param operator      The operator for the expression
 2620        *  @param operand       The right hand operand for the expression
 2621        */
 2622       void checkDivZero(DiagnosticPosition pos, Symbol operator, Type operand) {
 2623           if (operand.constValue() != null
 2624               && lint.isEnabled(LintCategory.DIVZERO)
 2625               && operand.tag <= LONG
 2626               && ((Number) (operand.constValue())).longValue() == 0) {
 2627               int opc = ((OperatorSymbol)operator).opcode;
 2628               if (opc == ByteCodes.idiv || opc == ByteCodes.imod
 2629                   || opc == ByteCodes.ldiv || opc == ByteCodes.lmod) {
 2630                   log.warning(LintCategory.DIVZERO, pos, "div.zero");
 2631               }
 2632           }
 2633       }
 2634   
 2635       /**
 2636        * Check for empty statements after if
 2637        */
 2638       void checkEmptyIf(JCIf tree) {
 2639           if (tree.thenpart.getTag() == JCTree.SKIP && tree.elsepart == null && lint.isEnabled(LintCategory.EMPTY))
 2640               log.warning(LintCategory.EMPTY, tree.thenpart.pos(), "empty.if");
 2641       }
 2642   
 2643       /** Check that symbol is unique in given scope.
 2644        *  @param pos           Position for error reporting.
 2645        *  @param sym           The symbol.
 2646        *  @param s             The scope.
 2647        */
 2648       boolean checkUnique(DiagnosticPosition pos, Symbol sym, Scope s) {
 2649           if (sym.type.isErroneous())
 2650               return true;
 2651           if (sym.owner.name == names.any) return false;
 2652           for (Scope.Entry e = s.lookup(sym.name); e.scope == s; e = e.next()) {
 2653               if (sym != e.sym &&
 2654                       (e.sym.flags() & CLASH) == 0 &&
 2655                       sym.kind == e.sym.kind &&
 2656                       sym.name != names.error &&
 2657                       (sym.kind != MTH || types.hasSameArgs(types.erasure(sym.type), types.erasure(e.sym.type)))) {
 2658                   if ((sym.flags() & VARARGS) != (e.sym.flags() & VARARGS)) {
 2659                       varargsDuplicateError(pos, sym, e.sym);
 2660                       return true;
 2661                   } else if (sym.kind == MTH && !types.hasSameArgs(sym.type, e.sym.type, false)) {
 2662                       duplicateErasureError(pos, sym, e.sym);
 2663                       sym.flags_field |= CLASH;
 2664                       return true;
 2665                   } else {
 2666                       duplicateError(pos, e.sym);
 2667                       return false;
 2668                   }
 2669               }
 2670           }
 2671           return true;
 2672       }
 2673   
 2674       /** Report duplicate declaration error.
 2675        */
 2676       void duplicateErasureError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) {
 2677           if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) {
 2678               log.error(pos, "name.clash.same.erasure", sym1, sym2);
 2679           }
 2680       }
 2681   
 2682       /** Check that single-type import is not already imported or top-level defined,
 2683        *  but make an exception for two single-type imports which denote the same type.
 2684        *  @param pos           Position for error reporting.
 2685        *  @param sym           The symbol.
 2686        *  @param s             The scope
 2687        */
 2688       boolean checkUniqueImport(DiagnosticPosition pos, Symbol sym, Scope s) {
 2689           return checkUniqueImport(pos, sym, s, false);
 2690       }
 2691   
 2692       /** Check that static single-type import is not already imported or top-level defined,
 2693        *  but make an exception for two single-type imports which denote the same type.
 2694        *  @param pos           Position for error reporting.
 2695        *  @param sym           The symbol.
 2696        *  @param s             The scope
 2697        *  @param staticImport  Whether or not this was a static import
 2698        */
 2699       boolean checkUniqueStaticImport(DiagnosticPosition pos, Symbol sym, Scope s) {
 2700           return checkUniqueImport(pos, sym, s, true);
 2701       }
 2702   
 2703       /** Check that single-type import is not already imported or top-level defined,
 2704        *  but make an exception for two single-type imports which denote the same type.
 2705        *  @param pos           Position for error reporting.
 2706        *  @param sym           The symbol.
 2707        *  @param s             The scope.
 2708        *  @param staticImport  Whether or not this was a static import
 2709        */
 2710       private boolean checkUniqueImport(DiagnosticPosition pos, Symbol sym, Scope s, boolean staticImport) {
 2711           for (Scope.Entry e = s.lookup(sym.name); e.scope != null; e = e.next()) {
 2712               // is encountered class entered via a class declaration?
 2713               boolean isClassDecl = e.scope == s;
 2714               if ((isClassDecl || sym != e.sym) &&
 2715                   sym.kind == e.sym.kind &&
 2716                   sym.name != names.error) {
 2717                   if (!e.sym.type.isErroneous()) {
 2718                       String what = e.sym.toString();
 2719                       if (!isClassDecl) {
 2720                           if (staticImport)
 2721                               log.error(pos, "already.defined.static.single.import", what);
 2722                           else
 2723                               log.error(pos, "already.defined.single.import", what);
 2724                       }
 2725                       else if (sym != e.sym)
 2726                           log.error(pos, "already.defined.this.unit", what);
 2727                   }
 2728                   return false;
 2729               }
 2730           }
 2731           return true;
 2732       }
 2733   
 2734       /** Check that a qualified name is in canonical form (for import decls).
 2735        */
 2736       public void checkCanonical(JCTree tree) {
 2737           if (!isCanonical(tree))
 2738               log.error(tree.pos(), "import.requires.canonical",
 2739                         TreeInfo.symbol(tree));
 2740       }
 2741           // where
 2742           private boolean isCanonical(JCTree tree) {
 2743               while (tree.getTag() == JCTree.SELECT) {
 2744                   JCFieldAccess s = (JCFieldAccess) tree;
 2745                   if (s.sym.owner != TreeInfo.symbol(s.selected))
 2746                       return false;
 2747                   tree = s.selected;
 2748               }
 2749               return true;
 2750           }
 2751   
 2752       private class ConversionWarner extends Warner {
 2753           final String uncheckedKey;
 2754           final Type found;
 2755           final Type expected;
 2756           public ConversionWarner(DiagnosticPosition pos, String uncheckedKey, Type found, Type expected) {
 2757               super(pos);
 2758               this.uncheckedKey = uncheckedKey;
 2759               this.found = found;
 2760               this.expected = expected;
 2761           }
 2762   
 2763           @Override
 2764           public void warn(LintCategory lint) {
 2765               boolean warned = this.warned;
 2766               super.warn(lint);
 2767               if (warned) return; // suppress redundant diagnostics
 2768               switch (lint) {
 2769                   case UNCHECKED:
 2770                       Check.this.warnUnchecked(pos(), "prob.found.req", diags.fragment(uncheckedKey), found, expected);
 2771                       break;
 2772                   case VARARGS:
 2773                       if (method != null &&
 2774                               method.attribute(syms.trustMeType.tsym) != null &&
 2775                               isTrustMeAllowedOnMethod(method) &&
 2776                               !types.isReifiable(method.type.getParameterTypes().last())) {
 2777                           Check.this.warnUnsafeVararg(pos(), "varargs.unsafe.use.varargs.param", method.params.last());
 2778                       }
 2779                       break;
 2780                   default:
 2781                       throw new AssertionError("Unexpected lint: " + lint);
 2782               }
 2783           }
 2784       }
 2785   
 2786       public Warner castWarner(DiagnosticPosition pos, Type found, Type expected) {
 2787           return new ConversionWarner(pos, "unchecked.cast.to.type", found, expected);
 2788       }
 2789   
 2790       public Warner convertWarner(DiagnosticPosition pos, Type found, Type expected) {
 2791           return new ConversionWarner(pos, "unchecked.assign", found, expected);
 2792       }
 2793   }

Save This Page
Home » openjdk-7 » com.sun.tools » javac » comp » [javadoc | source]