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

changeset 0
959103a6100f
child 2525
2eb010b6cb22
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Wed Apr 27 01:34:52 2016 +0800
     1.3 @@ -0,0 +1,3588 @@
     1.4 +/*
     1.5 + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.  Oracle designates this
    1.11 + * particular file as subject to the "Classpath" exception as provided
    1.12 + * by Oracle in the LICENSE file that accompanied this code.
    1.13 + *
    1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.17 + * version 2 for more details (a copy is included in the LICENSE file that
    1.18 + * accompanied this code).
    1.19 + *
    1.20 + * You should have received a copy of the GNU General Public License version
    1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.23 + *
    1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.25 + * or visit www.oracle.com if you need additional information or have any
    1.26 + * questions.
    1.27 + */
    1.28 +
    1.29 +package com.sun.tools.javac.comp;
    1.30 +
    1.31 +import java.util.*;
    1.32 +
    1.33 +import javax.tools.JavaFileManager;
    1.34 +
    1.35 +import com.sun.tools.javac.code.*;
    1.36 +import com.sun.tools.javac.code.Attribute.Compound;
    1.37 +import com.sun.tools.javac.jvm.*;
    1.38 +import com.sun.tools.javac.tree.*;
    1.39 +import com.sun.tools.javac.util.*;
    1.40 +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    1.41 +import com.sun.tools.javac.util.List;
    1.42 +
    1.43 +import com.sun.tools.javac.code.Lint;
    1.44 +import com.sun.tools.javac.code.Lint.LintCategory;
    1.45 +import com.sun.tools.javac.code.Type.*;
    1.46 +import com.sun.tools.javac.code.Symbol.*;
    1.47 +import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
    1.48 +import com.sun.tools.javac.comp.Infer.InferenceContext;
    1.49 +import com.sun.tools.javac.comp.Infer.FreeTypeListener;
    1.50 +import com.sun.tools.javac.tree.JCTree.*;
    1.51 +import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
    1.52 +
    1.53 +import static com.sun.tools.javac.code.Flags.*;
    1.54 +import static com.sun.tools.javac.code.Flags.ANNOTATION;
    1.55 +import static com.sun.tools.javac.code.Flags.SYNCHRONIZED;
    1.56 +import static com.sun.tools.javac.code.Kinds.*;
    1.57 +import static com.sun.tools.javac.code.TypeTag.*;
    1.58 +import static com.sun.tools.javac.code.TypeTag.WILDCARD;
    1.59 +
    1.60 +import static com.sun.tools.javac.tree.JCTree.Tag.*;
    1.61 +
    1.62 +/** Type checking helper class for the attribution phase.
    1.63 + *
    1.64 + *  <p><b>This is NOT part of any supported API.
    1.65 + *  If you write code that depends on this, you do so at your own risk.
    1.66 + *  This code and its internal interfaces are subject to change or
    1.67 + *  deletion without notice.</b>
    1.68 + */
    1.69 +public class Check {
    1.70 +    protected static final Context.Key<Check> checkKey =
    1.71 +        new Context.Key<Check>();
    1.72 +
    1.73 +    private final Names names;
    1.74 +    private final Log log;
    1.75 +    private final Resolve rs;
    1.76 +    private final Symtab syms;
    1.77 +    private final Enter enter;
    1.78 +    private final DeferredAttr deferredAttr;
    1.79 +    private final Infer infer;
    1.80 +    private final Types types;
    1.81 +    private final JCDiagnostic.Factory diags;
    1.82 +    private boolean warnOnSyntheticConflicts;
    1.83 +    private boolean suppressAbortOnBadClassFile;
    1.84 +    private boolean enableSunApiLintControl;
    1.85 +    private final TreeInfo treeinfo;
    1.86 +    private final JavaFileManager fileManager;
    1.87 +    private final Profile profile;
    1.88 +    private final boolean warnOnAccessToSensitiveMembers;
    1.89 +
    1.90 +    // The set of lint options currently in effect. It is initialized
    1.91 +    // from the context, and then is set/reset as needed by Attr as it
    1.92 +    // visits all the various parts of the trees during attribution.
    1.93 +    private Lint lint;
    1.94 +
    1.95 +    // The method being analyzed in Attr - it is set/reset as needed by
    1.96 +    // Attr as it visits new method declarations.
    1.97 +    private MethodSymbol method;
    1.98 +
    1.99 +    public static Check instance(Context context) {
   1.100 +        Check instance = context.get(checkKey);
   1.101 +        if (instance == null)
   1.102 +            instance = new Check(context);
   1.103 +        return instance;
   1.104 +    }
   1.105 +
   1.106 +    protected Check(Context context) {
   1.107 +        context.put(checkKey, this);
   1.108 +
   1.109 +        names = Names.instance(context);
   1.110 +        dfltTargetMeta = new Name[] { names.PACKAGE, names.TYPE,
   1.111 +            names.FIELD, names.METHOD, names.CONSTRUCTOR,
   1.112 +            names.ANNOTATION_TYPE, names.LOCAL_VARIABLE, names.PARAMETER};
   1.113 +        log = Log.instance(context);
   1.114 +        rs = Resolve.instance(context);
   1.115 +        syms = Symtab.instance(context);
   1.116 +        enter = Enter.instance(context);
   1.117 +        deferredAttr = DeferredAttr.instance(context);
   1.118 +        infer = Infer.instance(context);
   1.119 +        types = Types.instance(context);
   1.120 +        diags = JCDiagnostic.Factory.instance(context);
   1.121 +        Options options = Options.instance(context);
   1.122 +        lint = Lint.instance(context);
   1.123 +        treeinfo = TreeInfo.instance(context);
   1.124 +        fileManager = context.get(JavaFileManager.class);
   1.125 +
   1.126 +        Source source = Source.instance(context);
   1.127 +        allowGenerics = source.allowGenerics();
   1.128 +        allowVarargs = source.allowVarargs();
   1.129 +        allowAnnotations = source.allowAnnotations();
   1.130 +        allowCovariantReturns = source.allowCovariantReturns();
   1.131 +        allowSimplifiedVarargs = source.allowSimplifiedVarargs();
   1.132 +        allowDefaultMethods = source.allowDefaultMethods();
   1.133 +        allowStrictMethodClashCheck = source.allowStrictMethodClashCheck();
   1.134 +        complexInference = options.isSet("complexinference");
   1.135 +        warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts");
   1.136 +        suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile");
   1.137 +        enableSunApiLintControl = options.isSet("enableSunApiLintControl");
   1.138 +        warnOnAccessToSensitiveMembers = options.isSet("warnOnAccessToSensitiveMembers");
   1.139 +
   1.140 +        Target target = Target.instance(context);
   1.141 +        syntheticNameChar = target.syntheticNameChar();
   1.142 +
   1.143 +        profile = Profile.instance(context);
   1.144 +
   1.145 +        boolean verboseDeprecated = lint.isEnabled(LintCategory.DEPRECATION);
   1.146 +        boolean verboseUnchecked = lint.isEnabled(LintCategory.UNCHECKED);
   1.147 +        boolean verboseSunApi = lint.isEnabled(LintCategory.SUNAPI);
   1.148 +        boolean enforceMandatoryWarnings = source.enforceMandatoryWarnings();
   1.149 +
   1.150 +        deprecationHandler = new MandatoryWarningHandler(log, verboseDeprecated,
   1.151 +                enforceMandatoryWarnings, "deprecated", LintCategory.DEPRECATION);
   1.152 +        uncheckedHandler = new MandatoryWarningHandler(log, verboseUnchecked,
   1.153 +                enforceMandatoryWarnings, "unchecked", LintCategory.UNCHECKED);
   1.154 +        sunApiHandler = new MandatoryWarningHandler(log, verboseSunApi,
   1.155 +                enforceMandatoryWarnings, "sunapi", null);
   1.156 +
   1.157 +        deferredLintHandler = DeferredLintHandler.instance(context);
   1.158 +    }
   1.159 +
   1.160 +    /** Switch: generics enabled?
   1.161 +     */
   1.162 +    boolean allowGenerics;
   1.163 +
   1.164 +    /** Switch: varargs enabled?
   1.165 +     */
   1.166 +    boolean allowVarargs;
   1.167 +
   1.168 +    /** Switch: annotations enabled?
   1.169 +     */
   1.170 +    boolean allowAnnotations;
   1.171 +
   1.172 +    /** Switch: covariant returns enabled?
   1.173 +     */
   1.174 +    boolean allowCovariantReturns;
   1.175 +
   1.176 +    /** Switch: simplified varargs enabled?
   1.177 +     */
   1.178 +    boolean allowSimplifiedVarargs;
   1.179 +
   1.180 +    /** Switch: default methods enabled?
   1.181 +     */
   1.182 +    boolean allowDefaultMethods;
   1.183 +
   1.184 +    /** Switch: should unrelated return types trigger a method clash?
   1.185 +     */
   1.186 +    boolean allowStrictMethodClashCheck;
   1.187 +
   1.188 +    /** Switch: -complexinference option set?
   1.189 +     */
   1.190 +    boolean complexInference;
   1.191 +
   1.192 +    /** Character for synthetic names
   1.193 +     */
   1.194 +    char syntheticNameChar;
   1.195 +
   1.196 +    /** A table mapping flat names of all compiled classes in this run to their
   1.197 +     *  symbols; maintained from outside.
   1.198 +     */
   1.199 +    public Map<Name,ClassSymbol> compiled = new HashMap<Name, ClassSymbol>();
   1.200 +
   1.201 +    /** A handler for messages about deprecated usage.
   1.202 +     */
   1.203 +    private MandatoryWarningHandler deprecationHandler;
   1.204 +
   1.205 +    /** A handler for messages about unchecked or unsafe usage.
   1.206 +     */
   1.207 +    private MandatoryWarningHandler uncheckedHandler;
   1.208 +
   1.209 +    /** A handler for messages about using proprietary API.
   1.210 +     */
   1.211 +    private MandatoryWarningHandler sunApiHandler;
   1.212 +
   1.213 +    /** A handler for deferred lint warnings.
   1.214 +     */
   1.215 +    private DeferredLintHandler deferredLintHandler;
   1.216 +
   1.217 +/* *************************************************************************
   1.218 + * Errors and Warnings
   1.219 + **************************************************************************/
   1.220 +
   1.221 +    Lint setLint(Lint newLint) {
   1.222 +        Lint prev = lint;
   1.223 +        lint = newLint;
   1.224 +        return prev;
   1.225 +    }
   1.226 +
   1.227 +    MethodSymbol setMethod(MethodSymbol newMethod) {
   1.228 +        MethodSymbol prev = method;
   1.229 +        method = newMethod;
   1.230 +        return prev;
   1.231 +    }
   1.232 +
   1.233 +    /** Warn about deprecated symbol.
   1.234 +     *  @param pos        Position to be used for error reporting.
   1.235 +     *  @param sym        The deprecated symbol.
   1.236 +     */
   1.237 +    void warnDeprecated(DiagnosticPosition pos, Symbol sym) {
   1.238 +        if (!lint.isSuppressed(LintCategory.DEPRECATION))
   1.239 +            deprecationHandler.report(pos, "has.been.deprecated", sym, sym.location());
   1.240 +    }
   1.241 +
   1.242 +    /** Warn about unchecked operation.
   1.243 +     *  @param pos        Position to be used for error reporting.
   1.244 +     *  @param msg        A string describing the problem.
   1.245 +     */
   1.246 +    public void warnUnchecked(DiagnosticPosition pos, String msg, Object... args) {
   1.247 +        if (!lint.isSuppressed(LintCategory.UNCHECKED))
   1.248 +            uncheckedHandler.report(pos, msg, args);
   1.249 +    }
   1.250 +
   1.251 +    /** Warn about unsafe vararg method decl.
   1.252 +     *  @param pos        Position to be used for error reporting.
   1.253 +     */
   1.254 +    void warnUnsafeVararg(DiagnosticPosition pos, String key, Object... args) {
   1.255 +        if (lint.isEnabled(LintCategory.VARARGS) && allowSimplifiedVarargs)
   1.256 +            log.warning(LintCategory.VARARGS, pos, key, args);
   1.257 +    }
   1.258 +
   1.259 +    /** Warn about using proprietary API.
   1.260 +     *  @param pos        Position to be used for error reporting.
   1.261 +     *  @param msg        A string describing the problem.
   1.262 +     */
   1.263 +    public void warnSunApi(DiagnosticPosition pos, String msg, Object... args) {
   1.264 +        if (!lint.isSuppressed(LintCategory.SUNAPI))
   1.265 +            sunApiHandler.report(pos, msg, args);
   1.266 +    }
   1.267 +
   1.268 +    public void warnStatic(DiagnosticPosition pos, String msg, Object... args) {
   1.269 +        if (lint.isEnabled(LintCategory.STATIC))
   1.270 +            log.warning(LintCategory.STATIC, pos, msg, args);
   1.271 +    }
   1.272 +
   1.273 +    /**
   1.274 +     * Report any deferred diagnostics.
   1.275 +     */
   1.276 +    public void reportDeferredDiagnostics() {
   1.277 +        deprecationHandler.reportDeferredDiagnostic();
   1.278 +        uncheckedHandler.reportDeferredDiagnostic();
   1.279 +        sunApiHandler.reportDeferredDiagnostic();
   1.280 +    }
   1.281 +
   1.282 +
   1.283 +    /** Report a failure to complete a class.
   1.284 +     *  @param pos        Position to be used for error reporting.
   1.285 +     *  @param ex         The failure to report.
   1.286 +     */
   1.287 +    public Type completionError(DiagnosticPosition pos, CompletionFailure ex) {
   1.288 +        log.error(JCDiagnostic.DiagnosticFlag.NON_DEFERRABLE, pos, "cant.access", ex.sym, ex.getDetailValue());
   1.289 +        if (ex instanceof ClassReader.BadClassFile
   1.290 +                && !suppressAbortOnBadClassFile) throw new Abort();
   1.291 +        else return syms.errType;
   1.292 +    }
   1.293 +
   1.294 +    /** Report an error that wrong type tag was found.
   1.295 +     *  @param pos        Position to be used for error reporting.
   1.296 +     *  @param required   An internationalized string describing the type tag
   1.297 +     *                    required.
   1.298 +     *  @param found      The type that was found.
   1.299 +     */
   1.300 +    Type typeTagError(DiagnosticPosition pos, Object required, Object found) {
   1.301 +        // this error used to be raised by the parser,
   1.302 +        // but has been delayed to this point:
   1.303 +        if (found instanceof Type && ((Type)found).hasTag(VOID)) {
   1.304 +            log.error(pos, "illegal.start.of.type");
   1.305 +            return syms.errType;
   1.306 +        }
   1.307 +        log.error(pos, "type.found.req", found, required);
   1.308 +        return types.createErrorType(found instanceof Type ? (Type)found : syms.errType);
   1.309 +    }
   1.310 +
   1.311 +    /** Report an error that symbol cannot be referenced before super
   1.312 +     *  has been called.
   1.313 +     *  @param pos        Position to be used for error reporting.
   1.314 +     *  @param sym        The referenced symbol.
   1.315 +     */
   1.316 +    void earlyRefError(DiagnosticPosition pos, Symbol sym) {
   1.317 +        log.error(pos, "cant.ref.before.ctor.called", sym);
   1.318 +    }
   1.319 +
   1.320 +    /** Report duplicate declaration error.
   1.321 +     */
   1.322 +    void duplicateError(DiagnosticPosition pos, Symbol sym) {
   1.323 +        if (!sym.type.isErroneous()) {
   1.324 +            Symbol location = sym.location();
   1.325 +            if (location.kind == MTH &&
   1.326 +                    ((MethodSymbol)location).isStaticOrInstanceInit()) {
   1.327 +                log.error(pos, "already.defined.in.clinit", kindName(sym), sym,
   1.328 +                        kindName(sym.location()), kindName(sym.location().enclClass()),
   1.329 +                        sym.location().enclClass());
   1.330 +            } else {
   1.331 +                log.error(pos, "already.defined", kindName(sym), sym,
   1.332 +                        kindName(sym.location()), sym.location());
   1.333 +            }
   1.334 +        }
   1.335 +    }
   1.336 +
   1.337 +    /** Report array/varargs duplicate declaration
   1.338 +     */
   1.339 +    void varargsDuplicateError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) {
   1.340 +        if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) {
   1.341 +            log.error(pos, "array.and.varargs", sym1, sym2, sym2.location());
   1.342 +        }
   1.343 +    }
   1.344 +
   1.345 +/* ************************************************************************
   1.346 + * duplicate declaration checking
   1.347 + *************************************************************************/
   1.348 +
   1.349 +    /** Check that variable does not hide variable with same name in
   1.350 +     *  immediately enclosing local scope.
   1.351 +     *  @param pos           Position for error reporting.
   1.352 +     *  @param v             The symbol.
   1.353 +     *  @param s             The scope.
   1.354 +     */
   1.355 +    void checkTransparentVar(DiagnosticPosition pos, VarSymbol v, Scope s) {
   1.356 +        if (s.next != null) {
   1.357 +            for (Scope.Entry e = s.next.lookup(v.name);
   1.358 +                 e.scope != null && e.sym.owner == v.owner;
   1.359 +                 e = e.next()) {
   1.360 +                if (e.sym.kind == VAR &&
   1.361 +                    (e.sym.owner.kind & (VAR | MTH)) != 0 &&
   1.362 +                    v.name != names.error) {
   1.363 +                    duplicateError(pos, e.sym);
   1.364 +                    return;
   1.365 +                }
   1.366 +            }
   1.367 +        }
   1.368 +    }
   1.369 +
   1.370 +    /** Check that a class or interface does not hide a class or
   1.371 +     *  interface with same name in immediately enclosing local scope.
   1.372 +     *  @param pos           Position for error reporting.
   1.373 +     *  @param c             The symbol.
   1.374 +     *  @param s             The scope.
   1.375 +     */
   1.376 +    void checkTransparentClass(DiagnosticPosition pos, ClassSymbol c, Scope s) {
   1.377 +        if (s.next != null) {
   1.378 +            for (Scope.Entry e = s.next.lookup(c.name);
   1.379 +                 e.scope != null && e.sym.owner == c.owner;
   1.380 +                 e = e.next()) {
   1.381 +                if (e.sym.kind == TYP && !e.sym.type.hasTag(TYPEVAR) &&
   1.382 +                    (e.sym.owner.kind & (VAR | MTH)) != 0 &&
   1.383 +                    c.name != names.error) {
   1.384 +                    duplicateError(pos, e.sym);
   1.385 +                    return;
   1.386 +                }
   1.387 +            }
   1.388 +        }
   1.389 +    }
   1.390 +
   1.391 +    /** Check that class does not have the same name as one of
   1.392 +     *  its enclosing classes, or as a class defined in its enclosing scope.
   1.393 +     *  return true if class is unique in its enclosing scope.
   1.394 +     *  @param pos           Position for error reporting.
   1.395 +     *  @param name          The class name.
   1.396 +     *  @param s             The enclosing scope.
   1.397 +     */
   1.398 +    boolean checkUniqueClassName(DiagnosticPosition pos, Name name, Scope s) {
   1.399 +        for (Scope.Entry e = s.lookup(name); e.scope == s; e = e.next()) {
   1.400 +            if (e.sym.kind == TYP && e.sym.name != names.error) {
   1.401 +                duplicateError(pos, e.sym);
   1.402 +                return false;
   1.403 +            }
   1.404 +        }
   1.405 +        for (Symbol sym = s.owner; sym != null; sym = sym.owner) {
   1.406 +            if (sym.kind == TYP && sym.name == name && sym.name != names.error) {
   1.407 +                duplicateError(pos, sym);
   1.408 +                return true;
   1.409 +            }
   1.410 +        }
   1.411 +        return true;
   1.412 +    }
   1.413 +
   1.414 +/* *************************************************************************
   1.415 + * Class name generation
   1.416 + **************************************************************************/
   1.417 +
   1.418 +    /** Return name of local class.
   1.419 +     *  This is of the form   {@code <enclClass> $ n <classname> }
   1.420 +     *  where
   1.421 +     *    enclClass is the flat name of the enclosing class,
   1.422 +     *    classname is the simple name of the local class
   1.423 +     */
   1.424 +    Name localClassName(ClassSymbol c) {
   1.425 +        for (int i=1; ; i++) {
   1.426 +            Name flatname = names.
   1.427 +                fromString("" + c.owner.enclClass().flatname +
   1.428 +                           syntheticNameChar + i +
   1.429 +                           c.name);
   1.430 +            if (compiled.get(flatname) == null) return flatname;
   1.431 +        }
   1.432 +    }
   1.433 +
   1.434 +/* *************************************************************************
   1.435 + * Type Checking
   1.436 + **************************************************************************/
   1.437 +
   1.438 +    /**
   1.439 +     * A check context is an object that can be used to perform compatibility
   1.440 +     * checks - depending on the check context, meaning of 'compatibility' might
   1.441 +     * vary significantly.
   1.442 +     */
   1.443 +    public interface CheckContext {
   1.444 +        /**
   1.445 +         * Is type 'found' compatible with type 'req' in given context
   1.446 +         */
   1.447 +        boolean compatible(Type found, Type req, Warner warn);
   1.448 +        /**
   1.449 +         * Report a check error
   1.450 +         */
   1.451 +        void report(DiagnosticPosition pos, JCDiagnostic details);
   1.452 +        /**
   1.453 +         * Obtain a warner for this check context
   1.454 +         */
   1.455 +        public Warner checkWarner(DiagnosticPosition pos, Type found, Type req);
   1.456 +
   1.457 +        public Infer.InferenceContext inferenceContext();
   1.458 +
   1.459 +        public DeferredAttr.DeferredAttrContext deferredAttrContext();
   1.460 +    }
   1.461 +
   1.462 +    /**
   1.463 +     * This class represent a check context that is nested within another check
   1.464 +     * context - useful to check sub-expressions. The default behavior simply
   1.465 +     * redirects all method calls to the enclosing check context leveraging
   1.466 +     * the forwarding pattern.
   1.467 +     */
   1.468 +    static class NestedCheckContext implements CheckContext {
   1.469 +        CheckContext enclosingContext;
   1.470 +
   1.471 +        NestedCheckContext(CheckContext enclosingContext) {
   1.472 +            this.enclosingContext = enclosingContext;
   1.473 +        }
   1.474 +
   1.475 +        public boolean compatible(Type found, Type req, Warner warn) {
   1.476 +            return enclosingContext.compatible(found, req, warn);
   1.477 +        }
   1.478 +
   1.479 +        public void report(DiagnosticPosition pos, JCDiagnostic details) {
   1.480 +            enclosingContext.report(pos, details);
   1.481 +        }
   1.482 +
   1.483 +        public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
   1.484 +            return enclosingContext.checkWarner(pos, found, req);
   1.485 +        }
   1.486 +
   1.487 +        public Infer.InferenceContext inferenceContext() {
   1.488 +            return enclosingContext.inferenceContext();
   1.489 +        }
   1.490 +
   1.491 +        public DeferredAttrContext deferredAttrContext() {
   1.492 +            return enclosingContext.deferredAttrContext();
   1.493 +        }
   1.494 +    }
   1.495 +
   1.496 +    /**
   1.497 +     * Check context to be used when evaluating assignment/return statements
   1.498 +     */
   1.499 +    CheckContext basicHandler = new CheckContext() {
   1.500 +        public void report(DiagnosticPosition pos, JCDiagnostic details) {
   1.501 +            log.error(pos, "prob.found.req", details);
   1.502 +        }
   1.503 +        public boolean compatible(Type found, Type req, Warner warn) {
   1.504 +            return types.isAssignable(found, req, warn);
   1.505 +        }
   1.506 +
   1.507 +        public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
   1.508 +            return convertWarner(pos, found, req);
   1.509 +        }
   1.510 +
   1.511 +        public InferenceContext inferenceContext() {
   1.512 +            return infer.emptyContext;
   1.513 +        }
   1.514 +
   1.515 +        public DeferredAttrContext deferredAttrContext() {
   1.516 +            return deferredAttr.emptyDeferredAttrContext;
   1.517 +        }
   1.518 +
   1.519 +        @Override
   1.520 +        public String toString() {
   1.521 +            return "CheckContext: basicHandler";
   1.522 +        }
   1.523 +    };
   1.524 +
   1.525 +    /** Check that a given type is assignable to a given proto-type.
   1.526 +     *  If it is, return the type, otherwise return errType.
   1.527 +     *  @param pos        Position to be used for error reporting.
   1.528 +     *  @param found      The type that was found.
   1.529 +     *  @param req        The type that was required.
   1.530 +     */
   1.531 +    Type checkType(DiagnosticPosition pos, Type found, Type req) {
   1.532 +        return checkType(pos, found, req, basicHandler);
   1.533 +    }
   1.534 +
   1.535 +    Type checkType(final DiagnosticPosition pos, final Type found, final Type req, final CheckContext checkContext) {
   1.536 +        final Infer.InferenceContext inferenceContext = checkContext.inferenceContext();
   1.537 +        if (inferenceContext.free(req)) {
   1.538 +            inferenceContext.addFreeTypeListener(List.of(req), new FreeTypeListener() {
   1.539 +                @Override
   1.540 +                public void typesInferred(InferenceContext inferenceContext) {
   1.541 +                    checkType(pos, inferenceContext.asInstType(found), inferenceContext.asInstType(req), checkContext);
   1.542 +                }
   1.543 +            });
   1.544 +        }
   1.545 +        if (req.hasTag(ERROR))
   1.546 +            return req;
   1.547 +        if (req.hasTag(NONE))
   1.548 +            return found;
   1.549 +        if (checkContext.compatible(found, req, checkContext.checkWarner(pos, found, req))) {
   1.550 +            return found;
   1.551 +        } else {
   1.552 +            if (found.isNumeric() && req.isNumeric()) {
   1.553 +                checkContext.report(pos, diags.fragment("possible.loss.of.precision", found, req));
   1.554 +                return types.createErrorType(found);
   1.555 +            }
   1.556 +            checkContext.report(pos, diags.fragment("inconvertible.types", found, req));
   1.557 +            return types.createErrorType(found);
   1.558 +        }
   1.559 +    }
   1.560 +
   1.561 +    /** Check that a given type can be cast to a given target type.
   1.562 +     *  Return the result of the cast.
   1.563 +     *  @param pos        Position to be used for error reporting.
   1.564 +     *  @param found      The type that is being cast.
   1.565 +     *  @param req        The target type of the cast.
   1.566 +     */
   1.567 +    Type checkCastable(DiagnosticPosition pos, Type found, Type req) {
   1.568 +        return checkCastable(pos, found, req, basicHandler);
   1.569 +    }
   1.570 +    Type checkCastable(DiagnosticPosition pos, Type found, Type req, CheckContext checkContext) {
   1.571 +        if (types.isCastable(found, req, castWarner(pos, found, req))) {
   1.572 +            return req;
   1.573 +        } else {
   1.574 +            checkContext.report(pos, diags.fragment("inconvertible.types", found, req));
   1.575 +            return types.createErrorType(found);
   1.576 +        }
   1.577 +    }
   1.578 +
   1.579 +    /** Check for redundant casts (i.e. where source type is a subtype of target type)
   1.580 +     * The problem should only be reported for non-292 cast
   1.581 +     */
   1.582 +    public void checkRedundantCast(Env<AttrContext> env, final JCTypeCast tree) {
   1.583 +        if (!tree.type.isErroneous()
   1.584 +                && types.isSameType(tree.expr.type, tree.clazz.type)
   1.585 +                && !(ignoreAnnotatedCasts && TreeInfo.containsTypeAnnotation(tree.clazz))
   1.586 +                && !is292targetTypeCast(tree)) {
   1.587 +            deferredLintHandler.report(new DeferredLintHandler.LintLogger() {
   1.588 +                @Override
   1.589 +                public void report() {
   1.590 +                    if (lint.isEnabled(Lint.LintCategory.CAST))
   1.591 +                        log.warning(Lint.LintCategory.CAST,
   1.592 +                                tree.pos(), "redundant.cast", tree.expr.type);
   1.593 +                }
   1.594 +            });
   1.595 +        }
   1.596 +    }
   1.597 +    //where
   1.598 +        private boolean is292targetTypeCast(JCTypeCast tree) {
   1.599 +            boolean is292targetTypeCast = false;
   1.600 +            JCExpression expr = TreeInfo.skipParens(tree.expr);
   1.601 +            if (expr.hasTag(APPLY)) {
   1.602 +                JCMethodInvocation apply = (JCMethodInvocation)expr;
   1.603 +                Symbol sym = TreeInfo.symbol(apply.meth);
   1.604 +                is292targetTypeCast = sym != null &&
   1.605 +                    sym.kind == MTH &&
   1.606 +                    (sym.flags() & HYPOTHETICAL) != 0;
   1.607 +            }
   1.608 +            return is292targetTypeCast;
   1.609 +        }
   1.610 +
   1.611 +        private static final boolean ignoreAnnotatedCasts = true;
   1.612 +
   1.613 +    /** Check that a type is within some bounds.
   1.614 +     *
   1.615 +     *  Used in TypeApply to verify that, e.g., X in {@code V<X>} is a valid
   1.616 +     *  type argument.
   1.617 +     *  @param a             The type that should be bounded by bs.
   1.618 +     *  @param bound         The bound.
   1.619 +     */
   1.620 +    private boolean checkExtends(Type a, Type bound) {
   1.621 +         if (a.isUnbound()) {
   1.622 +             return true;
   1.623 +         } else if (!a.hasTag(WILDCARD)) {
   1.624 +             a = types.cvarUpperBound(a);
   1.625 +             return types.isSubtype(a, bound);
   1.626 +         } else if (a.isExtendsBound()) {
   1.627 +             return types.isCastable(bound, types.wildUpperBound(a), types.noWarnings);
   1.628 +         } else if (a.isSuperBound()) {
   1.629 +             return !types.notSoftSubtype(types.wildLowerBound(a), bound);
   1.630 +         }
   1.631 +         return true;
   1.632 +     }
   1.633 +
   1.634 +    /** Check that type is different from 'void'.
   1.635 +     *  @param pos           Position to be used for error reporting.
   1.636 +     *  @param t             The type to be checked.
   1.637 +     */
   1.638 +    Type checkNonVoid(DiagnosticPosition pos, Type t) {
   1.639 +        if (t.hasTag(VOID)) {
   1.640 +            log.error(pos, "void.not.allowed.here");
   1.641 +            return types.createErrorType(t);
   1.642 +        } else {
   1.643 +            return t;
   1.644 +        }
   1.645 +    }
   1.646 +
   1.647 +    Type checkClassOrArrayType(DiagnosticPosition pos, Type t) {
   1.648 +        if (!t.hasTag(CLASS) && !t.hasTag(ARRAY) && !t.hasTag(ERROR)) {
   1.649 +            return typeTagError(pos,
   1.650 +                                diags.fragment("type.req.class.array"),
   1.651 +                                asTypeParam(t));
   1.652 +        } else {
   1.653 +            return t;
   1.654 +        }
   1.655 +    }
   1.656 +
   1.657 +    /** Check that type is a class or interface type.
   1.658 +     *  @param pos           Position to be used for error reporting.
   1.659 +     *  @param t             The type to be checked.
   1.660 +     */
   1.661 +    Type checkClassType(DiagnosticPosition pos, Type t) {
   1.662 +        if (!t.hasTag(CLASS) && !t.hasTag(ERROR)) {
   1.663 +            return typeTagError(pos,
   1.664 +                                diags.fragment("type.req.class"),
   1.665 +                                asTypeParam(t));
   1.666 +        } else {
   1.667 +            return t;
   1.668 +        }
   1.669 +    }
   1.670 +    //where
   1.671 +        private Object asTypeParam(Type t) {
   1.672 +            return (t.hasTag(TYPEVAR))
   1.673 +                                    ? diags.fragment("type.parameter", t)
   1.674 +                                    : t;
   1.675 +        }
   1.676 +
   1.677 +    /** Check that type is a valid qualifier for a constructor reference expression
   1.678 +     */
   1.679 +    Type checkConstructorRefType(DiagnosticPosition pos, Type t) {
   1.680 +        t = checkClassOrArrayType(pos, t);
   1.681 +        if (t.hasTag(CLASS)) {
   1.682 +            if ((t.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) {
   1.683 +                log.error(pos, "abstract.cant.be.instantiated", t.tsym);
   1.684 +                t = types.createErrorType(t);
   1.685 +            } else if ((t.tsym.flags() & ENUM) != 0) {
   1.686 +                log.error(pos, "enum.cant.be.instantiated");
   1.687 +                t = types.createErrorType(t);
   1.688 +            } else {
   1.689 +                t = checkClassType(pos, t, true);
   1.690 +            }
   1.691 +        } else if (t.hasTag(ARRAY)) {
   1.692 +            if (!types.isReifiable(((ArrayType)t).elemtype)) {
   1.693 +                log.error(pos, "generic.array.creation");
   1.694 +                t = types.createErrorType(t);
   1.695 +            }
   1.696 +        }
   1.697 +        return t;
   1.698 +    }
   1.699 +
   1.700 +    /** Check that type is a class or interface type.
   1.701 +     *  @param pos           Position to be used for error reporting.
   1.702 +     *  @param t             The type to be checked.
   1.703 +     *  @param noBounds    True if type bounds are illegal here.
   1.704 +     */
   1.705 +    Type checkClassType(DiagnosticPosition pos, Type t, boolean noBounds) {
   1.706 +        t = checkClassType(pos, t);
   1.707 +        if (noBounds && t.isParameterized()) {
   1.708 +            List<Type> args = t.getTypeArguments();
   1.709 +            while (args.nonEmpty()) {
   1.710 +                if (args.head.hasTag(WILDCARD))
   1.711 +                    return typeTagError(pos,
   1.712 +                                        diags.fragment("type.req.exact"),
   1.713 +                                        args.head);
   1.714 +                args = args.tail;
   1.715 +            }
   1.716 +        }
   1.717 +        return t;
   1.718 +    }
   1.719 +
   1.720 +    /** Check that type is a reference type, i.e. a class, interface or array type
   1.721 +     *  or a type variable.
   1.722 +     *  @param pos           Position to be used for error reporting.
   1.723 +     *  @param t             The type to be checked.
   1.724 +     */
   1.725 +    Type checkRefType(DiagnosticPosition pos, Type t) {
   1.726 +        if (t.isReference())
   1.727 +            return t;
   1.728 +        else
   1.729 +            return typeTagError(pos,
   1.730 +                                diags.fragment("type.req.ref"),
   1.731 +                                t);
   1.732 +    }
   1.733 +
   1.734 +    /** Check that each type is a reference type, i.e. a class, interface or array type
   1.735 +     *  or a type variable.
   1.736 +     *  @param trees         Original trees, used for error reporting.
   1.737 +     *  @param types         The types to be checked.
   1.738 +     */
   1.739 +    List<Type> checkRefTypes(List<JCExpression> trees, List<Type> types) {
   1.740 +        List<JCExpression> tl = trees;
   1.741 +        for (List<Type> l = types; l.nonEmpty(); l = l.tail) {
   1.742 +            l.head = checkRefType(tl.head.pos(), l.head);
   1.743 +            tl = tl.tail;
   1.744 +        }
   1.745 +        return types;
   1.746 +    }
   1.747 +
   1.748 +    /** Check that type is a null or reference type.
   1.749 +     *  @param pos           Position to be used for error reporting.
   1.750 +     *  @param t             The type to be checked.
   1.751 +     */
   1.752 +    Type checkNullOrRefType(DiagnosticPosition pos, Type t) {
   1.753 +        if (t.isReference() || t.hasTag(BOT))
   1.754 +            return t;
   1.755 +        else
   1.756 +            return typeTagError(pos,
   1.757 +                                diags.fragment("type.req.ref"),
   1.758 +                                t);
   1.759 +    }
   1.760 +
   1.761 +    /** Check that flag set does not contain elements of two conflicting sets. s
   1.762 +     *  Return true if it doesn't.
   1.763 +     *  @param pos           Position to be used for error reporting.
   1.764 +     *  @param flags         The set of flags to be checked.
   1.765 +     *  @param set1          Conflicting flags set #1.
   1.766 +     *  @param set2          Conflicting flags set #2.
   1.767 +     */
   1.768 +    boolean checkDisjoint(DiagnosticPosition pos, long flags, long set1, long set2) {
   1.769 +        if ((flags & set1) != 0 && (flags & set2) != 0) {
   1.770 +            log.error(pos,
   1.771 +                      "illegal.combination.of.modifiers",
   1.772 +                      asFlagSet(TreeInfo.firstFlag(flags & set1)),
   1.773 +                      asFlagSet(TreeInfo.firstFlag(flags & set2)));
   1.774 +            return false;
   1.775 +        } else
   1.776 +            return true;
   1.777 +    }
   1.778 +
   1.779 +    /** Check that usage of diamond operator is correct (i.e. diamond should not
   1.780 +     * be used with non-generic classes or in anonymous class creation expressions)
   1.781 +     */
   1.782 +    Type checkDiamond(JCNewClass tree, Type t) {
   1.783 +        if (!TreeInfo.isDiamond(tree) ||
   1.784 +                t.isErroneous()) {
   1.785 +            return checkClassType(tree.clazz.pos(), t, true);
   1.786 +        } else if (tree.def != null) {
   1.787 +            log.error(tree.clazz.pos(),
   1.788 +                    "cant.apply.diamond.1",
   1.789 +                    t, diags.fragment("diamond.and.anon.class", t));
   1.790 +            return types.createErrorType(t);
   1.791 +        } else if (t.tsym.type.getTypeArguments().isEmpty()) {
   1.792 +            log.error(tree.clazz.pos(),
   1.793 +                "cant.apply.diamond.1",
   1.794 +                t, diags.fragment("diamond.non.generic", t));
   1.795 +            return types.createErrorType(t);
   1.796 +        } else if (tree.typeargs != null &&
   1.797 +                tree.typeargs.nonEmpty()) {
   1.798 +            log.error(tree.clazz.pos(),
   1.799 +                "cant.apply.diamond.1",
   1.800 +                t, diags.fragment("diamond.and.explicit.params", t));
   1.801 +            return types.createErrorType(t);
   1.802 +        } else {
   1.803 +            return t;
   1.804 +        }
   1.805 +    }
   1.806 +
   1.807 +    void checkVarargsMethodDecl(Env<AttrContext> env, JCMethodDecl tree) {
   1.808 +        MethodSymbol m = tree.sym;
   1.809 +        if (!allowSimplifiedVarargs) return;
   1.810 +        boolean hasTrustMeAnno = m.attribute(syms.trustMeType.tsym) != null;
   1.811 +        Type varargElemType = null;
   1.812 +        if (m.isVarArgs()) {
   1.813 +            varargElemType = types.elemtype(tree.params.last().type);
   1.814 +        }
   1.815 +        if (hasTrustMeAnno && !isTrustMeAllowedOnMethod(m)) {
   1.816 +            if (varargElemType != null) {
   1.817 +                log.error(tree,
   1.818 +                        "varargs.invalid.trustme.anno",
   1.819 +                        syms.trustMeType.tsym,
   1.820 +                        diags.fragment("varargs.trustme.on.virtual.varargs", m));
   1.821 +            } else {
   1.822 +                log.error(tree,
   1.823 +                            "varargs.invalid.trustme.anno",
   1.824 +                            syms.trustMeType.tsym,
   1.825 +                            diags.fragment("varargs.trustme.on.non.varargs.meth", m));
   1.826 +            }
   1.827 +        } else if (hasTrustMeAnno && varargElemType != null &&
   1.828 +                            types.isReifiable(varargElemType)) {
   1.829 +            warnUnsafeVararg(tree,
   1.830 +                            "varargs.redundant.trustme.anno",
   1.831 +                            syms.trustMeType.tsym,
   1.832 +                            diags.fragment("varargs.trustme.on.reifiable.varargs", varargElemType));
   1.833 +        }
   1.834 +        else if (!hasTrustMeAnno && varargElemType != null &&
   1.835 +                !types.isReifiable(varargElemType)) {
   1.836 +            warnUnchecked(tree.params.head.pos(), "unchecked.varargs.non.reifiable.type", varargElemType);
   1.837 +        }
   1.838 +    }
   1.839 +    //where
   1.840 +        private boolean isTrustMeAllowedOnMethod(Symbol s) {
   1.841 +            return (s.flags() & VARARGS) != 0 &&
   1.842 +                (s.isConstructor() ||
   1.843 +                    (s.flags() & (STATIC | FINAL)) != 0);
   1.844 +        }
   1.845 +
   1.846 +    Type checkMethod(final Type mtype,
   1.847 +            final Symbol sym,
   1.848 +            final Env<AttrContext> env,
   1.849 +            final List<JCExpression> argtrees,
   1.850 +            final List<Type> argtypes,
   1.851 +            final boolean useVarargs,
   1.852 +            InferenceContext inferenceContext) {
   1.853 +        // System.out.println("call   : " + env.tree);
   1.854 +        // System.out.println("method : " + owntype);
   1.855 +        // System.out.println("actuals: " + argtypes);
   1.856 +        if (inferenceContext.free(mtype)) {
   1.857 +            inferenceContext.addFreeTypeListener(List.of(mtype), new FreeTypeListener() {
   1.858 +                public void typesInferred(InferenceContext inferenceContext) {
   1.859 +                    checkMethod(inferenceContext.asInstType(mtype), sym, env, argtrees, argtypes, useVarargs, inferenceContext);
   1.860 +                }
   1.861 +            });
   1.862 +            return mtype;
   1.863 +        }
   1.864 +        Type owntype = mtype;
   1.865 +        List<Type> formals = owntype.getParameterTypes();
   1.866 +        List<Type> nonInferred = sym.type.getParameterTypes();
   1.867 +        if (nonInferred.length() != formals.length()) nonInferred = formals;
   1.868 +        Type last = useVarargs ? formals.last() : null;
   1.869 +        if (sym.name == names.init && sym.owner == syms.enumSym) {
   1.870 +            formals = formals.tail.tail;
   1.871 +            nonInferred = nonInferred.tail.tail;
   1.872 +        }
   1.873 +        List<JCExpression> args = argtrees;
   1.874 +        if (args != null) {
   1.875 +            //this is null when type-checking a method reference
   1.876 +            while (formals.head != last) {
   1.877 +                JCTree arg = args.head;
   1.878 +                Warner warn = convertWarner(arg.pos(), arg.type, nonInferred.head);
   1.879 +                assertConvertible(arg, arg.type, formals.head, warn);
   1.880 +                args = args.tail;
   1.881 +                formals = formals.tail;
   1.882 +                nonInferred = nonInferred.tail;
   1.883 +            }
   1.884 +            if (useVarargs) {
   1.885 +                Type varArg = types.elemtype(last);
   1.886 +                while (args.tail != null) {
   1.887 +                    JCTree arg = args.head;
   1.888 +                    Warner warn = convertWarner(arg.pos(), arg.type, varArg);
   1.889 +                    assertConvertible(arg, arg.type, varArg, warn);
   1.890 +                    args = args.tail;
   1.891 +                }
   1.892 +            } else if ((sym.flags() & (VARARGS | SIGNATURE_POLYMORPHIC)) == VARARGS &&
   1.893 +                    allowVarargs) {
   1.894 +                // non-varargs call to varargs method
   1.895 +                Type varParam = owntype.getParameterTypes().last();
   1.896 +                Type lastArg = argtypes.last();
   1.897 +                if (types.isSubtypeUnchecked(lastArg, types.elemtype(varParam)) &&
   1.898 +                    !types.isSameType(types.erasure(varParam), types.erasure(lastArg)))
   1.899 +                    log.warning(argtrees.last().pos(), "inexact.non-varargs.call",
   1.900 +                                types.elemtype(varParam), varParam);
   1.901 +            }
   1.902 +        }
   1.903 +        if (useVarargs) {
   1.904 +            Type argtype = owntype.getParameterTypes().last();
   1.905 +            if (!types.isReifiable(argtype) &&
   1.906 +                (!allowSimplifiedVarargs ||
   1.907 +                 sym.attribute(syms.trustMeType.tsym) == null ||
   1.908 +                 !isTrustMeAllowedOnMethod(sym))) {
   1.909 +                warnUnchecked(env.tree.pos(),
   1.910 +                                  "unchecked.generic.array.creation",
   1.911 +                                  argtype);
   1.912 +            }
   1.913 +            if ((sym.baseSymbol().flags() & SIGNATURE_POLYMORPHIC) == 0) {
   1.914 +                TreeInfo.setVarargsElement(env.tree, types.elemtype(argtype));
   1.915 +            }
   1.916 +         }
   1.917 +         PolyKind pkind = (sym.type.hasTag(FORALL) &&
   1.918 +                 sym.type.getReturnType().containsAny(((ForAll)sym.type).tvars)) ?
   1.919 +                 PolyKind.POLY : PolyKind.STANDALONE;
   1.920 +         TreeInfo.setPolyKind(env.tree, pkind);
   1.921 +         return owntype;
   1.922 +    }
   1.923 +    //where
   1.924 +    private void assertConvertible(JCTree tree, Type actual, Type formal, Warner warn) {
   1.925 +        if (types.isConvertible(actual, formal, warn))
   1.926 +            return;
   1.927 +
   1.928 +        if (formal.isCompound()
   1.929 +            && types.isSubtype(actual, types.supertype(formal))
   1.930 +            && types.isSubtypeUnchecked(actual, types.interfaces(formal), warn))
   1.931 +            return;
   1.932 +    }
   1.933 +
   1.934 +    /**
   1.935 +     * Check that type 't' is a valid instantiation of a generic class
   1.936 +     * (see JLS 4.5)
   1.937 +     *
   1.938 +     * @param t class type to be checked
   1.939 +     * @return true if 't' is well-formed
   1.940 +     */
   1.941 +    public boolean checkValidGenericType(Type t) {
   1.942 +        return firstIncompatibleTypeArg(t) == null;
   1.943 +    }
   1.944 +    //WHERE
   1.945 +        private Type firstIncompatibleTypeArg(Type type) {
   1.946 +            List<Type> formals = type.tsym.type.allparams();
   1.947 +            List<Type> actuals = type.allparams();
   1.948 +            List<Type> args = type.getTypeArguments();
   1.949 +            List<Type> forms = type.tsym.type.getTypeArguments();
   1.950 +            ListBuffer<Type> bounds_buf = new ListBuffer<Type>();
   1.951 +
   1.952 +            // For matching pairs of actual argument types `a' and
   1.953 +            // formal type parameters with declared bound `b' ...
   1.954 +            while (args.nonEmpty() && forms.nonEmpty()) {
   1.955 +                // exact type arguments needs to know their
   1.956 +                // bounds (for upper and lower bound
   1.957 +                // calculations).  So we create new bounds where
   1.958 +                // type-parameters are replaced with actuals argument types.
   1.959 +                bounds_buf.append(types.subst(forms.head.getUpperBound(), formals, actuals));
   1.960 +                args = args.tail;
   1.961 +                forms = forms.tail;
   1.962 +            }
   1.963 +
   1.964 +            args = type.getTypeArguments();
   1.965 +            List<Type> tvars_cap = types.substBounds(formals,
   1.966 +                                      formals,
   1.967 +                                      types.capture(type).allparams());
   1.968 +            while (args.nonEmpty() && tvars_cap.nonEmpty()) {
   1.969 +                // Let the actual arguments know their bound
   1.970 +                args.head.withTypeVar((TypeVar)tvars_cap.head);
   1.971 +                args = args.tail;
   1.972 +                tvars_cap = tvars_cap.tail;
   1.973 +            }
   1.974 +
   1.975 +            args = type.getTypeArguments();
   1.976 +            List<Type> bounds = bounds_buf.toList();
   1.977 +
   1.978 +            while (args.nonEmpty() && bounds.nonEmpty()) {
   1.979 +                Type actual = args.head;
   1.980 +                if (!isTypeArgErroneous(actual) &&
   1.981 +                        !bounds.head.isErroneous() &&
   1.982 +                        !checkExtends(actual, bounds.head)) {
   1.983 +                    return args.head;
   1.984 +                }
   1.985 +                args = args.tail;
   1.986 +                bounds = bounds.tail;
   1.987 +            }
   1.988 +
   1.989 +            args = type.getTypeArguments();
   1.990 +            bounds = bounds_buf.toList();
   1.991 +
   1.992 +            for (Type arg : types.capture(type).getTypeArguments()) {
   1.993 +                if (arg.hasTag(TYPEVAR) &&
   1.994 +                        arg.getUpperBound().isErroneous() &&
   1.995 +                        !bounds.head.isErroneous() &&
   1.996 +                        !isTypeArgErroneous(args.head)) {
   1.997 +                    return args.head;
   1.998 +                }
   1.999 +                bounds = bounds.tail;
  1.1000 +                args = args.tail;
  1.1001 +            }
  1.1002 +
  1.1003 +            return null;
  1.1004 +        }
  1.1005 +        //where
  1.1006 +        boolean isTypeArgErroneous(Type t) {
  1.1007 +            return isTypeArgErroneous.visit(t);
  1.1008 +        }
  1.1009 +
  1.1010 +        Types.UnaryVisitor<Boolean> isTypeArgErroneous = new Types.UnaryVisitor<Boolean>() {
  1.1011 +            public Boolean visitType(Type t, Void s) {
  1.1012 +                return t.isErroneous();
  1.1013 +            }
  1.1014 +            @Override
  1.1015 +            public Boolean visitTypeVar(TypeVar t, Void s) {
  1.1016 +                return visit(t.getUpperBound());
  1.1017 +            }
  1.1018 +            @Override
  1.1019 +            public Boolean visitCapturedType(CapturedType t, Void s) {
  1.1020 +                return visit(t.getUpperBound()) ||
  1.1021 +                        visit(t.getLowerBound());
  1.1022 +            }
  1.1023 +            @Override
  1.1024 +            public Boolean visitWildcardType(WildcardType t, Void s) {
  1.1025 +                return visit(t.type);
  1.1026 +            }
  1.1027 +        };
  1.1028 +
  1.1029 +    /** Check that given modifiers are legal for given symbol and
  1.1030 +     *  return modifiers together with any implicit modifiers for that symbol.
  1.1031 +     *  Warning: we can't use flags() here since this method
  1.1032 +     *  is called during class enter, when flags() would cause a premature
  1.1033 +     *  completion.
  1.1034 +     *  @param pos           Position to be used for error reporting.
  1.1035 +     *  @param flags         The set of modifiers given in a definition.
  1.1036 +     *  @param sym           The defined symbol.
  1.1037 +     */
  1.1038 +    long checkFlags(DiagnosticPosition pos, long flags, Symbol sym, JCTree tree) {
  1.1039 +        long mask;
  1.1040 +        long implicit = 0;
  1.1041 +
  1.1042 +        switch (sym.kind) {
  1.1043 +        case VAR:
  1.1044 +            if (TreeInfo.isReceiverParam(tree))
  1.1045 +                mask = ReceiverParamFlags;
  1.1046 +            else if (sym.owner.kind != TYP)
  1.1047 +                mask = LocalVarFlags;
  1.1048 +            else if ((sym.owner.flags_field & INTERFACE) != 0)
  1.1049 +                mask = implicit = InterfaceVarFlags;
  1.1050 +            else
  1.1051 +                mask = VarFlags;
  1.1052 +            break;
  1.1053 +        case MTH:
  1.1054 +            if (sym.name == names.init) {
  1.1055 +                if ((sym.owner.flags_field & ENUM) != 0) {
  1.1056 +                    // enum constructors cannot be declared public or
  1.1057 +                    // protected and must be implicitly or explicitly
  1.1058 +                    // private
  1.1059 +                    implicit = PRIVATE;
  1.1060 +                    mask = PRIVATE;
  1.1061 +                } else
  1.1062 +                    mask = ConstructorFlags;
  1.1063 +            }  else if ((sym.owner.flags_field & INTERFACE) != 0) {
  1.1064 +                if ((sym.owner.flags_field & ANNOTATION) != 0) {
  1.1065 +                    mask = AnnotationTypeElementMask;
  1.1066 +                    implicit = PUBLIC | ABSTRACT;
  1.1067 +                } else if ((flags & (DEFAULT | STATIC)) != 0) {
  1.1068 +                    mask = InterfaceMethodMask;
  1.1069 +                    implicit = PUBLIC;
  1.1070 +                    if ((flags & DEFAULT) != 0) {
  1.1071 +                        implicit |= ABSTRACT;
  1.1072 +                    }
  1.1073 +                } else {
  1.1074 +                    mask = implicit = InterfaceMethodFlags;
  1.1075 +                }
  1.1076 +            } else {
  1.1077 +                mask = MethodFlags;
  1.1078 +            }
  1.1079 +            // Imply STRICTFP if owner has STRICTFP set.
  1.1080 +            if (((flags|implicit) & Flags.ABSTRACT) == 0 ||
  1.1081 +                ((flags) & Flags.DEFAULT) != 0)
  1.1082 +                implicit |= sym.owner.flags_field & STRICTFP;
  1.1083 +            break;
  1.1084 +        case TYP:
  1.1085 +            if (sym.isLocal()) {
  1.1086 +                mask = LocalClassFlags;
  1.1087 +                if (sym.name.isEmpty()) { // Anonymous class
  1.1088 +                    // Anonymous classes in static methods are themselves static;
  1.1089 +                    // that's why we admit STATIC here.
  1.1090 +                    mask |= STATIC;
  1.1091 +                    // JLS: Anonymous classes are final.
  1.1092 +                    implicit |= FINAL;
  1.1093 +                }
  1.1094 +                if ((sym.owner.flags_field & STATIC) == 0 &&
  1.1095 +                    (flags & ENUM) != 0)
  1.1096 +                    log.error(pos, "enums.must.be.static");
  1.1097 +            } else if (sym.owner.kind == TYP) {
  1.1098 +                mask = MemberClassFlags;
  1.1099 +                if (sym.owner.owner.kind == PCK ||
  1.1100 +                    (sym.owner.flags_field & STATIC) != 0)
  1.1101 +                    mask |= STATIC;
  1.1102 +                else if ((flags & ENUM) != 0)
  1.1103 +                    log.error(pos, "enums.must.be.static");
  1.1104 +                // Nested interfaces and enums are always STATIC (Spec ???)
  1.1105 +                if ((flags & (INTERFACE | ENUM)) != 0 ) implicit = STATIC;
  1.1106 +            } else {
  1.1107 +                mask = ClassFlags;
  1.1108 +            }
  1.1109 +            // Interfaces are always ABSTRACT
  1.1110 +            if ((flags & INTERFACE) != 0) implicit |= ABSTRACT;
  1.1111 +
  1.1112 +            if ((flags & ENUM) != 0) {
  1.1113 +                // enums can't be declared abstract or final
  1.1114 +                mask &= ~(ABSTRACT | FINAL);
  1.1115 +                implicit |= implicitEnumFinalFlag(tree);
  1.1116 +            }
  1.1117 +            // Imply STRICTFP if owner has STRICTFP set.
  1.1118 +            implicit |= sym.owner.flags_field & STRICTFP;
  1.1119 +            break;
  1.1120 +        default:
  1.1121 +            throw new AssertionError();
  1.1122 +        }
  1.1123 +        long illegal = flags & ExtendedStandardFlags & ~mask;
  1.1124 +        if (illegal != 0) {
  1.1125 +            if ((illegal & INTERFACE) != 0) {
  1.1126 +                log.error(pos, "intf.not.allowed.here");
  1.1127 +                mask |= INTERFACE;
  1.1128 +            }
  1.1129 +            else {
  1.1130 +                log.error(pos,
  1.1131 +                          "mod.not.allowed.here", asFlagSet(illegal));
  1.1132 +            }
  1.1133 +        }
  1.1134 +        else if ((sym.kind == TYP ||
  1.1135 +                  // ISSUE: Disallowing abstract&private is no longer appropriate
  1.1136 +                  // in the presence of inner classes. Should it be deleted here?
  1.1137 +                  checkDisjoint(pos, flags,
  1.1138 +                                ABSTRACT,
  1.1139 +                                PRIVATE | STATIC | DEFAULT))
  1.1140 +                 &&
  1.1141 +                 checkDisjoint(pos, flags,
  1.1142 +                                STATIC,
  1.1143 +                                DEFAULT)
  1.1144 +                 &&
  1.1145 +                 checkDisjoint(pos, flags,
  1.1146 +                               ABSTRACT | INTERFACE,
  1.1147 +                               FINAL | NATIVE | SYNCHRONIZED)
  1.1148 +                 &&
  1.1149 +                 checkDisjoint(pos, flags,
  1.1150 +                               PUBLIC,
  1.1151 +                               PRIVATE | PROTECTED)
  1.1152 +                 &&
  1.1153 +                 checkDisjoint(pos, flags,
  1.1154 +                               PRIVATE,
  1.1155 +                               PUBLIC | PROTECTED)
  1.1156 +                 &&
  1.1157 +                 checkDisjoint(pos, flags,
  1.1158 +                               FINAL,
  1.1159 +                               VOLATILE)
  1.1160 +                 &&
  1.1161 +                 (sym.kind == TYP ||
  1.1162 +                  checkDisjoint(pos, flags,
  1.1163 +                                ABSTRACT | NATIVE,
  1.1164 +                                STRICTFP))) {
  1.1165 +            // skip
  1.1166 +        }
  1.1167 +        return flags & (mask | ~ExtendedStandardFlags) | implicit;
  1.1168 +    }
  1.1169 +
  1.1170 +
  1.1171 +    /** Determine if this enum should be implicitly final.
  1.1172 +     *
  1.1173 +     *  If the enum has no specialized enum contants, it is final.
  1.1174 +     *
  1.1175 +     *  If the enum does have specialized enum contants, it is
  1.1176 +     *  <i>not</i> final.
  1.1177 +     */
  1.1178 +    private long implicitEnumFinalFlag(JCTree tree) {
  1.1179 +        if (!tree.hasTag(CLASSDEF)) return 0;
  1.1180 +        class SpecialTreeVisitor extends JCTree.Visitor {
  1.1181 +            boolean specialized;
  1.1182 +            SpecialTreeVisitor() {
  1.1183 +                this.specialized = false;
  1.1184 +            };
  1.1185 +
  1.1186 +            @Override
  1.1187 +            public void visitTree(JCTree tree) { /* no-op */ }
  1.1188 +
  1.1189 +            @Override
  1.1190 +            public void visitVarDef(JCVariableDecl tree) {
  1.1191 +                if ((tree.mods.flags & ENUM) != 0) {
  1.1192 +                    if (tree.init instanceof JCNewClass &&
  1.1193 +                        ((JCNewClass) tree.init).def != null) {
  1.1194 +                        specialized = true;
  1.1195 +                    }
  1.1196 +                }
  1.1197 +            }
  1.1198 +        }
  1.1199 +
  1.1200 +        SpecialTreeVisitor sts = new SpecialTreeVisitor();
  1.1201 +        JCClassDecl cdef = (JCClassDecl) tree;
  1.1202 +        for (JCTree defs: cdef.defs) {
  1.1203 +            defs.accept(sts);
  1.1204 +            if (sts.specialized) return 0;
  1.1205 +        }
  1.1206 +        return FINAL;
  1.1207 +    }
  1.1208 +
  1.1209 +/* *************************************************************************
  1.1210 + * Type Validation
  1.1211 + **************************************************************************/
  1.1212 +
  1.1213 +    /** Validate a type expression. That is,
  1.1214 +     *  check that all type arguments of a parametric type are within
  1.1215 +     *  their bounds. This must be done in a second phase after type attribution
  1.1216 +     *  since a class might have a subclass as type parameter bound. E.g:
  1.1217 +     *
  1.1218 +     *  <pre>{@code
  1.1219 +     *  class B<A extends C> { ... }
  1.1220 +     *  class C extends B<C> { ... }
  1.1221 +     *  }</pre>
  1.1222 +     *
  1.1223 +     *  and we can't make sure that the bound is already attributed because
  1.1224 +     *  of possible cycles.
  1.1225 +     *
  1.1226 +     * Visitor method: Validate a type expression, if it is not null, catching
  1.1227 +     *  and reporting any completion failures.
  1.1228 +     */
  1.1229 +    void validate(JCTree tree, Env<AttrContext> env) {
  1.1230 +        validate(tree, env, true);
  1.1231 +    }
  1.1232 +    void validate(JCTree tree, Env<AttrContext> env, boolean checkRaw) {
  1.1233 +        new Validator(env).validateTree(tree, checkRaw, true);
  1.1234 +    }
  1.1235 +
  1.1236 +    /** Visitor method: Validate a list of type expressions.
  1.1237 +     */
  1.1238 +    void validate(List<? extends JCTree> trees, Env<AttrContext> env) {
  1.1239 +        for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail)
  1.1240 +            validate(l.head, env);
  1.1241 +    }
  1.1242 +
  1.1243 +    /** A visitor class for type validation.
  1.1244 +     */
  1.1245 +    class Validator extends JCTree.Visitor {
  1.1246 +
  1.1247 +        boolean checkRaw;
  1.1248 +        boolean isOuter;
  1.1249 +        Env<AttrContext> env;
  1.1250 +
  1.1251 +        Validator(Env<AttrContext> env) {
  1.1252 +            this.env = env;
  1.1253 +        }
  1.1254 +
  1.1255 +        @Override
  1.1256 +        public void visitTypeArray(JCArrayTypeTree tree) {
  1.1257 +            validateTree(tree.elemtype, checkRaw, isOuter);
  1.1258 +        }
  1.1259 +
  1.1260 +        @Override
  1.1261 +        public void visitTypeApply(JCTypeApply tree) {
  1.1262 +            if (tree.type.hasTag(CLASS)) {
  1.1263 +                List<JCExpression> args = tree.arguments;
  1.1264 +                List<Type> forms = tree.type.tsym.type.getTypeArguments();
  1.1265 +
  1.1266 +                Type incompatibleArg = firstIncompatibleTypeArg(tree.type);
  1.1267 +                if (incompatibleArg != null) {
  1.1268 +                    for (JCTree arg : tree.arguments) {
  1.1269 +                        if (arg.type == incompatibleArg) {
  1.1270 +                            log.error(arg, "not.within.bounds", incompatibleArg, forms.head);
  1.1271 +                        }
  1.1272 +                        forms = forms.tail;
  1.1273 +                     }
  1.1274 +                 }
  1.1275 +
  1.1276 +                forms = tree.type.tsym.type.getTypeArguments();
  1.1277 +
  1.1278 +                boolean is_java_lang_Class = tree.type.tsym.flatName() == names.java_lang_Class;
  1.1279 +
  1.1280 +                // For matching pairs of actual argument types `a' and
  1.1281 +                // formal type parameters with declared bound `b' ...
  1.1282 +                while (args.nonEmpty() && forms.nonEmpty()) {
  1.1283 +                    validateTree(args.head,
  1.1284 +                            !(isOuter && is_java_lang_Class),
  1.1285 +                            false);
  1.1286 +                    args = args.tail;
  1.1287 +                    forms = forms.tail;
  1.1288 +                }
  1.1289 +
  1.1290 +                // Check that this type is either fully parameterized, or
  1.1291 +                // not parameterized at all.
  1.1292 +                if (tree.type.getEnclosingType().isRaw())
  1.1293 +                    log.error(tree.pos(), "improperly.formed.type.inner.raw.param");
  1.1294 +                if (tree.clazz.hasTag(SELECT))
  1.1295 +                    visitSelectInternal((JCFieldAccess)tree.clazz);
  1.1296 +            }
  1.1297 +        }
  1.1298 +
  1.1299 +        @Override
  1.1300 +        public void visitTypeParameter(JCTypeParameter tree) {
  1.1301 +            validateTrees(tree.bounds, true, isOuter);
  1.1302 +            checkClassBounds(tree.pos(), tree.type);
  1.1303 +        }
  1.1304 +
  1.1305 +        @Override
  1.1306 +        public void visitWildcard(JCWildcard tree) {
  1.1307 +            if (tree.inner != null)
  1.1308 +                validateTree(tree.inner, true, isOuter);
  1.1309 +        }
  1.1310 +
  1.1311 +        @Override
  1.1312 +        public void visitSelect(JCFieldAccess tree) {
  1.1313 +            if (tree.type.hasTag(CLASS)) {
  1.1314 +                visitSelectInternal(tree);
  1.1315 +
  1.1316 +                // Check that this type is either fully parameterized, or
  1.1317 +                // not parameterized at all.
  1.1318 +                if (tree.selected.type.isParameterized() && tree.type.tsym.type.getTypeArguments().nonEmpty())
  1.1319 +                    log.error(tree.pos(), "improperly.formed.type.param.missing");
  1.1320 +            }
  1.1321 +        }
  1.1322 +
  1.1323 +        public void visitSelectInternal(JCFieldAccess tree) {
  1.1324 +            if (tree.type.tsym.isStatic() &&
  1.1325 +                tree.selected.type.isParameterized()) {
  1.1326 +                // The enclosing type is not a class, so we are
  1.1327 +                // looking at a static member type.  However, the
  1.1328 +                // qualifying expression is parameterized.
  1.1329 +                log.error(tree.pos(), "cant.select.static.class.from.param.type");
  1.1330 +            } else {
  1.1331 +                // otherwise validate the rest of the expression
  1.1332 +                tree.selected.accept(this);
  1.1333 +            }
  1.1334 +        }
  1.1335 +
  1.1336 +        @Override
  1.1337 +        public void visitAnnotatedType(JCAnnotatedType tree) {
  1.1338 +            tree.underlyingType.accept(this);
  1.1339 +        }
  1.1340 +
  1.1341 +        @Override
  1.1342 +        public void visitTypeIdent(JCPrimitiveTypeTree that) {
  1.1343 +            if (that.type.hasTag(TypeTag.VOID)) {
  1.1344 +                log.error(that.pos(), "void.not.allowed.here");
  1.1345 +            }
  1.1346 +            super.visitTypeIdent(that);
  1.1347 +        }
  1.1348 +
  1.1349 +        /** Default visitor method: do nothing.
  1.1350 +         */
  1.1351 +        @Override
  1.1352 +        public void visitTree(JCTree tree) {
  1.1353 +        }
  1.1354 +
  1.1355 +        public void validateTree(JCTree tree, boolean checkRaw, boolean isOuter) {
  1.1356 +            if (tree != null) {
  1.1357 +                boolean prevCheckRaw = this.checkRaw;
  1.1358 +                this.checkRaw = checkRaw;
  1.1359 +                this.isOuter = isOuter;
  1.1360 +
  1.1361 +                try {
  1.1362 +                    tree.accept(this);
  1.1363 +                    if (checkRaw)
  1.1364 +                        checkRaw(tree, env);
  1.1365 +                } catch (CompletionFailure ex) {
  1.1366 +                    completionError(tree.pos(), ex);
  1.1367 +                } finally {
  1.1368 +                    this.checkRaw = prevCheckRaw;
  1.1369 +                }
  1.1370 +            }
  1.1371 +        }
  1.1372 +
  1.1373 +        public void validateTrees(List<? extends JCTree> trees, boolean checkRaw, boolean isOuter) {
  1.1374 +            for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail)
  1.1375 +                validateTree(l.head, checkRaw, isOuter);
  1.1376 +        }
  1.1377 +    }
  1.1378 +
  1.1379 +    void checkRaw(JCTree tree, Env<AttrContext> env) {
  1.1380 +        if (lint.isEnabled(LintCategory.RAW) &&
  1.1381 +            tree.type.hasTag(CLASS) &&
  1.1382 +            !TreeInfo.isDiamond(tree) &&
  1.1383 +            !withinAnonConstr(env) &&
  1.1384 +            tree.type.isRaw()) {
  1.1385 +            log.warning(LintCategory.RAW,
  1.1386 +                    tree.pos(), "raw.class.use", tree.type, tree.type.tsym.type);
  1.1387 +        }
  1.1388 +    }
  1.1389 +    //where
  1.1390 +        private boolean withinAnonConstr(Env<AttrContext> env) {
  1.1391 +            return env.enclClass.name.isEmpty() &&
  1.1392 +                    env.enclMethod != null && env.enclMethod.name == names.init;
  1.1393 +        }
  1.1394 +
  1.1395 +/* *************************************************************************
  1.1396 + * Exception checking
  1.1397 + **************************************************************************/
  1.1398 +
  1.1399 +    /* The following methods treat classes as sets that contain
  1.1400 +     * the class itself and all their subclasses
  1.1401 +     */
  1.1402 +
  1.1403 +    /** Is given type a subtype of some of the types in given list?
  1.1404 +     */
  1.1405 +    boolean subset(Type t, List<Type> ts) {
  1.1406 +        for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
  1.1407 +            if (types.isSubtype(t, l.head)) return true;
  1.1408 +        return false;
  1.1409 +    }
  1.1410 +
  1.1411 +    /** Is given type a subtype or supertype of
  1.1412 +     *  some of the types in given list?
  1.1413 +     */
  1.1414 +    boolean intersects(Type t, List<Type> ts) {
  1.1415 +        for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
  1.1416 +            if (types.isSubtype(t, l.head) || types.isSubtype(l.head, t)) return true;
  1.1417 +        return false;
  1.1418 +    }
  1.1419 +
  1.1420 +    /** Add type set to given type list, unless it is a subclass of some class
  1.1421 +     *  in the list.
  1.1422 +     */
  1.1423 +    List<Type> incl(Type t, List<Type> ts) {
  1.1424 +        return subset(t, ts) ? ts : excl(t, ts).prepend(t);
  1.1425 +    }
  1.1426 +
  1.1427 +    /** Remove type set from type set list.
  1.1428 +     */
  1.1429 +    List<Type> excl(Type t, List<Type> ts) {
  1.1430 +        if (ts.isEmpty()) {
  1.1431 +            return ts;
  1.1432 +        } else {
  1.1433 +            List<Type> ts1 = excl(t, ts.tail);
  1.1434 +            if (types.isSubtype(ts.head, t)) return ts1;
  1.1435 +            else if (ts1 == ts.tail) return ts;
  1.1436 +            else return ts1.prepend(ts.head);
  1.1437 +        }
  1.1438 +    }
  1.1439 +
  1.1440 +    /** Form the union of two type set lists.
  1.1441 +     */
  1.1442 +    List<Type> union(List<Type> ts1, List<Type> ts2) {
  1.1443 +        List<Type> ts = ts1;
  1.1444 +        for (List<Type> l = ts2; l.nonEmpty(); l = l.tail)
  1.1445 +            ts = incl(l.head, ts);
  1.1446 +        return ts;
  1.1447 +    }
  1.1448 +
  1.1449 +    /** Form the difference of two type lists.
  1.1450 +     */
  1.1451 +    List<Type> diff(List<Type> ts1, List<Type> ts2) {
  1.1452 +        List<Type> ts = ts1;
  1.1453 +        for (List<Type> l = ts2; l.nonEmpty(); l = l.tail)
  1.1454 +            ts = excl(l.head, ts);
  1.1455 +        return ts;
  1.1456 +    }
  1.1457 +
  1.1458 +    /** Form the intersection of two type lists.
  1.1459 +     */
  1.1460 +    public List<Type> intersect(List<Type> ts1, List<Type> ts2) {
  1.1461 +        List<Type> ts = List.nil();
  1.1462 +        for (List<Type> l = ts1; l.nonEmpty(); l = l.tail)
  1.1463 +            if (subset(l.head, ts2)) ts = incl(l.head, ts);
  1.1464 +        for (List<Type> l = ts2; l.nonEmpty(); l = l.tail)
  1.1465 +            if (subset(l.head, ts1)) ts = incl(l.head, ts);
  1.1466 +        return ts;
  1.1467 +    }
  1.1468 +
  1.1469 +    /** Is exc an exception symbol that need not be declared?
  1.1470 +     */
  1.1471 +    boolean isUnchecked(ClassSymbol exc) {
  1.1472 +        return
  1.1473 +            exc.kind == ERR ||
  1.1474 +            exc.isSubClass(syms.errorType.tsym, types) ||
  1.1475 +            exc.isSubClass(syms.runtimeExceptionType.tsym, types);
  1.1476 +    }
  1.1477 +
  1.1478 +    /** Is exc an exception type that need not be declared?
  1.1479 +     */
  1.1480 +    boolean isUnchecked(Type exc) {
  1.1481 +        return
  1.1482 +            (exc.hasTag(TYPEVAR)) ? isUnchecked(types.supertype(exc)) :
  1.1483 +            (exc.hasTag(CLASS)) ? isUnchecked((ClassSymbol)exc.tsym) :
  1.1484 +            exc.hasTag(BOT);
  1.1485 +    }
  1.1486 +
  1.1487 +    /** Same, but handling completion failures.
  1.1488 +     */
  1.1489 +    boolean isUnchecked(DiagnosticPosition pos, Type exc) {
  1.1490 +        try {
  1.1491 +            return isUnchecked(exc);
  1.1492 +        } catch (CompletionFailure ex) {
  1.1493 +            completionError(pos, ex);
  1.1494 +            return true;
  1.1495 +        }
  1.1496 +    }
  1.1497 +
  1.1498 +    /** Is exc handled by given exception list?
  1.1499 +     */
  1.1500 +    boolean isHandled(Type exc, List<Type> handled) {
  1.1501 +        return isUnchecked(exc) || subset(exc, handled);
  1.1502 +    }
  1.1503 +
  1.1504 +    /** Return all exceptions in thrown list that are not in handled list.
  1.1505 +     *  @param thrown     The list of thrown exceptions.
  1.1506 +     *  @param handled    The list of handled exceptions.
  1.1507 +     */
  1.1508 +    List<Type> unhandled(List<Type> thrown, List<Type> handled) {
  1.1509 +        List<Type> unhandled = List.nil();
  1.1510 +        for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
  1.1511 +            if (!isHandled(l.head, handled)) unhandled = unhandled.prepend(l.head);
  1.1512 +        return unhandled;
  1.1513 +    }
  1.1514 +
  1.1515 +/* *************************************************************************
  1.1516 + * Overriding/Implementation checking
  1.1517 + **************************************************************************/
  1.1518 +
  1.1519 +    /** The level of access protection given by a flag set,
  1.1520 +     *  where PRIVATE is highest and PUBLIC is lowest.
  1.1521 +     */
  1.1522 +    static int protection(long flags) {
  1.1523 +        switch ((short)(flags & AccessFlags)) {
  1.1524 +        case PRIVATE: return 3;
  1.1525 +        case PROTECTED: return 1;
  1.1526 +        default:
  1.1527 +        case PUBLIC: return 0;
  1.1528 +        case 0: return 2;
  1.1529 +        }
  1.1530 +    }
  1.1531 +
  1.1532 +    /** A customized "cannot override" error message.
  1.1533 +     *  @param m      The overriding method.
  1.1534 +     *  @param other  The overridden method.
  1.1535 +     *  @return       An internationalized string.
  1.1536 +     */
  1.1537 +    Object cannotOverride(MethodSymbol m, MethodSymbol other) {
  1.1538 +        String key;
  1.1539 +        if ((other.owner.flags() & INTERFACE) == 0)
  1.1540 +            key = "cant.override";
  1.1541 +        else if ((m.owner.flags() & INTERFACE) == 0)
  1.1542 +            key = "cant.implement";
  1.1543 +        else
  1.1544 +            key = "clashes.with";
  1.1545 +        return diags.fragment(key, m, m.location(), other, other.location());
  1.1546 +    }
  1.1547 +
  1.1548 +    /** A customized "override" warning message.
  1.1549 +     *  @param m      The overriding method.
  1.1550 +     *  @param other  The overridden method.
  1.1551 +     *  @return       An internationalized string.
  1.1552 +     */
  1.1553 +    Object uncheckedOverrides(MethodSymbol m, MethodSymbol other) {
  1.1554 +        String key;
  1.1555 +        if ((other.owner.flags() & INTERFACE) == 0)
  1.1556 +            key = "unchecked.override";
  1.1557 +        else if ((m.owner.flags() & INTERFACE) == 0)
  1.1558 +            key = "unchecked.implement";
  1.1559 +        else
  1.1560 +            key = "unchecked.clash.with";
  1.1561 +        return diags.fragment(key, m, m.location(), other, other.location());
  1.1562 +    }
  1.1563 +
  1.1564 +    /** A customized "override" warning message.
  1.1565 +     *  @param m      The overriding method.
  1.1566 +     *  @param other  The overridden method.
  1.1567 +     *  @return       An internationalized string.
  1.1568 +     */
  1.1569 +    Object varargsOverrides(MethodSymbol m, MethodSymbol other) {
  1.1570 +        String key;
  1.1571 +        if ((other.owner.flags() & INTERFACE) == 0)
  1.1572 +            key = "varargs.override";
  1.1573 +        else  if ((m.owner.flags() & INTERFACE) == 0)
  1.1574 +            key = "varargs.implement";
  1.1575 +        else
  1.1576 +            key = "varargs.clash.with";
  1.1577 +        return diags.fragment(key, m, m.location(), other, other.location());
  1.1578 +    }
  1.1579 +
  1.1580 +    /** Check that this method conforms with overridden method 'other'.
  1.1581 +     *  where `origin' is the class where checking started.
  1.1582 +     *  Complications:
  1.1583 +     *  (1) Do not check overriding of synthetic methods
  1.1584 +     *      (reason: they might be final).
  1.1585 +     *      todo: check whether this is still necessary.
  1.1586 +     *  (2) Admit the case where an interface proxy throws fewer exceptions
  1.1587 +     *      than the method it implements. Augment the proxy methods with the
  1.1588 +     *      undeclared exceptions in this case.
  1.1589 +     *  (3) When generics are enabled, admit the case where an interface proxy
  1.1590 +     *      has a result type
  1.1591 +     *      extended by the result type of the method it implements.
  1.1592 +     *      Change the proxies result type to the smaller type in this case.
  1.1593 +     *
  1.1594 +     *  @param tree         The tree from which positions
  1.1595 +     *                      are extracted for errors.
  1.1596 +     *  @param m            The overriding method.
  1.1597 +     *  @param other        The overridden method.
  1.1598 +     *  @param origin       The class of which the overriding method
  1.1599 +     *                      is a member.
  1.1600 +     */
  1.1601 +    void checkOverride(JCTree tree,
  1.1602 +                       MethodSymbol m,
  1.1603 +                       MethodSymbol other,
  1.1604 +                       ClassSymbol origin) {
  1.1605 +        // Don't check overriding of synthetic methods or by bridge methods.
  1.1606 +        if ((m.flags() & (SYNTHETIC|BRIDGE)) != 0 || (other.flags() & SYNTHETIC) != 0) {
  1.1607 +            return;
  1.1608 +        }
  1.1609 +
  1.1610 +        // Error if static method overrides instance method (JLS 8.4.6.2).
  1.1611 +        if ((m.flags() & STATIC) != 0 &&
  1.1612 +                   (other.flags() & STATIC) == 0) {
  1.1613 +            log.error(TreeInfo.diagnosticPositionFor(m, tree), "override.static",
  1.1614 +                      cannotOverride(m, other));
  1.1615 +            m.flags_field |= BAD_OVERRIDE;
  1.1616 +            return;
  1.1617 +        }
  1.1618 +
  1.1619 +        // Error if instance method overrides static or final
  1.1620 +        // method (JLS 8.4.6.1).
  1.1621 +        if ((other.flags() & FINAL) != 0 ||
  1.1622 +                 (m.flags() & STATIC) == 0 &&
  1.1623 +                 (other.flags() & STATIC) != 0) {
  1.1624 +            log.error(TreeInfo.diagnosticPositionFor(m, tree), "override.meth",
  1.1625 +                      cannotOverride(m, other),
  1.1626 +                      asFlagSet(other.flags() & (FINAL | STATIC)));
  1.1627 +            m.flags_field |= BAD_OVERRIDE;
  1.1628 +            return;
  1.1629 +        }
  1.1630 +
  1.1631 +        if ((m.owner.flags() & ANNOTATION) != 0) {
  1.1632 +            // handled in validateAnnotationMethod
  1.1633 +            return;
  1.1634 +        }
  1.1635 +
  1.1636 +        // Error if overriding method has weaker access (JLS 8.4.6.3).
  1.1637 +        if ((origin.flags() & INTERFACE) == 0 &&
  1.1638 +                 protection(m.flags()) > protection(other.flags())) {
  1.1639 +            log.error(TreeInfo.diagnosticPositionFor(m, tree), "override.weaker.access",
  1.1640 +                      cannotOverride(m, other),
  1.1641 +                      other.flags() == 0 ?
  1.1642 +                          "package" :
  1.1643 +                          asFlagSet(other.flags() & AccessFlags));
  1.1644 +            m.flags_field |= BAD_OVERRIDE;
  1.1645 +            return;
  1.1646 +        }
  1.1647 +
  1.1648 +        Type mt = types.memberType(origin.type, m);
  1.1649 +        Type ot = types.memberType(origin.type, other);
  1.1650 +        // Error if overriding result type is different
  1.1651 +        // (or, in the case of generics mode, not a subtype) of
  1.1652 +        // overridden result type. We have to rename any type parameters
  1.1653 +        // before comparing types.
  1.1654 +        List<Type> mtvars = mt.getTypeArguments();
  1.1655 +        List<Type> otvars = ot.getTypeArguments();
  1.1656 +        Type mtres = mt.getReturnType();
  1.1657 +        Type otres = types.subst(ot.getReturnType(), otvars, mtvars);
  1.1658 +
  1.1659 +        overrideWarner.clear();
  1.1660 +        boolean resultTypesOK =
  1.1661 +            types.returnTypeSubstitutable(mt, ot, otres, overrideWarner);
  1.1662 +        if (!resultTypesOK) {
  1.1663 +            if (!allowCovariantReturns &&
  1.1664 +                m.owner != origin &&
  1.1665 +                m.owner.isSubClass(other.owner, types)) {
  1.1666 +                // allow limited interoperability with covariant returns
  1.1667 +            } else {
  1.1668 +                log.error(TreeInfo.diagnosticPositionFor(m, tree),
  1.1669 +                          "override.incompatible.ret",
  1.1670 +                          cannotOverride(m, other),
  1.1671 +                          mtres, otres);
  1.1672 +                m.flags_field |= BAD_OVERRIDE;
  1.1673 +                return;
  1.1674 +            }
  1.1675 +        } else if (overrideWarner.hasNonSilentLint(LintCategory.UNCHECKED)) {
  1.1676 +            warnUnchecked(TreeInfo.diagnosticPositionFor(m, tree),
  1.1677 +                    "override.unchecked.ret",
  1.1678 +                    uncheckedOverrides(m, other),
  1.1679 +                    mtres, otres);
  1.1680 +        }
  1.1681 +
  1.1682 +        // Error if overriding method throws an exception not reported
  1.1683 +        // by overridden method.
  1.1684 +        List<Type> otthrown = types.subst(ot.getThrownTypes(), otvars, mtvars);
  1.1685 +        List<Type> unhandledErased = unhandled(mt.getThrownTypes(), types.erasure(otthrown));
  1.1686 +        List<Type> unhandledUnerased = unhandled(mt.getThrownTypes(), otthrown);
  1.1687 +        if (unhandledErased.nonEmpty()) {
  1.1688 +            log.error(TreeInfo.diagnosticPositionFor(m, tree),
  1.1689 +                      "override.meth.doesnt.throw",
  1.1690 +                      cannotOverride(m, other),
  1.1691 +                      unhandledUnerased.head);
  1.1692 +            m.flags_field |= BAD_OVERRIDE;
  1.1693 +            return;
  1.1694 +        }
  1.1695 +        else if (unhandledUnerased.nonEmpty()) {
  1.1696 +            warnUnchecked(TreeInfo.diagnosticPositionFor(m, tree),
  1.1697 +                          "override.unchecked.thrown",
  1.1698 +                         cannotOverride(m, other),
  1.1699 +                         unhandledUnerased.head);
  1.1700 +            return;
  1.1701 +        }
  1.1702 +
  1.1703 +        // Optional warning if varargs don't agree
  1.1704 +        if ((((m.flags() ^ other.flags()) & Flags.VARARGS) != 0)
  1.1705 +            && lint.isEnabled(LintCategory.OVERRIDES)) {
  1.1706 +            log.warning(TreeInfo.diagnosticPositionFor(m, tree),
  1.1707 +                        ((m.flags() & Flags.VARARGS) != 0)
  1.1708 +                        ? "override.varargs.missing"
  1.1709 +                        : "override.varargs.extra",
  1.1710 +                        varargsOverrides(m, other));
  1.1711 +        }
  1.1712 +
  1.1713 +        // Warn if instance method overrides bridge method (compiler spec ??)
  1.1714 +        if ((other.flags() & BRIDGE) != 0) {
  1.1715 +            log.warning(TreeInfo.diagnosticPositionFor(m, tree), "override.bridge",
  1.1716 +                        uncheckedOverrides(m, other));
  1.1717 +        }
  1.1718 +
  1.1719 +        // Warn if a deprecated method overridden by a non-deprecated one.
  1.1720 +        if (!isDeprecatedOverrideIgnorable(other, origin)) {
  1.1721 +            checkDeprecated(TreeInfo.diagnosticPositionFor(m, tree), m, other);
  1.1722 +        }
  1.1723 +    }
  1.1724 +    // where
  1.1725 +        private boolean isDeprecatedOverrideIgnorable(MethodSymbol m, ClassSymbol origin) {
  1.1726 +            // If the method, m, is defined in an interface, then ignore the issue if the method
  1.1727 +            // is only inherited via a supertype and also implemented in the supertype,
  1.1728 +            // because in that case, we will rediscover the issue when examining the method
  1.1729 +            // in the supertype.
  1.1730 +            // If the method, m, is not defined in an interface, then the only time we need to
  1.1731 +            // address the issue is when the method is the supertype implemementation: any other
  1.1732 +            // case, we will have dealt with when examining the supertype classes
  1.1733 +            ClassSymbol mc = m.enclClass();
  1.1734 +            Type st = types.supertype(origin.type);
  1.1735 +            if (!st.hasTag(CLASS))
  1.1736 +                return true;
  1.1737 +            MethodSymbol stimpl = m.implementation((ClassSymbol)st.tsym, types, false);
  1.1738 +
  1.1739 +            if (mc != null && ((mc.flags() & INTERFACE) != 0)) {
  1.1740 +                List<Type> intfs = types.interfaces(origin.type);
  1.1741 +                return (intfs.contains(mc.type) ? false : (stimpl != null));
  1.1742 +            }
  1.1743 +            else
  1.1744 +                return (stimpl != m);
  1.1745 +        }
  1.1746 +
  1.1747 +
  1.1748 +    // used to check if there were any unchecked conversions
  1.1749 +    Warner overrideWarner = new Warner();
  1.1750 +
  1.1751 +    /** Check that a class does not inherit two concrete methods
  1.1752 +     *  with the same signature.
  1.1753 +     *  @param pos          Position to be used for error reporting.
  1.1754 +     *  @param site         The class type to be checked.
  1.1755 +     */
  1.1756 +    public void checkCompatibleConcretes(DiagnosticPosition pos, Type site) {
  1.1757 +        Type sup = types.supertype(site);
  1.1758 +        if (!sup.hasTag(CLASS)) return;
  1.1759 +
  1.1760 +        for (Type t1 = sup;
  1.1761 +             t1.hasTag(CLASS) && t1.tsym.type.isParameterized();
  1.1762 +             t1 = types.supertype(t1)) {
  1.1763 +            for (Scope.Entry e1 = t1.tsym.members().elems;
  1.1764 +                 e1 != null;
  1.1765 +                 e1 = e1.sibling) {
  1.1766 +                Symbol s1 = e1.sym;
  1.1767 +                if (s1.kind != MTH ||
  1.1768 +                    (s1.flags() & (STATIC|SYNTHETIC|BRIDGE)) != 0 ||
  1.1769 +                    !s1.isInheritedIn(site.tsym, types) ||
  1.1770 +                    ((MethodSymbol)s1).implementation(site.tsym,
  1.1771 +                                                      types,
  1.1772 +                                                      true) != s1)
  1.1773 +                    continue;
  1.1774 +                Type st1 = types.memberType(t1, s1);
  1.1775 +                int s1ArgsLength = st1.getParameterTypes().length();
  1.1776 +                if (st1 == s1.type) continue;
  1.1777 +
  1.1778 +                for (Type t2 = sup;
  1.1779 +                     t2.hasTag(CLASS);
  1.1780 +                     t2 = types.supertype(t2)) {
  1.1781 +                    for (Scope.Entry e2 = t2.tsym.members().lookup(s1.name);
  1.1782 +                         e2.scope != null;
  1.1783 +                         e2 = e2.next()) {
  1.1784 +                        Symbol s2 = e2.sym;
  1.1785 +                        if (s2 == s1 ||
  1.1786 +                            s2.kind != MTH ||
  1.1787 +                            (s2.flags() & (STATIC|SYNTHETIC|BRIDGE)) != 0 ||
  1.1788 +                            s2.type.getParameterTypes().length() != s1ArgsLength ||
  1.1789 +                            !s2.isInheritedIn(site.tsym, types) ||
  1.1790 +                            ((MethodSymbol)s2).implementation(site.tsym,
  1.1791 +                                                              types,
  1.1792 +                                                              true) != s2)
  1.1793 +                            continue;
  1.1794 +                        Type st2 = types.memberType(t2, s2);
  1.1795 +                        if (types.overrideEquivalent(st1, st2))
  1.1796 +                            log.error(pos, "concrete.inheritance.conflict",
  1.1797 +                                      s1, t1, s2, t2, sup);
  1.1798 +                    }
  1.1799 +                }
  1.1800 +            }
  1.1801 +        }
  1.1802 +    }
  1.1803 +
  1.1804 +    /** Check that classes (or interfaces) do not each define an abstract
  1.1805 +     *  method with same name and arguments but incompatible return types.
  1.1806 +     *  @param pos          Position to be used for error reporting.
  1.1807 +     *  @param t1           The first argument type.
  1.1808 +     *  @param t2           The second argument type.
  1.1809 +     */
  1.1810 +    public boolean checkCompatibleAbstracts(DiagnosticPosition pos,
  1.1811 +                                            Type t1,
  1.1812 +                                            Type t2) {
  1.1813 +        return checkCompatibleAbstracts(pos, t1, t2,
  1.1814 +                                        types.makeCompoundType(t1, t2));
  1.1815 +    }
  1.1816 +
  1.1817 +    public boolean checkCompatibleAbstracts(DiagnosticPosition pos,
  1.1818 +                                            Type t1,
  1.1819 +                                            Type t2,
  1.1820 +                                            Type site) {
  1.1821 +        if ((site.tsym.flags() & COMPOUND) != 0) {
  1.1822 +            // special case for intersections: need to eliminate wildcards in supertypes
  1.1823 +            t1 = types.capture(t1);
  1.1824 +            t2 = types.capture(t2);
  1.1825 +        }
  1.1826 +        return firstIncompatibility(pos, t1, t2, site) == null;
  1.1827 +    }
  1.1828 +
  1.1829 +    /** Return the first method which is defined with same args
  1.1830 +     *  but different return types in two given interfaces, or null if none
  1.1831 +     *  exists.
  1.1832 +     *  @param t1     The first type.
  1.1833 +     *  @param t2     The second type.
  1.1834 +     *  @param site   The most derived type.
  1.1835 +     *  @returns symbol from t2 that conflicts with one in t1.
  1.1836 +     */
  1.1837 +    private Symbol firstIncompatibility(DiagnosticPosition pos, Type t1, Type t2, Type site) {
  1.1838 +        Map<TypeSymbol,Type> interfaces1 = new HashMap<TypeSymbol,Type>();
  1.1839 +        closure(t1, interfaces1);
  1.1840 +        Map<TypeSymbol,Type> interfaces2;
  1.1841 +        if (t1 == t2)
  1.1842 +            interfaces2 = interfaces1;
  1.1843 +        else
  1.1844 +            closure(t2, interfaces1, interfaces2 = new HashMap<TypeSymbol,Type>());
  1.1845 +
  1.1846 +        for (Type t3 : interfaces1.values()) {
  1.1847 +            for (Type t4 : interfaces2.values()) {
  1.1848 +                Symbol s = firstDirectIncompatibility(pos, t3, t4, site);
  1.1849 +                if (s != null) return s;
  1.1850 +            }
  1.1851 +        }
  1.1852 +        return null;
  1.1853 +    }
  1.1854 +
  1.1855 +    /** Compute all the supertypes of t, indexed by type symbol. */
  1.1856 +    private void closure(Type t, Map<TypeSymbol,Type> typeMap) {
  1.1857 +        if (!t.hasTag(CLASS)) return;
  1.1858 +        if (typeMap.put(t.tsym, t) == null) {
  1.1859 +            closure(types.supertype(t), typeMap);
  1.1860 +            for (Type i : types.interfaces(t))
  1.1861 +                closure(i, typeMap);
  1.1862 +        }
  1.1863 +    }
  1.1864 +
  1.1865 +    /** Compute all the supertypes of t, indexed by type symbol (except thise in typesSkip). */
  1.1866 +    private void closure(Type t, Map<TypeSymbol,Type> typesSkip, Map<TypeSymbol,Type> typeMap) {
  1.1867 +        if (!t.hasTag(CLASS)) return;
  1.1868 +        if (typesSkip.get(t.tsym) != null) return;
  1.1869 +        if (typeMap.put(t.tsym, t) == null) {
  1.1870 +            closure(types.supertype(t), typesSkip, typeMap);
  1.1871 +            for (Type i : types.interfaces(t))
  1.1872 +                closure(i, typesSkip, typeMap);
  1.1873 +        }
  1.1874 +    }
  1.1875 +
  1.1876 +    /** Return the first method in t2 that conflicts with a method from t1. */
  1.1877 +    private Symbol firstDirectIncompatibility(DiagnosticPosition pos, Type t1, Type t2, Type site) {
  1.1878 +        for (Scope.Entry e1 = t1.tsym.members().elems; e1 != null; e1 = e1.sibling) {
  1.1879 +            Symbol s1 = e1.sym;
  1.1880 +            Type st1 = null;
  1.1881 +            if (s1.kind != MTH || !s1.isInheritedIn(site.tsym, types) ||
  1.1882 +                    (s1.flags() & SYNTHETIC) != 0) continue;
  1.1883 +            Symbol impl = ((MethodSymbol)s1).implementation(site.tsym, types, false);
  1.1884 +            if (impl != null && (impl.flags() & ABSTRACT) == 0) continue;
  1.1885 +            for (Scope.Entry e2 = t2.tsym.members().lookup(s1.name); e2.scope != null; e2 = e2.next()) {
  1.1886 +                Symbol s2 = e2.sym;
  1.1887 +                if (s1 == s2) continue;
  1.1888 +                if (s2.kind != MTH || !s2.isInheritedIn(site.tsym, types) ||
  1.1889 +                        (s2.flags() & SYNTHETIC) != 0) continue;
  1.1890 +                if (st1 == null) st1 = types.memberType(t1, s1);
  1.1891 +                Type st2 = types.memberType(t2, s2);
  1.1892 +                if (types.overrideEquivalent(st1, st2)) {
  1.1893 +                    List<Type> tvars1 = st1.getTypeArguments();
  1.1894 +                    List<Type> tvars2 = st2.getTypeArguments();
  1.1895 +                    Type rt1 = st1.getReturnType();
  1.1896 +                    Type rt2 = types.subst(st2.getReturnType(), tvars2, tvars1);
  1.1897 +                    boolean compat =
  1.1898 +                        types.isSameType(rt1, rt2) ||
  1.1899 +                        !rt1.isPrimitiveOrVoid() &&
  1.1900 +                        !rt2.isPrimitiveOrVoid() &&
  1.1901 +                        (types.covariantReturnType(rt1, rt2, types.noWarnings) ||
  1.1902 +                         types.covariantReturnType(rt2, rt1, types.noWarnings)) ||
  1.1903 +                         checkCommonOverriderIn(s1,s2,site);
  1.1904 +                    if (!compat) {
  1.1905 +                        log.error(pos, "types.incompatible.diff.ret",
  1.1906 +                            t1, t2, s2.name +
  1.1907 +                            "(" + types.memberType(t2, s2).getParameterTypes() + ")");
  1.1908 +                        return s2;
  1.1909 +                    }
  1.1910 +                } else if (checkNameClash((ClassSymbol)site.tsym, s1, s2) &&
  1.1911 +                        !checkCommonOverriderIn(s1, s2, site)) {
  1.1912 +                    log.error(pos,
  1.1913 +                            "name.clash.same.erasure.no.override",
  1.1914 +                            s1, s1.location(),
  1.1915 +                            s2, s2.location());
  1.1916 +                    return s2;
  1.1917 +                }
  1.1918 +            }
  1.1919 +        }
  1.1920 +        return null;
  1.1921 +    }
  1.1922 +    //WHERE
  1.1923 +    boolean checkCommonOverriderIn(Symbol s1, Symbol s2, Type site) {
  1.1924 +        Map<TypeSymbol,Type> supertypes = new HashMap<TypeSymbol,Type>();
  1.1925 +        Type st1 = types.memberType(site, s1);
  1.1926 +        Type st2 = types.memberType(site, s2);
  1.1927 +        closure(site, supertypes);
  1.1928 +        for (Type t : supertypes.values()) {
  1.1929 +            for (Scope.Entry e = t.tsym.members().lookup(s1.name); e.scope != null; e = e.next()) {
  1.1930 +                Symbol s3 = e.sym;
  1.1931 +                if (s3 == s1 || s3 == s2 || s3.kind != MTH || (s3.flags() & (BRIDGE|SYNTHETIC)) != 0) continue;
  1.1932 +                Type st3 = types.memberType(site,s3);
  1.1933 +                if (types.overrideEquivalent(st3, st1) &&
  1.1934 +                        types.overrideEquivalent(st3, st2) &&
  1.1935 +                        types.returnTypeSubstitutable(st3, st1) &&
  1.1936 +                        types.returnTypeSubstitutable(st3, st2)) {
  1.1937 +                    return true;
  1.1938 +                }
  1.1939 +            }
  1.1940 +        }
  1.1941 +        return false;
  1.1942 +    }
  1.1943 +
  1.1944 +    /** Check that a given method conforms with any method it overrides.
  1.1945 +     *  @param tree         The tree from which positions are extracted
  1.1946 +     *                      for errors.
  1.1947 +     *  @param m            The overriding method.
  1.1948 +     */
  1.1949 +    void checkOverride(JCMethodDecl tree, MethodSymbol m) {
  1.1950 +        ClassSymbol origin = (ClassSymbol)m.owner;
  1.1951 +        if ((origin.flags() & ENUM) != 0 && names.finalize.equals(m.name))
  1.1952 +            if (m.overrides(syms.enumFinalFinalize, origin, types, false)) {
  1.1953 +                log.error(tree.pos(), "enum.no.finalize");
  1.1954 +                return;
  1.1955 +            }
  1.1956 +        for (Type t = origin.type; t.hasTag(CLASS);
  1.1957 +             t = types.supertype(t)) {
  1.1958 +            if (t != origin.type) {
  1.1959 +                checkOverride(tree, t, origin, m);
  1.1960 +            }
  1.1961 +            for (Type t2 : types.interfaces(t)) {
  1.1962 +                checkOverride(tree, t2, origin, m);
  1.1963 +            }
  1.1964 +        }
  1.1965 +
  1.1966 +        if (m.attribute(syms.overrideType.tsym) != null && !isOverrider(m)) {
  1.1967 +            DiagnosticPosition pos = tree.pos();
  1.1968 +            for (JCAnnotation a : tree.getModifiers().annotations) {
  1.1969 +                if (a.annotationType.type.tsym == syms.overrideType.tsym) {
  1.1970 +                    pos = a.pos();
  1.1971 +                    break;
  1.1972 +                }
  1.1973 +            }
  1.1974 +            log.error(pos, "method.does.not.override.superclass");
  1.1975 +        }
  1.1976 +    }
  1.1977 +
  1.1978 +    void checkOverride(JCTree tree, Type site, ClassSymbol origin, MethodSymbol m) {
  1.1979 +        TypeSymbol c = site.tsym;
  1.1980 +        Scope.Entry e = c.members().lookup(m.name);
  1.1981 +        while (e.scope != null) {
  1.1982 +            if (m.overrides(e.sym, origin, types, false)) {
  1.1983 +                if ((e.sym.flags() & ABSTRACT) == 0) {
  1.1984 +                    checkOverride(tree, m, (MethodSymbol)e.sym, origin);
  1.1985 +                }
  1.1986 +            }
  1.1987 +            e = e.next();
  1.1988 +        }
  1.1989 +    }
  1.1990 +
  1.1991 +    private Filter<Symbol> equalsHasCodeFilter = new Filter<Symbol>() {
  1.1992 +        public boolean accepts(Symbol s) {
  1.1993 +            return MethodSymbol.implementation_filter.accepts(s) &&
  1.1994 +                    (s.flags() & BAD_OVERRIDE) == 0;
  1.1995 +
  1.1996 +        }
  1.1997 +    };
  1.1998 +
  1.1999 +    public void checkClassOverrideEqualsAndHashIfNeeded(DiagnosticPosition pos,
  1.2000 +            ClassSymbol someClass) {
  1.2001 +        /* At present, annotations cannot possibly have a method that is override
  1.2002 +         * equivalent with Object.equals(Object) but in any case the condition is
  1.2003 +         * fine for completeness.
  1.2004 +         */
  1.2005 +        if (someClass == (ClassSymbol)syms.objectType.tsym ||
  1.2006 +            someClass.isInterface() || someClass.isEnum() ||
  1.2007 +            (someClass.flags() & ANNOTATION) != 0 ||
  1.2008 +            (someClass.flags() & ABSTRACT) != 0) return;
  1.2009 +        //anonymous inner classes implementing interfaces need especial treatment
  1.2010 +        if (someClass.isAnonymous()) {
  1.2011 +            List<Type> interfaces =  types.interfaces(someClass.type);
  1.2012 +            if (interfaces != null && !interfaces.isEmpty() &&
  1.2013 +                interfaces.head.tsym == syms.comparatorType.tsym) return;
  1.2014 +        }
  1.2015 +        checkClassOverrideEqualsAndHash(pos, someClass);
  1.2016 +    }
  1.2017 +
  1.2018 +    private void checkClassOverrideEqualsAndHash(DiagnosticPosition pos,
  1.2019 +            ClassSymbol someClass) {
  1.2020 +        if (lint.isEnabled(LintCategory.OVERRIDES)) {
  1.2021 +            MethodSymbol equalsAtObject = (MethodSymbol)syms.objectType
  1.2022 +                    .tsym.members().lookup(names.equals).sym;
  1.2023 +            MethodSymbol hashCodeAtObject = (MethodSymbol)syms.objectType
  1.2024 +                    .tsym.members().lookup(names.hashCode).sym;
  1.2025 +            boolean overridesEquals = types.implementation(equalsAtObject,
  1.2026 +                someClass, false, equalsHasCodeFilter).owner == someClass;
  1.2027 +            boolean overridesHashCode = types.implementation(hashCodeAtObject,
  1.2028 +                someClass, false, equalsHasCodeFilter) != hashCodeAtObject;
  1.2029 +
  1.2030 +            if (overridesEquals && !overridesHashCode) {
  1.2031 +                log.warning(LintCategory.OVERRIDES, pos,
  1.2032 +                        "override.equals.but.not.hashcode", someClass);
  1.2033 +            }
  1.2034 +        }
  1.2035 +    }
  1.2036 +
  1.2037 +    private boolean checkNameClash(ClassSymbol origin, Symbol s1, Symbol s2) {
  1.2038 +        ClashFilter cf = new ClashFilter(origin.type);
  1.2039 +        return (cf.accepts(s1) &&
  1.2040 +                cf.accepts(s2) &&
  1.2041 +                types.hasSameArgs(s1.erasure(types), s2.erasure(types)));
  1.2042 +    }
  1.2043 +
  1.2044 +
  1.2045 +    /** Check that all abstract members of given class have definitions.
  1.2046 +     *  @param pos          Position to be used for error reporting.
  1.2047 +     *  @param c            The class.
  1.2048 +     */
  1.2049 +    void checkAllDefined(DiagnosticPosition pos, ClassSymbol c) {
  1.2050 +        try {
  1.2051 +            MethodSymbol undef = firstUndef(c, c);
  1.2052 +            if (undef != null) {
  1.2053 +                if ((c.flags() & ENUM) != 0 &&
  1.2054 +                    types.supertype(c.type).tsym == syms.enumSym &&
  1.2055 +                    (c.flags() & FINAL) == 0) {
  1.2056 +                    // add the ABSTRACT flag to an enum
  1.2057 +                    c.flags_field |= ABSTRACT;
  1.2058 +                } else {
  1.2059 +                    MethodSymbol undef1 =
  1.2060 +                        new MethodSymbol(undef.flags(), undef.name,
  1.2061 +                                         types.memberType(c.type, undef), undef.owner);
  1.2062 +                    log.error(pos, "does.not.override.abstract",
  1.2063 +                              c, undef1, undef1.location());
  1.2064 +                }
  1.2065 +            }
  1.2066 +        } catch (CompletionFailure ex) {
  1.2067 +            completionError(pos, ex);
  1.2068 +        }
  1.2069 +    }
  1.2070 +//where
  1.2071 +        /** Return first abstract member of class `c' that is not defined
  1.2072 +         *  in `impl', null if there is none.
  1.2073 +         */
  1.2074 +        private MethodSymbol firstUndef(ClassSymbol impl, ClassSymbol c) {
  1.2075 +            MethodSymbol undef = null;
  1.2076 +            // Do not bother to search in classes that are not abstract,
  1.2077 +            // since they cannot have abstract members.
  1.2078 +            if (c == impl || (c.flags() & (ABSTRACT | INTERFACE)) != 0) {
  1.2079 +                Scope s = c.members();
  1.2080 +                for (Scope.Entry e = s.elems;
  1.2081 +                     undef == null && e != null;
  1.2082 +                     e = e.sibling) {
  1.2083 +                    if (e.sym.kind == MTH &&
  1.2084 +                        (e.sym.flags() & (ABSTRACT|IPROXY|DEFAULT)) == ABSTRACT) {
  1.2085 +                        MethodSymbol absmeth = (MethodSymbol)e.sym;
  1.2086 +                        MethodSymbol implmeth = absmeth.implementation(impl, types, true);
  1.2087 +                        if (implmeth == null || implmeth == absmeth) {
  1.2088 +                            //look for default implementations
  1.2089 +                            if (allowDefaultMethods) {
  1.2090 +                                MethodSymbol prov = types.interfaceCandidates(impl.type, absmeth).head;
  1.2091 +                                if (prov != null && prov.overrides(absmeth, impl, types, true)) {
  1.2092 +                                    implmeth = prov;
  1.2093 +                                }
  1.2094 +                            }
  1.2095 +                        }
  1.2096 +                        if (implmeth == null || implmeth == absmeth) {
  1.2097 +                            undef = absmeth;
  1.2098 +                        }
  1.2099 +                    }
  1.2100 +                }
  1.2101 +                if (undef == null) {
  1.2102 +                    Type st = types.supertype(c.type);
  1.2103 +                    if (st.hasTag(CLASS))
  1.2104 +                        undef = firstUndef(impl, (ClassSymbol)st.tsym);
  1.2105 +                }
  1.2106 +                for (List<Type> l = types.interfaces(c.type);
  1.2107 +                     undef == null && l.nonEmpty();
  1.2108 +                     l = l.tail) {
  1.2109 +                    undef = firstUndef(impl, (ClassSymbol)l.head.tsym);
  1.2110 +                }
  1.2111 +            }
  1.2112 +            return undef;
  1.2113 +        }
  1.2114 +
  1.2115 +    void checkNonCyclicDecl(JCClassDecl tree) {
  1.2116 +        CycleChecker cc = new CycleChecker();
  1.2117 +        cc.scan(tree);
  1.2118 +        if (!cc.errorFound && !cc.partialCheck) {
  1.2119 +            tree.sym.flags_field |= ACYCLIC;
  1.2120 +        }
  1.2121 +    }
  1.2122 +
  1.2123 +    class CycleChecker extends TreeScanner {
  1.2124 +
  1.2125 +        List<Symbol> seenClasses = List.nil();
  1.2126 +        boolean errorFound = false;
  1.2127 +        boolean partialCheck = false;
  1.2128 +
  1.2129 +        private void checkSymbol(DiagnosticPosition pos, Symbol sym) {
  1.2130 +            if (sym != null && sym.kind == TYP) {
  1.2131 +                Env<AttrContext> classEnv = enter.getEnv((TypeSymbol)sym);
  1.2132 +                if (classEnv != null) {
  1.2133 +                    DiagnosticSource prevSource = log.currentSource();
  1.2134 +                    try {
  1.2135 +                        log.useSource(classEnv.toplevel.sourcefile);
  1.2136 +                        scan(classEnv.tree);
  1.2137 +                    }
  1.2138 +                    finally {
  1.2139 +                        log.useSource(prevSource.getFile());
  1.2140 +                    }
  1.2141 +                } else if (sym.kind == TYP) {
  1.2142 +                    checkClass(pos, sym, List.<JCTree>nil());
  1.2143 +                }
  1.2144 +            } else {
  1.2145 +                //not completed yet
  1.2146 +                partialCheck = true;
  1.2147 +            }
  1.2148 +        }
  1.2149 +
  1.2150 +        @Override
  1.2151 +        public void visitSelect(JCFieldAccess tree) {
  1.2152 +            super.visitSelect(tree);
  1.2153 +            checkSymbol(tree.pos(), tree.sym);
  1.2154 +        }
  1.2155 +
  1.2156 +        @Override
  1.2157 +        public void visitIdent(JCIdent tree) {
  1.2158 +            checkSymbol(tree.pos(), tree.sym);
  1.2159 +        }
  1.2160 +
  1.2161 +        @Override
  1.2162 +        public void visitTypeApply(JCTypeApply tree) {
  1.2163 +            scan(tree.clazz);
  1.2164 +        }
  1.2165 +
  1.2166 +        @Override
  1.2167 +        public void visitTypeArray(JCArrayTypeTree tree) {
  1.2168 +            scan(tree.elemtype);
  1.2169 +        }
  1.2170 +
  1.2171 +        @Override
  1.2172 +        public void visitClassDef(JCClassDecl tree) {
  1.2173 +            List<JCTree> supertypes = List.nil();
  1.2174 +            if (tree.getExtendsClause() != null) {
  1.2175 +                supertypes = supertypes.prepend(tree.getExtendsClause());
  1.2176 +            }
  1.2177 +            if (tree.getImplementsClause() != null) {
  1.2178 +                for (JCTree intf : tree.getImplementsClause()) {
  1.2179 +                    supertypes = supertypes.prepend(intf);
  1.2180 +                }
  1.2181 +            }
  1.2182 +            checkClass(tree.pos(), tree.sym, supertypes);
  1.2183 +        }
  1.2184 +
  1.2185 +        void checkClass(DiagnosticPosition pos, Symbol c, List<JCTree> supertypes) {
  1.2186 +            if ((c.flags_field & ACYCLIC) != 0)
  1.2187 +                return;
  1.2188 +            if (seenClasses.contains(c)) {
  1.2189 +                errorFound = true;
  1.2190 +                noteCyclic(pos, (ClassSymbol)c);
  1.2191 +            } else if (!c.type.isErroneous()) {
  1.2192 +                try {
  1.2193 +                    seenClasses = seenClasses.prepend(c);
  1.2194 +                    if (c.type.hasTag(CLASS)) {
  1.2195 +                        if (supertypes.nonEmpty()) {
  1.2196 +                            scan(supertypes);
  1.2197 +                        }
  1.2198 +                        else {
  1.2199 +                            ClassType ct = (ClassType)c.type;
  1.2200 +                            if (ct.supertype_field == null ||
  1.2201 +                                    ct.interfaces_field == null) {
  1.2202 +                                //not completed yet
  1.2203 +                                partialCheck = true;
  1.2204 +                                return;
  1.2205 +                            }
  1.2206 +                            checkSymbol(pos, ct.supertype_field.tsym);
  1.2207 +                            for (Type intf : ct.interfaces_field) {
  1.2208 +                                checkSymbol(pos, intf.tsym);
  1.2209 +                            }
  1.2210 +                        }
  1.2211 +                        if (c.owner.kind == TYP) {
  1.2212 +                            checkSymbol(pos, c.owner);
  1.2213 +                        }
  1.2214 +                    }
  1.2215 +                } finally {
  1.2216 +                    seenClasses = seenClasses.tail;
  1.2217 +                }
  1.2218 +            }
  1.2219 +        }
  1.2220 +    }
  1.2221 +
  1.2222 +    /** Check for cyclic references. Issue an error if the
  1.2223 +     *  symbol of the type referred to has a LOCKED flag set.
  1.2224 +     *
  1.2225 +     *  @param pos      Position to be used for error reporting.
  1.2226 +     *  @param t        The type referred to.
  1.2227 +     */
  1.2228 +    void checkNonCyclic(DiagnosticPosition pos, Type t) {
  1.2229 +        checkNonCyclicInternal(pos, t);
  1.2230 +    }
  1.2231 +
  1.2232 +
  1.2233 +    void checkNonCyclic(DiagnosticPosition pos, TypeVar t) {
  1.2234 +        checkNonCyclic1(pos, t, List.<TypeVar>nil());
  1.2235 +    }
  1.2236 +
  1.2237 +    private void checkNonCyclic1(DiagnosticPosition pos, Type t, List<TypeVar> seen) {
  1.2238 +        final TypeVar tv;
  1.2239 +        if  (t.hasTag(TYPEVAR) && (t.tsym.flags() & UNATTRIBUTED) != 0)
  1.2240 +            return;
  1.2241 +        if (seen.contains(t)) {
  1.2242 +            tv = (TypeVar)t.unannotatedType();
  1.2243 +            tv.bound = types.createErrorType(t);
  1.2244 +            log.error(pos, "cyclic.inheritance", t);
  1.2245 +        } else if (t.hasTag(TYPEVAR)) {
  1.2246 +            tv = (TypeVar)t.unannotatedType();
  1.2247 +            seen = seen.prepend(tv);
  1.2248 +            for (Type b : types.getBounds(tv))
  1.2249 +                checkNonCyclic1(pos, b, seen);
  1.2250 +        }
  1.2251 +    }
  1.2252 +
  1.2253 +    /** Check for cyclic references. Issue an error if the
  1.2254 +     *  symbol of the type referred to has a LOCKED flag set.
  1.2255 +     *
  1.2256 +     *  @param pos      Position to be used for error reporting.
  1.2257 +     *  @param t        The type referred to.
  1.2258 +     *  @returns        True if the check completed on all attributed classes
  1.2259 +     */
  1.2260 +    private boolean checkNonCyclicInternal(DiagnosticPosition pos, Type t) {
  1.2261 +        boolean complete = true; // was the check complete?
  1.2262 +        //- System.err.println("checkNonCyclicInternal("+t+");");//DEBUG
  1.2263 +        Symbol c = t.tsym;
  1.2264 +        if ((c.flags_field & ACYCLIC) != 0) return true;
  1.2265 +
  1.2266 +        if ((c.flags_field & LOCKED) != 0) {
  1.2267 +            noteCyclic(pos, (ClassSymbol)c);
  1.2268 +        } else if (!c.type.isErroneous()) {
  1.2269 +            try {
  1.2270 +                c.flags_field |= LOCKED;
  1.2271 +                if (c.type.hasTag(CLASS)) {
  1.2272 +                    ClassType clazz = (ClassType)c.type;
  1.2273 +                    if (clazz.interfaces_field != null)
  1.2274 +                        for (List<Type> l=clazz.interfaces_field; l.nonEmpty(); l=l.tail)
  1.2275 +                            complete &= checkNonCyclicInternal(pos, l.head);
  1.2276 +                    if (clazz.supertype_field != null) {
  1.2277 +                        Type st = clazz.supertype_field;
  1.2278 +                        if (st != null && st.hasTag(CLASS))
  1.2279 +                            complete &= checkNonCyclicInternal(pos, st);
  1.2280 +                    }
  1.2281 +                    if (c.owner.kind == TYP)
  1.2282 +                        complete &= checkNonCyclicInternal(pos, c.owner.type);
  1.2283 +                }
  1.2284 +            } finally {
  1.2285 +                c.flags_field &= ~LOCKED;
  1.2286 +            }
  1.2287 +        }
  1.2288 +        if (complete)
  1.2289 +            complete = ((c.flags_field & UNATTRIBUTED) == 0) && c.completer == null;
  1.2290 +        if (complete) c.flags_field |= ACYCLIC;
  1.2291 +        return complete;
  1.2292 +    }
  1.2293 +
  1.2294 +    /** Note that we found an inheritance cycle. */
  1.2295 +    private void noteCyclic(DiagnosticPosition pos, ClassSymbol c) {
  1.2296 +        log.error(pos, "cyclic.inheritance", c);
  1.2297 +        for (List<Type> l=types.interfaces(c.type); l.nonEmpty(); l=l.tail)
  1.2298 +            l.head = types.createErrorType((ClassSymbol)l.head.tsym, Type.noType);
  1.2299 +        Type st = types.supertype(c.type);
  1.2300 +        if (st.hasTag(CLASS))
  1.2301 +            ((ClassType)c.type).supertype_field = types.createErrorType((ClassSymbol)st.tsym, Type.noType);
  1.2302 +        c.type = types.createErrorType(c, c.type);
  1.2303 +        c.flags_field |= ACYCLIC;
  1.2304 +    }
  1.2305 +
  1.2306 +    /** Check that all methods which implement some
  1.2307 +     *  method conform to the method they implement.
  1.2308 +     *  @param tree         The class definition whose members are checked.
  1.2309 +     */
  1.2310 +    void checkImplementations(JCClassDecl tree) {
  1.2311 +        checkImplementations(tree, tree.sym, tree.sym);
  1.2312 +    }
  1.2313 +    //where
  1.2314 +        /** Check that all methods which implement some
  1.2315 +         *  method in `ic' conform to the method they implement.
  1.2316 +         */
  1.2317 +        void checkImplementations(JCTree tree, ClassSymbol origin, ClassSymbol ic) {
  1.2318 +            for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) {
  1.2319 +                ClassSymbol lc = (ClassSymbol)l.head.tsym;
  1.2320 +                if ((allowGenerics || origin != lc) && (lc.flags() & ABSTRACT) != 0) {
  1.2321 +                    for (Scope.Entry e=lc.members().elems; e != null; e=e.sibling) {
  1.2322 +                        if (e.sym.kind == MTH &&
  1.2323 +                            (e.sym.flags() & (STATIC|ABSTRACT)) == ABSTRACT) {
  1.2324 +                            MethodSymbol absmeth = (MethodSymbol)e.sym;
  1.2325 +                            MethodSymbol implmeth = absmeth.implementation(origin, types, false);
  1.2326 +                            if (implmeth != null && implmeth != absmeth &&
  1.2327 +                                (implmeth.owner.flags() & INTERFACE) ==
  1.2328 +                                (origin.flags() & INTERFACE)) {
  1.2329 +                                // don't check if implmeth is in a class, yet
  1.2330 +                                // origin is an interface. This case arises only
  1.2331 +                                // if implmeth is declared in Object. The reason is
  1.2332 +                                // that interfaces really don't inherit from
  1.2333 +                                // Object it's just that the compiler represents
  1.2334 +                                // things that way.
  1.2335 +                                checkOverride(tree, implmeth, absmeth, origin);
  1.2336 +                            }
  1.2337 +                        }
  1.2338 +                    }
  1.2339 +                }
  1.2340 +            }
  1.2341 +        }
  1.2342 +
  1.2343 +    /** Check that all abstract methods implemented by a class are
  1.2344 +     *  mutually compatible.
  1.2345 +     *  @param pos          Position to be used for error reporting.
  1.2346 +     *  @param c            The class whose interfaces are checked.
  1.2347 +     */
  1.2348 +    void checkCompatibleSupertypes(DiagnosticPosition pos, Type c) {
  1.2349 +        List<Type> supertypes = types.interfaces(c);
  1.2350 +        Type supertype = types.supertype(c);
  1.2351 +        if (supertype.hasTag(CLASS) &&
  1.2352 +            (supertype.tsym.flags() & ABSTRACT) != 0)
  1.2353 +            supertypes = supertypes.prepend(supertype);
  1.2354 +        for (List<Type> l = supertypes; l.nonEmpty(); l = l.tail) {
  1.2355 +            if (allowGenerics && !l.head.getTypeArguments().isEmpty() &&
  1.2356 +                !checkCompatibleAbstracts(pos, l.head, l.head, c))
  1.2357 +                return;
  1.2358 +            for (List<Type> m = supertypes; m != l; m = m.tail)
  1.2359 +                if (!checkCompatibleAbstracts(pos, l.head, m.head, c))
  1.2360 +                    return;
  1.2361 +        }
  1.2362 +        checkCompatibleConcretes(pos, c);
  1.2363 +    }
  1.2364 +
  1.2365 +    void checkConflicts(DiagnosticPosition pos, Symbol sym, TypeSymbol c) {
  1.2366 +        for (Type ct = c.type; ct != Type.noType ; ct = types.supertype(ct)) {
  1.2367 +            for (Scope.Entry e = ct.tsym.members().lookup(sym.name); e.scope == ct.tsym.members(); e = e.next()) {
  1.2368 +                // VM allows methods and variables with differing types
  1.2369 +                if (sym.kind == e.sym.kind &&
  1.2370 +                    types.isSameType(types.erasure(sym.type), types.erasure(e.sym.type)) &&
  1.2371 +                    sym != e.sym &&
  1.2372 +                    (sym.flags() & Flags.SYNTHETIC) != (e.sym.flags() & Flags.SYNTHETIC) &&
  1.2373 +                    (sym.flags() & IPROXY) == 0 && (e.sym.flags() & IPROXY) == 0 &&
  1.2374 +                    (sym.flags() & BRIDGE) == 0 && (e.sym.flags() & BRIDGE) == 0) {
  1.2375 +                    syntheticError(pos, (e.sym.flags() & SYNTHETIC) == 0 ? e.sym : sym);
  1.2376 +                    return;
  1.2377 +                }
  1.2378 +            }
  1.2379 +        }
  1.2380 +    }
  1.2381 +
  1.2382 +    /** Check that all non-override equivalent methods accessible from 'site'
  1.2383 +     *  are mutually compatible (JLS 8.4.8/9.4.1).
  1.2384 +     *
  1.2385 +     *  @param pos  Position to be used for error reporting.
  1.2386 +     *  @param site The class whose methods are checked.
  1.2387 +     *  @param sym  The method symbol to be checked.
  1.2388 +     */
  1.2389 +    void checkOverrideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
  1.2390 +         ClashFilter cf = new ClashFilter(site);
  1.2391 +        //for each method m1 that is overridden (directly or indirectly)
  1.2392 +        //by method 'sym' in 'site'...
  1.2393 +
  1.2394 +        List<MethodSymbol> potentiallyAmbiguousList = List.nil();
  1.2395 +        boolean overridesAny = false;
  1.2396 +        for (Symbol m1 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) {
  1.2397 +            if (!sym.overrides(m1, site.tsym, types, false)) {
  1.2398 +                if (m1 == sym) {
  1.2399 +                    continue;
  1.2400 +                }
  1.2401 +
  1.2402 +                if (!overridesAny) {
  1.2403 +                    potentiallyAmbiguousList = potentiallyAmbiguousList.prepend((MethodSymbol)m1);
  1.2404 +                }
  1.2405 +                continue;
  1.2406 +            }
  1.2407 +
  1.2408 +            if (m1 != sym) {
  1.2409 +                overridesAny = true;
  1.2410 +                potentiallyAmbiguousList = List.nil();
  1.2411 +            }
  1.2412 +
  1.2413 +            //...check each method m2 that is a member of 'site'
  1.2414 +            for (Symbol m2 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) {
  1.2415 +                if (m2 == m1) continue;
  1.2416 +                //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
  1.2417 +                //a member of 'site') and (ii) m1 has the same erasure as m2, issue an error
  1.2418 +                if (!types.isSubSignature(sym.type, types.memberType(site, m2), allowStrictMethodClashCheck) &&
  1.2419 +                        types.hasSameArgs(m2.erasure(types), m1.erasure(types))) {
  1.2420 +                    sym.flags_field |= CLASH;
  1.2421 +                    String key = m1 == sym ?
  1.2422 +                            "name.clash.same.erasure.no.override" :
  1.2423 +                            "name.clash.same.erasure.no.override.1";
  1.2424 +                    log.error(pos,
  1.2425 +                            key,
  1.2426 +                            sym, sym.location(),
  1.2427 +                            m2, m2.location(),
  1.2428 +                            m1, m1.location());
  1.2429 +                    return;
  1.2430 +                }
  1.2431 +            }
  1.2432 +        }
  1.2433 +
  1.2434 +        if (!overridesAny) {
  1.2435 +            for (MethodSymbol m: potentiallyAmbiguousList) {
  1.2436 +                checkPotentiallyAmbiguousOverloads(pos, site, sym, m);
  1.2437 +            }
  1.2438 +        }
  1.2439 +    }
  1.2440 +
  1.2441 +    /** Check that all static methods accessible from 'site' are
  1.2442 +     *  mutually compatible (JLS 8.4.8).
  1.2443 +     *
  1.2444 +     *  @param pos  Position to be used for error reporting.
  1.2445 +     *  @param site The class whose methods are checked.
  1.2446 +     *  @param sym  The method symbol to be checked.
  1.2447 +     */
  1.2448 +    void checkHideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
  1.2449 +        ClashFilter cf = new ClashFilter(site);
  1.2450 +        //for each method m1 that is a member of 'site'...
  1.2451 +        for (Symbol s : types.membersClosure(site, true).getElementsByName(sym.name, cf)) {
  1.2452 +            //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
  1.2453 +            //a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error
  1.2454 +            if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck)) {
  1.2455 +                if (types.hasSameArgs(s.erasure(types), sym.erasure(types))) {
  1.2456 +                    log.error(pos,
  1.2457 +                            "name.clash.same.erasure.no.hide",
  1.2458 +                            sym, sym.location(),
  1.2459 +                            s, s.location());
  1.2460 +                    return;
  1.2461 +                } else {
  1.2462 +                    checkPotentiallyAmbiguousOverloads(pos, site, sym, (MethodSymbol)s);
  1.2463 +                }
  1.2464 +            }
  1.2465 +         }
  1.2466 +     }
  1.2467 +
  1.2468 +     //where
  1.2469 +     private class ClashFilter implements Filter<Symbol> {
  1.2470 +
  1.2471 +         Type site;
  1.2472 +
  1.2473 +         ClashFilter(Type site) {
  1.2474 +             this.site = site;
  1.2475 +         }
  1.2476 +
  1.2477 +         boolean shouldSkip(Symbol s) {
  1.2478 +             return (s.flags() & CLASH) != 0 &&
  1.2479 +                s.owner == site.tsym;
  1.2480 +         }
  1.2481 +
  1.2482 +         public boolean accepts(Symbol s) {
  1.2483 +             return s.kind == MTH &&
  1.2484 +                     (s.flags() & SYNTHETIC) == 0 &&
  1.2485 +                     !shouldSkip(s) &&
  1.2486 +                     s.isInheritedIn(site.tsym, types) &&
  1.2487 +                     !s.isConstructor();
  1.2488 +         }
  1.2489 +     }
  1.2490 +
  1.2491 +    void checkDefaultMethodClashes(DiagnosticPosition pos, Type site) {
  1.2492 +        DefaultMethodClashFilter dcf = new DefaultMethodClashFilter(site);
  1.2493 +        for (Symbol m : types.membersClosure(site, false).getElements(dcf)) {
  1.2494 +            Assert.check(m.kind == MTH);
  1.2495 +            List<MethodSymbol> prov = types.interfaceCandidates(site, (MethodSymbol)m);
  1.2496 +            if (prov.size() > 1) {
  1.2497 +                ListBuffer<Symbol> abstracts = new ListBuffer<>();
  1.2498 +                ListBuffer<Symbol> defaults = new ListBuffer<>();
  1.2499 +                for (MethodSymbol provSym : prov) {
  1.2500 +                    if ((provSym.flags() & DEFAULT) != 0) {
  1.2501 +                        defaults = defaults.append(provSym);
  1.2502 +                    } else if ((provSym.flags() & ABSTRACT) != 0) {
  1.2503 +                        abstracts = abstracts.append(provSym);
  1.2504 +                    }
  1.2505 +                    if (defaults.nonEmpty() && defaults.size() + abstracts.size() >= 2) {
  1.2506 +                        //strong semantics - issue an error if two sibling interfaces
  1.2507 +                        //have two override-equivalent defaults - or if one is abstract
  1.2508 +                        //and the other is default
  1.2509 +                        String errKey;
  1.2510 +                        Symbol s1 = defaults.first();
  1.2511 +                        Symbol s2;
  1.2512 +                        if (defaults.size() > 1) {
  1.2513 +                            errKey = "types.incompatible.unrelated.defaults";
  1.2514 +                            s2 = defaults.toList().tail.head;
  1.2515 +                        } else {
  1.2516 +                            errKey = "types.incompatible.abstract.default";
  1.2517 +                            s2 = abstracts.first();
  1.2518 +                        }
  1.2519 +                        log.error(pos, errKey,
  1.2520 +                                Kinds.kindName(site.tsym), site,
  1.2521 +                                m.name, types.memberType(site, m).getParameterTypes(),
  1.2522 +                                s1.location(), s2.location());
  1.2523 +                        break;
  1.2524 +                    }
  1.2525 +                }
  1.2526 +            }
  1.2527 +        }
  1.2528 +    }
  1.2529 +
  1.2530 +    //where
  1.2531 +     private class DefaultMethodClashFilter implements Filter<Symbol> {
  1.2532 +
  1.2533 +         Type site;
  1.2534 +
  1.2535 +         DefaultMethodClashFilter(Type site) {
  1.2536 +             this.site = site;
  1.2537 +         }
  1.2538 +
  1.2539 +         public boolean accepts(Symbol s) {
  1.2540 +             return s.kind == MTH &&
  1.2541 +                     (s.flags() & DEFAULT) != 0 &&
  1.2542 +                     s.isInheritedIn(site.tsym, types) &&
  1.2543 +                     !s.isConstructor();
  1.2544 +         }
  1.2545 +     }
  1.2546 +
  1.2547 +    /**
  1.2548 +      * Report warnings for potentially ambiguous method declarations. Two declarations
  1.2549 +      * are potentially ambiguous if they feature two unrelated functional interface
  1.2550 +      * in same argument position (in which case, a call site passing an implicit
  1.2551 +      * lambda would be ambiguous).
  1.2552 +      */
  1.2553 +    void checkPotentiallyAmbiguousOverloads(DiagnosticPosition pos, Type site,
  1.2554 +            MethodSymbol msym1, MethodSymbol msym2) {
  1.2555 +        if (msym1 != msym2 &&
  1.2556 +                allowDefaultMethods &&
  1.2557 +                lint.isEnabled(LintCategory.OVERLOADS) &&
  1.2558 +                (msym1.flags() & POTENTIALLY_AMBIGUOUS) == 0 &&
  1.2559 +                (msym2.flags() & POTENTIALLY_AMBIGUOUS) == 0) {
  1.2560 +            Type mt1 = types.memberType(site, msym1);
  1.2561 +            Type mt2 = types.memberType(site, msym2);
  1.2562 +            //if both generic methods, adjust type variables
  1.2563 +            if (mt1.hasTag(FORALL) && mt2.hasTag(FORALL) &&
  1.2564 +                    types.hasSameBounds((ForAll)mt1, (ForAll)mt2)) {
  1.2565 +                mt2 = types.subst(mt2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars);
  1.2566 +            }
  1.2567 +            //expand varargs methods if needed
  1.2568 +            int maxLength = Math.max(mt1.getParameterTypes().length(), mt2.getParameterTypes().length());
  1.2569 +            List<Type> args1 = rs.adjustArgs(mt1.getParameterTypes(), msym1, maxLength, true);
  1.2570 +            List<Type> args2 = rs.adjustArgs(mt2.getParameterTypes(), msym2, maxLength, true);
  1.2571 +            //if arities don't match, exit
  1.2572 +            if (args1.length() != args2.length()) return;
  1.2573 +            boolean potentiallyAmbiguous = false;
  1.2574 +            while (args1.nonEmpty() && args2.nonEmpty()) {
  1.2575 +                Type s = args1.head;
  1.2576 +                Type t = args2.head;
  1.2577 +                if (!types.isSubtype(t, s) && !types.isSubtype(s, t)) {
  1.2578 +                    if (types.isFunctionalInterface(s) && types.isFunctionalInterface(t) &&
  1.2579 +                            types.findDescriptorType(s).getParameterTypes().length() > 0 &&
  1.2580 +                            types.findDescriptorType(s).getParameterTypes().length() ==
  1.2581 +                            types.findDescriptorType(t).getParameterTypes().length()) {
  1.2582 +                        potentiallyAmbiguous = true;
  1.2583 +                    } else {
  1.2584 +                        break;
  1.2585 +                    }
  1.2586 +                }
  1.2587 +                args1 = args1.tail;
  1.2588 +                args2 = args2.tail;
  1.2589 +            }
  1.2590 +            if (potentiallyAmbiguous) {
  1.2591 +                //we found two incompatible functional interfaces with same arity
  1.2592 +                //this means a call site passing an implicit lambda would be ambigiuous
  1.2593 +                msym1.flags_field |= POTENTIALLY_AMBIGUOUS;
  1.2594 +                msym2.flags_field |= POTENTIALLY_AMBIGUOUS;
  1.2595 +                log.warning(LintCategory.OVERLOADS, pos, "potentially.ambiguous.overload",
  1.2596 +                            msym1, msym1.location(),
  1.2597 +                            msym2, msym2.location());
  1.2598 +                return;
  1.2599 +            }
  1.2600 +        }
  1.2601 +    }
  1.2602 +
  1.2603 +    void checkElemAccessFromSerializableLambda(final JCTree tree) {
  1.2604 +        if (warnOnAccessToSensitiveMembers) {
  1.2605 +            Symbol sym = TreeInfo.symbol(tree);
  1.2606 +            if ((sym.kind & (VAR | MTH)) == 0) {
  1.2607 +                return;
  1.2608 +            }
  1.2609 +
  1.2610 +            if (sym.kind == VAR) {
  1.2611 +                if ((sym.flags() & PARAMETER) != 0 ||
  1.2612 +                    sym.isLocal() ||
  1.2613 +                    sym.name == names._this ||
  1.2614 +                    sym.name == names._super) {
  1.2615 +                    return;
  1.2616 +                }
  1.2617 +            }
  1.2618 +
  1.2619 +            if (!types.isSubtype(sym.owner.type, syms.serializableType) &&
  1.2620 +                    isEffectivelyNonPublic(sym)) {
  1.2621 +                log.warning(tree.pos(),
  1.2622 +                        "access.to.sensitive.member.from.serializable.element", sym);
  1.2623 +            }
  1.2624 +        }
  1.2625 +    }
  1.2626 +
  1.2627 +    private boolean isEffectivelyNonPublic(Symbol sym) {
  1.2628 +        if (sym.packge() == syms.rootPackage) {
  1.2629 +            return false;
  1.2630 +        }
  1.2631 +
  1.2632 +        while (sym.kind != Kinds.PCK) {
  1.2633 +            if ((sym.flags() & PUBLIC) == 0) {
  1.2634 +                return true;
  1.2635 +            }
  1.2636 +            sym = sym.owner;
  1.2637 +        }
  1.2638 +        return false;
  1.2639 +    }
  1.2640 +
  1.2641 +    /** Report a conflict between a user symbol and a synthetic symbol.
  1.2642 +     */
  1.2643 +    private void syntheticError(DiagnosticPosition pos, Symbol sym) {
  1.2644 +        if (!sym.type.isErroneous()) {
  1.2645 +            if (warnOnSyntheticConflicts) {
  1.2646 +                log.warning(pos, "synthetic.name.conflict", sym, sym.location());
  1.2647 +            }
  1.2648 +            else {
  1.2649 +                log.error(pos, "synthetic.name.conflict", sym, sym.location());
  1.2650 +            }
  1.2651 +        }
  1.2652 +    }
  1.2653 +
  1.2654 +    /** Check that class c does not implement directly or indirectly
  1.2655 +     *  the same parameterized interface with two different argument lists.
  1.2656 +     *  @param pos          Position to be used for error reporting.
  1.2657 +     *  @param type         The type whose interfaces are checked.
  1.2658 +     */
  1.2659 +    void checkClassBounds(DiagnosticPosition pos, Type type) {
  1.2660 +        checkClassBounds(pos, new HashMap<TypeSymbol,Type>(), type);
  1.2661 +    }
  1.2662 +//where
  1.2663 +        /** Enter all interfaces of type `type' into the hash table `seensofar'
  1.2664 +         *  with their class symbol as key and their type as value. Make
  1.2665 +         *  sure no class is entered with two different types.
  1.2666 +         */
  1.2667 +        void checkClassBounds(DiagnosticPosition pos,
  1.2668 +                              Map<TypeSymbol,Type> seensofar,
  1.2669 +                              Type type) {
  1.2670 +            if (type.isErroneous()) return;
  1.2671 +            for (List<Type> l = types.interfaces(type); l.nonEmpty(); l = l.tail) {
  1.2672 +                Type it = l.head;
  1.2673 +                Type oldit = seensofar.put(it.tsym, it);
  1.2674 +                if (oldit != null) {
  1.2675 +                    List<Type> oldparams = oldit.allparams();
  1.2676 +                    List<Type> newparams = it.allparams();
  1.2677 +                    if (!types.containsTypeEquivalent(oldparams, newparams))
  1.2678 +                        log.error(pos, "cant.inherit.diff.arg",
  1.2679 +                                  it.tsym, Type.toString(oldparams),
  1.2680 +                                  Type.toString(newparams));
  1.2681 +                }
  1.2682 +                checkClassBounds(pos, seensofar, it);
  1.2683 +            }
  1.2684 +            Type st = types.supertype(type);
  1.2685 +            if (st != Type.noType) checkClassBounds(pos, seensofar, st);
  1.2686 +        }
  1.2687 +
  1.2688 +    /** Enter interface into into set.
  1.2689 +     *  If it existed already, issue a "repeated interface" error.
  1.2690 +     */
  1.2691 +    void checkNotRepeated(DiagnosticPosition pos, Type it, Set<Type> its) {
  1.2692 +        if (its.contains(it))
  1.2693 +            log.error(pos, "repeated.interface");
  1.2694 +        else {
  1.2695 +            its.add(it);
  1.2696 +        }
  1.2697 +    }
  1.2698 +
  1.2699 +/* *************************************************************************
  1.2700 + * Check annotations
  1.2701 + **************************************************************************/
  1.2702 +
  1.2703 +    /**
  1.2704 +     * Recursively validate annotations values
  1.2705 +     */
  1.2706 +    void validateAnnotationTree(JCTree tree) {
  1.2707 +        class AnnotationValidator extends TreeScanner {
  1.2708 +            @Override
  1.2709 +            public void visitAnnotation(JCAnnotation tree) {
  1.2710 +                if (!tree.type.isErroneous()) {
  1.2711 +                    super.visitAnnotation(tree);
  1.2712 +                    validateAnnotation(tree);
  1.2713 +                }
  1.2714 +            }
  1.2715 +        }
  1.2716 +        tree.accept(new AnnotationValidator());
  1.2717 +    }
  1.2718 +
  1.2719 +    /**
  1.2720 +     *  {@literal
  1.2721 +     *  Annotation types are restricted to primitives, String, an
  1.2722 +     *  enum, an annotation, Class, Class<?>, Class<? extends
  1.2723 +     *  Anything>, arrays of the preceding.
  1.2724 +     *  }
  1.2725 +     */
  1.2726 +    void validateAnnotationType(JCTree restype) {
  1.2727 +        // restype may be null if an error occurred, so don't bother validating it
  1.2728 +        if (restype != null) {
  1.2729 +            validateAnnotationType(restype.pos(), restype.type);
  1.2730 +        }
  1.2731 +    }
  1.2732 +
  1.2733 +    void validateAnnotationType(DiagnosticPosition pos, Type type) {
  1.2734 +        if (type.isPrimitive()) return;
  1.2735 +        if (types.isSameType(type, syms.stringType)) return;
  1.2736 +        if ((type.tsym.flags() & Flags.ENUM) != 0) return;
  1.2737 +        if ((type.tsym.flags() & Flags.ANNOTATION) != 0) return;
  1.2738 +        if (types.cvarLowerBound(type).tsym == syms.classType.tsym) return;
  1.2739 +        if (types.isArray(type) && !types.isArray(types.elemtype(type))) {
  1.2740 +            validateAnnotationType(pos, types.elemtype(type));
  1.2741 +            return;
  1.2742 +        }
  1.2743 +        log.error(pos, "invalid.annotation.member.type");
  1.2744 +    }
  1.2745 +
  1.2746 +    /**
  1.2747 +     * "It is also a compile-time error if any method declared in an
  1.2748 +     * annotation type has a signature that is override-equivalent to
  1.2749 +     * that of any public or protected method declared in class Object
  1.2750 +     * or in the interface annotation.Annotation."
  1.2751 +     *
  1.2752 +     * @jls 9.6 Annotation Types
  1.2753 +     */
  1.2754 +    void validateAnnotationMethod(DiagnosticPosition pos, MethodSymbol m) {
  1.2755 +        for (Type sup = syms.annotationType; sup.hasTag(CLASS); sup = types.supertype(sup)) {
  1.2756 +            Scope s = sup.tsym.members();
  1.2757 +            for (Scope.Entry e = s.lookup(m.name); e.scope != null; e = e.next()) {
  1.2758 +                if (e.sym.kind == MTH &&
  1.2759 +                    (e.sym.flags() & (PUBLIC | PROTECTED)) != 0 &&
  1.2760 +                    types.overrideEquivalent(m.type, e.sym.type))
  1.2761 +                    log.error(pos, "intf.annotation.member.clash", e.sym, sup);
  1.2762 +            }
  1.2763 +        }
  1.2764 +    }
  1.2765 +
  1.2766 +    /** Check the annotations of a symbol.
  1.2767 +     */
  1.2768 +    public void validateAnnotations(List<JCAnnotation> annotations, Symbol s) {
  1.2769 +        for (JCAnnotation a : annotations)
  1.2770 +            validateAnnotation(a, s);
  1.2771 +    }
  1.2772 +
  1.2773 +    /** Check the type annotations.
  1.2774 +     */
  1.2775 +    public void validateTypeAnnotations(List<JCAnnotation> annotations, boolean isTypeParameter) {
  1.2776 +        for (JCAnnotation a : annotations)
  1.2777 +            validateTypeAnnotation(a, isTypeParameter);
  1.2778 +    }
  1.2779 +
  1.2780 +    /** Check an annotation of a symbol.
  1.2781 +     */
  1.2782 +    private void validateAnnotation(JCAnnotation a, Symbol s) {
  1.2783 +        validateAnnotationTree(a);
  1.2784 +
  1.2785 +        if (!annotationApplicable(a, s))
  1.2786 +            log.error(a.pos(), "annotation.type.not.applicable");
  1.2787 +
  1.2788 +        if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) {
  1.2789 +            if (s.kind != TYP) {
  1.2790 +                log.error(a.pos(), "bad.functional.intf.anno");
  1.2791 +            } else if (!s.isInterface() || (s.flags() & ANNOTATION) != 0) {
  1.2792 +                log.error(a.pos(), "bad.functional.intf.anno.1", diags.fragment("not.a.functional.intf", s));
  1.2793 +            }
  1.2794 +        }
  1.2795 +    }
  1.2796 +
  1.2797 +    public void validateTypeAnnotation(JCAnnotation a, boolean isTypeParameter) {
  1.2798 +        Assert.checkNonNull(a.type, "annotation tree hasn't been attributed yet: " + a);
  1.2799 +        validateAnnotationTree(a);
  1.2800 +
  1.2801 +        if (a.hasTag(TYPE_ANNOTATION) &&
  1.2802 +                !a.annotationType.type.isErroneous() &&
  1.2803 +                !isTypeAnnotation(a, isTypeParameter)) {
  1.2804 +            log.error(a.pos(), "annotation.type.not.applicable");
  1.2805 +        }
  1.2806 +    }
  1.2807 +
  1.2808 +    /**
  1.2809 +     * Validate the proposed container 'repeatable' on the
  1.2810 +     * annotation type symbol 's'. Report errors at position
  1.2811 +     * 'pos'.
  1.2812 +     *
  1.2813 +     * @param s The (annotation)type declaration annotated with a @Repeatable
  1.2814 +     * @param repeatable the @Repeatable on 's'
  1.2815 +     * @param pos where to report errors
  1.2816 +     */
  1.2817 +    public void validateRepeatable(TypeSymbol s, Attribute.Compound repeatable, DiagnosticPosition pos) {
  1.2818 +        Assert.check(types.isSameType(repeatable.type, syms.repeatableType));
  1.2819 +
  1.2820 +        Type t = null;
  1.2821 +        List<Pair<MethodSymbol,Attribute>> l = repeatable.values;
  1.2822 +        if (!l.isEmpty()) {
  1.2823 +            Assert.check(l.head.fst.name == names.value);
  1.2824 +            t = ((Attribute.Class)l.head.snd).getValue();
  1.2825 +        }
  1.2826 +
  1.2827 +        if (t == null) {
  1.2828 +            // errors should already have been reported during Annotate
  1.2829 +            return;
  1.2830 +        }
  1.2831 +
  1.2832 +        validateValue(t.tsym, s, pos);
  1.2833 +        validateRetention(t.tsym, s, pos);
  1.2834 +        validateDocumented(t.tsym, s, pos);
  1.2835 +        validateInherited(t.tsym, s, pos);
  1.2836 +        validateTarget(t.tsym, s, pos);
  1.2837 +        validateDefault(t.tsym, pos);
  1.2838 +    }
  1.2839 +
  1.2840 +    private void validateValue(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
  1.2841 +        Scope.Entry e = container.members().lookup(names.value);
  1.2842 +        if (e.scope != null && e.sym.kind == MTH) {
  1.2843 +            MethodSymbol m = (MethodSymbol) e.sym;
  1.2844 +            Type ret = m.getReturnType();
  1.2845 +            if (!(ret.hasTag(ARRAY) && types.isSameType(((ArrayType)ret).elemtype, contained.type))) {
  1.2846 +                log.error(pos, "invalid.repeatable.annotation.value.return",
  1.2847 +                        container, ret, types.makeArrayType(contained.type));
  1.2848 +            }
  1.2849 +        } else {
  1.2850 +            log.error(pos, "invalid.repeatable.annotation.no.value", container);
  1.2851 +        }
  1.2852 +    }
  1.2853 +
  1.2854 +    private void validateRetention(Symbol container, Symbol contained, DiagnosticPosition pos) {
  1.2855 +        Attribute.RetentionPolicy containerRetention = types.getRetention(container);
  1.2856 +        Attribute.RetentionPolicy containedRetention = types.getRetention(contained);
  1.2857 +
  1.2858 +        boolean error = false;
  1.2859 +        switch (containedRetention) {
  1.2860 +        case RUNTIME:
  1.2861 +            if (containerRetention != Attribute.RetentionPolicy.RUNTIME) {
  1.2862 +                error = true;
  1.2863 +            }
  1.2864 +            break;
  1.2865 +        case CLASS:
  1.2866 +            if (containerRetention == Attribute.RetentionPolicy.SOURCE)  {
  1.2867 +                error = true;
  1.2868 +            }
  1.2869 +        }
  1.2870 +        if (error ) {
  1.2871 +            log.error(pos, "invalid.repeatable.annotation.retention",
  1.2872 +                      container, containerRetention,
  1.2873 +                      contained, containedRetention);
  1.2874 +        }
  1.2875 +    }
  1.2876 +
  1.2877 +    private void validateDocumented(Symbol container, Symbol contained, DiagnosticPosition pos) {
  1.2878 +        if (contained.attribute(syms.documentedType.tsym) != null) {
  1.2879 +            if (container.attribute(syms.documentedType.tsym) == null) {
  1.2880 +                log.error(pos, "invalid.repeatable.annotation.not.documented", container, contained);
  1.2881 +            }
  1.2882 +        }
  1.2883 +    }
  1.2884 +
  1.2885 +    private void validateInherited(Symbol container, Symbol contained, DiagnosticPosition pos) {
  1.2886 +        if (contained.attribute(syms.inheritedType.tsym) != null) {
  1.2887 +            if (container.attribute(syms.inheritedType.tsym) == null) {
  1.2888 +                log.error(pos, "invalid.repeatable.annotation.not.inherited", container, contained);
  1.2889 +            }
  1.2890 +        }
  1.2891 +    }
  1.2892 +
  1.2893 +    private void validateTarget(Symbol container, Symbol contained, DiagnosticPosition pos) {
  1.2894 +        // The set of targets the container is applicable to must be a subset
  1.2895 +        // (with respect to annotation target semantics) of the set of targets
  1.2896 +        // the contained is applicable to. The target sets may be implicit or
  1.2897 +        // explicit.
  1.2898 +
  1.2899 +        Set<Name> containerTargets;
  1.2900 +        Attribute.Array containerTarget = getAttributeTargetAttribute(container);
  1.2901 +        if (containerTarget == null) {
  1.2902 +            containerTargets = getDefaultTargetSet();
  1.2903 +        } else {
  1.2904 +            containerTargets = new HashSet<Name>();
  1.2905 +        for (Attribute app : containerTarget.values) {
  1.2906 +            if (!(app instanceof Attribute.Enum)) {
  1.2907 +                continue; // recovery
  1.2908 +            }
  1.2909 +            Attribute.Enum e = (Attribute.Enum)app;
  1.2910 +            containerTargets.add(e.value.name);
  1.2911 +        }
  1.2912 +        }
  1.2913 +
  1.2914 +        Set<Name> containedTargets;
  1.2915 +        Attribute.Array containedTarget = getAttributeTargetAttribute(contained);
  1.2916 +        if (containedTarget == null) {
  1.2917 +            containedTargets = getDefaultTargetSet();
  1.2918 +        } else {
  1.2919 +            containedTargets = new HashSet<Name>();
  1.2920 +        for (Attribute app : containedTarget.values) {
  1.2921 +            if (!(app instanceof Attribute.Enum)) {
  1.2922 +                continue; // recovery
  1.2923 +            }
  1.2924 +            Attribute.Enum e = (Attribute.Enum)app;
  1.2925 +            containedTargets.add(e.value.name);
  1.2926 +        }
  1.2927 +        }
  1.2928 +
  1.2929 +        if (!isTargetSubsetOf(containerTargets, containedTargets)) {
  1.2930 +            log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained);
  1.2931 +        }
  1.2932 +    }
  1.2933 +
  1.2934 +    /* get a set of names for the default target */
  1.2935 +    private Set<Name> getDefaultTargetSet() {
  1.2936 +        if (defaultTargets == null) {
  1.2937 +            Set<Name> targets = new HashSet<Name>();
  1.2938 +            targets.add(names.ANNOTATION_TYPE);
  1.2939 +            targets.add(names.CONSTRUCTOR);
  1.2940 +            targets.add(names.FIELD);
  1.2941 +            targets.add(names.LOCAL_VARIABLE);
  1.2942 +            targets.add(names.METHOD);
  1.2943 +            targets.add(names.PACKAGE);
  1.2944 +            targets.add(names.PARAMETER);
  1.2945 +            targets.add(names.TYPE);
  1.2946 +
  1.2947 +            defaultTargets = java.util.Collections.unmodifiableSet(targets);
  1.2948 +        }
  1.2949 +
  1.2950 +        return defaultTargets;
  1.2951 +    }
  1.2952 +    private Set<Name> defaultTargets;
  1.2953 +
  1.2954 +
  1.2955 +    /** Checks that s is a subset of t, with respect to ElementType
  1.2956 +     * semantics, specifically {ANNOTATION_TYPE} is a subset of {TYPE},
  1.2957 +     * and {TYPE_USE} covers the set {ANNOTATION_TYPE, TYPE, TYPE_USE,
  1.2958 +     * TYPE_PARAMETER}.
  1.2959 +     */
  1.2960 +    private boolean isTargetSubsetOf(Set<Name> s, Set<Name> t) {
  1.2961 +        // Check that all elements in s are present in t
  1.2962 +        for (Name n2 : s) {
  1.2963 +            boolean currentElementOk = false;
  1.2964 +            for (Name n1 : t) {
  1.2965 +                if (n1 == n2) {
  1.2966 +                    currentElementOk = true;
  1.2967 +                    break;
  1.2968 +                } else if (n1 == names.TYPE && n2 == names.ANNOTATION_TYPE) {
  1.2969 +                    currentElementOk = true;
  1.2970 +                    break;
  1.2971 +                } else if (n1 == names.TYPE_USE &&
  1.2972 +                        (n2 == names.TYPE ||
  1.2973 +                         n2 == names.ANNOTATION_TYPE ||
  1.2974 +                         n2 == names.TYPE_PARAMETER)) {
  1.2975 +                    currentElementOk = true;
  1.2976 +                    break;
  1.2977 +                }
  1.2978 +            }
  1.2979 +            if (!currentElementOk)
  1.2980 +                return false;
  1.2981 +        }
  1.2982 +        return true;
  1.2983 +    }
  1.2984 +
  1.2985 +    private void validateDefault(Symbol container, DiagnosticPosition pos) {
  1.2986 +        // validate that all other elements of containing type has defaults
  1.2987 +        Scope scope = container.members();
  1.2988 +        for(Symbol elm : scope.getElements()) {
  1.2989 +            if (elm.name != names.value &&
  1.2990 +                elm.kind == Kinds.MTH &&
  1.2991 +                ((MethodSymbol)elm).defaultValue == null) {
  1.2992 +                log.error(pos,
  1.2993 +                          "invalid.repeatable.annotation.elem.nondefault",
  1.2994 +                          container,
  1.2995 +                          elm);
  1.2996 +            }
  1.2997 +        }
  1.2998 +    }
  1.2999 +
  1.3000 +    /** Is s a method symbol that overrides a method in a superclass? */
  1.3001 +    boolean isOverrider(Symbol s) {
  1.3002 +        if (s.kind != MTH || s.isStatic())
  1.3003 +            return false;
  1.3004 +        MethodSymbol m = (MethodSymbol)s;
  1.3005 +        TypeSymbol owner = (TypeSymbol)m.owner;
  1.3006 +        for (Type sup : types.closure(owner.type)) {
  1.3007 +            if (sup == owner.type)
  1.3008 +                continue; // skip "this"
  1.3009 +            Scope scope = sup.tsym.members();
  1.3010 +            for (Scope.Entry e = scope.lookup(m.name); e.scope != null; e = e.next()) {
  1.3011 +                if (!e.sym.isStatic() && m.overrides(e.sym, owner, types, true))
  1.3012 +                    return true;
  1.3013 +            }
  1.3014 +        }
  1.3015 +        return false;
  1.3016 +    }
  1.3017 +
  1.3018 +    /** Is the annotation applicable to types? */
  1.3019 +    protected boolean isTypeAnnotation(JCAnnotation a, boolean isTypeParameter) {
  1.3020 +        Attribute.Compound atTarget =
  1.3021 +            a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym);
  1.3022 +        if (atTarget == null) {
  1.3023 +            // An annotation without @Target is not a type annotation.
  1.3024 +            return false;
  1.3025 +        }
  1.3026 +
  1.3027 +        Attribute atValue = atTarget.member(names.value);
  1.3028 +        if (!(atValue instanceof Attribute.Array)) {
  1.3029 +            return false; // error recovery
  1.3030 +        }
  1.3031 +
  1.3032 +        Attribute.Array arr = (Attribute.Array) atValue;
  1.3033 +        for (Attribute app : arr.values) {
  1.3034 +            if (!(app instanceof Attribute.Enum)) {
  1.3035 +                return false; // recovery
  1.3036 +            }
  1.3037 +            Attribute.Enum e = (Attribute.Enum) app;
  1.3038 +
  1.3039 +            if (e.value.name == names.TYPE_USE)
  1.3040 +                return true;
  1.3041 +            else if (isTypeParameter && e.value.name == names.TYPE_PARAMETER)
  1.3042 +                return true;
  1.3043 +        }
  1.3044 +        return false;
  1.3045 +    }
  1.3046 +
  1.3047 +    /** Is the annotation applicable to the symbol? */
  1.3048 +    boolean annotationApplicable(JCAnnotation a, Symbol s) {
  1.3049 +        Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym);
  1.3050 +        Name[] targets;
  1.3051 +
  1.3052 +        if (arr == null) {
  1.3053 +            targets = defaultTargetMetaInfo(a, s);
  1.3054 +        } else {
  1.3055 +            // TODO: can we optimize this?
  1.3056 +            targets = new Name[arr.values.length];
  1.3057 +            for (int i=0; i<arr.values.length; ++i) {
  1.3058 +                Attribute app = arr.values[i];
  1.3059 +                if (!(app instanceof Attribute.Enum)) {
  1.3060 +                    return true; // recovery
  1.3061 +                }
  1.3062 +                Attribute.Enum e = (Attribute.Enum) app;
  1.3063 +                targets[i] = e.value.name;
  1.3064 +            }
  1.3065 +        }
  1.3066 +        for (Name target : targets) {
  1.3067 +            if (target == names.TYPE)
  1.3068 +                { if (s.kind == TYP) return true; }
  1.3069 +            else if (target == names.FIELD)
  1.3070 +                { if (s.kind == VAR && s.owner.kind != MTH) return true; }
  1.3071 +            else if (target == names.METHOD)
  1.3072 +                { if (s.kind == MTH && !s.isConstructor()) return true; }
  1.3073 +            else if (target == names.PARAMETER)
  1.3074 +                { if (s.kind == VAR &&
  1.3075 +                      s.owner.kind == MTH &&
  1.3076 +                      (s.flags() & PARAMETER) != 0)
  1.3077 +                    return true;
  1.3078 +                }
  1.3079 +            else if (target == names.CONSTRUCTOR)
  1.3080 +                { if (s.kind == MTH && s.isConstructor()) return true; }
  1.3081 +            else if (target == names.LOCAL_VARIABLE)
  1.3082 +                { if (s.kind == VAR && s.owner.kind == MTH &&
  1.3083 +                      (s.flags() & PARAMETER) == 0)
  1.3084 +                    return true;
  1.3085 +                }
  1.3086 +            else if (target == names.ANNOTATION_TYPE)
  1.3087 +                { if (s.kind == TYP && (s.flags() & ANNOTATION) != 0)
  1.3088 +                    return true;
  1.3089 +                }
  1.3090 +            else if (target == names.PACKAGE)
  1.3091 +                { if (s.kind == PCK) return true; }
  1.3092 +            else if (target == names.TYPE_USE)
  1.3093 +                { if (s.kind == TYP ||
  1.3094 +                      s.kind == VAR ||
  1.3095 +                      (s.kind == MTH && !s.isConstructor() &&
  1.3096 +                      !s.type.getReturnType().hasTag(VOID)) ||
  1.3097 +                      (s.kind == MTH && s.isConstructor()))
  1.3098 +                    return true;
  1.3099 +                }
  1.3100 +            else if (target == names.TYPE_PARAMETER)
  1.3101 +                { if (s.kind == TYP && s.type.hasTag(TYPEVAR))
  1.3102 +                    return true;
  1.3103 +                }
  1.3104 +            else
  1.3105 +                return true; // recovery
  1.3106 +        }
  1.3107 +        return false;
  1.3108 +    }
  1.3109 +
  1.3110 +
  1.3111 +    Attribute.Array getAttributeTargetAttribute(Symbol s) {
  1.3112 +        Attribute.Compound atTarget =
  1.3113 +            s.attribute(syms.annotationTargetType.tsym);
  1.3114 +        if (atTarget == null) return null; // ok, is applicable
  1.3115 +        Attribute atValue = atTarget.member(names.value);
  1.3116 +        if (!(atValue instanceof Attribute.Array)) return null; // error recovery
  1.3117 +        return (Attribute.Array) atValue;
  1.3118 +    }
  1.3119 +
  1.3120 +    private final Name[] dfltTargetMeta;
  1.3121 +    private Name[] defaultTargetMetaInfo(JCAnnotation a, Symbol s) {
  1.3122 +        return dfltTargetMeta;
  1.3123 +    }
  1.3124 +
  1.3125 +    /** Check an annotation value.
  1.3126 +     *
  1.3127 +     * @param a The annotation tree to check
  1.3128 +     * @return true if this annotation tree is valid, otherwise false
  1.3129 +     */
  1.3130 +    public boolean validateAnnotationDeferErrors(JCAnnotation a) {
  1.3131 +        boolean res = false;
  1.3132 +        final Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
  1.3133 +        try {
  1.3134 +            res = validateAnnotation(a);
  1.3135 +        } finally {
  1.3136 +            log.popDiagnosticHandler(diagHandler);
  1.3137 +        }
  1.3138 +        return res;
  1.3139 +    }
  1.3140 +
  1.3141 +    private boolean validateAnnotation(JCAnnotation a) {
  1.3142 +        boolean isValid = true;
  1.3143 +        // collect an inventory of the annotation elements
  1.3144 +        Set<MethodSymbol> members = new LinkedHashSet<MethodSymbol>();
  1.3145 +        for (Scope.Entry e = a.annotationType.type.tsym.members().elems;
  1.3146 +                e != null;
  1.3147 +                e = e.sibling)
  1.3148 +            if (e.sym.kind == MTH && e.sym.name != names.clinit &&
  1.3149 +                    (e.sym.flags() & SYNTHETIC) == 0)
  1.3150 +                members.add((MethodSymbol) e.sym);
  1.3151 +
  1.3152 +        // remove the ones that are assigned values
  1.3153 +        for (JCTree arg : a.args) {
  1.3154 +            if (!arg.hasTag(ASSIGN)) continue; // recovery
  1.3155 +            JCAssign assign = (JCAssign) arg;
  1.3156 +            Symbol m = TreeInfo.symbol(assign.lhs);
  1.3157 +            if (m == null || m.type.isErroneous()) continue;
  1.3158 +            if (!members.remove(m)) {
  1.3159 +                isValid = false;
  1.3160 +                log.error(assign.lhs.pos(), "duplicate.annotation.member.value",
  1.3161 +                          m.name, a.type);
  1.3162 +            }
  1.3163 +        }
  1.3164 +
  1.3165 +        // all the remaining ones better have default values
  1.3166 +        List<Name> missingDefaults = List.nil();
  1.3167 +        for (MethodSymbol m : members) {
  1.3168 +            if (m.defaultValue == null && !m.type.isErroneous()) {
  1.3169 +                missingDefaults = missingDefaults.append(m.name);
  1.3170 +            }
  1.3171 +        }
  1.3172 +        missingDefaults = missingDefaults.reverse();
  1.3173 +        if (missingDefaults.nonEmpty()) {
  1.3174 +            isValid = false;
  1.3175 +            String key = (missingDefaults.size() > 1)
  1.3176 +                    ? "annotation.missing.default.value.1"
  1.3177 +                    : "annotation.missing.default.value";
  1.3178 +            log.error(a.pos(), key, a.type, missingDefaults);
  1.3179 +        }
  1.3180 +
  1.3181 +        // special case: java.lang.annotation.Target must not have
  1.3182 +        // repeated values in its value member
  1.3183 +        if (a.annotationType.type.tsym != syms.annotationTargetType.tsym ||
  1.3184 +            a.args.tail == null)
  1.3185 +            return isValid;
  1.3186 +
  1.3187 +        if (!a.args.head.hasTag(ASSIGN)) return false; // error recovery
  1.3188 +        JCAssign assign = (JCAssign) a.args.head;
  1.3189 +        Symbol m = TreeInfo.symbol(assign.lhs);
  1.3190 +        if (m.name != names.value) return false;
  1.3191 +        JCTree rhs = assign.rhs;
  1.3192 +        if (!rhs.hasTag(NEWARRAY)) return false;
  1.3193 +        JCNewArray na = (JCNewArray) rhs;
  1.3194 +        Set<Symbol> targets = new HashSet<Symbol>();
  1.3195 +        for (JCTree elem : na.elems) {
  1.3196 +            if (!targets.add(TreeInfo.symbol(elem))) {
  1.3197 +                isValid = false;
  1.3198 +                log.error(elem.pos(), "repeated.annotation.target");
  1.3199 +            }
  1.3200 +        }
  1.3201 +        return isValid;
  1.3202 +    }
  1.3203 +
  1.3204 +    void checkDeprecatedAnnotation(DiagnosticPosition pos, Symbol s) {
  1.3205 +        if (allowAnnotations &&
  1.3206 +            lint.isEnabled(LintCategory.DEP_ANN) &&
  1.3207 +            (s.flags() & DEPRECATED) != 0 &&
  1.3208 +            !syms.deprecatedType.isErroneous() &&
  1.3209 +            s.attribute(syms.deprecatedType.tsym) == null) {
  1.3210 +            log.warning(LintCategory.DEP_ANN,
  1.3211 +                    pos, "missing.deprecated.annotation");
  1.3212 +        }
  1.3213 +    }
  1.3214 +
  1.3215 +    void checkDeprecated(final DiagnosticPosition pos, final Symbol other, final Symbol s) {
  1.3216 +        if ((s.flags() & DEPRECATED) != 0 &&
  1.3217 +                (other.flags() & DEPRECATED) == 0 &&
  1.3218 +                s.outermostClass() != other.outermostClass()) {
  1.3219 +            deferredLintHandler.report(new DeferredLintHandler.LintLogger() {
  1.3220 +                @Override
  1.3221 +                public void report() {
  1.3222 +                    warnDeprecated(pos, s);
  1.3223 +                }
  1.3224 +            });
  1.3225 +        }
  1.3226 +    }
  1.3227 +
  1.3228 +    void checkSunAPI(final DiagnosticPosition pos, final Symbol s) {
  1.3229 +        if ((s.flags() & PROPRIETARY) != 0) {
  1.3230 +            deferredLintHandler.report(new DeferredLintHandler.LintLogger() {
  1.3231 +                public void report() {
  1.3232 +                    if (enableSunApiLintControl)
  1.3233 +                      warnSunApi(pos, "sun.proprietary", s);
  1.3234 +                    else
  1.3235 +                      log.mandatoryWarning(pos, "sun.proprietary", s);
  1.3236 +                }
  1.3237 +            });
  1.3238 +        }
  1.3239 +    }
  1.3240 +
  1.3241 +    void checkProfile(final DiagnosticPosition pos, final Symbol s) {
  1.3242 +        if (profile != Profile.DEFAULT && (s.flags() & NOT_IN_PROFILE) != 0) {
  1.3243 +            log.error(pos, "not.in.profile", s, profile);
  1.3244 +        }
  1.3245 +    }
  1.3246 +
  1.3247 +/* *************************************************************************
  1.3248 + * Check for recursive annotation elements.
  1.3249 + **************************************************************************/
  1.3250 +
  1.3251 +    /** Check for cycles in the graph of annotation elements.
  1.3252 +     */
  1.3253 +    void checkNonCyclicElements(JCClassDecl tree) {
  1.3254 +        if ((tree.sym.flags_field & ANNOTATION) == 0) return;
  1.3255 +        Assert.check((tree.sym.flags_field & LOCKED) == 0);
  1.3256 +        try {
  1.3257 +            tree.sym.flags_field |= LOCKED;
  1.3258 +            for (JCTree def : tree.defs) {
  1.3259 +                if (!def.hasTag(METHODDEF)) continue;
  1.3260 +                JCMethodDecl meth = (JCMethodDecl)def;
  1.3261 +                checkAnnotationResType(meth.pos(), meth.restype.type);
  1.3262 +            }
  1.3263 +        } finally {
  1.3264 +            tree.sym.flags_field &= ~LOCKED;
  1.3265 +            tree.sym.flags_field |= ACYCLIC_ANN;
  1.3266 +        }
  1.3267 +    }
  1.3268 +
  1.3269 +    void checkNonCyclicElementsInternal(DiagnosticPosition pos, TypeSymbol tsym) {
  1.3270 +        if ((tsym.flags_field & ACYCLIC_ANN) != 0)
  1.3271 +            return;
  1.3272 +        if ((tsym.flags_field & LOCKED) != 0) {
  1.3273 +            log.error(pos, "cyclic.annotation.element");
  1.3274 +            return;
  1.3275 +        }
  1.3276 +        try {
  1.3277 +            tsym.flags_field |= LOCKED;
  1.3278 +            for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) {
  1.3279 +                Symbol s = e.sym;
  1.3280 +                if (s.kind != Kinds.MTH)
  1.3281 +                    continue;
  1.3282 +                checkAnnotationResType(pos, ((MethodSymbol)s).type.getReturnType());
  1.3283 +            }
  1.3284 +        } finally {
  1.3285 +            tsym.flags_field &= ~LOCKED;
  1.3286 +            tsym.flags_field |= ACYCLIC_ANN;
  1.3287 +        }
  1.3288 +    }
  1.3289 +
  1.3290 +    void checkAnnotationResType(DiagnosticPosition pos, Type type) {
  1.3291 +        switch (type.getTag()) {
  1.3292 +        case CLASS:
  1.3293 +            if ((type.tsym.flags() & ANNOTATION) != 0)
  1.3294 +                checkNonCyclicElementsInternal(pos, type.tsym);
  1.3295 +            break;
  1.3296 +        case ARRAY:
  1.3297 +            checkAnnotationResType(pos, types.elemtype(type));
  1.3298 +            break;
  1.3299 +        default:
  1.3300 +            break; // int etc
  1.3301 +        }
  1.3302 +    }
  1.3303 +
  1.3304 +/* *************************************************************************
  1.3305 + * Check for cycles in the constructor call graph.
  1.3306 + **************************************************************************/
  1.3307 +
  1.3308 +    /** Check for cycles in the graph of constructors calling other
  1.3309 +     *  constructors.
  1.3310 +     */
  1.3311 +    void checkCyclicConstructors(JCClassDecl tree) {
  1.3312 +        Map<Symbol,Symbol> callMap = new HashMap<Symbol, Symbol>();
  1.3313 +
  1.3314 +        // enter each constructor this-call into the map
  1.3315 +        for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
  1.3316 +            JCMethodInvocation app = TreeInfo.firstConstructorCall(l.head);
  1.3317 +            if (app == null) continue;
  1.3318 +            JCMethodDecl meth = (JCMethodDecl) l.head;
  1.3319 +            if (TreeInfo.name(app.meth) == names._this) {
  1.3320 +                callMap.put(meth.sym, TreeInfo.symbol(app.meth));
  1.3321 +            } else {
  1.3322 +                meth.sym.flags_field |= ACYCLIC;
  1.3323 +            }
  1.3324 +        }
  1.3325 +
  1.3326 +        // Check for cycles in the map
  1.3327 +        Symbol[] ctors = new Symbol[0];
  1.3328 +        ctors = callMap.keySet().toArray(ctors);
  1.3329 +        for (Symbol caller : ctors) {
  1.3330 +            checkCyclicConstructor(tree, caller, callMap);
  1.3331 +        }
  1.3332 +    }
  1.3333 +
  1.3334 +    /** Look in the map to see if the given constructor is part of a
  1.3335 +     *  call cycle.
  1.3336 +     */
  1.3337 +    private void checkCyclicConstructor(JCClassDecl tree, Symbol ctor,
  1.3338 +                                        Map<Symbol,Symbol> callMap) {
  1.3339 +        if (ctor != null && (ctor.flags_field & ACYCLIC) == 0) {
  1.3340 +            if ((ctor.flags_field & LOCKED) != 0) {
  1.3341 +                log.error(TreeInfo.diagnosticPositionFor(ctor, tree),
  1.3342 +                          "recursive.ctor.invocation");
  1.3343 +            } else {
  1.3344 +                ctor.flags_field |= LOCKED;
  1.3345 +                checkCyclicConstructor(tree, callMap.remove(ctor), callMap);
  1.3346 +                ctor.flags_field &= ~LOCKED;
  1.3347 +            }
  1.3348 +            ctor.flags_field |= ACYCLIC;
  1.3349 +        }
  1.3350 +    }
  1.3351 +
  1.3352 +/* *************************************************************************
  1.3353 + * Miscellaneous
  1.3354 + **************************************************************************/
  1.3355 +
  1.3356 +    /**
  1.3357 +     * Return the opcode of the operator but emit an error if it is an
  1.3358 +     * error.
  1.3359 +     * @param pos        position for error reporting.
  1.3360 +     * @param operator   an operator
  1.3361 +     * @param tag        a tree tag
  1.3362 +     * @param left       type of left hand side
  1.3363 +     * @param right      type of right hand side
  1.3364 +     */
  1.3365 +    int checkOperator(DiagnosticPosition pos,
  1.3366 +                       OperatorSymbol operator,
  1.3367 +                       JCTree.Tag tag,
  1.3368 +                       Type left,
  1.3369 +                       Type right) {
  1.3370 +        if (operator.opcode == ByteCodes.error) {
  1.3371 +            log.error(pos,
  1.3372 +                      "operator.cant.be.applied.1",
  1.3373 +                      treeinfo.operatorName(tag),
  1.3374 +                      left, right);
  1.3375 +        }
  1.3376 +        return operator.opcode;
  1.3377 +    }
  1.3378 +
  1.3379 +
  1.3380 +    /**
  1.3381 +     *  Check for division by integer constant zero
  1.3382 +     *  @param pos           Position for error reporting.
  1.3383 +     *  @param operator      The operator for the expression
  1.3384 +     *  @param operand       The right hand operand for the expression
  1.3385 +     */
  1.3386 +    void checkDivZero(DiagnosticPosition pos, Symbol operator, Type operand) {
  1.3387 +        if (operand.constValue() != null
  1.3388 +            && lint.isEnabled(LintCategory.DIVZERO)
  1.3389 +            && operand.getTag().isSubRangeOf(LONG)
  1.3390 +            && ((Number) (operand.constValue())).longValue() == 0) {
  1.3391 +            int opc = ((OperatorSymbol)operator).opcode;
  1.3392 +            if (opc == ByteCodes.idiv || opc == ByteCodes.imod
  1.3393 +                || opc == ByteCodes.ldiv || opc == ByteCodes.lmod) {
  1.3394 +                log.warning(LintCategory.DIVZERO, pos, "div.zero");
  1.3395 +            }
  1.3396 +        }
  1.3397 +    }
  1.3398 +
  1.3399 +    /**
  1.3400 +     * Check for empty statements after if
  1.3401 +     */
  1.3402 +    void checkEmptyIf(JCIf tree) {
  1.3403 +        if (tree.thenpart.hasTag(SKIP) && tree.elsepart == null &&
  1.3404 +                lint.isEnabled(LintCategory.EMPTY))
  1.3405 +            log.warning(LintCategory.EMPTY, tree.thenpart.pos(), "empty.if");
  1.3406 +    }
  1.3407 +
  1.3408 +    /** Check that symbol is unique in given scope.
  1.3409 +     *  @param pos           Position for error reporting.
  1.3410 +     *  @param sym           The symbol.
  1.3411 +     *  @param s             The scope.
  1.3412 +     */
  1.3413 +    boolean checkUnique(DiagnosticPosition pos, Symbol sym, Scope s) {
  1.3414 +        if (sym.type.isErroneous())
  1.3415 +            return true;
  1.3416 +        if (sym.owner.name == names.any) return false;
  1.3417 +        for (Scope.Entry e = s.lookup(sym.name); e.scope == s; e = e.next()) {
  1.3418 +            if (sym != e.sym &&
  1.3419 +                    (e.sym.flags() & CLASH) == 0 &&
  1.3420 +                    sym.kind == e.sym.kind &&
  1.3421 +                    sym.name != names.error &&
  1.3422 +                    (sym.kind != MTH ||
  1.3423 +                     types.hasSameArgs(sym.type, e.sym.type) ||
  1.3424 +                     types.hasSameArgs(types.erasure(sym.type), types.erasure(e.sym.type)))) {
  1.3425 +                if ((sym.flags() & VARARGS) != (e.sym.flags() & VARARGS)) {
  1.3426 +                    varargsDuplicateError(pos, sym, e.sym);
  1.3427 +                    return true;
  1.3428 +                } else if (sym.kind == MTH && !types.hasSameArgs(sym.type, e.sym.type, false)) {
  1.3429 +                    duplicateErasureError(pos, sym, e.sym);
  1.3430 +                    sym.flags_field |= CLASH;
  1.3431 +                    return true;
  1.3432 +                } else {
  1.3433 +                    duplicateError(pos, e.sym);
  1.3434 +                    return false;
  1.3435 +                }
  1.3436 +            }
  1.3437 +        }
  1.3438 +        return true;
  1.3439 +    }
  1.3440 +
  1.3441 +    /** Report duplicate declaration error.
  1.3442 +     */
  1.3443 +    void duplicateErasureError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) {
  1.3444 +        if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) {
  1.3445 +            log.error(pos, "name.clash.same.erasure", sym1, sym2);
  1.3446 +        }
  1.3447 +    }
  1.3448 +
  1.3449 +    /** Check that single-type import is not already imported or top-level defined,
  1.3450 +     *  but make an exception for two single-type imports which denote the same type.
  1.3451 +     *  @param pos           Position for error reporting.
  1.3452 +     *  @param sym           The symbol.
  1.3453 +     *  @param s             The scope
  1.3454 +     */
  1.3455 +    boolean checkUniqueImport(DiagnosticPosition pos, Symbol sym, Scope s) {
  1.3456 +        return checkUniqueImport(pos, sym, s, false);
  1.3457 +    }
  1.3458 +
  1.3459 +    /** Check that static single-type import is not already imported or top-level defined,
  1.3460 +     *  but make an exception for two single-type imports which denote the same type.
  1.3461 +     *  @param pos           Position for error reporting.
  1.3462 +     *  @param sym           The symbol.
  1.3463 +     *  @param s             The scope
  1.3464 +     */
  1.3465 +    boolean checkUniqueStaticImport(DiagnosticPosition pos, Symbol sym, Scope s) {
  1.3466 +        return checkUniqueImport(pos, sym, s, true);
  1.3467 +    }
  1.3468 +
  1.3469 +    /** Check that single-type import is not already imported or top-level defined,
  1.3470 +     *  but make an exception for two single-type imports which denote the same type.
  1.3471 +     *  @param pos           Position for error reporting.
  1.3472 +     *  @param sym           The symbol.
  1.3473 +     *  @param s             The scope.
  1.3474 +     *  @param staticImport  Whether or not this was a static import
  1.3475 +     */
  1.3476 +    private boolean checkUniqueImport(DiagnosticPosition pos, Symbol sym, Scope s, boolean staticImport) {
  1.3477 +        for (Scope.Entry e = s.lookup(sym.name); e.scope != null; e = e.next()) {
  1.3478 +            // is encountered class entered via a class declaration?
  1.3479 +            boolean isClassDecl = e.scope == s;
  1.3480 +            if ((isClassDecl || sym != e.sym) &&
  1.3481 +                sym.kind == e.sym.kind &&
  1.3482 +                sym.name != names.error &&
  1.3483 +                (!staticImport || !e.isStaticallyImported())) {
  1.3484 +                if (!e.sym.type.isErroneous()) {
  1.3485 +                    if (!isClassDecl) {
  1.3486 +                        if (staticImport)
  1.3487 +                            log.error(pos, "already.defined.static.single.import", e.sym);
  1.3488 +                        else
  1.3489 +                        log.error(pos, "already.defined.single.import", e.sym);
  1.3490 +                    }
  1.3491 +                    else if (sym != e.sym)
  1.3492 +                        log.error(pos, "already.defined.this.unit", e.sym);
  1.3493 +                }
  1.3494 +                return false;
  1.3495 +            }
  1.3496 +        }
  1.3497 +        return true;
  1.3498 +    }
  1.3499 +
  1.3500 +    /** Check that a qualified name is in canonical form (for import decls).
  1.3501 +     */
  1.3502 +    public void checkCanonical(JCTree tree) {
  1.3503 +        if (!isCanonical(tree))
  1.3504 +            log.error(tree.pos(), "import.requires.canonical",
  1.3505 +                      TreeInfo.symbol(tree));
  1.3506 +    }
  1.3507 +        // where
  1.3508 +        private boolean isCanonical(JCTree tree) {
  1.3509 +            while (tree.hasTag(SELECT)) {
  1.3510 +                JCFieldAccess s = (JCFieldAccess) tree;
  1.3511 +                if (s.sym.owner != TreeInfo.symbol(s.selected))
  1.3512 +                    return false;
  1.3513 +                tree = s.selected;
  1.3514 +            }
  1.3515 +            return true;
  1.3516 +        }
  1.3517 +
  1.3518 +    /** Check that an auxiliary class is not accessed from any other file than its own.
  1.3519 +     */
  1.3520 +    void checkForBadAuxiliaryClassAccess(DiagnosticPosition pos, Env<AttrContext> env, ClassSymbol c) {
  1.3521 +        if (lint.isEnabled(Lint.LintCategory.AUXILIARYCLASS) &&
  1.3522 +            (c.flags() & AUXILIARY) != 0 &&
  1.3523 +            rs.isAccessible(env, c) &&
  1.3524 +            !fileManager.isSameFile(c.sourcefile, env.toplevel.sourcefile))
  1.3525 +        {
  1.3526 +            log.warning(pos, "auxiliary.class.accessed.from.outside.of.its.source.file",
  1.3527 +                        c, c.sourcefile);
  1.3528 +        }
  1.3529 +    }
  1.3530 +
  1.3531 +    private class ConversionWarner extends Warner {
  1.3532 +        final String uncheckedKey;
  1.3533 +        final Type found;
  1.3534 +        final Type expected;
  1.3535 +        public ConversionWarner(DiagnosticPosition pos, String uncheckedKey, Type found, Type expected) {
  1.3536 +            super(pos);
  1.3537 +            this.uncheckedKey = uncheckedKey;
  1.3538 +            this.found = found;
  1.3539 +            this.expected = expected;
  1.3540 +        }
  1.3541 +
  1.3542 +        @Override
  1.3543 +        public void warn(LintCategory lint) {
  1.3544 +            boolean warned = this.warned;
  1.3545 +            super.warn(lint);
  1.3546 +            if (warned) return; // suppress redundant diagnostics
  1.3547 +            switch (lint) {
  1.3548 +                case UNCHECKED:
  1.3549 +                    Check.this.warnUnchecked(pos(), "prob.found.req", diags.fragment(uncheckedKey), found, expected);
  1.3550 +                    break;
  1.3551 +                case VARARGS:
  1.3552 +                    if (method != null &&
  1.3553 +                            method.attribute(syms.trustMeType.tsym) != null &&
  1.3554 +                            isTrustMeAllowedOnMethod(method) &&
  1.3555 +                            !types.isReifiable(method.type.getParameterTypes().last())) {
  1.3556 +                        Check.this.warnUnsafeVararg(pos(), "varargs.unsafe.use.varargs.param", method.params.last());
  1.3557 +                    }
  1.3558 +                    break;
  1.3559 +                default:
  1.3560 +                    throw new AssertionError("Unexpected lint: " + lint);
  1.3561 +            }
  1.3562 +        }
  1.3563 +    }
  1.3564 +
  1.3565 +    public Warner castWarner(DiagnosticPosition pos, Type found, Type expected) {
  1.3566 +        return new ConversionWarner(pos, "unchecked.cast.to.type", found, expected);
  1.3567 +    }
  1.3568 +
  1.3569 +    public Warner convertWarner(DiagnosticPosition pos, Type found, Type expected) {
  1.3570 +        return new ConversionWarner(pos, "unchecked.assign", found, expected);
  1.3571 +    }
  1.3572 +
  1.3573 +    public void checkFunctionalInterface(JCClassDecl tree, ClassSymbol cs) {
  1.3574 +        Compound functionalType = cs.attribute(syms.functionalInterfaceType.tsym);
  1.3575 +
  1.3576 +        if (functionalType != null) {
  1.3577 +            try {
  1.3578 +                types.findDescriptorSymbol((TypeSymbol)cs);
  1.3579 +            } catch (Types.FunctionDescriptorLookupError ex) {
  1.3580 +                DiagnosticPosition pos = tree.pos();
  1.3581 +                for (JCAnnotation a : tree.getModifiers().annotations) {
  1.3582 +                    if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) {
  1.3583 +                        pos = a.pos();
  1.3584 +                        break;
  1.3585 +                    }
  1.3586 +                }
  1.3587 +                log.error(pos, "bad.functional.intf.anno.1", ex.getDiagnostic());
  1.3588 +            }
  1.3589 +        }
  1.3590 +    }
  1.3591 +}

mercurial