Check.java revision 4235:0b74aa85c3c5
1139823Simp/*
275374Sbp * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
375374Sbp * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
475374Sbp *
575374Sbp * This code is free software; you can redistribute it and/or modify it
675374Sbp * under the terms of the GNU General Public License version 2 only, as
775374Sbp * published by the Free Software Foundation.  Oracle designates this
875374Sbp * particular file as subject to the "Classpath" exception as provided
975374Sbp * by Oracle in the LICENSE file that accompanied this code.
1075374Sbp *
1175374Sbp * This code is distributed in the hope that it will be useful, but WITHOUT
1275374Sbp * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1375374Sbp * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1475374Sbp * version 2 for more details (a copy is included in the LICENSE file that
1575374Sbp * accompanied this code).
1675374Sbp *
1775374Sbp * You should have received a copy of the GNU General Public License version
1875374Sbp * 2 along with this work; if not, write to the Free Software Foundation,
1975374Sbp * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2075374Sbp *
2175374Sbp * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2275374Sbp * or visit www.oracle.com if you need additional information or have any
2375374Sbp * questions.
2475374Sbp */
2575374Sbp
2675374Sbppackage com.sun.tools.javac.comp;
2775374Sbp
2875374Sbpimport java.util.*;
2975374Sbp
3075374Sbpimport javax.tools.JavaFileManager;
3175374Sbp
32116189Sobrienimport com.sun.tools.javac.code.*;
33116189Sobrienimport com.sun.tools.javac.code.Attribute.Compound;
34116189Sobrienimport com.sun.tools.javac.code.Directive.ExportsDirective;
35116189Sobrienimport com.sun.tools.javac.code.Directive.RequiresDirective;
3675374Sbpimport com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
3775374Sbpimport com.sun.tools.javac.jvm.*;
3895533Smikeimport com.sun.tools.javac.resources.CompilerProperties.Errors;
3975374Sbpimport com.sun.tools.javac.resources.CompilerProperties.Fragments;
4075374Sbpimport com.sun.tools.javac.resources.CompilerProperties.Warnings;
41129880Sphkimport com.sun.tools.javac.tree.*;
4275374Sbpimport com.sun.tools.javac.util.*;
4375374Sbpimport com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
4475374Sbpimport com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
4575374Sbpimport com.sun.tools.javac.util.JCDiagnostic.Fragment;
4675374Sbpimport com.sun.tools.javac.util.List;
4775374Sbp
4875374Sbpimport com.sun.tools.javac.code.Lint;
4975374Sbpimport com.sun.tools.javac.code.Lint.LintCategory;
5075374Sbpimport com.sun.tools.javac.code.Scope.WriteableScope;
5175374Sbpimport com.sun.tools.javac.code.Type.*;
5275374Sbpimport com.sun.tools.javac.code.Symbol.*;
5375374Sbpimport com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
5475374Sbpimport com.sun.tools.javac.comp.Infer.FreeTypeListener;
5575374Sbpimport com.sun.tools.javac.tree.JCTree.*;
5675374Sbp
5775374Sbpimport static com.sun.tools.javac.code.Flags.*;
5875374Sbpimport static com.sun.tools.javac.code.Flags.ANNOTATION;
5975374Sbpimport static com.sun.tools.javac.code.Flags.SYNCHRONIZED;
6075374Sbpimport static com.sun.tools.javac.code.Kinds.*;
6175374Sbpimport static com.sun.tools.javac.code.Kinds.Kind.*;
6275374Sbpimport static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
6375374Sbpimport static com.sun.tools.javac.code.TypeTag.*;
6475374Sbpimport static com.sun.tools.javac.code.TypeTag.WILDCARD;
6575374Sbp
6675374Sbpimport static com.sun.tools.javac.tree.JCTree.Tag.*;
6775374Sbp
6875374Sbp/** Type checking helper class for the attribution phase.
6975374Sbp *
7075374Sbp *  <p><b>This is NOT part of any supported API.
7175374Sbp *  If you write code that depends on this, you do so at your own risk.
7275374Sbp *  This code and its internal interfaces are subject to change or
73111119Simp *  deletion without notice.</b>
7475374Sbp */
7575374Sbppublic class Check {
7675374Sbp    protected static final Context.Key<Check> checkKey = new Context.Key<>();
7775374Sbp
7875374Sbp    private final Names names;
7975374Sbp    private final Log log;
8075374Sbp    private final Resolve rs;
8175374Sbp    private final Symtab syms;
8275374Sbp    private final Enter enter;
8375374Sbp    private final DeferredAttr deferredAttr;
8475374Sbp    private final Infer infer;
8575374Sbp    private final Types types;
8675374Sbp    private final TypeAnnotations typeAnnotations;
8775374Sbp    private final JCDiagnostic.Factory diags;
8875374Sbp    private final JavaFileManager fileManager;
8975374Sbp    private final Source source;
9075374Sbp    private final Profile profile;
9175374Sbp    private final boolean warnOnAnyAccessToMembers;
9275374Sbp
9375374Sbp    // The set of lint options currently in effect. It is initialized
9475374Sbp    // from the context, and then is set/reset as needed by Attr as it
9575374Sbp    // visits all the various parts of the trees during attribution.
9675374Sbp    private Lint lint;
9775374Sbp
9875374Sbp    // The method being analyzed in Attr - it is set/reset as needed by
9975374Sbp    // Attr as it visits new method declarations.
10075374Sbp    private MethodSymbol method;
10175374Sbp
10275374Sbp    public static Check instance(Context context) {
10375374Sbp        Check instance = context.get(checkKey);
10475374Sbp        if (instance == null)
10575374Sbp            instance = new Check(context);
10675374Sbp        return instance;
10775374Sbp    }
10875374Sbp
10975374Sbp    protected Check(Context context) {
11075374Sbp        context.put(checkKey, this);
11175374Sbp
11275374Sbp        names = Names.instance(context);
11375374Sbp        dfltTargetMeta = new Name[] { names.PACKAGE, names.TYPE,
11475374Sbp            names.FIELD, names.METHOD, names.CONSTRUCTOR,
11575374Sbp            names.ANNOTATION_TYPE, names.LOCAL_VARIABLE, names.PARAMETER};
11675374Sbp        log = Log.instance(context);
11775374Sbp        rs = Resolve.instance(context);
118124087Stjr        syms = Symtab.instance(context);
11975374Sbp        enter = Enter.instance(context);
12075374Sbp        deferredAttr = DeferredAttr.instance(context);
12175374Sbp        infer = Infer.instance(context);
12275374Sbp        types = Types.instance(context);
12375374Sbp        typeAnnotations = TypeAnnotations.instance(context);
12475374Sbp        diags = JCDiagnostic.Factory.instance(context);
12575374Sbp        Options options = Options.instance(context);
12675374Sbp        lint = Lint.instance(context);
12775374Sbp        fileManager = context.get(JavaFileManager.class);
12875374Sbp
12975374Sbp        source = Source.instance(context);
130124087Stjr        allowSimplifiedVarargs = source.allowSimplifiedVarargs();
131103391Sbp        allowDefaultMethods = source.allowDefaultMethods();
132124087Stjr        allowStrictMethodClashCheck = source.allowStrictMethodClashCheck();
133124087Stjr        allowPrivateSafeVarargs = source.allowPrivateSafeVarargs();
134124087Stjr        allowDiamondWithAnonymousClassCreation = source.allowDiamondWithAnonymousClassCreation();
135124087Stjr        warnOnAnyAccessToMembers = options.isSet("warnOnAccessToMembers");
136124087Stjr
137124087Stjr        Target target = Target.instance(context);
138124087Stjr        syntheticNameChar = target.syntheticNameChar();
139124087Stjr
140124087Stjr        profile = Profile.instance(context);
141124087Stjr
142124087Stjr        boolean verboseDeprecated = lint.isEnabled(LintCategory.DEPRECATION);
143124087Stjr        boolean verboseRemoval = lint.isEnabled(LintCategory.REMOVAL);
144161523Smarcel        boolean verboseUnchecked = lint.isEnabled(LintCategory.UNCHECKED);
14575374Sbp        boolean enforceMandatoryWarnings = true;
146161523Smarcel
14775374Sbp        deprecationHandler = new MandatoryWarningHandler(log, verboseDeprecated,
14875374Sbp                enforceMandatoryWarnings, "deprecated", LintCategory.DEPRECATION);
14975374Sbp        removalHandler = new MandatoryWarningHandler(log, verboseRemoval,
15075374Sbp                enforceMandatoryWarnings, "removal", LintCategory.REMOVAL);
15175374Sbp        uncheckedHandler = new MandatoryWarningHandler(log, verboseUnchecked,
15275374Sbp                enforceMandatoryWarnings, "unchecked", LintCategory.UNCHECKED);
15375374Sbp        sunApiHandler = new MandatoryWarningHandler(log, false,
15475374Sbp                enforceMandatoryWarnings, "sunapi", null);
15575374Sbp
15675374Sbp        deferredLintHandler = DeferredLintHandler.instance(context);
15775374Sbp    }
15875374Sbp
15975374Sbp    /** Switch: simplified varargs enabled?
16075374Sbp     */
16175374Sbp    boolean allowSimplifiedVarargs;
16275374Sbp
16375374Sbp    /** Switch: default methods enabled?
16475374Sbp     */
16575374Sbp    boolean allowDefaultMethods;
16675374Sbp
16775374Sbp    /** Switch: should unrelated return types trigger a method clash?
16875374Sbp     */
16975374Sbp    boolean allowStrictMethodClashCheck;
17075374Sbp
17175374Sbp    /** Switch: can the @SafeVarargs annotation be applied to private methods?
17275374Sbp     */
17375374Sbp    boolean allowPrivateSafeVarargs;
17475374Sbp
17575374Sbp    /** Switch: can diamond inference be used in anonymous instance creation ?
17675374Sbp     */
17775374Sbp    boolean allowDiamondWithAnonymousClassCreation;
17875374Sbp
17975374Sbp    /** Character for synthetic names
18075374Sbp     */
18175374Sbp    char syntheticNameChar;
18275374Sbp
18375374Sbp    /** A table mapping flat names of all compiled classes for each module in this run
18475374Sbp     *  to their symbols; maintained from outside.
18575374Sbp     */
18675374Sbp    private Map<Pair<ModuleSymbol, Name>,ClassSymbol> compiled = new HashMap<>();
18775374Sbp
18875374Sbp    /** A handler for messages about deprecated usage.
18975374Sbp     */
19075374Sbp    private MandatoryWarningHandler deprecationHandler;
19175374Sbp
19275374Sbp    /** A handler for messages about deprecated-for-removal usage.
19375374Sbp     */
19475374Sbp    private MandatoryWarningHandler removalHandler;
19575374Sbp
19675374Sbp    /** A handler for messages about unchecked or unsafe usage.
19775374Sbp     */
19875374Sbp    private MandatoryWarningHandler uncheckedHandler;
19975374Sbp
200112888Sjeff    /** A handler for messages about using proprietary API.
20175374Sbp     */
20275374Sbp    private MandatoryWarningHandler sunApiHandler;
20375374Sbp
20475374Sbp    /** A handler for deferred lint warnings.
20575374Sbp     */
20675374Sbp    private DeferredLintHandler deferredLintHandler;
20775374Sbp
20875374Sbp/* *************************************************************************
20975374Sbp * Errors and Warnings
21075374Sbp **************************************************************************/
21175374Sbp
21275374Sbp    Lint setLint(Lint newLint) {
21375374Sbp        Lint prev = lint;
21475374Sbp        lint = newLint;
21575374Sbp        return prev;
21675374Sbp    }
21775374Sbp
21875374Sbp    MethodSymbol setMethod(MethodSymbol newMethod) {
21975374Sbp        MethodSymbol prev = method;
22075374Sbp        method = newMethod;
22175374Sbp        return prev;
22275374Sbp    }
22375374Sbp
22475374Sbp    /** Warn about deprecated symbol.
22575374Sbp     *  @param pos        Position to be used for error reporting.
22675374Sbp     *  @param sym        The deprecated symbol.
22775374Sbp     */
22875374Sbp    void warnDeprecated(DiagnosticPosition pos, Symbol sym) {
22975374Sbp        if (sym.isDeprecatedForRemoval()) {
23075374Sbp            if (!lint.isSuppressed(LintCategory.REMOVAL)) {
23175374Sbp                if (sym.kind == MDL) {
23275374Sbp                    removalHandler.report(pos, "has.been.deprecated.for.removal.module", sym);
23375374Sbp                } else {
23475374Sbp                    removalHandler.report(pos, "has.been.deprecated.for.removal", sym, sym.location());
23575374Sbp                }
23675374Sbp            }
23775374Sbp        } else if (!lint.isSuppressed(LintCategory.DEPRECATION)) {
23875374Sbp            if (sym.kind == MDL) {
23975374Sbp                deprecationHandler.report(pos, "has.been.deprecated.module", sym);
24075374Sbp            } else {
24175374Sbp                deprecationHandler.report(pos, "has.been.deprecated", sym, sym.location());
242161523Smarcel            }
24375374Sbp        }
24475374Sbp    }
24575374Sbp
24675374Sbp    /** Warn about unchecked operation.
24775374Sbp     *  @param pos        Position to be used for error reporting.
24875374Sbp     *  @param msg        A string describing the problem.
24975374Sbp     */
25075374Sbp    public void warnUnchecked(DiagnosticPosition pos, String msg, Object... args) {
25175374Sbp        if (!lint.isSuppressed(LintCategory.UNCHECKED))
25275374Sbp            uncheckedHandler.report(pos, msg, args);
25375374Sbp    }
25475374Sbp
25575374Sbp    /** Warn about unsafe vararg method decl.
25675374Sbp     *  @param pos        Position to be used for error reporting.
25775374Sbp     */
258161523Smarcel    void warnUnsafeVararg(DiagnosticPosition pos, String key, Object... args) {
25975374Sbp        if (lint.isEnabled(LintCategory.VARARGS) && allowSimplifiedVarargs)
26075374Sbp            log.warning(LintCategory.VARARGS, pos, key, args);
26175374Sbp    }
26275374Sbp
26375374Sbp    public void warnStatic(DiagnosticPosition pos, String msg, Object... args) {
26475374Sbp        if (lint.isEnabled(LintCategory.STATIC))
26575374Sbp            log.warning(LintCategory.STATIC, pos, msg, args);
266112888Sjeff    }
26775374Sbp
26875374Sbp    /** Warn about division by integer constant zero.
26975374Sbp     *  @param pos        Position to be used for error reporting.
27075374Sbp     */
27175374Sbp    void warnDivZero(DiagnosticPosition pos) {
27275374Sbp        if (lint.isEnabled(LintCategory.DIVZERO))
27375374Sbp            log.warning(LintCategory.DIVZERO, pos, Warnings.DivZero);
27475374Sbp    }
27575374Sbp
27675374Sbp    /**
27775374Sbp     * Report any deferred diagnostics.
27875374Sbp     */
27975374Sbp    public void reportDeferredDiagnostics() {
28075374Sbp        deprecationHandler.reportDeferredDiagnostic();
28175374Sbp        removalHandler.reportDeferredDiagnostic();
28275374Sbp        uncheckedHandler.reportDeferredDiagnostic();
28375374Sbp        sunApiHandler.reportDeferredDiagnostic();
28475374Sbp    }
28575374Sbp
28675374Sbp
28775374Sbp    /** Report a failure to complete a class.
28875374Sbp     *  @param pos        Position to be used for error reporting.
28975374Sbp     *  @param ex         The failure to report.
29075374Sbp     */
29175374Sbp    public Type completionError(DiagnosticPosition pos, CompletionFailure ex) {
29275374Sbp        log.error(JCDiagnostic.DiagnosticFlag.NON_DEFERRABLE, pos, Errors.CantAccess(ex.sym, ex.getDetailValue()));
29375374Sbp        if (ex instanceof ClassFinder.BadClassFile) throw new Abort();
29475374Sbp        else return syms.errType;
29575374Sbp    }
29675374Sbp
29775374Sbp    /** Report an error that wrong type tag was found.
29875374Sbp     *  @param pos        Position to be used for error reporting.
29975374Sbp     *  @param required   An internationalized string describing the type tag
30075374Sbp     *                    required.
30175374Sbp     *  @param found      The type that was found.
30275374Sbp     */
30375374Sbp    Type typeTagError(DiagnosticPosition pos, JCDiagnostic required, Object found) {
30475374Sbp        // this error used to be raised by the parser,
30575374Sbp        // but has been delayed to this point:
30675374Sbp        if (found instanceof Type && ((Type)found).hasTag(VOID)) {
30775374Sbp            log.error(pos, Errors.IllegalStartOfType);
30875374Sbp            return syms.errType;
30975374Sbp        }
31075374Sbp        log.error(pos, Errors.TypeFoundReq(found, required));
31175374Sbp        return types.createErrorType(found instanceof Type ? (Type)found : syms.errType);
31275374Sbp    }
31375374Sbp
31475374Sbp    /** Report an error that symbol cannot be referenced before super
31575374Sbp     *  has been called.
31675374Sbp     *  @param pos        Position to be used for error reporting.
31775374Sbp     *  @param sym        The referenced symbol.
31875374Sbp     */
31975374Sbp    void earlyRefError(DiagnosticPosition pos, Symbol sym) {
32075374Sbp        log.error(pos, Errors.CantRefBeforeCtorCalled(sym));
32175374Sbp    }
32275374Sbp
32375374Sbp    /** Report duplicate declaration error.
32475374Sbp     */
32575374Sbp    void duplicateError(DiagnosticPosition pos, Symbol sym) {
32675374Sbp        if (!sym.type.isErroneous()) {
32775374Sbp            Symbol location = sym.location();
32875374Sbp            if (location.kind == MTH &&
32975374Sbp                    ((MethodSymbol)location).isStaticOrInstanceInit()) {
33075374Sbp                log.error(pos,
33175374Sbp                          Errors.AlreadyDefinedInClinit(kindName(sym),
33275374Sbp                                                        sym,
33375374Sbp                                                        kindName(sym.location()),
33475374Sbp                                                        kindName(sym.location().enclClass()),
33575374Sbp                                                        sym.location().enclClass()));
33675374Sbp            } else {
33775374Sbp                log.error(pos,
33875374Sbp                          Errors.AlreadyDefined(kindName(sym),
33975374Sbp                                                sym,
34075374Sbp                                                kindName(sym.location()),
34175374Sbp                                                sym.location()));
34275374Sbp            }
34375374Sbp        }
34475374Sbp    }
34575374Sbp
34675374Sbp    /** Report array/varargs duplicate declaration
34775374Sbp     */
34875374Sbp    void varargsDuplicateError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) {
34975374Sbp        if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) {
35075374Sbp            log.error(pos, Errors.ArrayAndVarargs(sym1, sym2, sym2.location()));
35175374Sbp        }
35275374Sbp    }
35375374Sbp
35475374Sbp/* ************************************************************************
35575374Sbp * duplicate declaration checking
35675374Sbp *************************************************************************/
35775374Sbp
35875374Sbp    /** Check that variable does not hide variable with same name in
35975374Sbp     *  immediately enclosing local scope.
36075374Sbp     *  @param pos           Position for error reporting.
36175374Sbp     *  @param v             The symbol.
36275374Sbp     *  @param s             The scope.
363124087Stjr     */
364124087Stjr    void checkTransparentVar(DiagnosticPosition pos, VarSymbol v, Scope s) {
365124087Stjr        for (Symbol sym : s.getSymbolsByName(v.name)) {
366124087Stjr            if (sym.owner != v.owner) break;
36775374Sbp            if (sym.kind == VAR &&
36875374Sbp                sym.owner.kind.matches(KindSelector.VAL_MTH) &&
36975374Sbp                v.name != names.error) {
37075374Sbp                duplicateError(pos, sym);
37175374Sbp                return;
37275374Sbp            }
37375374Sbp        }
37475374Sbp    }
37575374Sbp
37675374Sbp    /** Check that a class or interface does not hide a class or
37775374Sbp     *  interface with same name in immediately enclosing local scope.
37875374Sbp     *  @param pos           Position for error reporting.
37975374Sbp     *  @param c             The symbol.
38075374Sbp     *  @param s             The scope.
38175374Sbp     */
38275374Sbp    void checkTransparentClass(DiagnosticPosition pos, ClassSymbol c, Scope s) {
38375374Sbp        for (Symbol sym : s.getSymbolsByName(c.name)) {
38475374Sbp            if (sym.owner != c.owner) break;
38575374Sbp            if (sym.kind == TYP && !sym.type.hasTag(TYPEVAR) &&
386111119Simp                sym.owner.kind.matches(KindSelector.VAL_MTH) &&
38775374Sbp                c.name != names.error) {
38875374Sbp                duplicateError(pos, sym);
38975374Sbp                return;
39075374Sbp            }
39175374Sbp        }
39275374Sbp    }
39375374Sbp
39475374Sbp    /** Check that class does not have the same name as one of
39575374Sbp     *  its enclosing classes, or as a class defined in its enclosing scope.
39675374Sbp     *  return true if class is unique in its enclosing scope.
39775374Sbp     *  @param pos           Position for error reporting.
39875374Sbp     *  @param name          The class name.
39975374Sbp     *  @param s             The enclosing scope.
40075374Sbp     */
40175374Sbp    boolean checkUniqueClassName(DiagnosticPosition pos, Name name, Scope s) {
40275374Sbp        for (Symbol sym : s.getSymbolsByName(name, NON_RECURSIVE)) {
40375374Sbp            if (sym.kind == TYP && sym.name != names.error) {
40475374Sbp                duplicateError(pos, sym);
40575374Sbp                return false;
40675374Sbp            }
40775374Sbp        }
40875374Sbp        for (Symbol sym = s.owner; sym != null; sym = sym.owner) {
40975374Sbp            if (sym.kind == TYP && sym.name == name && sym.name != names.error) {
41075374Sbp                duplicateError(pos, sym);
41175374Sbp                return true;
41275374Sbp            }
41375374Sbp        }
41475374Sbp        return true;
41575374Sbp    }
41675374Sbp
41775374Sbp/* *************************************************************************
41875374Sbp * Class name generation
41975374Sbp **************************************************************************/
42075374Sbp
42175374Sbp
42275374Sbp    private Map<Pair<Name, Name>, Integer> localClassNameIndexes = new HashMap<>();
42375374Sbp
42475374Sbp    /** Return name of local class.
42575374Sbp     *  This is of the form   {@code <enclClass> $ n <classname> }
42675374Sbp     *  where
42775374Sbp     *    enclClass is the flat name of the enclosing class,
42875374Sbp     *    classname is the simple name of the local class
42975374Sbp     */
43075374Sbp    Name localClassName(ClassSymbol c) {
43175374Sbp        Name enclFlatname = c.owner.enclClass().flatname;
43275374Sbp        String enclFlatnameStr = enclFlatname.toString();
43375374Sbp        Pair<Name, Name> key = new Pair<>(enclFlatname, c.name);
43475374Sbp        Integer index = localClassNameIndexes.get(key);
43575374Sbp        for (int i = (index == null) ? 1 : index; ; i++) {
436111119Simp            Name flatname = names.fromString(enclFlatnameStr
43775374Sbp                    + syntheticNameChar + i + c.name);
43875374Sbp            if (getCompiled(c.packge().modle, flatname) == null) {
439103554Sphk                localClassNameIndexes.put(key, i + 1);
44075374Sbp                return flatname;
44175374Sbp            }
44275374Sbp        }
44375374Sbp    }
44475374Sbp
44575374Sbp    void clearLocalClassNameIndexes(ClassSymbol c) {
44675374Sbp        if (c.owner != null && c.owner.kind != NIL) {
44775374Sbp            localClassNameIndexes.remove(new Pair<>(
44875374Sbp                    c.owner.enclClass().flatname, c.name));
44975374Sbp        }
45075374Sbp    }
45175374Sbp
45275374Sbp    public void newRound() {
45375374Sbp        compiled.clear();
45475374Sbp        localClassNameIndexes.clear();
45575374Sbp    }
45675374Sbp
45775374Sbp    public void putCompiled(ClassSymbol csym) {
45875374Sbp        compiled.put(Pair.of(csym.packge().modle, csym.flatname), csym);
45975374Sbp    }
46075374Sbp
46175374Sbp    public ClassSymbol getCompiled(ClassSymbol csym) {
46275374Sbp        return compiled.get(Pair.of(csym.packge().modle, csym.flatname));
46375374Sbp    }
46475374Sbp
46575374Sbp    public ClassSymbol getCompiled(ModuleSymbol msym, Name flatname) {
46675374Sbp        return compiled.get(Pair.of(msym, flatname));
46775374Sbp    }
46875374Sbp
46975374Sbp    public void removeCompiled(ClassSymbol csym) {
47075374Sbp        compiled.remove(Pair.of(csym.packge().modle, csym.flatname));
47188741Sbp    }
47288741Sbp
47375374Sbp/* *************************************************************************
47475374Sbp * Type Checking
47575374Sbp **************************************************************************/
47675374Sbp
47775374Sbp    /**
47875374Sbp     * A check context is an object that can be used to perform compatibility
47975374Sbp     * checks - depending on the check context, meaning of 'compatibility' might
48075374Sbp     * vary significantly.
48175374Sbp     */
48275374Sbp    public interface CheckContext {
48375374Sbp        /**
48475374Sbp         * Is type 'found' compatible with type 'req' in given context
48575374Sbp         */
48675374Sbp        boolean compatible(Type found, Type req, Warner warn);
48775374Sbp        /**
48875374Sbp         * Report a check error
48975374Sbp         */
49075374Sbp        void report(DiagnosticPosition pos, JCDiagnostic details);
49175374Sbp        /**
49275374Sbp         * Obtain a warner for this check context
49375374Sbp         */
49475374Sbp        public Warner checkWarner(DiagnosticPosition pos, Type found, Type req);
49575374Sbp
49675374Sbp        public InferenceContext inferenceContext();
49775374Sbp
49875374Sbp        public DeferredAttr.DeferredAttrContext deferredAttrContext();
49988741Sbp    }
50075374Sbp
50175374Sbp    /**
50275374Sbp     * This class represent a check context that is nested within another check
50375374Sbp     * context - useful to check sub-expressions. The default behavior simply
50475374Sbp     * redirects all method calls to the enclosing check context leveraging
50575374Sbp     * the forwarding pattern.
50675374Sbp     */
50775374Sbp    static class NestedCheckContext implements CheckContext {
50875374Sbp        CheckContext enclosingContext;
50988741Sbp
51075374Sbp        NestedCheckContext(CheckContext enclosingContext) {
51175374Sbp            this.enclosingContext = enclosingContext;
51275374Sbp        }
51375374Sbp
51475374Sbp        public boolean compatible(Type found, Type req, Warner warn) {
51575374Sbp            return enclosingContext.compatible(found, req, warn);
51675374Sbp        }
51775374Sbp
51875374Sbp        public void report(DiagnosticPosition pos, JCDiagnostic details) {
51975374Sbp            enclosingContext.report(pos, details);
52075374Sbp        }
52175374Sbp
52275374Sbp        public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
52375374Sbp            return enclosingContext.checkWarner(pos, found, req);
52475374Sbp        }
52575374Sbp
52675374Sbp        public InferenceContext inferenceContext() {
52775374Sbp            return enclosingContext.inferenceContext();
52875374Sbp        }
52975374Sbp
53075374Sbp        public DeferredAttrContext deferredAttrContext() {
53175374Sbp            return enclosingContext.deferredAttrContext();
53275374Sbp        }
53375374Sbp    }
53475374Sbp
53575374Sbp    /**
53675374Sbp     * Check context to be used when evaluating assignment/return statements
53775374Sbp     */
53875374Sbp    CheckContext basicHandler = new CheckContext() {
53975374Sbp        public void report(DiagnosticPosition pos, JCDiagnostic details) {
54075374Sbp            log.error(pos, Errors.ProbFoundReq(details));
54175374Sbp        }
54275374Sbp        public boolean compatible(Type found, Type req, Warner warn) {
54375374Sbp            return types.isAssignable(found, req, warn);
54475374Sbp        }
54575374Sbp
54675374Sbp        public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
54775374Sbp            return convertWarner(pos, found, req);
54875374Sbp        }
54975374Sbp
55075374Sbp        public InferenceContext inferenceContext() {
55175374Sbp            return infer.emptyContext;
55275374Sbp        }
55375374Sbp
55475374Sbp        public DeferredAttrContext deferredAttrContext() {
55575374Sbp            return deferredAttr.emptyDeferredAttrContext;
55675374Sbp        }
55775374Sbp
55875374Sbp        @Override
55975374Sbp        public String toString() {
56075374Sbp            return "CheckContext: basicHandler";
56175374Sbp        }
56275374Sbp    };
56375374Sbp
56475374Sbp    /** Check that a given type is assignable to a given proto-type.
56575374Sbp     *  If it is, return the type, otherwise return errType.
56675374Sbp     *  @param pos        Position to be used for error reporting.
56775374Sbp     *  @param found      The type that was found.
56875374Sbp     *  @param req        The type that was required.
56975374Sbp     */
57075374Sbp    public Type checkType(DiagnosticPosition pos, Type found, Type req) {
57175374Sbp        return checkType(pos, found, req, basicHandler);
57275374Sbp    }
57375374Sbp
57475374Sbp    Type checkType(final DiagnosticPosition pos, final Type found, final Type req, final CheckContext checkContext) {
57575374Sbp        final InferenceContext inferenceContext = checkContext.inferenceContext();
57675374Sbp        if (inferenceContext.free(req) || inferenceContext.free(found)) {
57775374Sbp            inferenceContext.addFreeTypeListener(List.of(req, found),
57875374Sbp                    solvedContext -> checkType(pos, solvedContext.asInstType(found), solvedContext.asInstType(req), checkContext));
57975374Sbp        }
58075374Sbp        if (req.hasTag(ERROR))
58175374Sbp            return req;
58275374Sbp        if (req.hasTag(NONE))
58375374Sbp            return found;
58475374Sbp        if (checkContext.compatible(found, req, checkContext.checkWarner(pos, found, req))) {
58575374Sbp            return found;
58675374Sbp        } else {
58775374Sbp            if (found.isNumeric() && req.isNumeric()) {
58875374Sbp                checkContext.report(pos, diags.fragment(Fragments.PossibleLossOfPrecision(found, req)));
58975374Sbp                return types.createErrorType(found);
59075374Sbp            }
59175374Sbp            checkContext.report(pos, diags.fragment(Fragments.InconvertibleTypes(found, req)));
59275374Sbp            return types.createErrorType(found);
593124087Stjr        }
59475374Sbp    }
59575374Sbp
59675374Sbp    /** Check that a given type can be cast to a given target type.
59775374Sbp     *  Return the result of the cast.
59875374Sbp     *  @param pos        Position to be used for error reporting.
59975374Sbp     *  @param found      The type that is being cast.
60075374Sbp     *  @param req        The target type of the cast.
60175374Sbp     */
60275374Sbp    Type checkCastable(DiagnosticPosition pos, Type found, Type req) {
60375374Sbp        return checkCastable(pos, found, req, basicHandler);
60475374Sbp    }
60575374Sbp    Type checkCastable(DiagnosticPosition pos, Type found, Type req, CheckContext checkContext) {
60675374Sbp        if (types.isCastable(found, req, castWarner(pos, found, req))) {
60775374Sbp            return req;
60875374Sbp        } else {
60975374Sbp            checkContext.report(pos, diags.fragment(Fragments.InconvertibleTypes(found, req)));
61075374Sbp            return types.createErrorType(found);
61175374Sbp        }
61275374Sbp    }
61375374Sbp
61475374Sbp    /** Check for redundant casts (i.e. where source type is a subtype of target type)
61575374Sbp     * The problem should only be reported for non-292 cast
61675374Sbp     */
61775374Sbp    public void checkRedundantCast(Env<AttrContext> env, final JCTypeCast tree) {
61875374Sbp        if (!tree.type.isErroneous()
61975374Sbp                && types.isSameType(tree.expr.type, tree.clazz.type)
62075374Sbp                && !(ignoreAnnotatedCasts && TreeInfo.containsTypeAnnotation(tree.clazz))
62175374Sbp                && !is292targetTypeCast(tree)) {
62275374Sbp            deferredLintHandler.report(() -> {
62375374Sbp                if (lint.isEnabled(LintCategory.CAST))
62475374Sbp                    log.warning(LintCategory.CAST,
62575374Sbp                            tree.pos(), Warnings.RedundantCast(tree.clazz.type));
62675374Sbp            });
62775374Sbp        }
62875374Sbp    }
62975374Sbp    //where
63075374Sbp        private boolean is292targetTypeCast(JCTypeCast tree) {
63175374Sbp            boolean is292targetTypeCast = false;
63275374Sbp            JCExpression expr = TreeInfo.skipParens(tree.expr);
63375374Sbp            if (expr.hasTag(APPLY)) {
63475374Sbp                JCMethodInvocation apply = (JCMethodInvocation)expr;
63575374Sbp                Symbol sym = TreeInfo.symbol(apply.meth);
63675374Sbp                is292targetTypeCast = sym != null &&
63775374Sbp                    sym.kind == MTH &&
63875374Sbp                    (sym.flags() & HYPOTHETICAL) != 0;
63975374Sbp            }
64075374Sbp            return is292targetTypeCast;
64175374Sbp        }
64275374Sbp
64375374Sbp        private static final boolean ignoreAnnotatedCasts = true;
64475374Sbp
64575374Sbp    /** Check that a type is within some bounds.
64675374Sbp     *
64775374Sbp     *  Used in TypeApply to verify that, e.g., X in {@code V<X>} is a valid
64875374Sbp     *  type argument.
64975374Sbp     *  @param a             The type that should be bounded by bs.
65075374Sbp     *  @param bound         The bound.
65175374Sbp     */
65275374Sbp    private boolean checkExtends(Type a, Type bound) {
65375374Sbp         if (a.isUnbound()) {
65475374Sbp             return true;
65575374Sbp         } else if (!a.hasTag(WILDCARD)) {
65675374Sbp             a = types.cvarUpperBound(a);
65775374Sbp             return types.isSubtype(a, bound);
65875374Sbp         } else if (a.isExtendsBound()) {
65975374Sbp             return types.isCastable(bound, types.wildUpperBound(a), types.noWarnings);
66075374Sbp         } else if (a.isSuperBound()) {
66175374Sbp             return !types.notSoftSubtype(types.wildLowerBound(a), bound);
66275374Sbp         }
66375374Sbp         return true;
66475374Sbp     }
66575374Sbp
66675374Sbp    /** Check that type is different from 'void'.
66775374Sbp     *  @param pos           Position to be used for error reporting.
668124087Stjr     *  @param t             The type to be checked.
66975374Sbp     */
67075374Sbp    Type checkNonVoid(DiagnosticPosition pos, Type t) {
67175374Sbp        if (t.hasTag(VOID)) {
67275374Sbp            log.error(pos, Errors.VoidNotAllowedHere);
67375374Sbp            return types.createErrorType(t);
67475374Sbp        } else {
67575374Sbp            return t;
67675374Sbp        }
67775374Sbp    }
67875374Sbp
67975374Sbp    Type checkClassOrArrayType(DiagnosticPosition pos, Type t) {
68075374Sbp        if (!t.hasTag(CLASS) && !t.hasTag(ARRAY) && !t.hasTag(ERROR)) {
68175374Sbp            return typeTagError(pos,
68275374Sbp                                diags.fragment(Fragments.TypeReqClassArray),
68375374Sbp                                asTypeParam(t));
68475374Sbp        } else {
68575374Sbp            return t;
68675374Sbp        }
68775374Sbp    }
68875374Sbp
68975374Sbp    /** Check that type is a class or interface type.
69075374Sbp     *  @param pos           Position to be used for error reporting.
69175374Sbp     *  @param t             The type to be checked.
69275374Sbp     */
69375374Sbp    Type checkClassType(DiagnosticPosition pos, Type t) {
69475374Sbp        if (!t.hasTag(CLASS) && !t.hasTag(ERROR)) {
69575374Sbp            return typeTagError(pos,
69675374Sbp                                diags.fragment(Fragments.TypeReqClass),
69775374Sbp                                asTypeParam(t));
69875374Sbp        } else {
69975374Sbp            return t;
70075374Sbp        }
70175374Sbp    }
70275374Sbp    //where
70375374Sbp        private Object asTypeParam(Type t) {
70475374Sbp            return (t.hasTag(TYPEVAR))
70575374Sbp                                    ? diags.fragment(Fragments.TypeParameter(t))
70675374Sbp                                    : t;
70775374Sbp        }
70875374Sbp
70975374Sbp    /** Check that type is a valid qualifier for a constructor reference expression
71075374Sbp     */
71175374Sbp    Type checkConstructorRefType(DiagnosticPosition pos, Type t) {
71275374Sbp        t = checkClassOrArrayType(pos, t);
71375374Sbp        if (t.hasTag(CLASS)) {
71475374Sbp            if ((t.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) {
71575374Sbp                log.error(pos, Errors.AbstractCantBeInstantiated(t.tsym));
71675374Sbp                t = types.createErrorType(t);
71775374Sbp            } else if ((t.tsym.flags() & ENUM) != 0) {
71875374Sbp                log.error(pos, Errors.EnumCantBeInstantiated);
71975374Sbp                t = types.createErrorType(t);
72075374Sbp            } else {
72175374Sbp                t = checkClassType(pos, t, true);
72275374Sbp            }
72375374Sbp        } else if (t.hasTag(ARRAY)) {
72475374Sbp            if (!types.isReifiable(((ArrayType)t).elemtype)) {
72575374Sbp                log.error(pos, Errors.GenericArrayCreation);
72675374Sbp                t = types.createErrorType(t);
72775374Sbp            }
72875374Sbp        }
72975374Sbp        return t;
73075374Sbp    }
73175374Sbp
73275374Sbp    /** Check that type is a class or interface type.
73375374Sbp     *  @param pos           Position to be used for error reporting.
73475374Sbp     *  @param t             The type to be checked.
73575374Sbp     *  @param noBounds    True if type bounds are illegal here.
73675374Sbp     */
73775374Sbp    Type checkClassType(DiagnosticPosition pos, Type t, boolean noBounds) {
73875374Sbp        t = checkClassType(pos, t);
73975374Sbp        if (noBounds && t.isParameterized()) {
74075374Sbp            List<Type> args = t.getTypeArguments();
74175374Sbp            while (args.nonEmpty()) {
74275374Sbp                if (args.head.hasTag(WILDCARD))
74375374Sbp                    return typeTagError(pos,
74475374Sbp                                        diags.fragment(Fragments.TypeReqExact),
74575374Sbp                                        args.head);
74675374Sbp                args = args.tail;
74775374Sbp            }
74875374Sbp        }
74975374Sbp        return t;
75075374Sbp    }
75175374Sbp
75275374Sbp    /** Check that type is a reference type, i.e. a class, interface or array type
75375374Sbp     *  or a type variable.
75475374Sbp     *  @param pos           Position to be used for error reporting.
75575374Sbp     *  @param t             The type to be checked.
75675374Sbp     */
75775374Sbp    Type checkRefType(DiagnosticPosition pos, Type t) {
75875374Sbp        if (t.isReference())
75975374Sbp            return t;
76075374Sbp        else
76175374Sbp            return typeTagError(pos,
76275374Sbp                                diags.fragment(Fragments.TypeReqRef),
76375374Sbp                                t);
76475374Sbp    }
76575374Sbp
76675374Sbp    /** Check that each type is a reference type, i.e. a class, interface or array type
76775374Sbp     *  or a type variable.
76875374Sbp     *  @param trees         Original trees, used for error reporting.
76975374Sbp     *  @param types         The types to be checked.
77075374Sbp     */
77175374Sbp    List<Type> checkRefTypes(List<JCExpression> trees, List<Type> types) {
772        List<JCExpression> tl = trees;
773        for (List<Type> l = types; l.nonEmpty(); l = l.tail) {
774            l.head = checkRefType(tl.head.pos(), l.head);
775            tl = tl.tail;
776        }
777        return types;
778    }
779
780    /** Check that type is a null or reference type.
781     *  @param pos           Position to be used for error reporting.
782     *  @param t             The type to be checked.
783     */
784    Type checkNullOrRefType(DiagnosticPosition pos, Type t) {
785        if (t.isReference() || t.hasTag(BOT))
786            return t;
787        else
788            return typeTagError(pos,
789                                diags.fragment(Fragments.TypeReqRef),
790                                t);
791    }
792
793    /** Check that flag set does not contain elements of two conflicting sets. s
794     *  Return true if it doesn't.
795     *  @param pos           Position to be used for error reporting.
796     *  @param flags         The set of flags to be checked.
797     *  @param set1          Conflicting flags set #1.
798     *  @param set2          Conflicting flags set #2.
799     */
800    boolean checkDisjoint(DiagnosticPosition pos, long flags, long set1, long set2) {
801        if ((flags & set1) != 0 && (flags & set2) != 0) {
802            log.error(pos,
803                      Errors.IllegalCombinationOfModifiers(asFlagSet(TreeInfo.firstFlag(flags & set1)),
804                                                           asFlagSet(TreeInfo.firstFlag(flags & set2))));
805            return false;
806        } else
807            return true;
808    }
809
810    /** Check that usage of diamond operator is correct (i.e. diamond should not
811     * be used with non-generic classes or in anonymous class creation expressions)
812     */
813    Type checkDiamond(JCNewClass tree, Type t) {
814        if (!TreeInfo.isDiamond(tree) ||
815                t.isErroneous()) {
816            return checkClassType(tree.clazz.pos(), t, true);
817        } else {
818            if (tree.def != null && !allowDiamondWithAnonymousClassCreation) {
819                log.error(DiagnosticFlag.SOURCE_LEVEL, tree.clazz.pos(),
820                        Errors.CantApplyDiamond1(t, Fragments.DiamondAndAnonClassNotSupportedInSource(source.name)));
821            }
822            if (t.tsym.type.getTypeArguments().isEmpty()) {
823                log.error(tree.clazz.pos(),
824                          Errors.CantApplyDiamond1(t,
825                                                   Fragments.DiamondNonGeneric(t)));
826                return types.createErrorType(t);
827            } else if (tree.typeargs != null &&
828                    tree.typeargs.nonEmpty()) {
829                log.error(tree.clazz.pos(),
830                          Errors.CantApplyDiamond1(t,
831                                                   Fragments.DiamondAndExplicitParams(t)));
832                return types.createErrorType(t);
833            } else {
834                return t;
835            }
836        }
837    }
838
839    /** Check that the type inferred using the diamond operator does not contain
840     *  non-denotable types such as captured types or intersection types.
841     *  @param t the type inferred using the diamond operator
842     *  @return  the (possibly empty) list of non-denotable types.
843     */
844    List<Type> checkDiamondDenotable(ClassType t) {
845        ListBuffer<Type> buf = new ListBuffer<>();
846        for (Type arg : t.allparams()) {
847            if (!diamondTypeChecker.visit(arg, null)) {
848                buf.append(arg);
849            }
850        }
851        return buf.toList();
852    }
853        // where
854
855        /** diamondTypeChecker: A type visitor that descends down the given type looking for non-denotable
856         *  types. The visit methods return false as soon as a non-denotable type is encountered and true
857         *  otherwise.
858         */
859        private static final Types.SimpleVisitor<Boolean, Void> diamondTypeChecker = new Types.SimpleVisitor<Boolean, Void>() {
860            @Override
861            public Boolean visitType(Type t, Void s) {
862                return true;
863            }
864            @Override
865            public Boolean visitClassType(ClassType t, Void s) {
866                if (t.isCompound()) {
867                    return false;
868                }
869                for (Type targ : t.allparams()) {
870                    if (!visit(targ, s)) {
871                        return false;
872                    }
873                }
874                return true;
875            }
876
877            @Override
878            public Boolean visitTypeVar(TypeVar t, Void s) {
879                /* Any type variable mentioned in the inferred type must have been declared as a type parameter
880                  (i.e cannot have been produced by inference (18.4))
881                */
882                return t.tsym.owner.type.getTypeArguments().contains(t);
883            }
884
885            @Override
886            public Boolean visitCapturedType(CapturedType t, Void s) {
887                /* Any type variable mentioned in the inferred type must have been declared as a type parameter
888                  (i.e cannot have been produced by capture conversion (5.1.10))
889                */
890                return false;
891            }
892
893            @Override
894            public Boolean visitArrayType(ArrayType t, Void s) {
895                return visit(t.elemtype, s);
896            }
897
898            @Override
899            public Boolean visitWildcardType(WildcardType t, Void s) {
900                return visit(t.type, s);
901            }
902        };
903
904    void checkVarargsMethodDecl(Env<AttrContext> env, JCMethodDecl tree) {
905        MethodSymbol m = tree.sym;
906        if (!allowSimplifiedVarargs) return;
907        boolean hasTrustMeAnno = m.attribute(syms.trustMeType.tsym) != null;
908        Type varargElemType = null;
909        if (m.isVarArgs()) {
910            varargElemType = types.elemtype(tree.params.last().type);
911        }
912        if (hasTrustMeAnno && !isTrustMeAllowedOnMethod(m)) {
913            if (varargElemType != null) {
914                JCDiagnostic msg = allowPrivateSafeVarargs ?
915                        diags.fragment(Fragments.VarargsTrustmeOnVirtualVarargs(m)) :
916                        diags.fragment(Fragments.VarargsTrustmeOnVirtualVarargsFinalOnly(m));
917                log.error(tree,
918                          Errors.VarargsInvalidTrustmeAnno(syms.trustMeType.tsym,
919                                                           msg));
920            } else {
921                log.error(tree,
922                          Errors.VarargsInvalidTrustmeAnno(syms.trustMeType.tsym,
923                                                           Fragments.VarargsTrustmeOnNonVarargsMeth(m)));
924            }
925        } else if (hasTrustMeAnno && varargElemType != null &&
926                            types.isReifiable(varargElemType)) {
927            warnUnsafeVararg(tree,
928                            "varargs.redundant.trustme.anno",
929                            syms.trustMeType.tsym,
930                            diags.fragment(Fragments.VarargsTrustmeOnReifiableVarargs(varargElemType)));
931        }
932        else if (!hasTrustMeAnno && varargElemType != null &&
933                !types.isReifiable(varargElemType)) {
934            warnUnchecked(tree.params.head.pos(), "unchecked.varargs.non.reifiable.type", varargElemType);
935        }
936    }
937    //where
938        private boolean isTrustMeAllowedOnMethod(Symbol s) {
939            return (s.flags() & VARARGS) != 0 &&
940                (s.isConstructor() ||
941                    (s.flags() & (STATIC | FINAL |
942                                  (allowPrivateSafeVarargs ? PRIVATE : 0) )) != 0);
943        }
944
945    Type checkMethod(final Type mtype,
946            final Symbol sym,
947            final Env<AttrContext> env,
948            final List<JCExpression> argtrees,
949            final List<Type> argtypes,
950            final boolean useVarargs,
951            InferenceContext inferenceContext) {
952        // System.out.println("call   : " + env.tree);
953        // System.out.println("method : " + owntype);
954        // System.out.println("actuals: " + argtypes);
955        if (inferenceContext.free(mtype)) {
956            inferenceContext.addFreeTypeListener(List.of(mtype),
957                    solvedContext -> checkMethod(solvedContext.asInstType(mtype), sym, env, argtrees, argtypes, useVarargs, solvedContext));
958            return mtype;
959        }
960        Type owntype = mtype;
961        List<Type> formals = owntype.getParameterTypes();
962        List<Type> nonInferred = sym.type.getParameterTypes();
963        if (nonInferred.length() != formals.length()) nonInferred = formals;
964        Type last = useVarargs ? formals.last() : null;
965        if (sym.name == names.init && sym.owner == syms.enumSym) {
966            formals = formals.tail.tail;
967            nonInferred = nonInferred.tail.tail;
968        }
969        List<JCExpression> args = argtrees;
970        if (args != null) {
971            //this is null when type-checking a method reference
972            while (formals.head != last) {
973                JCTree arg = args.head;
974                Warner warn = convertWarner(arg.pos(), arg.type, nonInferred.head);
975                assertConvertible(arg, arg.type, formals.head, warn);
976                args = args.tail;
977                formals = formals.tail;
978                nonInferred = nonInferred.tail;
979            }
980            if (useVarargs) {
981                Type varArg = types.elemtype(last);
982                while (args.tail != null) {
983                    JCTree arg = args.head;
984                    Warner warn = convertWarner(arg.pos(), arg.type, varArg);
985                    assertConvertible(arg, arg.type, varArg, warn);
986                    args = args.tail;
987                }
988            } else if ((sym.flags() & (VARARGS | SIGNATURE_POLYMORPHIC)) == VARARGS) {
989                // non-varargs call to varargs method
990                Type varParam = owntype.getParameterTypes().last();
991                Type lastArg = argtypes.last();
992                if (types.isSubtypeUnchecked(lastArg, types.elemtype(varParam)) &&
993                    !types.isSameType(types.erasure(varParam), types.erasure(lastArg)))
994                    log.warning(argtrees.last().pos(),
995                                Warnings.InexactNonVarargsCall(types.elemtype(varParam),varParam));
996            }
997        }
998        if (useVarargs) {
999            Type argtype = owntype.getParameterTypes().last();
1000            if (!types.isReifiable(argtype) &&
1001                (!allowSimplifiedVarargs ||
1002                 sym.baseSymbol().attribute(syms.trustMeType.tsym) == null ||
1003                 !isTrustMeAllowedOnMethod(sym))) {
1004                warnUnchecked(env.tree.pos(),
1005                                  "unchecked.generic.array.creation",
1006                                  argtype);
1007            }
1008            if ((sym.baseSymbol().flags() & SIGNATURE_POLYMORPHIC) == 0) {
1009                TreeInfo.setVarargsElement(env.tree, types.elemtype(argtype));
1010            }
1011         }
1012         return owntype;
1013    }
1014    //where
1015    private void assertConvertible(JCTree tree, Type actual, Type formal, Warner warn) {
1016        if (types.isConvertible(actual, formal, warn))
1017            return;
1018
1019        if (formal.isCompound()
1020            && types.isSubtype(actual, types.supertype(formal))
1021            && types.isSubtypeUnchecked(actual, types.interfaces(formal), warn))
1022            return;
1023    }
1024
1025    /**
1026     * Check that type 't' is a valid instantiation of a generic class
1027     * (see JLS 4.5)
1028     *
1029     * @param t class type to be checked
1030     * @return true if 't' is well-formed
1031     */
1032    public boolean checkValidGenericType(Type t) {
1033        return firstIncompatibleTypeArg(t) == null;
1034    }
1035    //WHERE
1036        private Type firstIncompatibleTypeArg(Type type) {
1037            List<Type> formals = type.tsym.type.allparams();
1038            List<Type> actuals = type.allparams();
1039            List<Type> args = type.getTypeArguments();
1040            List<Type> forms = type.tsym.type.getTypeArguments();
1041            ListBuffer<Type> bounds_buf = new ListBuffer<>();
1042
1043            // For matching pairs of actual argument types `a' and
1044            // formal type parameters with declared bound `b' ...
1045            while (args.nonEmpty() && forms.nonEmpty()) {
1046                // exact type arguments needs to know their
1047                // bounds (for upper and lower bound
1048                // calculations).  So we create new bounds where
1049                // type-parameters are replaced with actuals argument types.
1050                bounds_buf.append(types.subst(forms.head.getUpperBound(), formals, actuals));
1051                args = args.tail;
1052                forms = forms.tail;
1053            }
1054
1055            args = type.getTypeArguments();
1056            List<Type> tvars_cap = types.substBounds(formals,
1057                                      formals,
1058                                      types.capture(type).allparams());
1059            while (args.nonEmpty() && tvars_cap.nonEmpty()) {
1060                // Let the actual arguments know their bound
1061                args.head.withTypeVar((TypeVar)tvars_cap.head);
1062                args = args.tail;
1063                tvars_cap = tvars_cap.tail;
1064            }
1065
1066            args = type.getTypeArguments();
1067            List<Type> bounds = bounds_buf.toList();
1068
1069            while (args.nonEmpty() && bounds.nonEmpty()) {
1070                Type actual = args.head;
1071                if (!isTypeArgErroneous(actual) &&
1072                        !bounds.head.isErroneous() &&
1073                        !checkExtends(actual, bounds.head)) {
1074                    return args.head;
1075                }
1076                args = args.tail;
1077                bounds = bounds.tail;
1078            }
1079
1080            args = type.getTypeArguments();
1081            bounds = bounds_buf.toList();
1082
1083            for (Type arg : types.capture(type).getTypeArguments()) {
1084                if (arg.hasTag(TYPEVAR) &&
1085                        arg.getUpperBound().isErroneous() &&
1086                        !bounds.head.isErroneous() &&
1087                        !isTypeArgErroneous(args.head)) {
1088                    return args.head;
1089                }
1090                bounds = bounds.tail;
1091                args = args.tail;
1092            }
1093
1094            return null;
1095        }
1096        //where
1097        boolean isTypeArgErroneous(Type t) {
1098            return isTypeArgErroneous.visit(t);
1099        }
1100
1101        Types.UnaryVisitor<Boolean> isTypeArgErroneous = new Types.UnaryVisitor<Boolean>() {
1102            public Boolean visitType(Type t, Void s) {
1103                return t.isErroneous();
1104            }
1105            @Override
1106            public Boolean visitTypeVar(TypeVar t, Void s) {
1107                return visit(t.getUpperBound());
1108            }
1109            @Override
1110            public Boolean visitCapturedType(CapturedType t, Void s) {
1111                return visit(t.getUpperBound()) ||
1112                        visit(t.getLowerBound());
1113            }
1114            @Override
1115            public Boolean visitWildcardType(WildcardType t, Void s) {
1116                return visit(t.type);
1117            }
1118        };
1119
1120    /** Check that given modifiers are legal for given symbol and
1121     *  return modifiers together with any implicit modifiers for that symbol.
1122     *  Warning: we can't use flags() here since this method
1123     *  is called during class enter, when flags() would cause a premature
1124     *  completion.
1125     *  @param pos           Position to be used for error reporting.
1126     *  @param flags         The set of modifiers given in a definition.
1127     *  @param sym           The defined symbol.
1128     */
1129    long checkFlags(DiagnosticPosition pos, long flags, Symbol sym, JCTree tree) {
1130        long mask;
1131        long implicit = 0;
1132
1133        switch (sym.kind) {
1134        case VAR:
1135            if (TreeInfo.isReceiverParam(tree))
1136                mask = ReceiverParamFlags;
1137            else if (sym.owner.kind != TYP)
1138                mask = LocalVarFlags;
1139            else if ((sym.owner.flags_field & INTERFACE) != 0)
1140                mask = implicit = InterfaceVarFlags;
1141            else
1142                mask = VarFlags;
1143            break;
1144        case MTH:
1145            if (sym.name == names.init) {
1146                if ((sym.owner.flags_field & ENUM) != 0) {
1147                    // enum constructors cannot be declared public or
1148                    // protected and must be implicitly or explicitly
1149                    // private
1150                    implicit = PRIVATE;
1151                    mask = PRIVATE;
1152                } else
1153                    mask = ConstructorFlags;
1154            }  else if ((sym.owner.flags_field & INTERFACE) != 0) {
1155                if ((sym.owner.flags_field & ANNOTATION) != 0) {
1156                    mask = AnnotationTypeElementMask;
1157                    implicit = PUBLIC | ABSTRACT;
1158                } else if ((flags & (DEFAULT | STATIC | PRIVATE)) != 0) {
1159                    mask = InterfaceMethodMask;
1160                    implicit = (flags & PRIVATE) != 0 ? 0 : PUBLIC;
1161                    if ((flags & DEFAULT) != 0) {
1162                        implicit |= ABSTRACT;
1163                    }
1164                } else {
1165                    mask = implicit = InterfaceMethodFlags;
1166                }
1167            } else {
1168                mask = MethodFlags;
1169            }
1170            // Imply STRICTFP if owner has STRICTFP set.
1171            if (((flags|implicit) & Flags.ABSTRACT) == 0 ||
1172                ((flags) & Flags.DEFAULT) != 0)
1173                implicit |= sym.owner.flags_field & STRICTFP;
1174            break;
1175        case TYP:
1176            if (sym.isLocal()) {
1177                mask = LocalClassFlags;
1178                if ((sym.owner.flags_field & STATIC) == 0 &&
1179                    (flags & ENUM) != 0)
1180                    log.error(pos, Errors.EnumsMustBeStatic);
1181            } else if (sym.owner.kind == TYP) {
1182                mask = MemberClassFlags;
1183                if (sym.owner.owner.kind == PCK ||
1184                    (sym.owner.flags_field & STATIC) != 0)
1185                    mask |= STATIC;
1186                else if ((flags & ENUM) != 0)
1187                    log.error(pos, Errors.EnumsMustBeStatic);
1188                // Nested interfaces and enums are always STATIC (Spec ???)
1189                if ((flags & (INTERFACE | ENUM)) != 0 ) implicit = STATIC;
1190            } else {
1191                mask = ClassFlags;
1192            }
1193            // Interfaces are always ABSTRACT
1194            if ((flags & INTERFACE) != 0) implicit |= ABSTRACT;
1195
1196            if ((flags & ENUM) != 0) {
1197                // enums can't be declared abstract or final
1198                mask &= ~(ABSTRACT | FINAL);
1199                implicit |= implicitEnumFinalFlag(tree);
1200            }
1201            // Imply STRICTFP if owner has STRICTFP set.
1202            implicit |= sym.owner.flags_field & STRICTFP;
1203            break;
1204        default:
1205            throw new AssertionError();
1206        }
1207        long illegal = flags & ExtendedStandardFlags & ~mask;
1208        if (illegal != 0) {
1209            if ((illegal & INTERFACE) != 0) {
1210                log.error(pos, Errors.IntfNotAllowedHere);
1211                mask |= INTERFACE;
1212            }
1213            else {
1214                log.error(pos,
1215                          Errors.ModNotAllowedHere(asFlagSet(illegal)));
1216            }
1217        }
1218        else if ((sym.kind == TYP ||
1219                  // ISSUE: Disallowing abstract&private is no longer appropriate
1220                  // in the presence of inner classes. Should it be deleted here?
1221                  checkDisjoint(pos, flags,
1222                                ABSTRACT,
1223                                PRIVATE | STATIC | DEFAULT))
1224                 &&
1225                 checkDisjoint(pos, flags,
1226                                STATIC | PRIVATE,
1227                                DEFAULT)
1228                 &&
1229                 checkDisjoint(pos, flags,
1230                               ABSTRACT | INTERFACE,
1231                               FINAL | NATIVE | SYNCHRONIZED)
1232                 &&
1233                 checkDisjoint(pos, flags,
1234                               PUBLIC,
1235                               PRIVATE | PROTECTED)
1236                 &&
1237                 checkDisjoint(pos, flags,
1238                               PRIVATE,
1239                               PUBLIC | PROTECTED)
1240                 &&
1241                 checkDisjoint(pos, flags,
1242                               FINAL,
1243                               VOLATILE)
1244                 &&
1245                 (sym.kind == TYP ||
1246                  checkDisjoint(pos, flags,
1247                                ABSTRACT | NATIVE,
1248                                STRICTFP))) {
1249            // skip
1250        }
1251        return flags & (mask | ~ExtendedStandardFlags) | implicit;
1252    }
1253
1254
1255    /** Determine if this enum should be implicitly final.
1256     *
1257     *  If the enum has no specialized enum contants, it is final.
1258     *
1259     *  If the enum does have specialized enum contants, it is
1260     *  <i>not</i> final.
1261     */
1262    private long implicitEnumFinalFlag(JCTree tree) {
1263        if (!tree.hasTag(CLASSDEF)) return 0;
1264        class SpecialTreeVisitor extends JCTree.Visitor {
1265            boolean specialized;
1266            SpecialTreeVisitor() {
1267                this.specialized = false;
1268            }
1269
1270            @Override
1271            public void visitTree(JCTree tree) { /* no-op */ }
1272
1273            @Override
1274            public void visitVarDef(JCVariableDecl tree) {
1275                if ((tree.mods.flags & ENUM) != 0) {
1276                    if (tree.init instanceof JCNewClass &&
1277                        ((JCNewClass) tree.init).def != null) {
1278                        specialized = true;
1279                    }
1280                }
1281            }
1282        }
1283
1284        SpecialTreeVisitor sts = new SpecialTreeVisitor();
1285        JCClassDecl cdef = (JCClassDecl) tree;
1286        for (JCTree defs: cdef.defs) {
1287            defs.accept(sts);
1288            if (sts.specialized) return 0;
1289        }
1290        return FINAL;
1291    }
1292
1293/* *************************************************************************
1294 * Type Validation
1295 **************************************************************************/
1296
1297    /** Validate a type expression. That is,
1298     *  check that all type arguments of a parametric type are within
1299     *  their bounds. This must be done in a second phase after type attribution
1300     *  since a class might have a subclass as type parameter bound. E.g:
1301     *
1302     *  <pre>{@code
1303     *  class B<A extends C> { ... }
1304     *  class C extends B<C> { ... }
1305     *  }</pre>
1306     *
1307     *  and we can't make sure that the bound is already attributed because
1308     *  of possible cycles.
1309     *
1310     * Visitor method: Validate a type expression, if it is not null, catching
1311     *  and reporting any completion failures.
1312     */
1313    void validate(JCTree tree, Env<AttrContext> env) {
1314        validate(tree, env, true);
1315    }
1316    void validate(JCTree tree, Env<AttrContext> env, boolean checkRaw) {
1317        new Validator(env).validateTree(tree, checkRaw, true);
1318    }
1319
1320    /** Visitor method: Validate a list of type expressions.
1321     */
1322    void validate(List<? extends JCTree> trees, Env<AttrContext> env) {
1323        for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail)
1324            validate(l.head, env);
1325    }
1326
1327    /** A visitor class for type validation.
1328     */
1329    class Validator extends JCTree.Visitor {
1330
1331        boolean checkRaw;
1332        boolean isOuter;
1333        Env<AttrContext> env;
1334
1335        Validator(Env<AttrContext> env) {
1336            this.env = env;
1337        }
1338
1339        @Override
1340        public void visitTypeArray(JCArrayTypeTree tree) {
1341            validateTree(tree.elemtype, checkRaw, isOuter);
1342        }
1343
1344        @Override
1345        public void visitTypeApply(JCTypeApply tree) {
1346            if (tree.type.hasTag(CLASS)) {
1347                List<JCExpression> args = tree.arguments;
1348                List<Type> forms = tree.type.tsym.type.getTypeArguments();
1349
1350                Type incompatibleArg = firstIncompatibleTypeArg(tree.type);
1351                if (incompatibleArg != null) {
1352                    for (JCTree arg : tree.arguments) {
1353                        if (arg.type == incompatibleArg) {
1354                            log.error(arg, Errors.NotWithinBounds(incompatibleArg, forms.head));
1355                        }
1356                        forms = forms.tail;
1357                     }
1358                 }
1359
1360                forms = tree.type.tsym.type.getTypeArguments();
1361
1362                boolean is_java_lang_Class = tree.type.tsym.flatName() == names.java_lang_Class;
1363
1364                // For matching pairs of actual argument types `a' and
1365                // formal type parameters with declared bound `b' ...
1366                while (args.nonEmpty() && forms.nonEmpty()) {
1367                    validateTree(args.head,
1368                            !(isOuter && is_java_lang_Class),
1369                            false);
1370                    args = args.tail;
1371                    forms = forms.tail;
1372                }
1373
1374                // Check that this type is either fully parameterized, or
1375                // not parameterized at all.
1376                if (tree.type.getEnclosingType().isRaw())
1377                    log.error(tree.pos(), Errors.ImproperlyFormedTypeInnerRawParam);
1378                if (tree.clazz.hasTag(SELECT))
1379                    visitSelectInternal((JCFieldAccess)tree.clazz);
1380            }
1381        }
1382
1383        @Override
1384        public void visitTypeParameter(JCTypeParameter tree) {
1385            validateTrees(tree.bounds, true, isOuter);
1386            checkClassBounds(tree.pos(), tree.type);
1387        }
1388
1389        @Override
1390        public void visitWildcard(JCWildcard tree) {
1391            if (tree.inner != null)
1392                validateTree(tree.inner, true, isOuter);
1393        }
1394
1395        @Override
1396        public void visitSelect(JCFieldAccess tree) {
1397            if (tree.type.hasTag(CLASS)) {
1398                visitSelectInternal(tree);
1399
1400                // Check that this type is either fully parameterized, or
1401                // not parameterized at all.
1402                if (tree.selected.type.isParameterized() && tree.type.tsym.type.getTypeArguments().nonEmpty())
1403                    log.error(tree.pos(), Errors.ImproperlyFormedTypeParamMissing);
1404            }
1405        }
1406
1407        public void visitSelectInternal(JCFieldAccess tree) {
1408            if (tree.type.tsym.isStatic() &&
1409                tree.selected.type.isParameterized()) {
1410                // The enclosing type is not a class, so we are
1411                // looking at a static member type.  However, the
1412                // qualifying expression is parameterized.
1413                log.error(tree.pos(), Errors.CantSelectStaticClassFromParamType);
1414            } else {
1415                // otherwise validate the rest of the expression
1416                tree.selected.accept(this);
1417            }
1418        }
1419
1420        @Override
1421        public void visitAnnotatedType(JCAnnotatedType tree) {
1422            tree.underlyingType.accept(this);
1423        }
1424
1425        @Override
1426        public void visitTypeIdent(JCPrimitiveTypeTree that) {
1427            if (that.type.hasTag(TypeTag.VOID)) {
1428                log.error(that.pos(), Errors.VoidNotAllowedHere);
1429            }
1430            super.visitTypeIdent(that);
1431        }
1432
1433        /** Default visitor method: do nothing.
1434         */
1435        @Override
1436        public void visitTree(JCTree tree) {
1437        }
1438
1439        public void validateTree(JCTree tree, boolean checkRaw, boolean isOuter) {
1440            if (tree != null) {
1441                boolean prevCheckRaw = this.checkRaw;
1442                this.checkRaw = checkRaw;
1443                this.isOuter = isOuter;
1444
1445                try {
1446                    tree.accept(this);
1447                    if (checkRaw)
1448                        checkRaw(tree, env);
1449                } catch (CompletionFailure ex) {
1450                    completionError(tree.pos(), ex);
1451                } finally {
1452                    this.checkRaw = prevCheckRaw;
1453                }
1454            }
1455        }
1456
1457        public void validateTrees(List<? extends JCTree> trees, boolean checkRaw, boolean isOuter) {
1458            for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail)
1459                validateTree(l.head, checkRaw, isOuter);
1460        }
1461    }
1462
1463    void checkRaw(JCTree tree, Env<AttrContext> env) {
1464        if (lint.isEnabled(LintCategory.RAW) &&
1465            tree.type.hasTag(CLASS) &&
1466            !TreeInfo.isDiamond(tree) &&
1467            !withinAnonConstr(env) &&
1468            tree.type.isRaw()) {
1469            log.warning(LintCategory.RAW,
1470                    tree.pos(), Warnings.RawClassUse(tree.type, tree.type.tsym.type));
1471        }
1472    }
1473    //where
1474        private boolean withinAnonConstr(Env<AttrContext> env) {
1475            return env.enclClass.name.isEmpty() &&
1476                    env.enclMethod != null && env.enclMethod.name == names.init;
1477        }
1478
1479/* *************************************************************************
1480 * Exception checking
1481 **************************************************************************/
1482
1483    /* The following methods treat classes as sets that contain
1484     * the class itself and all their subclasses
1485     */
1486
1487    /** Is given type a subtype of some of the types in given list?
1488     */
1489    boolean subset(Type t, List<Type> ts) {
1490        for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
1491            if (types.isSubtype(t, l.head)) return true;
1492        return false;
1493    }
1494
1495    /** Is given type a subtype or supertype of
1496     *  some of the types in given list?
1497     */
1498    boolean intersects(Type t, List<Type> ts) {
1499        for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
1500            if (types.isSubtype(t, l.head) || types.isSubtype(l.head, t)) return true;
1501        return false;
1502    }
1503
1504    /** Add type set to given type list, unless it is a subclass of some class
1505     *  in the list.
1506     */
1507    List<Type> incl(Type t, List<Type> ts) {
1508        return subset(t, ts) ? ts : excl(t, ts).prepend(t);
1509    }
1510
1511    /** Remove type set from type set list.
1512     */
1513    List<Type> excl(Type t, List<Type> ts) {
1514        if (ts.isEmpty()) {
1515            return ts;
1516        } else {
1517            List<Type> ts1 = excl(t, ts.tail);
1518            if (types.isSubtype(ts.head, t)) return ts1;
1519            else if (ts1 == ts.tail) return ts;
1520            else return ts1.prepend(ts.head);
1521        }
1522    }
1523
1524    /** Form the union of two type set lists.
1525     */
1526    List<Type> union(List<Type> ts1, List<Type> ts2) {
1527        List<Type> ts = ts1;
1528        for (List<Type> l = ts2; l.nonEmpty(); l = l.tail)
1529            ts = incl(l.head, ts);
1530        return ts;
1531    }
1532
1533    /** Form the difference of two type lists.
1534     */
1535    List<Type> diff(List<Type> ts1, List<Type> ts2) {
1536        List<Type> ts = ts1;
1537        for (List<Type> l = ts2; l.nonEmpty(); l = l.tail)
1538            ts = excl(l.head, ts);
1539        return ts;
1540    }
1541
1542    /** Form the intersection of two type lists.
1543     */
1544    public List<Type> intersect(List<Type> ts1, List<Type> ts2) {
1545        List<Type> ts = List.nil();
1546        for (List<Type> l = ts1; l.nonEmpty(); l = l.tail)
1547            if (subset(l.head, ts2)) ts = incl(l.head, ts);
1548        for (List<Type> l = ts2; l.nonEmpty(); l = l.tail)
1549            if (subset(l.head, ts1)) ts = incl(l.head, ts);
1550        return ts;
1551    }
1552
1553    /** Is exc an exception symbol that need not be declared?
1554     */
1555    boolean isUnchecked(ClassSymbol exc) {
1556        return
1557            exc.kind == ERR ||
1558            exc.isSubClass(syms.errorType.tsym, types) ||
1559            exc.isSubClass(syms.runtimeExceptionType.tsym, types);
1560    }
1561
1562    /** Is exc an exception type that need not be declared?
1563     */
1564    boolean isUnchecked(Type exc) {
1565        return
1566            (exc.hasTag(TYPEVAR)) ? isUnchecked(types.supertype(exc)) :
1567            (exc.hasTag(CLASS)) ? isUnchecked((ClassSymbol)exc.tsym) :
1568            exc.hasTag(BOT);
1569    }
1570
1571    boolean isChecked(Type exc) {
1572        return !isUnchecked(exc);
1573    }
1574
1575    /** Same, but handling completion failures.
1576     */
1577    boolean isUnchecked(DiagnosticPosition pos, Type exc) {
1578        try {
1579            return isUnchecked(exc);
1580        } catch (CompletionFailure ex) {
1581            completionError(pos, ex);
1582            return true;
1583        }
1584    }
1585
1586    /** Is exc handled by given exception list?
1587     */
1588    boolean isHandled(Type exc, List<Type> handled) {
1589        return isUnchecked(exc) || subset(exc, handled);
1590    }
1591
1592    /** Return all exceptions in thrown list that are not in handled list.
1593     *  @param thrown     The list of thrown exceptions.
1594     *  @param handled    The list of handled exceptions.
1595     */
1596    List<Type> unhandled(List<Type> thrown, List<Type> handled) {
1597        List<Type> unhandled = List.nil();
1598        for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
1599            if (!isHandled(l.head, handled)) unhandled = unhandled.prepend(l.head);
1600        return unhandled;
1601    }
1602
1603/* *************************************************************************
1604 * Overriding/Implementation checking
1605 **************************************************************************/
1606
1607    /** The level of access protection given by a flag set,
1608     *  where PRIVATE is highest and PUBLIC is lowest.
1609     */
1610    static int protection(long flags) {
1611        switch ((short)(flags & AccessFlags)) {
1612        case PRIVATE: return 3;
1613        case PROTECTED: return 1;
1614        default:
1615        case PUBLIC: return 0;
1616        case 0: return 2;
1617        }
1618    }
1619
1620    /** A customized "cannot override" error message.
1621     *  @param m      The overriding method.
1622     *  @param other  The overridden method.
1623     *  @return       An internationalized string.
1624     */
1625    Fragment cannotOverride(MethodSymbol m, MethodSymbol other) {
1626        Symbol mloc = m.location();
1627        Symbol oloc = other.location();
1628
1629        if ((other.owner.flags() & INTERFACE) == 0)
1630            return Fragments.CantOverride(m, mloc, other, oloc);
1631        else if ((m.owner.flags() & INTERFACE) == 0)
1632            return Fragments.CantImplement(m, mloc, other, oloc);
1633        else
1634            return Fragments.ClashesWith(m, mloc, other, oloc);
1635    }
1636
1637    /** A customized "override" warning message.
1638     *  @param m      The overriding method.
1639     *  @param other  The overridden method.
1640     *  @return       An internationalized string.
1641     */
1642    Fragment uncheckedOverrides(MethodSymbol m, MethodSymbol other) {
1643        Symbol mloc = m.location();
1644        Symbol oloc = other.location();
1645
1646        if ((other.owner.flags() & INTERFACE) == 0)
1647            return Fragments.UncheckedOverride(m, mloc, other, oloc);
1648        else if ((m.owner.flags() & INTERFACE) == 0)
1649            return Fragments.UncheckedImplement(m, mloc, other, oloc);
1650        else
1651            return Fragments.UncheckedClashWith(m, mloc, other, oloc);
1652    }
1653
1654    /** A customized "override" warning message.
1655     *  @param m      The overriding method.
1656     *  @param other  The overridden method.
1657     *  @return       An internationalized string.
1658     */
1659    Fragment varargsOverrides(MethodSymbol m, MethodSymbol other) {
1660        Symbol mloc = m.location();
1661        Symbol oloc = other.location();
1662
1663        if ((other.owner.flags() & INTERFACE) == 0)
1664            return Fragments.VarargsOverride(m, mloc, other, oloc);
1665        else  if ((m.owner.flags() & INTERFACE) == 0)
1666            return Fragments.VarargsImplement(m, mloc, other, oloc);
1667        else
1668            return Fragments.VarargsClashWith(m, mloc, other, oloc);
1669    }
1670
1671    /** Check that this method conforms with overridden method 'other'.
1672     *  where `origin' is the class where checking started.
1673     *  Complications:
1674     *  (1) Do not check overriding of synthetic methods
1675     *      (reason: they might be final).
1676     *      todo: check whether this is still necessary.
1677     *  (2) Admit the case where an interface proxy throws fewer exceptions
1678     *      than the method it implements. Augment the proxy methods with the
1679     *      undeclared exceptions in this case.
1680     *  (3) When generics are enabled, admit the case where an interface proxy
1681     *      has a result type
1682     *      extended by the result type of the method it implements.
1683     *      Change the proxies result type to the smaller type in this case.
1684     *
1685     *  @param tree         The tree from which positions
1686     *                      are extracted for errors.
1687     *  @param m            The overriding method.
1688     *  @param other        The overridden method.
1689     *  @param origin       The class of which the overriding method
1690     *                      is a member.
1691     */
1692    void checkOverride(JCTree tree,
1693                       MethodSymbol m,
1694                       MethodSymbol other,
1695                       ClassSymbol origin) {
1696        // Don't check overriding of synthetic methods or by bridge methods.
1697        if ((m.flags() & (SYNTHETIC|BRIDGE)) != 0 || (other.flags() & SYNTHETIC) != 0) {
1698            return;
1699        }
1700
1701        // Error if static method overrides instance method (JLS 8.4.6.2).
1702        if ((m.flags() & STATIC) != 0 &&
1703                   (other.flags() & STATIC) == 0) {
1704            log.error(TreeInfo.diagnosticPositionFor(m, tree),
1705                      Errors.OverrideStatic(cannotOverride(m, other)));
1706            m.flags_field |= BAD_OVERRIDE;
1707            return;
1708        }
1709
1710        // Error if instance method overrides static or final
1711        // method (JLS 8.4.6.1).
1712        if ((other.flags() & FINAL) != 0 ||
1713                 (m.flags() & STATIC) == 0 &&
1714                 (other.flags() & STATIC) != 0) {
1715            log.error(TreeInfo.diagnosticPositionFor(m, tree),
1716                      Errors.OverrideMeth(cannotOverride(m, other),
1717                                          asFlagSet(other.flags() & (FINAL | STATIC))));
1718            m.flags_field |= BAD_OVERRIDE;
1719            return;
1720        }
1721
1722        if ((m.owner.flags() & ANNOTATION) != 0) {
1723            // handled in validateAnnotationMethod
1724            return;
1725        }
1726
1727        // Error if overriding method has weaker access (JLS 8.4.6.3).
1728        if (protection(m.flags()) > protection(other.flags())) {
1729            log.error(TreeInfo.diagnosticPositionFor(m, tree),
1730                      (other.flags() & AccessFlags) == 0 ?
1731                              Errors.OverrideWeakerAccess(cannotOverride(m, other),
1732                                                          "package") :
1733                              Errors.OverrideWeakerAccess(cannotOverride(m, other),
1734                                                          asFlagSet(other.flags() & AccessFlags)));
1735            m.flags_field |= BAD_OVERRIDE;
1736            return;
1737        }
1738
1739        Type mt = types.memberType(origin.type, m);
1740        Type ot = types.memberType(origin.type, other);
1741        // Error if overriding result type is different
1742        // (or, in the case of generics mode, not a subtype) of
1743        // overridden result type. We have to rename any type parameters
1744        // before comparing types.
1745        List<Type> mtvars = mt.getTypeArguments();
1746        List<Type> otvars = ot.getTypeArguments();
1747        Type mtres = mt.getReturnType();
1748        Type otres = types.subst(ot.getReturnType(), otvars, mtvars);
1749
1750        overrideWarner.clear();
1751        boolean resultTypesOK =
1752            types.returnTypeSubstitutable(mt, ot, otres, overrideWarner);
1753        if (!resultTypesOK) {
1754            if ((m.flags() & STATIC) != 0 && (other.flags() & STATIC) != 0) {
1755                log.error(TreeInfo.diagnosticPositionFor(m, tree),
1756                          Errors.OverrideIncompatibleRet(Fragments.CantHide(m, m.location(), other,
1757                                        other.location()), mtres, otres));
1758                m.flags_field |= BAD_OVERRIDE;
1759            } else {
1760                log.error(TreeInfo.diagnosticPositionFor(m, tree),
1761                          Errors.OverrideIncompatibleRet(cannotOverride(m, other), mtres, otres));
1762                m.flags_field |= BAD_OVERRIDE;
1763            }
1764            return;
1765        } else if (overrideWarner.hasNonSilentLint(LintCategory.UNCHECKED)) {
1766            warnUnchecked(TreeInfo.diagnosticPositionFor(m, tree),
1767                    "override.unchecked.ret",
1768                    uncheckedOverrides(m, other),
1769                    mtres, otres);
1770        }
1771
1772        // Error if overriding method throws an exception not reported
1773        // by overridden method.
1774        List<Type> otthrown = types.subst(ot.getThrownTypes(), otvars, mtvars);
1775        List<Type> unhandledErased = unhandled(mt.getThrownTypes(), types.erasure(otthrown));
1776        List<Type> unhandledUnerased = unhandled(mt.getThrownTypes(), otthrown);
1777        if (unhandledErased.nonEmpty()) {
1778            log.error(TreeInfo.diagnosticPositionFor(m, tree),
1779                      Errors.OverrideMethDoesntThrow(cannotOverride(m, other), unhandledUnerased.head));
1780            m.flags_field |= BAD_OVERRIDE;
1781            return;
1782        }
1783        else if (unhandledUnerased.nonEmpty()) {
1784            warnUnchecked(TreeInfo.diagnosticPositionFor(m, tree),
1785                          "override.unchecked.thrown",
1786                         cannotOverride(m, other),
1787                         unhandledUnerased.head);
1788            return;
1789        }
1790
1791        // Optional warning if varargs don't agree
1792        if ((((m.flags() ^ other.flags()) & Flags.VARARGS) != 0)
1793            && lint.isEnabled(LintCategory.OVERRIDES)) {
1794            log.warning(TreeInfo.diagnosticPositionFor(m, tree),
1795                        ((m.flags() & Flags.VARARGS) != 0)
1796                        ? Warnings.OverrideVarargsMissing(varargsOverrides(m, other))
1797                        : Warnings.OverrideVarargsExtra(varargsOverrides(m, other)));
1798        }
1799
1800        // Warn if instance method overrides bridge method (compiler spec ??)
1801        if ((other.flags() & BRIDGE) != 0) {
1802            log.warning(TreeInfo.diagnosticPositionFor(m, tree),
1803                        Warnings.OverrideBridge(uncheckedOverrides(m, other)));
1804        }
1805
1806        // Warn if a deprecated method overridden by a non-deprecated one.
1807        if (!isDeprecatedOverrideIgnorable(other, origin)) {
1808            Lint prevLint = setLint(lint.augment(m));
1809            try {
1810                checkDeprecated(TreeInfo.diagnosticPositionFor(m, tree), m, other);
1811            } finally {
1812                setLint(prevLint);
1813            }
1814        }
1815    }
1816    // where
1817        private boolean isDeprecatedOverrideIgnorable(MethodSymbol m, ClassSymbol origin) {
1818            // If the method, m, is defined in an interface, then ignore the issue if the method
1819            // is only inherited via a supertype and also implemented in the supertype,
1820            // because in that case, we will rediscover the issue when examining the method
1821            // in the supertype.
1822            // If the method, m, is not defined in an interface, then the only time we need to
1823            // address the issue is when the method is the supertype implemementation: any other
1824            // case, we will have dealt with when examining the supertype classes
1825            ClassSymbol mc = m.enclClass();
1826            Type st = types.supertype(origin.type);
1827            if (!st.hasTag(CLASS))
1828                return true;
1829            MethodSymbol stimpl = m.implementation((ClassSymbol)st.tsym, types, false);
1830
1831            if (mc != null && ((mc.flags() & INTERFACE) != 0)) {
1832                List<Type> intfs = types.interfaces(origin.type);
1833                return (intfs.contains(mc.type) ? false : (stimpl != null));
1834            }
1835            else
1836                return (stimpl != m);
1837        }
1838
1839
1840    // used to check if there were any unchecked conversions
1841    Warner overrideWarner = new Warner();
1842
1843    /** Check that a class does not inherit two concrete methods
1844     *  with the same signature.
1845     *  @param pos          Position to be used for error reporting.
1846     *  @param site         The class type to be checked.
1847     */
1848    public void checkCompatibleConcretes(DiagnosticPosition pos, Type site) {
1849        Type sup = types.supertype(site);
1850        if (!sup.hasTag(CLASS)) return;
1851
1852        for (Type t1 = sup;
1853             t1.hasTag(CLASS) && t1.tsym.type.isParameterized();
1854             t1 = types.supertype(t1)) {
1855            for (Symbol s1 : t1.tsym.members().getSymbols(NON_RECURSIVE)) {
1856                if (s1.kind != MTH ||
1857                    (s1.flags() & (STATIC|SYNTHETIC|BRIDGE)) != 0 ||
1858                    !s1.isInheritedIn(site.tsym, types) ||
1859                    ((MethodSymbol)s1).implementation(site.tsym,
1860                                                      types,
1861                                                      true) != s1)
1862                    continue;
1863                Type st1 = types.memberType(t1, s1);
1864                int s1ArgsLength = st1.getParameterTypes().length();
1865                if (st1 == s1.type) continue;
1866
1867                for (Type t2 = sup;
1868                     t2.hasTag(CLASS);
1869                     t2 = types.supertype(t2)) {
1870                    for (Symbol s2 : t2.tsym.members().getSymbolsByName(s1.name)) {
1871                        if (s2 == s1 ||
1872                            s2.kind != MTH ||
1873                            (s2.flags() & (STATIC|SYNTHETIC|BRIDGE)) != 0 ||
1874                            s2.type.getParameterTypes().length() != s1ArgsLength ||
1875                            !s2.isInheritedIn(site.tsym, types) ||
1876                            ((MethodSymbol)s2).implementation(site.tsym,
1877                                                              types,
1878                                                              true) != s2)
1879                            continue;
1880                        Type st2 = types.memberType(t2, s2);
1881                        if (types.overrideEquivalent(st1, st2))
1882                            log.error(pos,
1883                                      Errors.ConcreteInheritanceConflict(s1, t1, s2, t2, sup));
1884                    }
1885                }
1886            }
1887        }
1888    }
1889
1890    /** Check that classes (or interfaces) do not each define an abstract
1891     *  method with same name and arguments but incompatible return types.
1892     *  @param pos          Position to be used for error reporting.
1893     *  @param t1           The first argument type.
1894     *  @param t2           The second argument type.
1895     */
1896    public boolean checkCompatibleAbstracts(DiagnosticPosition pos,
1897                                            Type t1,
1898                                            Type t2,
1899                                            Type site) {
1900        if ((site.tsym.flags() & COMPOUND) != 0) {
1901            // special case for intersections: need to eliminate wildcards in supertypes
1902            t1 = types.capture(t1);
1903            t2 = types.capture(t2);
1904        }
1905        return firstIncompatibility(pos, t1, t2, site) == null;
1906    }
1907
1908    /** Return the first method which is defined with same args
1909     *  but different return types in two given interfaces, or null if none
1910     *  exists.
1911     *  @param t1     The first type.
1912     *  @param t2     The second type.
1913     *  @param site   The most derived type.
1914     *  @returns symbol from t2 that conflicts with one in t1.
1915     */
1916    private Symbol firstIncompatibility(DiagnosticPosition pos, Type t1, Type t2, Type site) {
1917        Map<TypeSymbol,Type> interfaces1 = new HashMap<>();
1918        closure(t1, interfaces1);
1919        Map<TypeSymbol,Type> interfaces2;
1920        if (t1 == t2)
1921            interfaces2 = interfaces1;
1922        else
1923            closure(t2, interfaces1, interfaces2 = new HashMap<>());
1924
1925        for (Type t3 : interfaces1.values()) {
1926            for (Type t4 : interfaces2.values()) {
1927                Symbol s = firstDirectIncompatibility(pos, t3, t4, site);
1928                if (s != null) return s;
1929            }
1930        }
1931        return null;
1932    }
1933
1934    /** Compute all the supertypes of t, indexed by type symbol. */
1935    private void closure(Type t, Map<TypeSymbol,Type> typeMap) {
1936        if (!t.hasTag(CLASS)) return;
1937        if (typeMap.put(t.tsym, t) == null) {
1938            closure(types.supertype(t), typeMap);
1939            for (Type i : types.interfaces(t))
1940                closure(i, typeMap);
1941        }
1942    }
1943
1944    /** Compute all the supertypes of t, indexed by type symbol (except thise in typesSkip). */
1945    private void closure(Type t, Map<TypeSymbol,Type> typesSkip, Map<TypeSymbol,Type> typeMap) {
1946        if (!t.hasTag(CLASS)) return;
1947        if (typesSkip.get(t.tsym) != null) return;
1948        if (typeMap.put(t.tsym, t) == null) {
1949            closure(types.supertype(t), typesSkip, typeMap);
1950            for (Type i : types.interfaces(t))
1951                closure(i, typesSkip, typeMap);
1952        }
1953    }
1954
1955    /** Return the first method in t2 that conflicts with a method from t1. */
1956    private Symbol firstDirectIncompatibility(DiagnosticPosition pos, Type t1, Type t2, Type site) {
1957        for (Symbol s1 : t1.tsym.members().getSymbols(NON_RECURSIVE)) {
1958            Type st1 = null;
1959            if (s1.kind != MTH || !s1.isInheritedIn(site.tsym, types) ||
1960                    (s1.flags() & SYNTHETIC) != 0) continue;
1961            Symbol impl = ((MethodSymbol)s1).implementation(site.tsym, types, false);
1962            if (impl != null && (impl.flags() & ABSTRACT) == 0) continue;
1963            for (Symbol s2 : t2.tsym.members().getSymbolsByName(s1.name)) {
1964                if (s1 == s2) continue;
1965                if (s2.kind != MTH || !s2.isInheritedIn(site.tsym, types) ||
1966                        (s2.flags() & SYNTHETIC) != 0) continue;
1967                if (st1 == null) st1 = types.memberType(t1, s1);
1968                Type st2 = types.memberType(t2, s2);
1969                if (types.overrideEquivalent(st1, st2)) {
1970                    List<Type> tvars1 = st1.getTypeArguments();
1971                    List<Type> tvars2 = st2.getTypeArguments();
1972                    Type rt1 = st1.getReturnType();
1973                    Type rt2 = types.subst(st2.getReturnType(), tvars2, tvars1);
1974                    boolean compat =
1975                        types.isSameType(rt1, rt2) ||
1976                        !rt1.isPrimitiveOrVoid() &&
1977                        !rt2.isPrimitiveOrVoid() &&
1978                        (types.covariantReturnType(rt1, rt2, types.noWarnings) ||
1979                         types.covariantReturnType(rt2, rt1, types.noWarnings)) ||
1980                         checkCommonOverriderIn(s1,s2,site);
1981                    if (!compat) {
1982                        log.error(pos, Errors.TypesIncompatibleDiffRet(t1, t2, s2.name +
1983                                "(" + types.memberType(t2, s2).getParameterTypes() + ")"));
1984                        return s2;
1985                    }
1986                } else if (checkNameClash((ClassSymbol)site.tsym, s1, s2) &&
1987                        !checkCommonOverriderIn(s1, s2, site)) {
1988                    log.error(pos, Errors.NameClashSameErasureNoOverride(
1989                            s1.name, types.memberType(site, s1).asMethodType().getParameterTypes(), s1.location(),
1990                            s2.name, types.memberType(site, s2).asMethodType().getParameterTypes(), s2.location()));
1991                    return s2;
1992                }
1993            }
1994        }
1995        return null;
1996    }
1997    //WHERE
1998    boolean checkCommonOverriderIn(Symbol s1, Symbol s2, Type site) {
1999        Map<TypeSymbol,Type> supertypes = new HashMap<>();
2000        Type st1 = types.memberType(site, s1);
2001        Type st2 = types.memberType(site, s2);
2002        closure(site, supertypes);
2003        for (Type t : supertypes.values()) {
2004            for (Symbol s3 : t.tsym.members().getSymbolsByName(s1.name)) {
2005                if (s3 == s1 || s3 == s2 || s3.kind != MTH || (s3.flags() & (BRIDGE|SYNTHETIC)) != 0) continue;
2006                Type st3 = types.memberType(site,s3);
2007                if (types.overrideEquivalent(st3, st1) &&
2008                        types.overrideEquivalent(st3, st2) &&
2009                        types.returnTypeSubstitutable(st3, st1) &&
2010                        types.returnTypeSubstitutable(st3, st2)) {
2011                    return true;
2012                }
2013            }
2014        }
2015        return false;
2016    }
2017
2018    /** Check that a given method conforms with any method it overrides.
2019     *  @param tree         The tree from which positions are extracted
2020     *                      for errors.
2021     *  @param m            The overriding method.
2022     */
2023    void checkOverride(Env<AttrContext> env, JCMethodDecl tree, MethodSymbol m) {
2024        ClassSymbol origin = (ClassSymbol)m.owner;
2025        if ((origin.flags() & ENUM) != 0 && names.finalize.equals(m.name))
2026            if (m.overrides(syms.enumFinalFinalize, origin, types, false)) {
2027                log.error(tree.pos(), Errors.EnumNoFinalize);
2028                return;
2029            }
2030        for (Type t = origin.type; t.hasTag(CLASS);
2031             t = types.supertype(t)) {
2032            if (t != origin.type) {
2033                checkOverride(tree, t, origin, m);
2034            }
2035            for (Type t2 : types.interfaces(t)) {
2036                checkOverride(tree, t2, origin, m);
2037            }
2038        }
2039
2040        final boolean explicitOverride = m.attribute(syms.overrideType.tsym) != null;
2041        // Check if this method must override a super method due to being annotated with @Override
2042        // or by virtue of being a member of a diamond inferred anonymous class. Latter case is to
2043        // be treated "as if as they were annotated" with @Override.
2044        boolean mustOverride = explicitOverride ||
2045                (env.info.isAnonymousDiamond && !m.isConstructor() && !m.isPrivate());
2046        if (mustOverride && !isOverrider(m)) {
2047            DiagnosticPosition pos = tree.pos();
2048            for (JCAnnotation a : tree.getModifiers().annotations) {
2049                if (a.annotationType.type.tsym == syms.overrideType.tsym) {
2050                    pos = a.pos();
2051                    break;
2052                }
2053            }
2054            log.error(pos,
2055                      explicitOverride ? Errors.MethodDoesNotOverrideSuperclass :
2056                                Errors.AnonymousDiamondMethodDoesNotOverrideSuperclass(Fragments.DiamondAnonymousMethodsImplicitlyOverride));
2057        }
2058    }
2059
2060    void checkOverride(JCTree tree, Type site, ClassSymbol origin, MethodSymbol m) {
2061        TypeSymbol c = site.tsym;
2062        for (Symbol sym : c.members().getSymbolsByName(m.name)) {
2063            if (m.overrides(sym, origin, types, false)) {
2064                if ((sym.flags() & ABSTRACT) == 0) {
2065                    checkOverride(tree, m, (MethodSymbol)sym, origin);
2066                }
2067            }
2068        }
2069    }
2070
2071    private Filter<Symbol> equalsHasCodeFilter = s -> MethodSymbol.implementation_filter.accepts(s) &&
2072            (s.flags() & BAD_OVERRIDE) == 0;
2073
2074    public void checkClassOverrideEqualsAndHashIfNeeded(DiagnosticPosition pos,
2075            ClassSymbol someClass) {
2076        /* At present, annotations cannot possibly have a method that is override
2077         * equivalent with Object.equals(Object) but in any case the condition is
2078         * fine for completeness.
2079         */
2080        if (someClass == (ClassSymbol)syms.objectType.tsym ||
2081            someClass.isInterface() || someClass.isEnum() ||
2082            (someClass.flags() & ANNOTATION) != 0 ||
2083            (someClass.flags() & ABSTRACT) != 0) return;
2084        //anonymous inner classes implementing interfaces need especial treatment
2085        if (someClass.isAnonymous()) {
2086            List<Type> interfaces =  types.interfaces(someClass.type);
2087            if (interfaces != null && !interfaces.isEmpty() &&
2088                interfaces.head.tsym == syms.comparatorType.tsym) return;
2089        }
2090        checkClassOverrideEqualsAndHash(pos, someClass);
2091    }
2092
2093    private void checkClassOverrideEqualsAndHash(DiagnosticPosition pos,
2094            ClassSymbol someClass) {
2095        if (lint.isEnabled(LintCategory.OVERRIDES)) {
2096            MethodSymbol equalsAtObject = (MethodSymbol)syms.objectType
2097                    .tsym.members().findFirst(names.equals);
2098            MethodSymbol hashCodeAtObject = (MethodSymbol)syms.objectType
2099                    .tsym.members().findFirst(names.hashCode);
2100            boolean overridesEquals = types.implementation(equalsAtObject,
2101                someClass, false, equalsHasCodeFilter).owner == someClass;
2102            boolean overridesHashCode = types.implementation(hashCodeAtObject,
2103                someClass, false, equalsHasCodeFilter) != hashCodeAtObject;
2104
2105            if (overridesEquals && !overridesHashCode) {
2106                log.warning(LintCategory.OVERRIDES, pos,
2107                            Warnings.OverrideEqualsButNotHashcode(someClass));
2108            }
2109        }
2110    }
2111
2112    public void checkModuleName (JCModuleDecl tree) {
2113        Name moduleName = tree.sym.name;
2114        Assert.checkNonNull(moduleName);
2115        if (lint.isEnabled(LintCategory.MODULE)) {
2116            JCExpression qualId = tree.qualId;
2117            while (qualId != null) {
2118                Name componentName;
2119                DiagnosticPosition pos;
2120                switch (qualId.getTag()) {
2121                    case SELECT:
2122                        JCFieldAccess selectNode = ((JCFieldAccess) qualId);
2123                        componentName = selectNode.name;
2124                        pos = selectNode.pos();
2125                        qualId = selectNode.selected;
2126                        break;
2127                    case IDENT:
2128                        componentName = ((JCIdent) qualId).name;
2129                        pos = qualId.pos();
2130                        qualId = null;
2131                        break;
2132                    default:
2133                        throw new AssertionError("Unexpected qualified identifier: " + qualId.toString());
2134                }
2135                if (componentName != null) {
2136                    String moduleNameComponentString = componentName.toString();
2137                    int nameLength = moduleNameComponentString.length();
2138                    if (nameLength > 0 && Character.isDigit(moduleNameComponentString.charAt(nameLength - 1))) {
2139                        log.warning(Lint.LintCategory.MODULE, pos, Warnings.PoorChoiceForModuleName(componentName));
2140                    }
2141                }
2142            }
2143        }
2144    }
2145
2146    private boolean checkNameClash(ClassSymbol origin, Symbol s1, Symbol s2) {
2147        ClashFilter cf = new ClashFilter(origin.type);
2148        return (cf.accepts(s1) &&
2149                cf.accepts(s2) &&
2150                types.hasSameArgs(s1.erasure(types), s2.erasure(types)));
2151    }
2152
2153
2154    /** Check that all abstract members of given class have definitions.
2155     *  @param pos          Position to be used for error reporting.
2156     *  @param c            The class.
2157     */
2158    void checkAllDefined(DiagnosticPosition pos, ClassSymbol c) {
2159        MethodSymbol undef = types.firstUnimplementedAbstract(c);
2160        if (undef != null) {
2161            MethodSymbol undef1 =
2162                new MethodSymbol(undef.flags(), undef.name,
2163                                 types.memberType(c.type, undef), undef.owner);
2164            log.error(pos,
2165                      Errors.DoesNotOverrideAbstract(c, undef1, undef1.location()));
2166        }
2167    }
2168
2169    void checkNonCyclicDecl(JCClassDecl tree) {
2170        CycleChecker cc = new CycleChecker();
2171        cc.scan(tree);
2172        if (!cc.errorFound && !cc.partialCheck) {
2173            tree.sym.flags_field |= ACYCLIC;
2174        }
2175    }
2176
2177    class CycleChecker extends TreeScanner {
2178
2179        List<Symbol> seenClasses = List.nil();
2180        boolean errorFound = false;
2181        boolean partialCheck = false;
2182
2183        private void checkSymbol(DiagnosticPosition pos, Symbol sym) {
2184            if (sym != null && sym.kind == TYP) {
2185                Env<AttrContext> classEnv = enter.getEnv((TypeSymbol)sym);
2186                if (classEnv != null) {
2187                    DiagnosticSource prevSource = log.currentSource();
2188                    try {
2189                        log.useSource(classEnv.toplevel.sourcefile);
2190                        scan(classEnv.tree);
2191                    }
2192                    finally {
2193                        log.useSource(prevSource.getFile());
2194                    }
2195                } else if (sym.kind == TYP) {
2196                    checkClass(pos, sym, List.nil());
2197                }
2198            } else {
2199                //not completed yet
2200                partialCheck = true;
2201            }
2202        }
2203
2204        @Override
2205        public void visitSelect(JCFieldAccess tree) {
2206            super.visitSelect(tree);
2207            checkSymbol(tree.pos(), tree.sym);
2208        }
2209
2210        @Override
2211        public void visitIdent(JCIdent tree) {
2212            checkSymbol(tree.pos(), tree.sym);
2213        }
2214
2215        @Override
2216        public void visitTypeApply(JCTypeApply tree) {
2217            scan(tree.clazz);
2218        }
2219
2220        @Override
2221        public void visitTypeArray(JCArrayTypeTree tree) {
2222            scan(tree.elemtype);
2223        }
2224
2225        @Override
2226        public void visitClassDef(JCClassDecl tree) {
2227            List<JCTree> supertypes = List.nil();
2228            if (tree.getExtendsClause() != null) {
2229                supertypes = supertypes.prepend(tree.getExtendsClause());
2230            }
2231            if (tree.getImplementsClause() != null) {
2232                for (JCTree intf : tree.getImplementsClause()) {
2233                    supertypes = supertypes.prepend(intf);
2234                }
2235            }
2236            checkClass(tree.pos(), tree.sym, supertypes);
2237        }
2238
2239        void checkClass(DiagnosticPosition pos, Symbol c, List<JCTree> supertypes) {
2240            if ((c.flags_field & ACYCLIC) != 0)
2241                return;
2242            if (seenClasses.contains(c)) {
2243                errorFound = true;
2244                noteCyclic(pos, (ClassSymbol)c);
2245            } else if (!c.type.isErroneous()) {
2246                try {
2247                    seenClasses = seenClasses.prepend(c);
2248                    if (c.type.hasTag(CLASS)) {
2249                        if (supertypes.nonEmpty()) {
2250                            scan(supertypes);
2251                        }
2252                        else {
2253                            ClassType ct = (ClassType)c.type;
2254                            if (ct.supertype_field == null ||
2255                                    ct.interfaces_field == null) {
2256                                //not completed yet
2257                                partialCheck = true;
2258                                return;
2259                            }
2260                            checkSymbol(pos, ct.supertype_field.tsym);
2261                            for (Type intf : ct.interfaces_field) {
2262                                checkSymbol(pos, intf.tsym);
2263                            }
2264                        }
2265                        if (c.owner.kind == TYP) {
2266                            checkSymbol(pos, c.owner);
2267                        }
2268                    }
2269                } finally {
2270                    seenClasses = seenClasses.tail;
2271                }
2272            }
2273        }
2274    }
2275
2276    /** Check for cyclic references. Issue an error if the
2277     *  symbol of the type referred to has a LOCKED flag set.
2278     *
2279     *  @param pos      Position to be used for error reporting.
2280     *  @param t        The type referred to.
2281     */
2282    void checkNonCyclic(DiagnosticPosition pos, Type t) {
2283        checkNonCyclicInternal(pos, t);
2284    }
2285
2286
2287    void checkNonCyclic(DiagnosticPosition pos, TypeVar t) {
2288        checkNonCyclic1(pos, t, List.nil());
2289    }
2290
2291    private void checkNonCyclic1(DiagnosticPosition pos, Type t, List<TypeVar> seen) {
2292        final TypeVar tv;
2293        if  (t.hasTag(TYPEVAR) && (t.tsym.flags() & UNATTRIBUTED) != 0)
2294            return;
2295        if (seen.contains(t)) {
2296            tv = (TypeVar)t;
2297            tv.bound = types.createErrorType(t);
2298            log.error(pos, Errors.CyclicInheritance(t));
2299        } else if (t.hasTag(TYPEVAR)) {
2300            tv = (TypeVar)t;
2301            seen = seen.prepend(tv);
2302            for (Type b : types.getBounds(tv))
2303                checkNonCyclic1(pos, b, seen);
2304        }
2305    }
2306
2307    /** Check for cyclic references. Issue an error if the
2308     *  symbol of the type referred to has a LOCKED flag set.
2309     *
2310     *  @param pos      Position to be used for error reporting.
2311     *  @param t        The type referred to.
2312     *  @returns        True if the check completed on all attributed classes
2313     */
2314    private boolean checkNonCyclicInternal(DiagnosticPosition pos, Type t) {
2315        boolean complete = true; // was the check complete?
2316        //- System.err.println("checkNonCyclicInternal("+t+");");//DEBUG
2317        Symbol c = t.tsym;
2318        if ((c.flags_field & ACYCLIC) != 0) return true;
2319
2320        if ((c.flags_field & LOCKED) != 0) {
2321            noteCyclic(pos, (ClassSymbol)c);
2322        } else if (!c.type.isErroneous()) {
2323            try {
2324                c.flags_field |= LOCKED;
2325                if (c.type.hasTag(CLASS)) {
2326                    ClassType clazz = (ClassType)c.type;
2327                    if (clazz.interfaces_field != null)
2328                        for (List<Type> l=clazz.interfaces_field; l.nonEmpty(); l=l.tail)
2329                            complete &= checkNonCyclicInternal(pos, l.head);
2330                    if (clazz.supertype_field != null) {
2331                        Type st = clazz.supertype_field;
2332                        if (st != null && st.hasTag(CLASS))
2333                            complete &= checkNonCyclicInternal(pos, st);
2334                    }
2335                    if (c.owner.kind == TYP)
2336                        complete &= checkNonCyclicInternal(pos, c.owner.type);
2337                }
2338            } finally {
2339                c.flags_field &= ~LOCKED;
2340            }
2341        }
2342        if (complete)
2343            complete = ((c.flags_field & UNATTRIBUTED) == 0) && c.isCompleted();
2344        if (complete) c.flags_field |= ACYCLIC;
2345        return complete;
2346    }
2347
2348    /** Note that we found an inheritance cycle. */
2349    private void noteCyclic(DiagnosticPosition pos, ClassSymbol c) {
2350        log.error(pos, Errors.CyclicInheritance(c));
2351        for (List<Type> l=types.interfaces(c.type); l.nonEmpty(); l=l.tail)
2352            l.head = types.createErrorType((ClassSymbol)l.head.tsym, Type.noType);
2353        Type st = types.supertype(c.type);
2354        if (st.hasTag(CLASS))
2355            ((ClassType)c.type).supertype_field = types.createErrorType((ClassSymbol)st.tsym, Type.noType);
2356        c.type = types.createErrorType(c, c.type);
2357        c.flags_field |= ACYCLIC;
2358    }
2359
2360    /** Check that all methods which implement some
2361     *  method conform to the method they implement.
2362     *  @param tree         The class definition whose members are checked.
2363     */
2364    void checkImplementations(JCClassDecl tree) {
2365        checkImplementations(tree, tree.sym, tree.sym);
2366    }
2367    //where
2368        /** Check that all methods which implement some
2369         *  method in `ic' conform to the method they implement.
2370         */
2371        void checkImplementations(JCTree tree, ClassSymbol origin, ClassSymbol ic) {
2372            for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) {
2373                ClassSymbol lc = (ClassSymbol)l.head.tsym;
2374                if ((lc.flags() & ABSTRACT) != 0) {
2375                    for (Symbol sym : lc.members().getSymbols(NON_RECURSIVE)) {
2376                        if (sym.kind == MTH &&
2377                            (sym.flags() & (STATIC|ABSTRACT)) == ABSTRACT) {
2378                            MethodSymbol absmeth = (MethodSymbol)sym;
2379                            MethodSymbol implmeth = absmeth.implementation(origin, types, false);
2380                            if (implmeth != null && implmeth != absmeth &&
2381                                (implmeth.owner.flags() & INTERFACE) ==
2382                                (origin.flags() & INTERFACE)) {
2383                                // don't check if implmeth is in a class, yet
2384                                // origin is an interface. This case arises only
2385                                // if implmeth is declared in Object. The reason is
2386                                // that interfaces really don't inherit from
2387                                // Object it's just that the compiler represents
2388                                // things that way.
2389                                checkOverride(tree, implmeth, absmeth, origin);
2390                            }
2391                        }
2392                    }
2393                }
2394            }
2395        }
2396
2397    /** Check that all abstract methods implemented by a class are
2398     *  mutually compatible.
2399     *  @param pos          Position to be used for error reporting.
2400     *  @param c            The class whose interfaces are checked.
2401     */
2402    void checkCompatibleSupertypes(DiagnosticPosition pos, Type c) {
2403        List<Type> supertypes = types.interfaces(c);
2404        Type supertype = types.supertype(c);
2405        if (supertype.hasTag(CLASS) &&
2406            (supertype.tsym.flags() & ABSTRACT) != 0)
2407            supertypes = supertypes.prepend(supertype);
2408        for (List<Type> l = supertypes; l.nonEmpty(); l = l.tail) {
2409            if (!l.head.getTypeArguments().isEmpty() &&
2410                !checkCompatibleAbstracts(pos, l.head, l.head, c))
2411                return;
2412            for (List<Type> m = supertypes; m != l; m = m.tail)
2413                if (!checkCompatibleAbstracts(pos, l.head, m.head, c))
2414                    return;
2415        }
2416        checkCompatibleConcretes(pos, c);
2417    }
2418
2419    void checkConflicts(DiagnosticPosition pos, Symbol sym, TypeSymbol c) {
2420        for (Type ct = c.type; ct != Type.noType ; ct = types.supertype(ct)) {
2421            for (Symbol sym2 : ct.tsym.members().getSymbolsByName(sym.name, NON_RECURSIVE)) {
2422                // VM allows methods and variables with differing types
2423                if (sym.kind == sym2.kind &&
2424                    types.isSameType(types.erasure(sym.type), types.erasure(sym2.type)) &&
2425                    sym != sym2 &&
2426                    (sym.flags() & Flags.SYNTHETIC) != (sym2.flags() & Flags.SYNTHETIC) &&
2427                    (sym.flags() & BRIDGE) == 0 && (sym2.flags() & BRIDGE) == 0) {
2428                    syntheticError(pos, (sym2.flags() & SYNTHETIC) == 0 ? sym2 : sym);
2429                    return;
2430                }
2431            }
2432        }
2433    }
2434
2435    /** Check that all non-override equivalent methods accessible from 'site'
2436     *  are mutually compatible (JLS 8.4.8/9.4.1).
2437     *
2438     *  @param pos  Position to be used for error reporting.
2439     *  @param site The class whose methods are checked.
2440     *  @param sym  The method symbol to be checked.
2441     */
2442    void checkOverrideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
2443         ClashFilter cf = new ClashFilter(site);
2444        //for each method m1 that is overridden (directly or indirectly)
2445        //by method 'sym' in 'site'...
2446
2447        List<MethodSymbol> potentiallyAmbiguousList = List.nil();
2448        boolean overridesAny = false;
2449        for (Symbol m1 : types.membersClosure(site, false).getSymbolsByName(sym.name, cf)) {
2450            if (!sym.overrides(m1, site.tsym, types, false)) {
2451                if (m1 == sym) {
2452                    continue;
2453                }
2454
2455                if (!overridesAny) {
2456                    potentiallyAmbiguousList = potentiallyAmbiguousList.prepend((MethodSymbol)m1);
2457                }
2458                continue;
2459            }
2460
2461            if (m1 != sym) {
2462                overridesAny = true;
2463                potentiallyAmbiguousList = List.nil();
2464            }
2465
2466            //...check each method m2 that is a member of 'site'
2467            for (Symbol m2 : types.membersClosure(site, false).getSymbolsByName(sym.name, cf)) {
2468                if (m2 == m1) continue;
2469                //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
2470                //a member of 'site') and (ii) m1 has the same erasure as m2, issue an error
2471                if (!types.isSubSignature(sym.type, types.memberType(site, m2), allowStrictMethodClashCheck) &&
2472                        types.hasSameArgs(m2.erasure(types), m1.erasure(types))) {
2473                    sym.flags_field |= CLASH;
2474                    if (m1 == sym) {
2475                        log.error(pos, Errors.NameClashSameErasureNoOverride(
2476                            m1.name, types.memberType(site, m1).asMethodType().getParameterTypes(), m1.location(),
2477                            m2.name, types.memberType(site, m2).asMethodType().getParameterTypes(), m2.location()));
2478                    } else {
2479                        ClassType ct = (ClassType)site;
2480                        String kind = ct.isInterface() ? "interface" : "class";
2481                        log.error(pos, Errors.NameClashSameErasureNoOverride1(
2482                            kind,
2483                            ct.tsym.name,
2484                            m1.name,
2485                            types.memberType(site, m1).asMethodType().getParameterTypes(),
2486                            m1.location(),
2487                            m2.name,
2488                            types.memberType(site, m2).asMethodType().getParameterTypes(),
2489                            m2.location()));
2490                    }
2491                    return;
2492                }
2493            }
2494        }
2495
2496        if (!overridesAny) {
2497            for (MethodSymbol m: potentiallyAmbiguousList) {
2498                checkPotentiallyAmbiguousOverloads(pos, site, sym, m);
2499            }
2500        }
2501    }
2502
2503    /** Check that all static methods accessible from 'site' are
2504     *  mutually compatible (JLS 8.4.8).
2505     *
2506     *  @param pos  Position to be used for error reporting.
2507     *  @param site The class whose methods are checked.
2508     *  @param sym  The method symbol to be checked.
2509     */
2510    void checkHideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
2511        ClashFilter cf = new ClashFilter(site);
2512        //for each method m1 that is a member of 'site'...
2513        for (Symbol s : types.membersClosure(site, true).getSymbolsByName(sym.name, cf)) {
2514            //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
2515            //a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error
2516            if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck)) {
2517                if (types.hasSameArgs(s.erasure(types), sym.erasure(types))) {
2518                    log.error(pos,
2519                              Errors.NameClashSameErasureNoHide(sym, sym.location(), s, s.location()));
2520                    return;
2521                } else {
2522                    checkPotentiallyAmbiguousOverloads(pos, site, sym, (MethodSymbol)s);
2523                }
2524            }
2525         }
2526     }
2527
2528     //where
2529     private class ClashFilter implements Filter<Symbol> {
2530
2531         Type site;
2532
2533         ClashFilter(Type site) {
2534             this.site = site;
2535         }
2536
2537         boolean shouldSkip(Symbol s) {
2538             return (s.flags() & CLASH) != 0 &&
2539                s.owner == site.tsym;
2540         }
2541
2542         public boolean accepts(Symbol s) {
2543             return s.kind == MTH &&
2544                     (s.flags() & SYNTHETIC) == 0 &&
2545                     !shouldSkip(s) &&
2546                     s.isInheritedIn(site.tsym, types) &&
2547                     !s.isConstructor();
2548         }
2549     }
2550
2551    void checkDefaultMethodClashes(DiagnosticPosition pos, Type site) {
2552        DefaultMethodClashFilter dcf = new DefaultMethodClashFilter(site);
2553        for (Symbol m : types.membersClosure(site, false).getSymbols(dcf)) {
2554            Assert.check(m.kind == MTH);
2555            List<MethodSymbol> prov = types.interfaceCandidates(site, (MethodSymbol)m);
2556            if (prov.size() > 1) {
2557                ListBuffer<Symbol> abstracts = new ListBuffer<>();
2558                ListBuffer<Symbol> defaults = new ListBuffer<>();
2559                for (MethodSymbol provSym : prov) {
2560                    if ((provSym.flags() & DEFAULT) != 0) {
2561                        defaults = defaults.append(provSym);
2562                    } else if ((provSym.flags() & ABSTRACT) != 0) {
2563                        abstracts = abstracts.append(provSym);
2564                    }
2565                    if (defaults.nonEmpty() && defaults.size() + abstracts.size() >= 2) {
2566                        //strong semantics - issue an error if two sibling interfaces
2567                        //have two override-equivalent defaults - or if one is abstract
2568                        //and the other is default
2569                        String errKey;
2570                        Symbol s1 = defaults.first();
2571                        Symbol s2;
2572                        if (defaults.size() > 1) {
2573                            errKey = "types.incompatible.unrelated.defaults";
2574                            s2 = defaults.toList().tail.head;
2575                        } else {
2576                            errKey = "types.incompatible.abstract.default";
2577                            s2 = abstracts.first();
2578                        }
2579                        log.error(pos, errKey,
2580                                Kinds.kindName(site.tsym), site,
2581                                m.name, types.memberType(site, m).getParameterTypes(),
2582                                s1.location(), s2.location());
2583                        break;
2584                    }
2585                }
2586            }
2587        }
2588    }
2589
2590    //where
2591     private class DefaultMethodClashFilter implements Filter<Symbol> {
2592
2593         Type site;
2594
2595         DefaultMethodClashFilter(Type site) {
2596             this.site = site;
2597         }
2598
2599         public boolean accepts(Symbol s) {
2600             return s.kind == MTH &&
2601                     (s.flags() & DEFAULT) != 0 &&
2602                     s.isInheritedIn(site.tsym, types) &&
2603                     !s.isConstructor();
2604         }
2605     }
2606
2607    /**
2608      * Report warnings for potentially ambiguous method declarations. Two declarations
2609      * are potentially ambiguous if they feature two unrelated functional interface
2610      * in same argument position (in which case, a call site passing an implicit
2611      * lambda would be ambiguous).
2612      */
2613    void checkPotentiallyAmbiguousOverloads(DiagnosticPosition pos, Type site,
2614            MethodSymbol msym1, MethodSymbol msym2) {
2615        if (msym1 != msym2 &&
2616                allowDefaultMethods &&
2617                lint.isEnabled(LintCategory.OVERLOADS) &&
2618                (msym1.flags() & POTENTIALLY_AMBIGUOUS) == 0 &&
2619                (msym2.flags() & POTENTIALLY_AMBIGUOUS) == 0) {
2620            Type mt1 = types.memberType(site, msym1);
2621            Type mt2 = types.memberType(site, msym2);
2622            //if both generic methods, adjust type variables
2623            if (mt1.hasTag(FORALL) && mt2.hasTag(FORALL) &&
2624                    types.hasSameBounds((ForAll)mt1, (ForAll)mt2)) {
2625                mt2 = types.subst(mt2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars);
2626            }
2627            //expand varargs methods if needed
2628            int maxLength = Math.max(mt1.getParameterTypes().length(), mt2.getParameterTypes().length());
2629            List<Type> args1 = rs.adjustArgs(mt1.getParameterTypes(), msym1, maxLength, true);
2630            List<Type> args2 = rs.adjustArgs(mt2.getParameterTypes(), msym2, maxLength, true);
2631            //if arities don't match, exit
2632            if (args1.length() != args2.length()) return;
2633            boolean potentiallyAmbiguous = false;
2634            while (args1.nonEmpty() && args2.nonEmpty()) {
2635                Type s = args1.head;
2636                Type t = args2.head;
2637                if (!types.isSubtype(t, s) && !types.isSubtype(s, t)) {
2638                    if (types.isFunctionalInterface(s) && types.isFunctionalInterface(t) &&
2639                            types.findDescriptorType(s).getParameterTypes().length() > 0 &&
2640                            types.findDescriptorType(s).getParameterTypes().length() ==
2641                            types.findDescriptorType(t).getParameterTypes().length()) {
2642                        potentiallyAmbiguous = true;
2643                    } else {
2644                        break;
2645                    }
2646                }
2647                args1 = args1.tail;
2648                args2 = args2.tail;
2649            }
2650            if (potentiallyAmbiguous) {
2651                //we found two incompatible functional interfaces with same arity
2652                //this means a call site passing an implicit lambda would be ambigiuous
2653                msym1.flags_field |= POTENTIALLY_AMBIGUOUS;
2654                msym2.flags_field |= POTENTIALLY_AMBIGUOUS;
2655                log.warning(LintCategory.OVERLOADS, pos,
2656                            Warnings.PotentiallyAmbiguousOverload(msym1, msym1.location(),
2657                                                                  msym2, msym2.location()));
2658                return;
2659            }
2660        }
2661    }
2662
2663    void checkAccessFromSerializableElement(final JCTree tree, boolean isLambda) {
2664        if (warnOnAnyAccessToMembers ||
2665            (lint.isEnabled(LintCategory.SERIAL) &&
2666            !lint.isSuppressed(LintCategory.SERIAL) &&
2667            isLambda)) {
2668            Symbol sym = TreeInfo.symbol(tree);
2669            if (!sym.kind.matches(KindSelector.VAL_MTH)) {
2670                return;
2671            }
2672
2673            if (sym.kind == VAR) {
2674                if ((sym.flags() & PARAMETER) != 0 ||
2675                    sym.isLocal() ||
2676                    sym.name == names._this ||
2677                    sym.name == names._super) {
2678                    return;
2679                }
2680            }
2681
2682            if (!types.isSubtype(sym.owner.type, syms.serializableType) &&
2683                isEffectivelyNonPublic(sym)) {
2684                if (isLambda) {
2685                    if (belongsToRestrictedPackage(sym)) {
2686                        log.warning(LintCategory.SERIAL, tree.pos(),
2687                                    Warnings.AccessToMemberFromSerializableLambda(sym));
2688                    }
2689                } else {
2690                    log.warning(tree.pos(),
2691                                Warnings.AccessToMemberFromSerializableElement(sym));
2692                }
2693            }
2694        }
2695    }
2696
2697    private boolean isEffectivelyNonPublic(Symbol sym) {
2698        if (sym.packge() == syms.rootPackage) {
2699            return false;
2700        }
2701
2702        while (sym.kind != PCK) {
2703            if ((sym.flags() & PUBLIC) == 0) {
2704                return true;
2705            }
2706            sym = sym.owner;
2707        }
2708        return false;
2709    }
2710
2711    private boolean belongsToRestrictedPackage(Symbol sym) {
2712        String fullName = sym.packge().fullname.toString();
2713        return fullName.startsWith("java.") ||
2714                fullName.startsWith("javax.") ||
2715                fullName.startsWith("sun.") ||
2716                fullName.contains(".internal.");
2717    }
2718
2719    /** Report a conflict between a user symbol and a synthetic symbol.
2720     */
2721    private void syntheticError(DiagnosticPosition pos, Symbol sym) {
2722        if (!sym.type.isErroneous()) {
2723            log.error(pos, Errors.SyntheticNameConflict(sym, sym.location()));
2724        }
2725    }
2726
2727    /** Check that class c does not implement directly or indirectly
2728     *  the same parameterized interface with two different argument lists.
2729     *  @param pos          Position to be used for error reporting.
2730     *  @param type         The type whose interfaces are checked.
2731     */
2732    void checkClassBounds(DiagnosticPosition pos, Type type) {
2733        checkClassBounds(pos, new HashMap<TypeSymbol,Type>(), type);
2734    }
2735//where
2736        /** Enter all interfaces of type `type' into the hash table `seensofar'
2737         *  with their class symbol as key and their type as value. Make
2738         *  sure no class is entered with two different types.
2739         */
2740        void checkClassBounds(DiagnosticPosition pos,
2741                              Map<TypeSymbol,Type> seensofar,
2742                              Type type) {
2743            if (type.isErroneous()) return;
2744            for (List<Type> l = types.interfaces(type); l.nonEmpty(); l = l.tail) {
2745                Type it = l.head;
2746                Type oldit = seensofar.put(it.tsym, it);
2747                if (oldit != null) {
2748                    List<Type> oldparams = oldit.allparams();
2749                    List<Type> newparams = it.allparams();
2750                    if (!types.containsTypeEquivalent(oldparams, newparams))
2751                        log.error(pos,
2752                                  Errors.CantInheritDiffArg(it.tsym,
2753                                                            Type.toString(oldparams),
2754                                                            Type.toString(newparams)));
2755                }
2756                checkClassBounds(pos, seensofar, it);
2757            }
2758            Type st = types.supertype(type);
2759            if (st != Type.noType) checkClassBounds(pos, seensofar, st);
2760        }
2761
2762    /** Enter interface into into set.
2763     *  If it existed already, issue a "repeated interface" error.
2764     */
2765    void checkNotRepeated(DiagnosticPosition pos, Type it, Set<Type> its) {
2766        if (its.contains(it))
2767            log.error(pos, Errors.RepeatedInterface);
2768        else {
2769            its.add(it);
2770        }
2771    }
2772
2773/* *************************************************************************
2774 * Check annotations
2775 **************************************************************************/
2776
2777    /**
2778     * Recursively validate annotations values
2779     */
2780    void validateAnnotationTree(JCTree tree) {
2781        class AnnotationValidator extends TreeScanner {
2782            @Override
2783            public void visitAnnotation(JCAnnotation tree) {
2784                if (!tree.type.isErroneous()) {
2785                    super.visitAnnotation(tree);
2786                    validateAnnotation(tree);
2787                }
2788            }
2789        }
2790        tree.accept(new AnnotationValidator());
2791    }
2792
2793    /**
2794     *  {@literal
2795     *  Annotation types are restricted to primitives, String, an
2796     *  enum, an annotation, Class, Class<?>, Class<? extends
2797     *  Anything>, arrays of the preceding.
2798     *  }
2799     */
2800    void validateAnnotationType(JCTree restype) {
2801        // restype may be null if an error occurred, so don't bother validating it
2802        if (restype != null) {
2803            validateAnnotationType(restype.pos(), restype.type);
2804        }
2805    }
2806
2807    void validateAnnotationType(DiagnosticPosition pos, Type type) {
2808        if (type.isPrimitive()) return;
2809        if (types.isSameType(type, syms.stringType)) return;
2810        if ((type.tsym.flags() & Flags.ENUM) != 0) return;
2811        if ((type.tsym.flags() & Flags.ANNOTATION) != 0) return;
2812        if (types.cvarLowerBound(type).tsym == syms.classType.tsym) return;
2813        if (types.isArray(type) && !types.isArray(types.elemtype(type))) {
2814            validateAnnotationType(pos, types.elemtype(type));
2815            return;
2816        }
2817        log.error(pos, Errors.InvalidAnnotationMemberType);
2818    }
2819
2820    /**
2821     * "It is also a compile-time error if any method declared in an
2822     * annotation type has a signature that is override-equivalent to
2823     * that of any public or protected method declared in class Object
2824     * or in the interface annotation.Annotation."
2825     *
2826     * @jls 9.6 Annotation Types
2827     */
2828    void validateAnnotationMethod(DiagnosticPosition pos, MethodSymbol m) {
2829        for (Type sup = syms.annotationType; sup.hasTag(CLASS); sup = types.supertype(sup)) {
2830            Scope s = sup.tsym.members();
2831            for (Symbol sym : s.getSymbolsByName(m.name)) {
2832                if (sym.kind == MTH &&
2833                    (sym.flags() & (PUBLIC | PROTECTED)) != 0 &&
2834                    types.overrideEquivalent(m.type, sym.type))
2835                    log.error(pos, Errors.IntfAnnotationMemberClash(sym, sup));
2836            }
2837        }
2838    }
2839
2840    /** Check the annotations of a symbol.
2841     */
2842    public void validateAnnotations(List<JCAnnotation> annotations, Symbol s) {
2843        for (JCAnnotation a : annotations)
2844            validateAnnotation(a, s);
2845    }
2846
2847    /** Check the type annotations.
2848     */
2849    public void validateTypeAnnotations(List<JCAnnotation> annotations, boolean isTypeParameter) {
2850        for (JCAnnotation a : annotations)
2851            validateTypeAnnotation(a, isTypeParameter);
2852    }
2853
2854    /** Check an annotation of a symbol.
2855     */
2856    private void validateAnnotation(JCAnnotation a, Symbol s) {
2857        validateAnnotationTree(a);
2858
2859        if (a.type.tsym.isAnnotationType() && !annotationApplicable(a, s))
2860            log.error(a.pos(), Errors.AnnotationTypeNotApplicable);
2861
2862        if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) {
2863            if (s.kind != TYP) {
2864                log.error(a.pos(), Errors.BadFunctionalIntfAnno);
2865            } else if (!s.isInterface() || (s.flags() & ANNOTATION) != 0) {
2866                log.error(a.pos(), Errors.BadFunctionalIntfAnno1(Fragments.NotAFunctionalIntf(s)));
2867            }
2868        }
2869    }
2870
2871    public void validateTypeAnnotation(JCAnnotation a, boolean isTypeParameter) {
2872        Assert.checkNonNull(a.type);
2873        validateAnnotationTree(a);
2874
2875        if (a.hasTag(TYPE_ANNOTATION) &&
2876                !a.annotationType.type.isErroneous() &&
2877                !isTypeAnnotation(a, isTypeParameter)) {
2878            log.error(a.pos(), Errors.AnnotationTypeNotApplicableToType(a.type));
2879        }
2880    }
2881
2882    /**
2883     * Validate the proposed container 'repeatable' on the
2884     * annotation type symbol 's'. Report errors at position
2885     * 'pos'.
2886     *
2887     * @param s The (annotation)type declaration annotated with a @Repeatable
2888     * @param repeatable the @Repeatable on 's'
2889     * @param pos where to report errors
2890     */
2891    public void validateRepeatable(TypeSymbol s, Attribute.Compound repeatable, DiagnosticPosition pos) {
2892        Assert.check(types.isSameType(repeatable.type, syms.repeatableType));
2893
2894        Type t = null;
2895        List<Pair<MethodSymbol,Attribute>> l = repeatable.values;
2896        if (!l.isEmpty()) {
2897            Assert.check(l.head.fst.name == names.value);
2898            t = ((Attribute.Class)l.head.snd).getValue();
2899        }
2900
2901        if (t == null) {
2902            // errors should already have been reported during Annotate
2903            return;
2904        }
2905
2906        validateValue(t.tsym, s, pos);
2907        validateRetention(t.tsym, s, pos);
2908        validateDocumented(t.tsym, s, pos);
2909        validateInherited(t.tsym, s, pos);
2910        validateTarget(t.tsym, s, pos);
2911        validateDefault(t.tsym, pos);
2912    }
2913
2914    private void validateValue(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
2915        Symbol sym = container.members().findFirst(names.value);
2916        if (sym != null && sym.kind == MTH) {
2917            MethodSymbol m = (MethodSymbol) sym;
2918            Type ret = m.getReturnType();
2919            if (!(ret.hasTag(ARRAY) && types.isSameType(((ArrayType)ret).elemtype, contained.type))) {
2920                log.error(pos,
2921                          Errors.InvalidRepeatableAnnotationValueReturn(container,
2922                                                                        ret,
2923                                                                        types.makeArrayType(contained.type)));
2924            }
2925        } else {
2926            log.error(pos, Errors.InvalidRepeatableAnnotationNoValue(container));
2927        }
2928    }
2929
2930    private void validateRetention(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
2931        Attribute.RetentionPolicy containerRetention = types.getRetention(container);
2932        Attribute.RetentionPolicy containedRetention = types.getRetention(contained);
2933
2934        boolean error = false;
2935        switch (containedRetention) {
2936        case RUNTIME:
2937            if (containerRetention != Attribute.RetentionPolicy.RUNTIME) {
2938                error = true;
2939            }
2940            break;
2941        case CLASS:
2942            if (containerRetention == Attribute.RetentionPolicy.SOURCE)  {
2943                error = true;
2944            }
2945        }
2946        if (error ) {
2947            log.error(pos,
2948                      Errors.InvalidRepeatableAnnotationRetention(container,
2949                                                                  containerRetention.name(),
2950                                                                  contained,
2951                                                                  containedRetention.name()));
2952        }
2953    }
2954
2955    private void validateDocumented(Symbol container, Symbol contained, DiagnosticPosition pos) {
2956        if (contained.attribute(syms.documentedType.tsym) != null) {
2957            if (container.attribute(syms.documentedType.tsym) == null) {
2958                log.error(pos, Errors.InvalidRepeatableAnnotationNotDocumented(container, contained));
2959            }
2960        }
2961    }
2962
2963    private void validateInherited(Symbol container, Symbol contained, DiagnosticPosition pos) {
2964        if (contained.attribute(syms.inheritedType.tsym) != null) {
2965            if (container.attribute(syms.inheritedType.tsym) == null) {
2966                log.error(pos, Errors.InvalidRepeatableAnnotationNotInherited(container, contained));
2967            }
2968        }
2969    }
2970
2971    private void validateTarget(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
2972        // The set of targets the container is applicable to must be a subset
2973        // (with respect to annotation target semantics) of the set of targets
2974        // the contained is applicable to. The target sets may be implicit or
2975        // explicit.
2976
2977        Set<Name> containerTargets;
2978        Attribute.Array containerTarget = getAttributeTargetAttribute(container);
2979        if (containerTarget == null) {
2980            containerTargets = getDefaultTargetSet();
2981        } else {
2982            containerTargets = new HashSet<>();
2983            for (Attribute app : containerTarget.values) {
2984                if (!(app instanceof Attribute.Enum)) {
2985                    continue; // recovery
2986                }
2987                Attribute.Enum e = (Attribute.Enum)app;
2988                containerTargets.add(e.value.name);
2989            }
2990        }
2991
2992        Set<Name> containedTargets;
2993        Attribute.Array containedTarget = getAttributeTargetAttribute(contained);
2994        if (containedTarget == null) {
2995            containedTargets = getDefaultTargetSet();
2996        } else {
2997            containedTargets = new HashSet<>();
2998            for (Attribute app : containedTarget.values) {
2999                if (!(app instanceof Attribute.Enum)) {
3000                    continue; // recovery
3001                }
3002                Attribute.Enum e = (Attribute.Enum)app;
3003                containedTargets.add(e.value.name);
3004            }
3005        }
3006
3007        if (!isTargetSubsetOf(containerTargets, containedTargets)) {
3008            log.error(pos, Errors.InvalidRepeatableAnnotationIncompatibleTarget(container, contained));
3009        }
3010    }
3011
3012    /* get a set of names for the default target */
3013    private Set<Name> getDefaultTargetSet() {
3014        if (defaultTargets == null) {
3015            Set<Name> targets = new HashSet<>();
3016            targets.add(names.ANNOTATION_TYPE);
3017            targets.add(names.CONSTRUCTOR);
3018            targets.add(names.FIELD);
3019            targets.add(names.LOCAL_VARIABLE);
3020            targets.add(names.METHOD);
3021            targets.add(names.PACKAGE);
3022            targets.add(names.PARAMETER);
3023            targets.add(names.TYPE);
3024
3025            defaultTargets = java.util.Collections.unmodifiableSet(targets);
3026        }
3027
3028        return defaultTargets;
3029    }
3030    private Set<Name> defaultTargets;
3031
3032
3033    /** Checks that s is a subset of t, with respect to ElementType
3034     * semantics, specifically {ANNOTATION_TYPE} is a subset of {TYPE},
3035     * and {TYPE_USE} covers the set {ANNOTATION_TYPE, TYPE, TYPE_USE,
3036     * TYPE_PARAMETER}.
3037     */
3038    private boolean isTargetSubsetOf(Set<Name> s, Set<Name> t) {
3039        // Check that all elements in s are present in t
3040        for (Name n2 : s) {
3041            boolean currentElementOk = false;
3042            for (Name n1 : t) {
3043                if (n1 == n2) {
3044                    currentElementOk = true;
3045                    break;
3046                } else if (n1 == names.TYPE && n2 == names.ANNOTATION_TYPE) {
3047                    currentElementOk = true;
3048                    break;
3049                } else if (n1 == names.TYPE_USE &&
3050                        (n2 == names.TYPE ||
3051                         n2 == names.ANNOTATION_TYPE ||
3052                         n2 == names.TYPE_PARAMETER)) {
3053                    currentElementOk = true;
3054                    break;
3055                }
3056            }
3057            if (!currentElementOk)
3058                return false;
3059        }
3060        return true;
3061    }
3062
3063    private void validateDefault(Symbol container, DiagnosticPosition pos) {
3064        // validate that all other elements of containing type has defaults
3065        Scope scope = container.members();
3066        for(Symbol elm : scope.getSymbols()) {
3067            if (elm.name != names.value &&
3068                elm.kind == MTH &&
3069                ((MethodSymbol)elm).defaultValue == null) {
3070                log.error(pos,
3071                          Errors.InvalidRepeatableAnnotationElemNondefault(container, elm));
3072            }
3073        }
3074    }
3075
3076    /** Is s a method symbol that overrides a method in a superclass? */
3077    boolean isOverrider(Symbol s) {
3078        if (s.kind != MTH || s.isStatic())
3079            return false;
3080        MethodSymbol m = (MethodSymbol)s;
3081        TypeSymbol owner = (TypeSymbol)m.owner;
3082        for (Type sup : types.closure(owner.type)) {
3083            if (sup == owner.type)
3084                continue; // skip "this"
3085            Scope scope = sup.tsym.members();
3086            for (Symbol sym : scope.getSymbolsByName(m.name)) {
3087                if (!sym.isStatic() && m.overrides(sym, owner, types, true))
3088                    return true;
3089            }
3090        }
3091        return false;
3092    }
3093
3094    /** Is the annotation applicable to types? */
3095    protected boolean isTypeAnnotation(JCAnnotation a, boolean isTypeParameter) {
3096        List<Attribute> targets = typeAnnotations.annotationTargets(a.annotationType.type.tsym);
3097        return (targets == null) ?
3098                false :
3099                targets.stream()
3100                        .anyMatch(attr -> isTypeAnnotation(attr, isTypeParameter));
3101    }
3102    //where
3103        boolean isTypeAnnotation(Attribute a, boolean isTypeParameter) {
3104            Attribute.Enum e = (Attribute.Enum)a;
3105            return (e.value.name == names.TYPE_USE ||
3106                    (isTypeParameter && e.value.name == names.TYPE_PARAMETER));
3107        }
3108
3109    /** Is the annotation applicable to the symbol? */
3110    boolean annotationApplicable(JCAnnotation a, Symbol s) {
3111        Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym);
3112        Name[] targets;
3113
3114        if (arr == null) {
3115            targets = defaultTargetMetaInfo(a, s);
3116        } else {
3117            // TODO: can we optimize this?
3118            targets = new Name[arr.values.length];
3119            for (int i=0; i<arr.values.length; ++i) {
3120                Attribute app = arr.values[i];
3121                if (!(app instanceof Attribute.Enum)) {
3122                    return true; // recovery
3123                }
3124                Attribute.Enum e = (Attribute.Enum) app;
3125                targets[i] = e.value.name;
3126            }
3127        }
3128        for (Name target : targets) {
3129            if (target == names.TYPE) {
3130                if (s.kind == TYP)
3131                    return true;
3132            } else if (target == names.FIELD) {
3133                if (s.kind == VAR && s.owner.kind != MTH)
3134                    return true;
3135            } else if (target == names.METHOD) {
3136                if (s.kind == MTH && !s.isConstructor())
3137                    return true;
3138            } else if (target == names.PARAMETER) {
3139                if (s.kind == VAR && s.owner.kind == MTH &&
3140                      (s.flags() & PARAMETER) != 0) {
3141                    return true;
3142                }
3143            } else if (target == names.CONSTRUCTOR) {
3144                if (s.kind == MTH && s.isConstructor())
3145                    return true;
3146            } else if (target == names.LOCAL_VARIABLE) {
3147                if (s.kind == VAR && s.owner.kind == MTH &&
3148                      (s.flags() & PARAMETER) == 0) {
3149                    return true;
3150                }
3151            } else if (target == names.ANNOTATION_TYPE) {
3152                if (s.kind == TYP && (s.flags() & ANNOTATION) != 0) {
3153                    return true;
3154                }
3155            } else if (target == names.PACKAGE) {
3156                if (s.kind == PCK)
3157                    return true;
3158            } else if (target == names.TYPE_USE) {
3159                if (s.kind == TYP || s.kind == VAR ||
3160                        (s.kind == MTH && !s.isConstructor() &&
3161                                !s.type.getReturnType().hasTag(VOID)) ||
3162                        (s.kind == MTH && s.isConstructor())) {
3163                    return true;
3164                }
3165            } else if (target == names.TYPE_PARAMETER) {
3166                if (s.kind == TYP && s.type.hasTag(TYPEVAR))
3167                    return true;
3168            } else
3169                return true; // Unknown ElementType. This should be an error at declaration site,
3170                             // assume applicable.
3171        }
3172        return false;
3173    }
3174
3175
3176    Attribute.Array getAttributeTargetAttribute(TypeSymbol s) {
3177        Attribute.Compound atTarget = s.getAnnotationTypeMetadata().getTarget();
3178        if (atTarget == null) return null; // ok, is applicable
3179        Attribute atValue = atTarget.member(names.value);
3180        if (!(atValue instanceof Attribute.Array)) return null; // error recovery
3181        return (Attribute.Array) atValue;
3182    }
3183
3184    private final Name[] dfltTargetMeta;
3185    private Name[] defaultTargetMetaInfo(JCAnnotation a, Symbol s) {
3186        return dfltTargetMeta;
3187    }
3188
3189    /** Check an annotation value.
3190     *
3191     * @param a The annotation tree to check
3192     * @return true if this annotation tree is valid, otherwise false
3193     */
3194    public boolean validateAnnotationDeferErrors(JCAnnotation a) {
3195        boolean res = false;
3196        final Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
3197        try {
3198            res = validateAnnotation(a);
3199        } finally {
3200            log.popDiagnosticHandler(diagHandler);
3201        }
3202        return res;
3203    }
3204
3205    private boolean validateAnnotation(JCAnnotation a) {
3206        boolean isValid = true;
3207        AnnotationTypeMetadata metadata = a.annotationType.type.tsym.getAnnotationTypeMetadata();
3208
3209        // collect an inventory of the annotation elements
3210        Set<MethodSymbol> elements = metadata.getAnnotationElements();
3211
3212        // remove the ones that are assigned values
3213        for (JCTree arg : a.args) {
3214            if (!arg.hasTag(ASSIGN)) continue; // recovery
3215            JCAssign assign = (JCAssign)arg;
3216            Symbol m = TreeInfo.symbol(assign.lhs);
3217            if (m == null || m.type.isErroneous()) continue;
3218            if (!elements.remove(m)) {
3219                isValid = false;
3220                log.error(assign.lhs.pos(),
3221                          Errors.DuplicateAnnotationMemberValue(m.name, a.type));
3222            }
3223        }
3224
3225        // all the remaining ones better have default values
3226        List<Name> missingDefaults = List.nil();
3227        Set<MethodSymbol> membersWithDefault = metadata.getAnnotationElementsWithDefault();
3228        for (MethodSymbol m : elements) {
3229            if (m.type.isErroneous())
3230                continue;
3231
3232            if (!membersWithDefault.contains(m))
3233                missingDefaults = missingDefaults.append(m.name);
3234        }
3235        missingDefaults = missingDefaults.reverse();
3236        if (missingDefaults.nonEmpty()) {
3237            isValid = false;
3238            String key = (missingDefaults.size() > 1)
3239                    ? "annotation.missing.default.value.1"
3240                    : "annotation.missing.default.value";
3241            log.error(a.pos(), key, a.type, missingDefaults);
3242        }
3243
3244        return isValid && validateTargetAnnotationValue(a);
3245    }
3246
3247    /* Validate the special java.lang.annotation.Target annotation */
3248    boolean validateTargetAnnotationValue(JCAnnotation a) {
3249        // special case: java.lang.annotation.Target must not have
3250        // repeated values in its value member
3251        if (a.annotationType.type.tsym != syms.annotationTargetType.tsym ||
3252                a.args.tail == null)
3253            return true;
3254
3255        boolean isValid = true;
3256        if (!a.args.head.hasTag(ASSIGN)) return false; // error recovery
3257        JCAssign assign = (JCAssign) a.args.head;
3258        Symbol m = TreeInfo.symbol(assign.lhs);
3259        if (m.name != names.value) return false;
3260        JCTree rhs = assign.rhs;
3261        if (!rhs.hasTag(NEWARRAY)) return false;
3262        JCNewArray na = (JCNewArray) rhs;
3263        Set<Symbol> targets = new HashSet<>();
3264        for (JCTree elem : na.elems) {
3265            if (!targets.add(TreeInfo.symbol(elem))) {
3266                isValid = false;
3267                log.error(elem.pos(), Errors.RepeatedAnnotationTarget);
3268            }
3269        }
3270        return isValid;
3271    }
3272
3273    void checkDeprecatedAnnotation(DiagnosticPosition pos, Symbol s) {
3274        if (lint.isEnabled(LintCategory.DEP_ANN) && s.isDeprecatableViaAnnotation() &&
3275            (s.flags() & DEPRECATED) != 0 &&
3276            !syms.deprecatedType.isErroneous() &&
3277            s.attribute(syms.deprecatedType.tsym) == null) {
3278            log.warning(LintCategory.DEP_ANN,
3279                    pos, Warnings.MissingDeprecatedAnnotation);
3280        }
3281        // Note: @Deprecated has no effect on local variables, parameters and package decls.
3282        if (lint.isEnabled(LintCategory.DEPRECATION) && !s.isDeprecatableViaAnnotation()) {
3283            if (!syms.deprecatedType.isErroneous() && s.attribute(syms.deprecatedType.tsym) != null) {
3284                log.warning(LintCategory.DEPRECATION, pos,
3285                            Warnings.DeprecatedAnnotationHasNoEffect(Kinds.kindName(s)));
3286            }
3287        }
3288    }
3289
3290    void checkDeprecated(final DiagnosticPosition pos, final Symbol other, final Symbol s) {
3291        if ( (s.isDeprecatedForRemoval()
3292                || s.isDeprecated() && !other.isDeprecated())
3293                && (s.outermostClass() != other.outermostClass() || s.outermostClass() == null)) {
3294            deferredLintHandler.report(() -> warnDeprecated(pos, s));
3295        }
3296    }
3297
3298    void checkSunAPI(final DiagnosticPosition pos, final Symbol s) {
3299        if ((s.flags() & PROPRIETARY) != 0) {
3300            deferredLintHandler.report(() -> {
3301                log.mandatoryWarning(pos, Warnings.SunProprietary(s));
3302            });
3303        }
3304    }
3305
3306    void checkProfile(final DiagnosticPosition pos, final Symbol s) {
3307        if (profile != Profile.DEFAULT && (s.flags() & NOT_IN_PROFILE) != 0) {
3308            log.error(pos, Errors.NotInProfile(s, profile));
3309        }
3310    }
3311
3312/* *************************************************************************
3313 * Check for recursive annotation elements.
3314 **************************************************************************/
3315
3316    /** Check for cycles in the graph of annotation elements.
3317     */
3318    void checkNonCyclicElements(JCClassDecl tree) {
3319        if ((tree.sym.flags_field & ANNOTATION) == 0) return;
3320        Assert.check((tree.sym.flags_field & LOCKED) == 0);
3321        try {
3322            tree.sym.flags_field |= LOCKED;
3323            for (JCTree def : tree.defs) {
3324                if (!def.hasTag(METHODDEF)) continue;
3325                JCMethodDecl meth = (JCMethodDecl)def;
3326                checkAnnotationResType(meth.pos(), meth.restype.type);
3327            }
3328        } finally {
3329            tree.sym.flags_field &= ~LOCKED;
3330            tree.sym.flags_field |= ACYCLIC_ANN;
3331        }
3332    }
3333
3334    void checkNonCyclicElementsInternal(DiagnosticPosition pos, TypeSymbol tsym) {
3335        if ((tsym.flags_field & ACYCLIC_ANN) != 0)
3336            return;
3337        if ((tsym.flags_field & LOCKED) != 0) {
3338            log.error(pos, Errors.CyclicAnnotationElement(tsym));
3339            return;
3340        }
3341        try {
3342            tsym.flags_field |= LOCKED;
3343            for (Symbol s : tsym.members().getSymbols(NON_RECURSIVE)) {
3344                if (s.kind != MTH)
3345                    continue;
3346                checkAnnotationResType(pos, ((MethodSymbol)s).type.getReturnType());
3347            }
3348        } finally {
3349            tsym.flags_field &= ~LOCKED;
3350            tsym.flags_field |= ACYCLIC_ANN;
3351        }
3352    }
3353
3354    void checkAnnotationResType(DiagnosticPosition pos, Type type) {
3355        switch (type.getTag()) {
3356        case CLASS:
3357            if ((type.tsym.flags() & ANNOTATION) != 0)
3358                checkNonCyclicElementsInternal(pos, type.tsym);
3359            break;
3360        case ARRAY:
3361            checkAnnotationResType(pos, types.elemtype(type));
3362            break;
3363        default:
3364            break; // int etc
3365        }
3366    }
3367
3368/* *************************************************************************
3369 * Check for cycles in the constructor call graph.
3370 **************************************************************************/
3371
3372    /** Check for cycles in the graph of constructors calling other
3373     *  constructors.
3374     */
3375    void checkCyclicConstructors(JCClassDecl tree) {
3376        Map<Symbol,Symbol> callMap = new HashMap<>();
3377
3378        // enter each constructor this-call into the map
3379        for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
3380            JCMethodInvocation app = TreeInfo.firstConstructorCall(l.head);
3381            if (app == null) continue;
3382            JCMethodDecl meth = (JCMethodDecl) l.head;
3383            if (TreeInfo.name(app.meth) == names._this) {
3384                callMap.put(meth.sym, TreeInfo.symbol(app.meth));
3385            } else {
3386                meth.sym.flags_field |= ACYCLIC;
3387            }
3388        }
3389
3390        // Check for cycles in the map
3391        Symbol[] ctors = new Symbol[0];
3392        ctors = callMap.keySet().toArray(ctors);
3393        for (Symbol caller : ctors) {
3394            checkCyclicConstructor(tree, caller, callMap);
3395        }
3396    }
3397
3398    /** Look in the map to see if the given constructor is part of a
3399     *  call cycle.
3400     */
3401    private void checkCyclicConstructor(JCClassDecl tree, Symbol ctor,
3402                                        Map<Symbol,Symbol> callMap) {
3403        if (ctor != null && (ctor.flags_field & ACYCLIC) == 0) {
3404            if ((ctor.flags_field & LOCKED) != 0) {
3405                log.error(TreeInfo.diagnosticPositionFor(ctor, tree),
3406                          Errors.RecursiveCtorInvocation);
3407            } else {
3408                ctor.flags_field |= LOCKED;
3409                checkCyclicConstructor(tree, callMap.remove(ctor), callMap);
3410                ctor.flags_field &= ~LOCKED;
3411            }
3412            ctor.flags_field |= ACYCLIC;
3413        }
3414    }
3415
3416/* *************************************************************************
3417 * Miscellaneous
3418 **************************************************************************/
3419
3420    /**
3421     *  Check for division by integer constant zero
3422     *  @param pos           Position for error reporting.
3423     *  @param operator      The operator for the expression
3424     *  @param operand       The right hand operand for the expression
3425     */
3426    void checkDivZero(final DiagnosticPosition pos, Symbol operator, Type operand) {
3427        if (operand.constValue() != null
3428            && operand.getTag().isSubRangeOf(LONG)
3429            && ((Number) (operand.constValue())).longValue() == 0) {
3430            int opc = ((OperatorSymbol)operator).opcode;
3431            if (opc == ByteCodes.idiv || opc == ByteCodes.imod
3432                || opc == ByteCodes.ldiv || opc == ByteCodes.lmod) {
3433                deferredLintHandler.report(() -> warnDivZero(pos));
3434            }
3435        }
3436    }
3437
3438    /**
3439     * Check for empty statements after if
3440     */
3441    void checkEmptyIf(JCIf tree) {
3442        if (tree.thenpart.hasTag(SKIP) && tree.elsepart == null &&
3443                lint.isEnabled(LintCategory.EMPTY))
3444            log.warning(LintCategory.EMPTY, tree.thenpart.pos(), Warnings.EmptyIf);
3445    }
3446
3447    /** Check that symbol is unique in given scope.
3448     *  @param pos           Position for error reporting.
3449     *  @param sym           The symbol.
3450     *  @param s             The scope.
3451     */
3452    boolean checkUnique(DiagnosticPosition pos, Symbol sym, Scope s) {
3453        if (sym.type.isErroneous())
3454            return true;
3455        if (sym.owner.name == names.any) return false;
3456        for (Symbol byName : s.getSymbolsByName(sym.name, NON_RECURSIVE)) {
3457            if (sym != byName &&
3458                    (byName.flags() & CLASH) == 0 &&
3459                    sym.kind == byName.kind &&
3460                    sym.name != names.error &&
3461                    (sym.kind != MTH ||
3462                     types.hasSameArgs(sym.type, byName.type) ||
3463                     types.hasSameArgs(types.erasure(sym.type), types.erasure(byName.type)))) {
3464                if ((sym.flags() & VARARGS) != (byName.flags() & VARARGS)) {
3465                    varargsDuplicateError(pos, sym, byName);
3466                    return true;
3467                } else if (sym.kind == MTH && !types.hasSameArgs(sym.type, byName.type, false)) {
3468                    duplicateErasureError(pos, sym, byName);
3469                    sym.flags_field |= CLASH;
3470                    return true;
3471                } else {
3472                    duplicateError(pos, byName);
3473                    return false;
3474                }
3475            }
3476        }
3477        return true;
3478    }
3479
3480    /** Report duplicate declaration error.
3481     */
3482    void duplicateErasureError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) {
3483        if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) {
3484            log.error(pos, Errors.NameClashSameErasure(sym1, sym2));
3485        }
3486    }
3487
3488    /**Check that types imported through the ordinary imports don't clash with types imported
3489     * by other (static or ordinary) imports. Note that two static imports may import two clashing
3490     * types without an error on the imports.
3491     * @param toplevel       The toplevel tree for which the test should be performed.
3492     */
3493    void checkImportsUnique(JCCompilationUnit toplevel) {
3494        WriteableScope ordinallyImportedSoFar = WriteableScope.create(toplevel.packge);
3495        WriteableScope staticallyImportedSoFar = WriteableScope.create(toplevel.packge);
3496        WriteableScope topLevelScope = toplevel.toplevelScope;
3497
3498        for (JCTree def : toplevel.defs) {
3499            if (!def.hasTag(IMPORT))
3500                continue;
3501
3502            JCImport imp = (JCImport) def;
3503
3504            if (imp.importScope == null)
3505                continue;
3506
3507            for (Symbol sym : imp.importScope.getSymbols(sym -> sym.kind == TYP)) {
3508                if (imp.isStatic()) {
3509                    checkUniqueImport(imp.pos(), ordinallyImportedSoFar, staticallyImportedSoFar, topLevelScope, sym, true);
3510                    staticallyImportedSoFar.enter(sym);
3511                } else {
3512                    checkUniqueImport(imp.pos(), ordinallyImportedSoFar, staticallyImportedSoFar, topLevelScope, sym, false);
3513                    ordinallyImportedSoFar.enter(sym);
3514                }
3515            }
3516
3517            imp.importScope = null;
3518        }
3519    }
3520
3521    /** Check that single-type import is not already imported or top-level defined,
3522     *  but make an exception for two single-type imports which denote the same type.
3523     *  @param pos                     Position for error reporting.
3524     *  @param ordinallyImportedSoFar  A Scope containing types imported so far through
3525     *                                 ordinary imports.
3526     *  @param staticallyImportedSoFar A Scope containing types imported so far through
3527     *                                 static imports.
3528     *  @param topLevelScope           The current file's top-level Scope
3529     *  @param sym                     The symbol.
3530     *  @param staticImport            Whether or not this was a static import
3531     */
3532    private boolean checkUniqueImport(DiagnosticPosition pos, Scope ordinallyImportedSoFar,
3533                                      Scope staticallyImportedSoFar, Scope topLevelScope,
3534                                      Symbol sym, boolean staticImport) {
3535        Filter<Symbol> duplicates = candidate -> candidate != sym && !candidate.type.isErroneous();
3536        Symbol clashing = ordinallyImportedSoFar.findFirst(sym.name, duplicates);
3537        if (clashing == null && !staticImport) {
3538            clashing = staticallyImportedSoFar.findFirst(sym.name, duplicates);
3539        }
3540        if (clashing != null) {
3541            if (staticImport)
3542                log.error(pos, Errors.AlreadyDefinedStaticSingleImport(clashing));
3543            else
3544                log.error(pos, Errors.AlreadyDefinedSingleImport(clashing));
3545            return false;
3546        }
3547        clashing = topLevelScope.findFirst(sym.name, duplicates);
3548        if (clashing != null) {
3549            log.error(pos, Errors.AlreadyDefinedThisUnit(clashing));
3550            return false;
3551        }
3552        return true;
3553    }
3554
3555    /** Check that a qualified name is in canonical form (for import decls).
3556     */
3557    public void checkCanonical(JCTree tree) {
3558        if (!isCanonical(tree))
3559            log.error(tree.pos(),
3560                      Errors.ImportRequiresCanonical(TreeInfo.symbol(tree)));
3561    }
3562        // where
3563        private boolean isCanonical(JCTree tree) {
3564            while (tree.hasTag(SELECT)) {
3565                JCFieldAccess s = (JCFieldAccess) tree;
3566                if (s.sym.owner.name != TreeInfo.symbol(s.selected).name)
3567                    return false;
3568                tree = s.selected;
3569            }
3570            return true;
3571        }
3572
3573    /** Check that an auxiliary class is not accessed from any other file than its own.
3574     */
3575    void checkForBadAuxiliaryClassAccess(DiagnosticPosition pos, Env<AttrContext> env, ClassSymbol c) {
3576        if (lint.isEnabled(Lint.LintCategory.AUXILIARYCLASS) &&
3577            (c.flags() & AUXILIARY) != 0 &&
3578            rs.isAccessible(env, c) &&
3579            !fileManager.isSameFile(c.sourcefile, env.toplevel.sourcefile))
3580        {
3581            log.warning(pos,
3582                        Warnings.AuxiliaryClassAccessedFromOutsideOfItsSourceFile(c, c.sourcefile));
3583        }
3584    }
3585
3586    private class ConversionWarner extends Warner {
3587        final String uncheckedKey;
3588        final Type found;
3589        final Type expected;
3590        public ConversionWarner(DiagnosticPosition pos, String uncheckedKey, Type found, Type expected) {
3591            super(pos);
3592            this.uncheckedKey = uncheckedKey;
3593            this.found = found;
3594            this.expected = expected;
3595        }
3596
3597        @Override
3598        public void warn(LintCategory lint) {
3599            boolean warned = this.warned;
3600            super.warn(lint);
3601            if (warned) return; // suppress redundant diagnostics
3602            switch (lint) {
3603                case UNCHECKED:
3604                    Check.this.warnUnchecked(pos(), "prob.found.req", diags.fragment(uncheckedKey), found, expected);
3605                    break;
3606                case VARARGS:
3607                    if (method != null &&
3608                            method.attribute(syms.trustMeType.tsym) != null &&
3609                            isTrustMeAllowedOnMethod(method) &&
3610                            !types.isReifiable(method.type.getParameterTypes().last())) {
3611                        Check.this.warnUnsafeVararg(pos(), "varargs.unsafe.use.varargs.param", method.params.last());
3612                    }
3613                    break;
3614                default:
3615                    throw new AssertionError("Unexpected lint: " + lint);
3616            }
3617        }
3618    }
3619
3620    public Warner castWarner(DiagnosticPosition pos, Type found, Type expected) {
3621        return new ConversionWarner(pos, "unchecked.cast.to.type", found, expected);
3622    }
3623
3624    public Warner convertWarner(DiagnosticPosition pos, Type found, Type expected) {
3625        return new ConversionWarner(pos, "unchecked.assign", found, expected);
3626    }
3627
3628    public void checkFunctionalInterface(JCClassDecl tree, ClassSymbol cs) {
3629        Compound functionalType = cs.attribute(syms.functionalInterfaceType.tsym);
3630
3631        if (functionalType != null) {
3632            try {
3633                types.findDescriptorSymbol((TypeSymbol)cs);
3634            } catch (Types.FunctionDescriptorLookupError ex) {
3635                DiagnosticPosition pos = tree.pos();
3636                for (JCAnnotation a : tree.getModifiers().annotations) {
3637                    if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) {
3638                        pos = a.pos();
3639                        break;
3640                    }
3641                }
3642                log.error(pos, Errors.BadFunctionalIntfAnno1(ex.getDiagnostic()));
3643            }
3644        }
3645    }
3646
3647    public void checkImportsResolvable(final JCCompilationUnit toplevel) {
3648        for (final JCImport imp : toplevel.getImports()) {
3649            if (!imp.staticImport || !imp.qualid.hasTag(SELECT))
3650                continue;
3651            final JCFieldAccess select = (JCFieldAccess) imp.qualid;
3652            final Symbol origin;
3653            if (select.name == names.asterisk || (origin = TreeInfo.symbol(select.selected)) == null || origin.kind != TYP)
3654                continue;
3655
3656            TypeSymbol site = (TypeSymbol) TreeInfo.symbol(select.selected);
3657            if (!checkTypeContainsImportableElement(site, site, toplevel.packge, select.name, new HashSet<Symbol>())) {
3658                log.error(imp.pos(),
3659                          Errors.CantResolveLocation(KindName.STATIC,
3660                                                     select.name,
3661                                                     null,
3662                                                     null,
3663                                                     Fragments.Location(kindName(site),
3664                                                                        site,
3665                                                                        null)));
3666            }
3667        }
3668    }
3669
3670    // Check that packages imported are in scope (JLS 7.4.3, 6.3, 6.5.3.1, 6.5.3.2)
3671    public void checkImportedPackagesObservable(final JCCompilationUnit toplevel) {
3672        OUTER: for (JCImport imp : toplevel.getImports()) {
3673            if (!imp.staticImport && TreeInfo.name(imp.qualid) == names.asterisk) {
3674                TypeSymbol tsym = ((JCFieldAccess)imp.qualid).selected.type.tsym;
3675                if (toplevel.modle.visiblePackages != null) {
3676                    //TODO - unclear: selects like javax.* will get resolved from the current module
3677                    //(as javax is not an exported package from any module). And as javax in the current
3678                    //module typically does not contain any classes or subpackages, we need to go through
3679                    //the visible packages to find a sub-package:
3680                    for (PackageSymbol known : toplevel.modle.visiblePackages.values()) {
3681                        if (Convert.packagePart(known.fullname) == tsym.flatName())
3682                            continue OUTER;
3683                    }
3684                }
3685                if (tsym.kind == PCK && tsym.members().isEmpty() && !tsym.exists()) {
3686                    log.error(DiagnosticFlag.RESOLVE_ERROR, imp.pos, Errors.DoesntExist(tsym));
3687                }
3688            }
3689        }
3690    }
3691
3692    private boolean checkTypeContainsImportableElement(TypeSymbol tsym, TypeSymbol origin, PackageSymbol packge, Name name, Set<Symbol> processed) {
3693        if (tsym == null || !processed.add(tsym))
3694            return false;
3695
3696            // also search through inherited names
3697        if (checkTypeContainsImportableElement(types.supertype(tsym.type).tsym, origin, packge, name, processed))
3698            return true;
3699
3700        for (Type t : types.interfaces(tsym.type))
3701            if (checkTypeContainsImportableElement(t.tsym, origin, packge, name, processed))
3702                return true;
3703
3704        for (Symbol sym : tsym.members().getSymbolsByName(name)) {
3705            if (sym.isStatic() &&
3706                importAccessible(sym, packge) &&
3707                sym.isMemberOf(origin, types)) {
3708                return true;
3709            }
3710        }
3711
3712        return false;
3713    }
3714
3715    // is the sym accessible everywhere in packge?
3716    public boolean importAccessible(Symbol sym, PackageSymbol packge) {
3717        try {
3718            int flags = (int)(sym.flags() & AccessFlags);
3719            switch (flags) {
3720            default:
3721            case PUBLIC:
3722                return true;
3723            case PRIVATE:
3724                return false;
3725            case 0:
3726            case PROTECTED:
3727                return sym.packge() == packge;
3728            }
3729        } catch (ClassFinder.BadClassFile err) {
3730            throw err;
3731        } catch (CompletionFailure ex) {
3732            return false;
3733        }
3734    }
3735
3736    public void checkLeaksNotAccessible(Env<AttrContext> env, JCClassDecl check) {
3737        JCCompilationUnit toplevel = env.toplevel;
3738
3739        if (   toplevel.modle == syms.unnamedModule
3740            || toplevel.modle == syms.noModule
3741            || (check.sym.flags() & COMPOUND) != 0) {
3742            return ;
3743        }
3744
3745        ExportsDirective currentExport = findExport(toplevel.packge);
3746
3747        if (   currentExport == null //not exported
3748            || currentExport.modules != null) //don't check classes in qualified export
3749            return ;
3750
3751        new TreeScanner() {
3752            Lint lint = env.info.lint;
3753            boolean inSuperType;
3754
3755            @Override
3756            public void visitBlock(JCBlock tree) {
3757            }
3758            @Override
3759            public void visitMethodDef(JCMethodDecl tree) {
3760                if (!isAPISymbol(tree.sym))
3761                    return;
3762                Lint prevLint = lint;
3763                try {
3764                    lint = lint.augment(tree.sym);
3765                    if (lint.isEnabled(LintCategory.EXPORTS)) {
3766                        super.visitMethodDef(tree);
3767                    }
3768                } finally {
3769                    lint = prevLint;
3770                }
3771            }
3772            @Override
3773            public void visitVarDef(JCVariableDecl tree) {
3774                if (!isAPISymbol(tree.sym) && tree.sym.owner.kind != MTH)
3775                    return;
3776                Lint prevLint = lint;
3777                try {
3778                    lint = lint.augment(tree.sym);
3779                    if (lint.isEnabled(LintCategory.EXPORTS)) {
3780                        scan(tree.mods);
3781                        scan(tree.vartype);
3782                    }
3783                } finally {
3784                    lint = prevLint;
3785                }
3786            }
3787            @Override
3788            public void visitClassDef(JCClassDecl tree) {
3789                if (tree != check)
3790                    return ;
3791
3792                if (!isAPISymbol(tree.sym))
3793                    return ;
3794
3795                Lint prevLint = lint;
3796                try {
3797                    lint = lint.augment(tree.sym);
3798                    if (lint.isEnabled(LintCategory.EXPORTS)) {
3799                        scan(tree.mods);
3800                        scan(tree.typarams);
3801                        try {
3802                            inSuperType = true;
3803                            scan(tree.extending);
3804                            scan(tree.implementing);
3805                        } finally {
3806                            inSuperType = false;
3807                        }
3808                        scan(tree.defs);
3809                    }
3810                } finally {
3811                    lint = prevLint;
3812                }
3813            }
3814            @Override
3815            public void visitTypeApply(JCTypeApply tree) {
3816                scan(tree.clazz);
3817                boolean oldInSuperType = inSuperType;
3818                try {
3819                    inSuperType = false;
3820                    scan(tree.arguments);
3821                } finally {
3822                    inSuperType = oldInSuperType;
3823                }
3824            }
3825            @Override
3826            public void visitIdent(JCIdent tree) {
3827                Symbol sym = TreeInfo.symbol(tree);
3828                if (sym.kind == TYP && !sym.type.hasTag(TYPEVAR)) {
3829                    checkVisible(tree.pos(), sym, toplevel.packge, inSuperType);
3830                }
3831            }
3832
3833            @Override
3834            public void visitSelect(JCFieldAccess tree) {
3835                Symbol sym = TreeInfo.symbol(tree);
3836                Symbol sitesym = TreeInfo.symbol(tree.selected);
3837                if (sym.kind == TYP && sitesym.kind == PCK) {
3838                    checkVisible(tree.pos(), sym, toplevel.packge, inSuperType);
3839                } else {
3840                    super.visitSelect(tree);
3841                }
3842            }
3843
3844            @Override
3845            public void visitAnnotation(JCAnnotation tree) {
3846                if (tree.attribute.type.tsym.getAnnotation(java.lang.annotation.Documented.class) != null)
3847                    super.visitAnnotation(tree);
3848            }
3849
3850        }.scan(check);
3851    }
3852        //where:
3853        private ExportsDirective findExport(PackageSymbol pack) {
3854            for (ExportsDirective d : pack.modle.exports) {
3855                if (d.packge == pack)
3856                    return d;
3857            }
3858
3859            return null;
3860        }
3861        private boolean isAPISymbol(Symbol sym) {
3862            while (sym.kind != PCK) {
3863                if ((sym.flags() & Flags.PUBLIC) == 0 && (sym.flags() & Flags.PROTECTED) == 0) {
3864                    return false;
3865                }
3866                sym = sym.owner;
3867            }
3868            return true;
3869        }
3870        private void checkVisible(DiagnosticPosition pos, Symbol what, PackageSymbol inPackage, boolean inSuperType) {
3871            if (!isAPISymbol(what) && !inSuperType) { //package private/private element
3872                log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessible(kindName(what), what, what.packge().modle));
3873                return ;
3874            }
3875
3876            PackageSymbol whatPackage = what.packge();
3877            ExportsDirective whatExport = findExport(whatPackage);
3878            ExportsDirective inExport = findExport(inPackage);
3879
3880            if (whatExport == null) { //package not exported:
3881                log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessibleUnexported(kindName(what), what, what.packge().modle));
3882                return ;
3883            }
3884
3885            if (whatExport.modules != null) {
3886                if (inExport.modules == null || !whatExport.modules.containsAll(inExport.modules)) {
3887                    log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessibleUnexportedQualified(kindName(what), what, what.packge().modle));
3888                }
3889            }
3890
3891            if (whatPackage.modle != inPackage.modle && whatPackage.modle != syms.java_base) {
3892                //check that relativeTo.modle requires transitive what.modle, somehow:
3893                List<ModuleSymbol> todo = List.of(inPackage.modle);
3894
3895                while (todo.nonEmpty()) {
3896                    ModuleSymbol current = todo.head;
3897                    todo = todo.tail;
3898                    if (current == whatPackage.modle)
3899                        return ; //OK
3900                    for (RequiresDirective req : current.requires) {
3901                        if (req.isTransitive()) {
3902                            todo = todo.prepend(req.module);
3903                        }
3904                    }
3905                }
3906
3907                log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessibleNotRequiredTransitive(kindName(what), what, what.packge().modle));
3908            }
3909        }
3910
3911    void checkModuleExists(final DiagnosticPosition pos, ModuleSymbol msym) {
3912        if (msym.kind != MDL) {
3913            deferredLintHandler.report(() -> {
3914                if (lint.isEnabled(LintCategory.MODULE))
3915                    log.warning(LintCategory.MODULE, pos, Warnings.ModuleNotFound(msym));
3916            });
3917        }
3918    }
3919
3920    void checkPackageExistsForOpens(final DiagnosticPosition pos, PackageSymbol packge) {
3921        if (packge.members().isEmpty() &&
3922            ((packge.flags() & Flags.HAS_RESOURCE) == 0)) {
3923            deferredLintHandler.report(() -> {
3924                if (lint.isEnabled(LintCategory.OPENS))
3925                    log.warning(pos, Warnings.PackageEmptyOrNotFound(packge));
3926            });
3927        }
3928    }
3929
3930    void checkModuleRequires(final DiagnosticPosition pos, final RequiresDirective rd) {
3931        if ((rd.module.flags() & Flags.AUTOMATIC_MODULE) != 0) {
3932            deferredLintHandler.report(() -> {
3933                if (rd.isTransitive() && lint.isEnabled(LintCategory.REQUIRES_TRANSITIVE_AUTOMATIC)) {
3934                    log.warning(pos, Warnings.RequiresTransitiveAutomatic);
3935                } else if (lint.isEnabled(LintCategory.REQUIRES_AUTOMATIC)) {
3936                    log.warning(pos, Warnings.RequiresAutomatic);
3937                }
3938            });
3939        }
3940    }
3941
3942}
3943