Check.java revision 4202:2bd34895dda2
1/*
2 * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.tools.javac.comp;
27
28import java.util.*;
29
30import javax.tools.JavaFileManager;
31
32import com.sun.tools.javac.code.*;
33import com.sun.tools.javac.code.Attribute.Compound;
34import com.sun.tools.javac.code.Directive.ExportsDirective;
35import com.sun.tools.javac.code.Directive.RequiresDirective;
36import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
37import com.sun.tools.javac.jvm.*;
38import com.sun.tools.javac.resources.CompilerProperties.Errors;
39import com.sun.tools.javac.resources.CompilerProperties.Fragments;
40import com.sun.tools.javac.resources.CompilerProperties.Warnings;
41import com.sun.tools.javac.tree.*;
42import com.sun.tools.javac.util.*;
43import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
44import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
45import com.sun.tools.javac.util.JCDiagnostic.Fragment;
46import com.sun.tools.javac.util.List;
47
48import com.sun.tools.javac.code.Lint;
49import com.sun.tools.javac.code.Lint.LintCategory;
50import com.sun.tools.javac.code.Scope.WriteableScope;
51import com.sun.tools.javac.code.Type.*;
52import com.sun.tools.javac.code.Symbol.*;
53import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
54import com.sun.tools.javac.comp.Infer.FreeTypeListener;
55import com.sun.tools.javac.tree.JCTree.*;
56
57import static com.sun.tools.javac.code.Flags.*;
58import static com.sun.tools.javac.code.Flags.ANNOTATION;
59import static com.sun.tools.javac.code.Flags.SYNCHRONIZED;
60import static com.sun.tools.javac.code.Kinds.*;
61import static com.sun.tools.javac.code.Kinds.Kind.*;
62import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
63import static com.sun.tools.javac.code.TypeTag.*;
64import static com.sun.tools.javac.code.TypeTag.WILDCARD;
65
66import static com.sun.tools.javac.tree.JCTree.Tag.*;
67
68/** Type checking helper class for the attribution phase.
69 *
70 *  <p><b>This is NOT part of any supported API.
71 *  If you write code that depends on this, you do so at your own risk.
72 *  This code and its internal interfaces are subject to change or
73 *  deletion without notice.</b>
74 */
75public class Check {
76    protected static final Context.Key<Check> checkKey = new Context.Key<>();
77
78    private final Names names;
79    private final Log log;
80    private final Resolve rs;
81    private final Symtab syms;
82    private final Enter enter;
83    private final DeferredAttr deferredAttr;
84    private final Infer infer;
85    private final Types types;
86    private final TypeAnnotations typeAnnotations;
87    private final JCDiagnostic.Factory diags;
88    private final JavaFileManager fileManager;
89    private final Source source;
90    private final Profile profile;
91    private final boolean warnOnAnyAccessToMembers;
92
93    // The set of lint options currently in effect. It is initialized
94    // from the context, and then is set/reset as needed by Attr as it
95    // visits all the various parts of the trees during attribution.
96    private Lint lint;
97
98    // The method being analyzed in Attr - it is set/reset as needed by
99    // Attr as it visits new method declarations.
100    private MethodSymbol method;
101
102    public static Check instance(Context context) {
103        Check instance = context.get(checkKey);
104        if (instance == null)
105            instance = new Check(context);
106        return instance;
107    }
108
109    protected Check(Context context) {
110        context.put(checkKey, this);
111
112        names = Names.instance(context);
113        dfltTargetMeta = new Name[] { names.PACKAGE, names.TYPE,
114            names.FIELD, names.METHOD, names.CONSTRUCTOR,
115            names.ANNOTATION_TYPE, names.LOCAL_VARIABLE, names.PARAMETER};
116        log = Log.instance(context);
117        rs = Resolve.instance(context);
118        syms = Symtab.instance(context);
119        enter = Enter.instance(context);
120        deferredAttr = DeferredAttr.instance(context);
121        infer = Infer.instance(context);
122        types = Types.instance(context);
123        typeAnnotations = TypeAnnotations.instance(context);
124        diags = JCDiagnostic.Factory.instance(context);
125        Options options = Options.instance(context);
126        lint = Lint.instance(context);
127        fileManager = context.get(JavaFileManager.class);
128
129        source = Source.instance(context);
130        allowSimplifiedVarargs = source.allowSimplifiedVarargs();
131        allowDefaultMethods = source.allowDefaultMethods();
132        allowStrictMethodClashCheck = source.allowStrictMethodClashCheck();
133        allowPrivateSafeVarargs = source.allowPrivateSafeVarargs();
134        allowDiamondWithAnonymousClassCreation = source.allowDiamondWithAnonymousClassCreation();
135        warnOnAnyAccessToMembers = options.isSet("warnOnAccessToMembers");
136
137        Target target = Target.instance(context);
138        syntheticNameChar = target.syntheticNameChar();
139
140        profile = Profile.instance(context);
141
142        boolean verboseDeprecated = lint.isEnabled(LintCategory.DEPRECATION);
143        boolean verboseRemoval = lint.isEnabled(LintCategory.REMOVAL);
144        boolean verboseUnchecked = lint.isEnabled(LintCategory.UNCHECKED);
145        boolean enforceMandatoryWarnings = true;
146
147        deprecationHandler = new MandatoryWarningHandler(log, verboseDeprecated,
148                enforceMandatoryWarnings, "deprecated", LintCategory.DEPRECATION);
149        removalHandler = new MandatoryWarningHandler(log, verboseRemoval,
150                enforceMandatoryWarnings, "removal", LintCategory.REMOVAL);
151        uncheckedHandler = new MandatoryWarningHandler(log, verboseUnchecked,
152                enforceMandatoryWarnings, "unchecked", LintCategory.UNCHECKED);
153        sunApiHandler = new MandatoryWarningHandler(log, false,
154                enforceMandatoryWarnings, "sunapi", null);
155
156        deferredLintHandler = DeferredLintHandler.instance(context);
157    }
158
159    /** Switch: simplified varargs enabled?
160     */
161    boolean allowSimplifiedVarargs;
162
163    /** Switch: default methods enabled?
164     */
165    boolean allowDefaultMethods;
166
167    /** Switch: should unrelated return types trigger a method clash?
168     */
169    boolean allowStrictMethodClashCheck;
170
171    /** Switch: can the @SafeVarargs annotation be applied to private methods?
172     */
173    boolean allowPrivateSafeVarargs;
174
175    /** Switch: can diamond inference be used in anonymous instance creation ?
176     */
177    boolean allowDiamondWithAnonymousClassCreation;
178
179    /** Character for synthetic names
180     */
181    char syntheticNameChar;
182
183    /** A table mapping flat names of all compiled classes for each module in this run
184     *  to their symbols; maintained from outside.
185     */
186    private Map<Pair<ModuleSymbol, Name>,ClassSymbol> compiled = new HashMap<>();
187
188    /** A handler for messages about deprecated usage.
189     */
190    private MandatoryWarningHandler deprecationHandler;
191
192    /** A handler for messages about deprecated-for-removal usage.
193     */
194    private MandatoryWarningHandler removalHandler;
195
196    /** A handler for messages about unchecked or unsafe usage.
197     */
198    private MandatoryWarningHandler uncheckedHandler;
199
200    /** A handler for messages about using proprietary API.
201     */
202    private MandatoryWarningHandler sunApiHandler;
203
204    /** A handler for deferred lint warnings.
205     */
206    private DeferredLintHandler deferredLintHandler;
207
208/* *************************************************************************
209 * Errors and Warnings
210 **************************************************************************/
211
212    Lint setLint(Lint newLint) {
213        Lint prev = lint;
214        lint = newLint;
215        return prev;
216    }
217
218    MethodSymbol setMethod(MethodSymbol newMethod) {
219        MethodSymbol prev = method;
220        method = newMethod;
221        return prev;
222    }
223
224    /** Warn about deprecated symbol.
225     *  @param pos        Position to be used for error reporting.
226     *  @param sym        The deprecated symbol.
227     */
228    void warnDeprecated(DiagnosticPosition pos, Symbol sym) {
229        if (sym.isDeprecatedForRemoval()) {
230            if (!lint.isSuppressed(LintCategory.REMOVAL)) {
231                if (sym.kind == MDL) {
232                    removalHandler.report(pos, "has.been.deprecated.for.removal.module", sym);
233                } else {
234                    removalHandler.report(pos, "has.been.deprecated.for.removal", sym, sym.location());
235                }
236            }
237        } else if (!lint.isSuppressed(LintCategory.DEPRECATION)) {
238            if (sym.kind == MDL) {
239                deprecationHandler.report(pos, "has.been.deprecated.module", sym);
240            } else {
241                deprecationHandler.report(pos, "has.been.deprecated", sym, sym.location());
242            }
243        }
244    }
245
246    /** Warn about unchecked operation.
247     *  @param pos        Position to be used for error reporting.
248     *  @param msg        A string describing the problem.
249     */
250    public void warnUnchecked(DiagnosticPosition pos, String msg, Object... args) {
251        if (!lint.isSuppressed(LintCategory.UNCHECKED))
252            uncheckedHandler.report(pos, msg, args);
253    }
254
255    /** Warn about unsafe vararg method decl.
256     *  @param pos        Position to be used for error reporting.
257     */
258    void warnUnsafeVararg(DiagnosticPosition pos, String key, Object... args) {
259        if (lint.isEnabled(LintCategory.VARARGS) && allowSimplifiedVarargs)
260            log.warning(LintCategory.VARARGS, pos, key, args);
261    }
262
263    public void warnStatic(DiagnosticPosition pos, String msg, Object... args) {
264        if (lint.isEnabled(LintCategory.STATIC))
265            log.warning(LintCategory.STATIC, pos, msg, args);
266    }
267
268    /** Warn about division by integer constant zero.
269     *  @param pos        Position to be used for error reporting.
270     */
271    void warnDivZero(DiagnosticPosition pos) {
272        if (lint.isEnabled(LintCategory.DIVZERO))
273            log.warning(LintCategory.DIVZERO, pos, Warnings.DivZero);
274    }
275
276    /**
277     * Report any deferred diagnostics.
278     */
279    public void reportDeferredDiagnostics() {
280        deprecationHandler.reportDeferredDiagnostic();
281        removalHandler.reportDeferredDiagnostic();
282        uncheckedHandler.reportDeferredDiagnostic();
283        sunApiHandler.reportDeferredDiagnostic();
284    }
285
286
287    /** Report a failure to complete a class.
288     *  @param pos        Position to be used for error reporting.
289     *  @param ex         The failure to report.
290     */
291    public Type completionError(DiagnosticPosition pos, CompletionFailure ex) {
292        log.error(JCDiagnostic.DiagnosticFlag.NON_DEFERRABLE, pos, Errors.CantAccess(ex.sym, ex.getDetailValue()));
293        if (ex instanceof ClassFinder.BadClassFile) throw new Abort();
294        else return syms.errType;
295    }
296
297    /** Report an error that wrong type tag was found.
298     *  @param pos        Position to be used for error reporting.
299     *  @param required   An internationalized string describing the type tag
300     *                    required.
301     *  @param found      The type that was found.
302     */
303    Type typeTagError(DiagnosticPosition pos, JCDiagnostic required, Object found) {
304        // this error used to be raised by the parser,
305        // but has been delayed to this point:
306        if (found instanceof Type && ((Type)found).hasTag(VOID)) {
307            log.error(pos, Errors.IllegalStartOfType);
308            return syms.errType;
309        }
310        log.error(pos, Errors.TypeFoundReq(found, required));
311        return types.createErrorType(found instanceof Type ? (Type)found : syms.errType);
312    }
313
314    /** Report an error that symbol cannot be referenced before super
315     *  has been called.
316     *  @param pos        Position to be used for error reporting.
317     *  @param sym        The referenced symbol.
318     */
319    void earlyRefError(DiagnosticPosition pos, Symbol sym) {
320        log.error(pos, Errors.CantRefBeforeCtorCalled(sym));
321    }
322
323    /** Report duplicate declaration error.
324     */
325    void duplicateError(DiagnosticPosition pos, Symbol sym) {
326        if (!sym.type.isErroneous()) {
327            Symbol location = sym.location();
328            if (location.kind == MTH &&
329                    ((MethodSymbol)location).isStaticOrInstanceInit()) {
330                log.error(pos,
331                          Errors.AlreadyDefinedInClinit(kindName(sym),
332                                                        sym,
333                                                        kindName(sym.location()),
334                                                        kindName(sym.location().enclClass()),
335                                                        sym.location().enclClass()));
336            } else {
337                log.error(pos,
338                          Errors.AlreadyDefined(kindName(sym),
339                                                sym,
340                                                kindName(sym.location()),
341                                                sym.location()));
342            }
343        }
344    }
345
346    /** Report array/varargs duplicate declaration
347     */
348    void varargsDuplicateError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) {
349        if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) {
350            log.error(pos, Errors.ArrayAndVarargs(sym1, sym2, sym2.location()));
351        }
352    }
353
354/* ************************************************************************
355 * duplicate declaration checking
356 *************************************************************************/
357
358    /** Check that variable does not hide variable with same name in
359     *  immediately enclosing local scope.
360     *  @param pos           Position for error reporting.
361     *  @param v             The symbol.
362     *  @param s             The scope.
363     */
364    void checkTransparentVar(DiagnosticPosition pos, VarSymbol v, Scope s) {
365        for (Symbol sym : s.getSymbolsByName(v.name)) {
366            if (sym.owner != v.owner) break;
367            if (sym.kind == VAR &&
368                sym.owner.kind.matches(KindSelector.VAL_MTH) &&
369                v.name != names.error) {
370                duplicateError(pos, sym);
371                return;
372            }
373        }
374    }
375
376    /** Check that a class or interface does not hide a class or
377     *  interface with same name in immediately enclosing local scope.
378     *  @param pos           Position for error reporting.
379     *  @param c             The symbol.
380     *  @param s             The scope.
381     */
382    void checkTransparentClass(DiagnosticPosition pos, ClassSymbol c, Scope s) {
383        for (Symbol sym : s.getSymbolsByName(c.name)) {
384            if (sym.owner != c.owner) break;
385            if (sym.kind == TYP && !sym.type.hasTag(TYPEVAR) &&
386                sym.owner.kind.matches(KindSelector.VAL_MTH) &&
387                c.name != names.error) {
388                duplicateError(pos, sym);
389                return;
390            }
391        }
392    }
393
394    /** Check that class does not have the same name as one of
395     *  its enclosing classes, or as a class defined in its enclosing scope.
396     *  return true if class is unique in its enclosing scope.
397     *  @param pos           Position for error reporting.
398     *  @param name          The class name.
399     *  @param s             The enclosing scope.
400     */
401    boolean checkUniqueClassName(DiagnosticPosition pos, Name name, Scope s) {
402        for (Symbol sym : s.getSymbolsByName(name, NON_RECURSIVE)) {
403            if (sym.kind == TYP && sym.name != names.error) {
404                duplicateError(pos, sym);
405                return false;
406            }
407        }
408        for (Symbol sym = s.owner; sym != null; sym = sym.owner) {
409            if (sym.kind == TYP && sym.name == name && sym.name != names.error) {
410                duplicateError(pos, sym);
411                return true;
412            }
413        }
414        return true;
415    }
416
417/* *************************************************************************
418 * Class name generation
419 **************************************************************************/
420
421
422    private Map<Pair<Name, Name>, Integer> localClassNameIndexes = new HashMap<>();
423
424    /** Return name of local class.
425     *  This is of the form   {@code <enclClass> $ n <classname> }
426     *  where
427     *    enclClass is the flat name of the enclosing class,
428     *    classname is the simple name of the local class
429     */
430    Name localClassName(ClassSymbol c) {
431        Name enclFlatname = c.owner.enclClass().flatname;
432        String enclFlatnameStr = enclFlatname.toString();
433        Pair<Name, Name> key = new Pair<>(enclFlatname, c.name);
434        Integer index = localClassNameIndexes.get(key);
435        for (int i = (index == null) ? 1 : index; ; i++) {
436            Name flatname = names.fromString(enclFlatnameStr
437                    + syntheticNameChar + i + c.name);
438            if (getCompiled(c.packge().modle, flatname) == null) {
439                localClassNameIndexes.put(key, i + 1);
440                return flatname;
441            }
442        }
443    }
444
445    void clearLocalClassNameIndexes(ClassSymbol c) {
446        if (c.owner != null && c.owner.kind != NIL) {
447            localClassNameIndexes.remove(new Pair<>(
448                    c.owner.enclClass().flatname, c.name));
449        }
450    }
451
452    public void newRound() {
453        compiled.clear();
454        localClassNameIndexes.clear();
455    }
456
457    public void putCompiled(ClassSymbol csym) {
458        compiled.put(Pair.of(csym.packge().modle, csym.flatname), csym);
459    }
460
461    public ClassSymbol getCompiled(ClassSymbol csym) {
462        return compiled.get(Pair.of(csym.packge().modle, csym.flatname));
463    }
464
465    public ClassSymbol getCompiled(ModuleSymbol msym, Name flatname) {
466        return compiled.get(Pair.of(msym, flatname));
467    }
468
469    public void removeCompiled(ClassSymbol csym) {
470        compiled.remove(Pair.of(csym.packge().modle, csym.flatname));
471    }
472
473/* *************************************************************************
474 * Type Checking
475 **************************************************************************/
476
477    /**
478     * A check context is an object that can be used to perform compatibility
479     * checks - depending on the check context, meaning of 'compatibility' might
480     * vary significantly.
481     */
482    public interface CheckContext {
483        /**
484         * Is type 'found' compatible with type 'req' in given context
485         */
486        boolean compatible(Type found, Type req, Warner warn);
487        /**
488         * Report a check error
489         */
490        void report(DiagnosticPosition pos, JCDiagnostic details);
491        /**
492         * Obtain a warner for this check context
493         */
494        public Warner checkWarner(DiagnosticPosition pos, Type found, Type req);
495
496        public InferenceContext inferenceContext();
497
498        public DeferredAttr.DeferredAttrContext deferredAttrContext();
499    }
500
501    /**
502     * This class represent a check context that is nested within another check
503     * context - useful to check sub-expressions. The default behavior simply
504     * redirects all method calls to the enclosing check context leveraging
505     * the forwarding pattern.
506     */
507    static class NestedCheckContext implements CheckContext {
508        CheckContext enclosingContext;
509
510        NestedCheckContext(CheckContext enclosingContext) {
511            this.enclosingContext = enclosingContext;
512        }
513
514        public boolean compatible(Type found, Type req, Warner warn) {
515            return enclosingContext.compatible(found, req, warn);
516        }
517
518        public void report(DiagnosticPosition pos, JCDiagnostic details) {
519            enclosingContext.report(pos, details);
520        }
521
522        public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
523            return enclosingContext.checkWarner(pos, found, req);
524        }
525
526        public InferenceContext inferenceContext() {
527            return enclosingContext.inferenceContext();
528        }
529
530        public DeferredAttrContext deferredAttrContext() {
531            return enclosingContext.deferredAttrContext();
532        }
533    }
534
535    /**
536     * Check context to be used when evaluating assignment/return statements
537     */
538    CheckContext basicHandler = new CheckContext() {
539        public void report(DiagnosticPosition pos, JCDiagnostic details) {
540            log.error(pos, Errors.ProbFoundReq(details));
541        }
542        public boolean compatible(Type found, Type req, Warner warn) {
543            return types.isAssignable(found, req, warn);
544        }
545
546        public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
547            return convertWarner(pos, found, req);
548        }
549
550        public InferenceContext inferenceContext() {
551            return infer.emptyContext;
552        }
553
554        public DeferredAttrContext deferredAttrContext() {
555            return deferredAttr.emptyDeferredAttrContext;
556        }
557
558        @Override
559        public String toString() {
560            return "CheckContext: basicHandler";
561        }
562    };
563
564    /** Check that a given type is assignable to a given proto-type.
565     *  If it is, return the type, otherwise return errType.
566     *  @param pos        Position to be used for error reporting.
567     *  @param found      The type that was found.
568     *  @param req        The type that was required.
569     */
570    public Type checkType(DiagnosticPosition pos, Type found, Type req) {
571        return checkType(pos, found, req, basicHandler);
572    }
573
574    Type checkType(final DiagnosticPosition pos, final Type found, final Type req, final CheckContext checkContext) {
575        final InferenceContext inferenceContext = checkContext.inferenceContext();
576        if (inferenceContext.free(req) || inferenceContext.free(found)) {
577            inferenceContext.addFreeTypeListener(List.of(req, found),
578                    solvedContext -> checkType(pos, solvedContext.asInstType(found), solvedContext.asInstType(req), checkContext));
579        }
580        if (req.hasTag(ERROR))
581            return req;
582        if (req.hasTag(NONE))
583            return found;
584        if (checkContext.compatible(found, req, checkContext.checkWarner(pos, found, req))) {
585            return found;
586        } else {
587            if (found.isNumeric() && req.isNumeric()) {
588                checkContext.report(pos, diags.fragment(Fragments.PossibleLossOfPrecision(found, req)));
589                return types.createErrorType(found);
590            }
591            checkContext.report(pos, diags.fragment(Fragments.InconvertibleTypes(found, req)));
592            return types.createErrorType(found);
593        }
594    }
595
596    /** Check that a given type can be cast to a given target type.
597     *  Return the result of the cast.
598     *  @param pos        Position to be used for error reporting.
599     *  @param found      The type that is being cast.
600     *  @param req        The target type of the cast.
601     */
602    Type checkCastable(DiagnosticPosition pos, Type found, Type req) {
603        return checkCastable(pos, found, req, basicHandler);
604    }
605    Type checkCastable(DiagnosticPosition pos, Type found, Type req, CheckContext checkContext) {
606        if (types.isCastable(found, req, castWarner(pos, found, req))) {
607            return req;
608        } else {
609            checkContext.report(pos, diags.fragment(Fragments.InconvertibleTypes(found, req)));
610            return types.createErrorType(found);
611        }
612    }
613
614    /** Check for redundant casts (i.e. where source type is a subtype of target type)
615     * The problem should only be reported for non-292 cast
616     */
617    public void checkRedundantCast(Env<AttrContext> env, final JCTypeCast tree) {
618        if (!tree.type.isErroneous()
619                && types.isSameType(tree.expr.type, tree.clazz.type)
620                && !(ignoreAnnotatedCasts && TreeInfo.containsTypeAnnotation(tree.clazz))
621                && !is292targetTypeCast(tree)) {
622            deferredLintHandler.report(() -> {
623                if (lint.isEnabled(LintCategory.CAST))
624                    log.warning(LintCategory.CAST,
625                            tree.pos(), Warnings.RedundantCast(tree.clazz.type));
626            });
627        }
628    }
629    //where
630        private boolean is292targetTypeCast(JCTypeCast tree) {
631            boolean is292targetTypeCast = false;
632            JCExpression expr = TreeInfo.skipParens(tree.expr);
633            if (expr.hasTag(APPLY)) {
634                JCMethodInvocation apply = (JCMethodInvocation)expr;
635                Symbol sym = TreeInfo.symbol(apply.meth);
636                is292targetTypeCast = sym != null &&
637                    sym.kind == MTH &&
638                    (sym.flags() & HYPOTHETICAL) != 0;
639            }
640            return is292targetTypeCast;
641        }
642
643        private static final boolean ignoreAnnotatedCasts = true;
644
645    /** Check that a type is within some bounds.
646     *
647     *  Used in TypeApply to verify that, e.g., X in {@code V<X>} is a valid
648     *  type argument.
649     *  @param a             The type that should be bounded by bs.
650     *  @param bound         The bound.
651     */
652    private boolean checkExtends(Type a, Type bound) {
653         if (a.isUnbound()) {
654             return true;
655         } else if (!a.hasTag(WILDCARD)) {
656             a = types.cvarUpperBound(a);
657             return types.isSubtype(a, bound);
658         } else if (a.isExtendsBound()) {
659             return types.isCastable(bound, types.wildUpperBound(a), types.noWarnings);
660         } else if (a.isSuperBound()) {
661             return !types.notSoftSubtype(types.wildLowerBound(a), bound);
662         }
663         return true;
664     }
665
666    /** Check that type is different from 'void'.
667     *  @param pos           Position to be used for error reporting.
668     *  @param t             The type to be checked.
669     */
670    Type checkNonVoid(DiagnosticPosition pos, Type t) {
671        if (t.hasTag(VOID)) {
672            log.error(pos, Errors.VoidNotAllowedHere);
673            return types.createErrorType(t);
674        } else {
675            return t;
676        }
677    }
678
679    Type checkClassOrArrayType(DiagnosticPosition pos, Type t) {
680        if (!t.hasTag(CLASS) && !t.hasTag(ARRAY) && !t.hasTag(ERROR)) {
681            return typeTagError(pos,
682                                diags.fragment(Fragments.TypeReqClassArray),
683                                asTypeParam(t));
684        } else {
685            return t;
686        }
687    }
688
689    /** Check that type is a class or interface type.
690     *  @param pos           Position to be used for error reporting.
691     *  @param t             The type to be checked.
692     */
693    Type checkClassType(DiagnosticPosition pos, Type t) {
694        if (!t.hasTag(CLASS) && !t.hasTag(ERROR)) {
695            return typeTagError(pos,
696                                diags.fragment(Fragments.TypeReqClass),
697                                asTypeParam(t));
698        } else {
699            return t;
700        }
701    }
702    //where
703        private Object asTypeParam(Type t) {
704            return (t.hasTag(TYPEVAR))
705                                    ? diags.fragment(Fragments.TypeParameter(t))
706                                    : t;
707        }
708
709    /** Check that type is a valid qualifier for a constructor reference expression
710     */
711    Type checkConstructorRefType(DiagnosticPosition pos, Type t) {
712        t = checkClassOrArrayType(pos, t);
713        if (t.hasTag(CLASS)) {
714            if ((t.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) {
715                log.error(pos, Errors.AbstractCantBeInstantiated(t.tsym));
716                t = types.createErrorType(t);
717            } else if ((t.tsym.flags() & ENUM) != 0) {
718                log.error(pos, Errors.EnumCantBeInstantiated);
719                t = types.createErrorType(t);
720            } else {
721                t = checkClassType(pos, t, true);
722            }
723        } else if (t.hasTag(ARRAY)) {
724            if (!types.isReifiable(((ArrayType)t).elemtype)) {
725                log.error(pos, Errors.GenericArrayCreation);
726                t = types.createErrorType(t);
727            }
728        }
729        return t;
730    }
731
732    /** Check that type is a class or interface type.
733     *  @param pos           Position to be used for error reporting.
734     *  @param t             The type to be checked.
735     *  @param noBounds    True if type bounds are illegal here.
736     */
737    Type checkClassType(DiagnosticPosition pos, Type t, boolean noBounds) {
738        t = checkClassType(pos, t);
739        if (noBounds && t.isParameterized()) {
740            List<Type> args = t.getTypeArguments();
741            while (args.nonEmpty()) {
742                if (args.head.hasTag(WILDCARD))
743                    return typeTagError(pos,
744                                        diags.fragment(Fragments.TypeReqExact),
745                                        args.head);
746                args = args.tail;
747            }
748        }
749        return t;
750    }
751
752    /** Check that type is a reference type, i.e. a class, interface or array type
753     *  or a type variable.
754     *  @param pos           Position to be used for error reporting.
755     *  @param t             The type to be checked.
756     */
757    Type checkRefType(DiagnosticPosition pos, Type t) {
758        if (t.isReference())
759            return t;
760        else
761            return typeTagError(pos,
762                                diags.fragment(Fragments.TypeReqRef),
763                                t);
764    }
765
766    /** Check that each type is a reference type, i.e. a class, interface or array type
767     *  or a type variable.
768     *  @param trees         Original trees, used for error reporting.
769     *  @param types         The types to be checked.
770     */
771    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    /** Same, but handling completion failures.
1572     */
1573    boolean isUnchecked(DiagnosticPosition pos, Type exc) {
1574        try {
1575            return isUnchecked(exc);
1576        } catch (CompletionFailure ex) {
1577            completionError(pos, ex);
1578            return true;
1579        }
1580    }
1581
1582    /** Is exc handled by given exception list?
1583     */
1584    boolean isHandled(Type exc, List<Type> handled) {
1585        return isUnchecked(exc) || subset(exc, handled);
1586    }
1587
1588    /** Return all exceptions in thrown list that are not in handled list.
1589     *  @param thrown     The list of thrown exceptions.
1590     *  @param handled    The list of handled exceptions.
1591     */
1592    List<Type> unhandled(List<Type> thrown, List<Type> handled) {
1593        List<Type> unhandled = List.nil();
1594        for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
1595            if (!isHandled(l.head, handled)) unhandled = unhandled.prepend(l.head);
1596        return unhandled;
1597    }
1598
1599/* *************************************************************************
1600 * Overriding/Implementation checking
1601 **************************************************************************/
1602
1603    /** The level of access protection given by a flag set,
1604     *  where PRIVATE is highest and PUBLIC is lowest.
1605     */
1606    static int protection(long flags) {
1607        switch ((short)(flags & AccessFlags)) {
1608        case PRIVATE: return 3;
1609        case PROTECTED: return 1;
1610        default:
1611        case PUBLIC: return 0;
1612        case 0: return 2;
1613        }
1614    }
1615
1616    /** A customized "cannot override" error message.
1617     *  @param m      The overriding method.
1618     *  @param other  The overridden method.
1619     *  @return       An internationalized string.
1620     */
1621    Fragment cannotOverride(MethodSymbol m, MethodSymbol other) {
1622        Symbol mloc = m.location();
1623        Symbol oloc = other.location();
1624
1625        if ((other.owner.flags() & INTERFACE) == 0)
1626            return Fragments.CantOverride(m, mloc, other, oloc);
1627        else if ((m.owner.flags() & INTERFACE) == 0)
1628            return Fragments.CantImplement(m, mloc, other, oloc);
1629        else
1630            return Fragments.ClashesWith(m, mloc, other, oloc);
1631    }
1632
1633    /** A customized "override" warning message.
1634     *  @param m      The overriding method.
1635     *  @param other  The overridden method.
1636     *  @return       An internationalized string.
1637     */
1638    Fragment uncheckedOverrides(MethodSymbol m, MethodSymbol other) {
1639        Symbol mloc = m.location();
1640        Symbol oloc = other.location();
1641
1642        if ((other.owner.flags() & INTERFACE) == 0)
1643            return Fragments.UncheckedOverride(m, mloc, other, oloc);
1644        else if ((m.owner.flags() & INTERFACE) == 0)
1645            return Fragments.UncheckedImplement(m, mloc, other, oloc);
1646        else
1647            return Fragments.UncheckedClashWith(m, mloc, other, oloc);
1648    }
1649
1650    /** A customized "override" warning message.
1651     *  @param m      The overriding method.
1652     *  @param other  The overridden method.
1653     *  @return       An internationalized string.
1654     */
1655    Fragment varargsOverrides(MethodSymbol m, MethodSymbol other) {
1656        Symbol mloc = m.location();
1657        Symbol oloc = other.location();
1658
1659        if ((other.owner.flags() & INTERFACE) == 0)
1660            return Fragments.VarargsOverride(m, mloc, other, oloc);
1661        else  if ((m.owner.flags() & INTERFACE) == 0)
1662            return Fragments.VarargsImplement(m, mloc, other, oloc);
1663        else
1664            return Fragments.VarargsClashWith(m, mloc, other, oloc);
1665    }
1666
1667    /** Check that this method conforms with overridden method 'other'.
1668     *  where `origin' is the class where checking started.
1669     *  Complications:
1670     *  (1) Do not check overriding of synthetic methods
1671     *      (reason: they might be final).
1672     *      todo: check whether this is still necessary.
1673     *  (2) Admit the case where an interface proxy throws fewer exceptions
1674     *      than the method it implements. Augment the proxy methods with the
1675     *      undeclared exceptions in this case.
1676     *  (3) When generics are enabled, admit the case where an interface proxy
1677     *      has a result type
1678     *      extended by the result type of the method it implements.
1679     *      Change the proxies result type to the smaller type in this case.
1680     *
1681     *  @param tree         The tree from which positions
1682     *                      are extracted for errors.
1683     *  @param m            The overriding method.
1684     *  @param other        The overridden method.
1685     *  @param origin       The class of which the overriding method
1686     *                      is a member.
1687     */
1688    void checkOverride(JCTree tree,
1689                       MethodSymbol m,
1690                       MethodSymbol other,
1691                       ClassSymbol origin) {
1692        // Don't check overriding of synthetic methods or by bridge methods.
1693        if ((m.flags() & (SYNTHETIC|BRIDGE)) != 0 || (other.flags() & SYNTHETIC) != 0) {
1694            return;
1695        }
1696
1697        // Error if static method overrides instance method (JLS 8.4.6.2).
1698        if ((m.flags() & STATIC) != 0 &&
1699                   (other.flags() & STATIC) == 0) {
1700            log.error(TreeInfo.diagnosticPositionFor(m, tree),
1701                      Errors.OverrideStatic(cannotOverride(m, other)));
1702            m.flags_field |= BAD_OVERRIDE;
1703            return;
1704        }
1705
1706        // Error if instance method overrides static or final
1707        // method (JLS 8.4.6.1).
1708        if ((other.flags() & FINAL) != 0 ||
1709                 (m.flags() & STATIC) == 0 &&
1710                 (other.flags() & STATIC) != 0) {
1711            log.error(TreeInfo.diagnosticPositionFor(m, tree),
1712                      Errors.OverrideMeth(cannotOverride(m, other),
1713                                          asFlagSet(other.flags() & (FINAL | STATIC))));
1714            m.flags_field |= BAD_OVERRIDE;
1715            return;
1716        }
1717
1718        if ((m.owner.flags() & ANNOTATION) != 0) {
1719            // handled in validateAnnotationMethod
1720            return;
1721        }
1722
1723        // Error if overriding method has weaker access (JLS 8.4.6.3).
1724        if (protection(m.flags()) > protection(other.flags())) {
1725            log.error(TreeInfo.diagnosticPositionFor(m, tree),
1726                      (other.flags() & AccessFlags) == 0 ?
1727                              Errors.OverrideWeakerAccess(cannotOverride(m, other),
1728                                                          "package") :
1729                              Errors.OverrideWeakerAccess(cannotOverride(m, other),
1730                                                          asFlagSet(other.flags() & AccessFlags)));
1731            m.flags_field |= BAD_OVERRIDE;
1732            return;
1733        }
1734
1735        Type mt = types.memberType(origin.type, m);
1736        Type ot = types.memberType(origin.type, other);
1737        // Error if overriding result type is different
1738        // (or, in the case of generics mode, not a subtype) of
1739        // overridden result type. We have to rename any type parameters
1740        // before comparing types.
1741        List<Type> mtvars = mt.getTypeArguments();
1742        List<Type> otvars = ot.getTypeArguments();
1743        Type mtres = mt.getReturnType();
1744        Type otres = types.subst(ot.getReturnType(), otvars, mtvars);
1745
1746        overrideWarner.clear();
1747        boolean resultTypesOK =
1748            types.returnTypeSubstitutable(mt, ot, otres, overrideWarner);
1749        if (!resultTypesOK) {
1750            if ((m.flags() & STATIC) != 0 && (other.flags() & STATIC) != 0) {
1751                log.error(TreeInfo.diagnosticPositionFor(m, tree),
1752                          Errors.OverrideIncompatibleRet(Fragments.CantHide(m, m.location(), other,
1753                                        other.location()), mtres, otres));
1754                m.flags_field |= BAD_OVERRIDE;
1755            } else {
1756                log.error(TreeInfo.diagnosticPositionFor(m, tree),
1757                          Errors.OverrideIncompatibleRet(cannotOverride(m, other), mtres, otres));
1758                m.flags_field |= BAD_OVERRIDE;
1759            }
1760            return;
1761        } else if (overrideWarner.hasNonSilentLint(LintCategory.UNCHECKED)) {
1762            warnUnchecked(TreeInfo.diagnosticPositionFor(m, tree),
1763                    "override.unchecked.ret",
1764                    uncheckedOverrides(m, other),
1765                    mtres, otres);
1766        }
1767
1768        // Error if overriding method throws an exception not reported
1769        // by overridden method.
1770        List<Type> otthrown = types.subst(ot.getThrownTypes(), otvars, mtvars);
1771        List<Type> unhandledErased = unhandled(mt.getThrownTypes(), types.erasure(otthrown));
1772        List<Type> unhandledUnerased = unhandled(mt.getThrownTypes(), otthrown);
1773        if (unhandledErased.nonEmpty()) {
1774            log.error(TreeInfo.diagnosticPositionFor(m, tree),
1775                      Errors.OverrideMethDoesntThrow(cannotOverride(m, other), unhandledUnerased.head));
1776            m.flags_field |= BAD_OVERRIDE;
1777            return;
1778        }
1779        else if (unhandledUnerased.nonEmpty()) {
1780            warnUnchecked(TreeInfo.diagnosticPositionFor(m, tree),
1781                          "override.unchecked.thrown",
1782                         cannotOverride(m, other),
1783                         unhandledUnerased.head);
1784            return;
1785        }
1786
1787        // Optional warning if varargs don't agree
1788        if ((((m.flags() ^ other.flags()) & Flags.VARARGS) != 0)
1789            && lint.isEnabled(LintCategory.OVERRIDES)) {
1790            log.warning(TreeInfo.diagnosticPositionFor(m, tree),
1791                        ((m.flags() & Flags.VARARGS) != 0)
1792                        ? Warnings.OverrideVarargsMissing(varargsOverrides(m, other))
1793                        : Warnings.OverrideVarargsExtra(varargsOverrides(m, other)));
1794        }
1795
1796        // Warn if instance method overrides bridge method (compiler spec ??)
1797        if ((other.flags() & BRIDGE) != 0) {
1798            log.warning(TreeInfo.diagnosticPositionFor(m, tree),
1799                        Warnings.OverrideBridge(uncheckedOverrides(m, other)));
1800        }
1801
1802        // Warn if a deprecated method overridden by a non-deprecated one.
1803        if (!isDeprecatedOverrideIgnorable(other, origin)) {
1804            Lint prevLint = setLint(lint.augment(m));
1805            try {
1806                checkDeprecated(TreeInfo.diagnosticPositionFor(m, tree), m, other);
1807            } finally {
1808                setLint(prevLint);
1809            }
1810        }
1811    }
1812    // where
1813        private boolean isDeprecatedOverrideIgnorable(MethodSymbol m, ClassSymbol origin) {
1814            // If the method, m, is defined in an interface, then ignore the issue if the method
1815            // is only inherited via a supertype and also implemented in the supertype,
1816            // because in that case, we will rediscover the issue when examining the method
1817            // in the supertype.
1818            // If the method, m, is not defined in an interface, then the only time we need to
1819            // address the issue is when the method is the supertype implemementation: any other
1820            // case, we will have dealt with when examining the supertype classes
1821            ClassSymbol mc = m.enclClass();
1822            Type st = types.supertype(origin.type);
1823            if (!st.hasTag(CLASS))
1824                return true;
1825            MethodSymbol stimpl = m.implementation((ClassSymbol)st.tsym, types, false);
1826
1827            if (mc != null && ((mc.flags() & INTERFACE) != 0)) {
1828                List<Type> intfs = types.interfaces(origin.type);
1829                return (intfs.contains(mc.type) ? false : (stimpl != null));
1830            }
1831            else
1832                return (stimpl != m);
1833        }
1834
1835
1836    // used to check if there were any unchecked conversions
1837    Warner overrideWarner = new Warner();
1838
1839    /** Check that a class does not inherit two concrete methods
1840     *  with the same signature.
1841     *  @param pos          Position to be used for error reporting.
1842     *  @param site         The class type to be checked.
1843     */
1844    public void checkCompatibleConcretes(DiagnosticPosition pos, Type site) {
1845        Type sup = types.supertype(site);
1846        if (!sup.hasTag(CLASS)) return;
1847
1848        for (Type t1 = sup;
1849             t1.hasTag(CLASS) && t1.tsym.type.isParameterized();
1850             t1 = types.supertype(t1)) {
1851            for (Symbol s1 : t1.tsym.members().getSymbols(NON_RECURSIVE)) {
1852                if (s1.kind != MTH ||
1853                    (s1.flags() & (STATIC|SYNTHETIC|BRIDGE)) != 0 ||
1854                    !s1.isInheritedIn(site.tsym, types) ||
1855                    ((MethodSymbol)s1).implementation(site.tsym,
1856                                                      types,
1857                                                      true) != s1)
1858                    continue;
1859                Type st1 = types.memberType(t1, s1);
1860                int s1ArgsLength = st1.getParameterTypes().length();
1861                if (st1 == s1.type) continue;
1862
1863                for (Type t2 = sup;
1864                     t2.hasTag(CLASS);
1865                     t2 = types.supertype(t2)) {
1866                    for (Symbol s2 : t2.tsym.members().getSymbolsByName(s1.name)) {
1867                        if (s2 == s1 ||
1868                            s2.kind != MTH ||
1869                            (s2.flags() & (STATIC|SYNTHETIC|BRIDGE)) != 0 ||
1870                            s2.type.getParameterTypes().length() != s1ArgsLength ||
1871                            !s2.isInheritedIn(site.tsym, types) ||
1872                            ((MethodSymbol)s2).implementation(site.tsym,
1873                                                              types,
1874                                                              true) != s2)
1875                            continue;
1876                        Type st2 = types.memberType(t2, s2);
1877                        if (types.overrideEquivalent(st1, st2))
1878                            log.error(pos,
1879                                      Errors.ConcreteInheritanceConflict(s1, t1, s2, t2, sup));
1880                    }
1881                }
1882            }
1883        }
1884    }
1885
1886    /** Check that classes (or interfaces) do not each define an abstract
1887     *  method with same name and arguments but incompatible return types.
1888     *  @param pos          Position to be used for error reporting.
1889     *  @param t1           The first argument type.
1890     *  @param t2           The second argument type.
1891     */
1892    public boolean checkCompatibleAbstracts(DiagnosticPosition pos,
1893                                            Type t1,
1894                                            Type t2,
1895                                            Type site) {
1896        if ((site.tsym.flags() & COMPOUND) != 0) {
1897            // special case for intersections: need to eliminate wildcards in supertypes
1898            t1 = types.capture(t1);
1899            t2 = types.capture(t2);
1900        }
1901        return firstIncompatibility(pos, t1, t2, site) == null;
1902    }
1903
1904    /** Return the first method which is defined with same args
1905     *  but different return types in two given interfaces, or null if none
1906     *  exists.
1907     *  @param t1     The first type.
1908     *  @param t2     The second type.
1909     *  @param site   The most derived type.
1910     *  @returns symbol from t2 that conflicts with one in t1.
1911     */
1912    private Symbol firstIncompatibility(DiagnosticPosition pos, Type t1, Type t2, Type site) {
1913        Map<TypeSymbol,Type> interfaces1 = new HashMap<>();
1914        closure(t1, interfaces1);
1915        Map<TypeSymbol,Type> interfaces2;
1916        if (t1 == t2)
1917            interfaces2 = interfaces1;
1918        else
1919            closure(t2, interfaces1, interfaces2 = new HashMap<>());
1920
1921        for (Type t3 : interfaces1.values()) {
1922            for (Type t4 : interfaces2.values()) {
1923                Symbol s = firstDirectIncompatibility(pos, t3, t4, site);
1924                if (s != null) return s;
1925            }
1926        }
1927        return null;
1928    }
1929
1930    /** Compute all the supertypes of t, indexed by type symbol. */
1931    private void closure(Type t, Map<TypeSymbol,Type> typeMap) {
1932        if (!t.hasTag(CLASS)) return;
1933        if (typeMap.put(t.tsym, t) == null) {
1934            closure(types.supertype(t), typeMap);
1935            for (Type i : types.interfaces(t))
1936                closure(i, typeMap);
1937        }
1938    }
1939
1940    /** Compute all the supertypes of t, indexed by type symbol (except thise in typesSkip). */
1941    private void closure(Type t, Map<TypeSymbol,Type> typesSkip, Map<TypeSymbol,Type> typeMap) {
1942        if (!t.hasTag(CLASS)) return;
1943        if (typesSkip.get(t.tsym) != null) return;
1944        if (typeMap.put(t.tsym, t) == null) {
1945            closure(types.supertype(t), typesSkip, typeMap);
1946            for (Type i : types.interfaces(t))
1947                closure(i, typesSkip, typeMap);
1948        }
1949    }
1950
1951    /** Return the first method in t2 that conflicts with a method from t1. */
1952    private Symbol firstDirectIncompatibility(DiagnosticPosition pos, Type t1, Type t2, Type site) {
1953        for (Symbol s1 : t1.tsym.members().getSymbols(NON_RECURSIVE)) {
1954            Type st1 = null;
1955            if (s1.kind != MTH || !s1.isInheritedIn(site.tsym, types) ||
1956                    (s1.flags() & SYNTHETIC) != 0) continue;
1957            Symbol impl = ((MethodSymbol)s1).implementation(site.tsym, types, false);
1958            if (impl != null && (impl.flags() & ABSTRACT) == 0) continue;
1959            for (Symbol s2 : t2.tsym.members().getSymbolsByName(s1.name)) {
1960                if (s1 == s2) continue;
1961                if (s2.kind != MTH || !s2.isInheritedIn(site.tsym, types) ||
1962                        (s2.flags() & SYNTHETIC) != 0) continue;
1963                if (st1 == null) st1 = types.memberType(t1, s1);
1964                Type st2 = types.memberType(t2, s2);
1965                if (types.overrideEquivalent(st1, st2)) {
1966                    List<Type> tvars1 = st1.getTypeArguments();
1967                    List<Type> tvars2 = st2.getTypeArguments();
1968                    Type rt1 = st1.getReturnType();
1969                    Type rt2 = types.subst(st2.getReturnType(), tvars2, tvars1);
1970                    boolean compat =
1971                        types.isSameType(rt1, rt2) ||
1972                        !rt1.isPrimitiveOrVoid() &&
1973                        !rt2.isPrimitiveOrVoid() &&
1974                        (types.covariantReturnType(rt1, rt2, types.noWarnings) ||
1975                         types.covariantReturnType(rt2, rt1, types.noWarnings)) ||
1976                         checkCommonOverriderIn(s1,s2,site);
1977                    if (!compat) {
1978                        log.error(pos, Errors.TypesIncompatibleDiffRet(t1, t2, s2.name +
1979                                "(" + types.memberType(t2, s2).getParameterTypes() + ")"));
1980                        return s2;
1981                    }
1982                } else if (checkNameClash((ClassSymbol)site.tsym, s1, s2) &&
1983                        !checkCommonOverriderIn(s1, s2, site)) {
1984                    log.error(pos, Errors.NameClashSameErasureNoOverride(
1985                            s1.name, types.memberType(site, s1).asMethodType().getParameterTypes(), s1.location(),
1986                            s2.name, types.memberType(site, s2).asMethodType().getParameterTypes(), s2.location()));
1987                    return s2;
1988                }
1989            }
1990        }
1991        return null;
1992    }
1993    //WHERE
1994    boolean checkCommonOverriderIn(Symbol s1, Symbol s2, Type site) {
1995        Map<TypeSymbol,Type> supertypes = new HashMap<>();
1996        Type st1 = types.memberType(site, s1);
1997        Type st2 = types.memberType(site, s2);
1998        closure(site, supertypes);
1999        for (Type t : supertypes.values()) {
2000            for (Symbol s3 : t.tsym.members().getSymbolsByName(s1.name)) {
2001                if (s3 == s1 || s3 == s2 || s3.kind != MTH || (s3.flags() & (BRIDGE|SYNTHETIC)) != 0) continue;
2002                Type st3 = types.memberType(site,s3);
2003                if (types.overrideEquivalent(st3, st1) &&
2004                        types.overrideEquivalent(st3, st2) &&
2005                        types.returnTypeSubstitutable(st3, st1) &&
2006                        types.returnTypeSubstitutable(st3, st2)) {
2007                    return true;
2008                }
2009            }
2010        }
2011        return false;
2012    }
2013
2014    /** Check that a given method conforms with any method it overrides.
2015     *  @param tree         The tree from which positions are extracted
2016     *                      for errors.
2017     *  @param m            The overriding method.
2018     */
2019    void checkOverride(Env<AttrContext> env, JCMethodDecl tree, MethodSymbol m) {
2020        ClassSymbol origin = (ClassSymbol)m.owner;
2021        if ((origin.flags() & ENUM) != 0 && names.finalize.equals(m.name))
2022            if (m.overrides(syms.enumFinalFinalize, origin, types, false)) {
2023                log.error(tree.pos(), Errors.EnumNoFinalize);
2024                return;
2025            }
2026        for (Type t = origin.type; t.hasTag(CLASS);
2027             t = types.supertype(t)) {
2028            if (t != origin.type) {
2029                checkOverride(tree, t, origin, m);
2030            }
2031            for (Type t2 : types.interfaces(t)) {
2032                checkOverride(tree, t2, origin, m);
2033            }
2034        }
2035
2036        final boolean explicitOverride = m.attribute(syms.overrideType.tsym) != null;
2037        // Check if this method must override a super method due to being annotated with @Override
2038        // or by virtue of being a member of a diamond inferred anonymous class. Latter case is to
2039        // be treated "as if as they were annotated" with @Override.
2040        boolean mustOverride = explicitOverride ||
2041                (env.info.isAnonymousDiamond && !m.isConstructor() && !m.isPrivate());
2042        if (mustOverride && !isOverrider(m)) {
2043            DiagnosticPosition pos = tree.pos();
2044            for (JCAnnotation a : tree.getModifiers().annotations) {
2045                if (a.annotationType.type.tsym == syms.overrideType.tsym) {
2046                    pos = a.pos();
2047                    break;
2048                }
2049            }
2050            log.error(pos,
2051                      explicitOverride ? Errors.MethodDoesNotOverrideSuperclass :
2052                                Errors.AnonymousDiamondMethodDoesNotOverrideSuperclass(Fragments.DiamondAnonymousMethodsImplicitlyOverride));
2053        }
2054    }
2055
2056    void checkOverride(JCTree tree, Type site, ClassSymbol origin, MethodSymbol m) {
2057        TypeSymbol c = site.tsym;
2058        for (Symbol sym : c.members().getSymbolsByName(m.name)) {
2059            if (m.overrides(sym, origin, types, false)) {
2060                if ((sym.flags() & ABSTRACT) == 0) {
2061                    checkOverride(tree, m, (MethodSymbol)sym, origin);
2062                }
2063            }
2064        }
2065    }
2066
2067    private Filter<Symbol> equalsHasCodeFilter = s -> MethodSymbol.implementation_filter.accepts(s) &&
2068            (s.flags() & BAD_OVERRIDE) == 0;
2069
2070    public void checkClassOverrideEqualsAndHashIfNeeded(DiagnosticPosition pos,
2071            ClassSymbol someClass) {
2072        /* At present, annotations cannot possibly have a method that is override
2073         * equivalent with Object.equals(Object) but in any case the condition is
2074         * fine for completeness.
2075         */
2076        if (someClass == (ClassSymbol)syms.objectType.tsym ||
2077            someClass.isInterface() || someClass.isEnum() ||
2078            (someClass.flags() & ANNOTATION) != 0 ||
2079            (someClass.flags() & ABSTRACT) != 0) return;
2080        //anonymous inner classes implementing interfaces need especial treatment
2081        if (someClass.isAnonymous()) {
2082            List<Type> interfaces =  types.interfaces(someClass.type);
2083            if (interfaces != null && !interfaces.isEmpty() &&
2084                interfaces.head.tsym == syms.comparatorType.tsym) return;
2085        }
2086        checkClassOverrideEqualsAndHash(pos, someClass);
2087    }
2088
2089    private void checkClassOverrideEqualsAndHash(DiagnosticPosition pos,
2090            ClassSymbol someClass) {
2091        if (lint.isEnabled(LintCategory.OVERRIDES)) {
2092            MethodSymbol equalsAtObject = (MethodSymbol)syms.objectType
2093                    .tsym.members().findFirst(names.equals);
2094            MethodSymbol hashCodeAtObject = (MethodSymbol)syms.objectType
2095                    .tsym.members().findFirst(names.hashCode);
2096            boolean overridesEquals = types.implementation(equalsAtObject,
2097                someClass, false, equalsHasCodeFilter).owner == someClass;
2098            boolean overridesHashCode = types.implementation(hashCodeAtObject,
2099                someClass, false, equalsHasCodeFilter) != hashCodeAtObject;
2100
2101            if (overridesEquals && !overridesHashCode) {
2102                log.warning(LintCategory.OVERRIDES, pos,
2103                            Warnings.OverrideEqualsButNotHashcode(someClass));
2104            }
2105        }
2106    }
2107
2108    public void checkModuleName (JCModuleDecl tree) {
2109        Name moduleName = tree.sym.name;
2110        Assert.checkNonNull(moduleName);
2111        if (lint.isEnabled(LintCategory.MODULE)) {
2112            JCExpression qualId = tree.qualId;
2113            while (qualId != null) {
2114                Name componentName;
2115                DiagnosticPosition pos;
2116                switch (qualId.getTag()) {
2117                    case SELECT:
2118                        JCFieldAccess selectNode = ((JCFieldAccess) qualId);
2119                        componentName = selectNode.name;
2120                        pos = selectNode.pos();
2121                        qualId = selectNode.selected;
2122                        break;
2123                    case IDENT:
2124                        componentName = ((JCIdent) qualId).name;
2125                        pos = qualId.pos();
2126                        qualId = null;
2127                        break;
2128                    default:
2129                        throw new AssertionError("Unexpected qualified identifier: " + qualId.toString());
2130                }
2131                if (componentName != null) {
2132                    String moduleNameComponentString = componentName.toString();
2133                    int nameLength = moduleNameComponentString.length();
2134                    if (nameLength > 0 && Character.isDigit(moduleNameComponentString.charAt(nameLength - 1))) {
2135                        log.warning(Lint.LintCategory.MODULE, pos, Warnings.PoorChoiceForModuleName(componentName));
2136                    }
2137                }
2138            }
2139        }
2140    }
2141
2142    private boolean checkNameClash(ClassSymbol origin, Symbol s1, Symbol s2) {
2143        ClashFilter cf = new ClashFilter(origin.type);
2144        return (cf.accepts(s1) &&
2145                cf.accepts(s2) &&
2146                types.hasSameArgs(s1.erasure(types), s2.erasure(types)));
2147    }
2148
2149
2150    /** Check that all abstract members of given class have definitions.
2151     *  @param pos          Position to be used for error reporting.
2152     *  @param c            The class.
2153     */
2154    void checkAllDefined(DiagnosticPosition pos, ClassSymbol c) {
2155        MethodSymbol undef = types.firstUnimplementedAbstract(c);
2156        if (undef != null) {
2157            MethodSymbol undef1 =
2158                new MethodSymbol(undef.flags(), undef.name,
2159                                 types.memberType(c.type, undef), undef.owner);
2160            log.error(pos,
2161                      Errors.DoesNotOverrideAbstract(c, undef1, undef1.location()));
2162        }
2163    }
2164
2165    void checkNonCyclicDecl(JCClassDecl tree) {
2166        CycleChecker cc = new CycleChecker();
2167        cc.scan(tree);
2168        if (!cc.errorFound && !cc.partialCheck) {
2169            tree.sym.flags_field |= ACYCLIC;
2170        }
2171    }
2172
2173    class CycleChecker extends TreeScanner {
2174
2175        List<Symbol> seenClasses = List.nil();
2176        boolean errorFound = false;
2177        boolean partialCheck = false;
2178
2179        private void checkSymbol(DiagnosticPosition pos, Symbol sym) {
2180            if (sym != null && sym.kind == TYP) {
2181                Env<AttrContext> classEnv = enter.getEnv((TypeSymbol)sym);
2182                if (classEnv != null) {
2183                    DiagnosticSource prevSource = log.currentSource();
2184                    try {
2185                        log.useSource(classEnv.toplevel.sourcefile);
2186                        scan(classEnv.tree);
2187                    }
2188                    finally {
2189                        log.useSource(prevSource.getFile());
2190                    }
2191                } else if (sym.kind == TYP) {
2192                    checkClass(pos, sym, List.nil());
2193                }
2194            } else {
2195                //not completed yet
2196                partialCheck = true;
2197            }
2198        }
2199
2200        @Override
2201        public void visitSelect(JCFieldAccess tree) {
2202            super.visitSelect(tree);
2203            checkSymbol(tree.pos(), tree.sym);
2204        }
2205
2206        @Override
2207        public void visitIdent(JCIdent tree) {
2208            checkSymbol(tree.pos(), tree.sym);
2209        }
2210
2211        @Override
2212        public void visitTypeApply(JCTypeApply tree) {
2213            scan(tree.clazz);
2214        }
2215
2216        @Override
2217        public void visitTypeArray(JCArrayTypeTree tree) {
2218            scan(tree.elemtype);
2219        }
2220
2221        @Override
2222        public void visitClassDef(JCClassDecl tree) {
2223            List<JCTree> supertypes = List.nil();
2224            if (tree.getExtendsClause() != null) {
2225                supertypes = supertypes.prepend(tree.getExtendsClause());
2226            }
2227            if (tree.getImplementsClause() != null) {
2228                for (JCTree intf : tree.getImplementsClause()) {
2229                    supertypes = supertypes.prepend(intf);
2230                }
2231            }
2232            checkClass(tree.pos(), tree.sym, supertypes);
2233        }
2234
2235        void checkClass(DiagnosticPosition pos, Symbol c, List<JCTree> supertypes) {
2236            if ((c.flags_field & ACYCLIC) != 0)
2237                return;
2238            if (seenClasses.contains(c)) {
2239                errorFound = true;
2240                noteCyclic(pos, (ClassSymbol)c);
2241            } else if (!c.type.isErroneous()) {
2242                try {
2243                    seenClasses = seenClasses.prepend(c);
2244                    if (c.type.hasTag(CLASS)) {
2245                        if (supertypes.nonEmpty()) {
2246                            scan(supertypes);
2247                        }
2248                        else {
2249                            ClassType ct = (ClassType)c.type;
2250                            if (ct.supertype_field == null ||
2251                                    ct.interfaces_field == null) {
2252                                //not completed yet
2253                                partialCheck = true;
2254                                return;
2255                            }
2256                            checkSymbol(pos, ct.supertype_field.tsym);
2257                            for (Type intf : ct.interfaces_field) {
2258                                checkSymbol(pos, intf.tsym);
2259                            }
2260                        }
2261                        if (c.owner.kind == TYP) {
2262                            checkSymbol(pos, c.owner);
2263                        }
2264                    }
2265                } finally {
2266                    seenClasses = seenClasses.tail;
2267                }
2268            }
2269        }
2270    }
2271
2272    /** Check for cyclic references. Issue an error if the
2273     *  symbol of the type referred to has a LOCKED flag set.
2274     *
2275     *  @param pos      Position to be used for error reporting.
2276     *  @param t        The type referred to.
2277     */
2278    void checkNonCyclic(DiagnosticPosition pos, Type t) {
2279        checkNonCyclicInternal(pos, t);
2280    }
2281
2282
2283    void checkNonCyclic(DiagnosticPosition pos, TypeVar t) {
2284        checkNonCyclic1(pos, t, List.nil());
2285    }
2286
2287    private void checkNonCyclic1(DiagnosticPosition pos, Type t, List<TypeVar> seen) {
2288        final TypeVar tv;
2289        if  (t.hasTag(TYPEVAR) && (t.tsym.flags() & UNATTRIBUTED) != 0)
2290            return;
2291        if (seen.contains(t)) {
2292            tv = (TypeVar)t;
2293            tv.bound = types.createErrorType(t);
2294            log.error(pos, Errors.CyclicInheritance(t));
2295        } else if (t.hasTag(TYPEVAR)) {
2296            tv = (TypeVar)t;
2297            seen = seen.prepend(tv);
2298            for (Type b : types.getBounds(tv))
2299                checkNonCyclic1(pos, b, seen);
2300        }
2301    }
2302
2303    /** Check for cyclic references. Issue an error if the
2304     *  symbol of the type referred to has a LOCKED flag set.
2305     *
2306     *  @param pos      Position to be used for error reporting.
2307     *  @param t        The type referred to.
2308     *  @returns        True if the check completed on all attributed classes
2309     */
2310    private boolean checkNonCyclicInternal(DiagnosticPosition pos, Type t) {
2311        boolean complete = true; // was the check complete?
2312        //- System.err.println("checkNonCyclicInternal("+t+");");//DEBUG
2313        Symbol c = t.tsym;
2314        if ((c.flags_field & ACYCLIC) != 0) return true;
2315
2316        if ((c.flags_field & LOCKED) != 0) {
2317            noteCyclic(pos, (ClassSymbol)c);
2318        } else if (!c.type.isErroneous()) {
2319            try {
2320                c.flags_field |= LOCKED;
2321                if (c.type.hasTag(CLASS)) {
2322                    ClassType clazz = (ClassType)c.type;
2323                    if (clazz.interfaces_field != null)
2324                        for (List<Type> l=clazz.interfaces_field; l.nonEmpty(); l=l.tail)
2325                            complete &= checkNonCyclicInternal(pos, l.head);
2326                    if (clazz.supertype_field != null) {
2327                        Type st = clazz.supertype_field;
2328                        if (st != null && st.hasTag(CLASS))
2329                            complete &= checkNonCyclicInternal(pos, st);
2330                    }
2331                    if (c.owner.kind == TYP)
2332                        complete &= checkNonCyclicInternal(pos, c.owner.type);
2333                }
2334            } finally {
2335                c.flags_field &= ~LOCKED;
2336            }
2337        }
2338        if (complete)
2339            complete = ((c.flags_field & UNATTRIBUTED) == 0) && c.isCompleted();
2340        if (complete) c.flags_field |= ACYCLIC;
2341        return complete;
2342    }
2343
2344    /** Note that we found an inheritance cycle. */
2345    private void noteCyclic(DiagnosticPosition pos, ClassSymbol c) {
2346        log.error(pos, Errors.CyclicInheritance(c));
2347        for (List<Type> l=types.interfaces(c.type); l.nonEmpty(); l=l.tail)
2348            l.head = types.createErrorType((ClassSymbol)l.head.tsym, Type.noType);
2349        Type st = types.supertype(c.type);
2350        if (st.hasTag(CLASS))
2351            ((ClassType)c.type).supertype_field = types.createErrorType((ClassSymbol)st.tsym, Type.noType);
2352        c.type = types.createErrorType(c, c.type);
2353        c.flags_field |= ACYCLIC;
2354    }
2355
2356    /** Check that all methods which implement some
2357     *  method conform to the method they implement.
2358     *  @param tree         The class definition whose members are checked.
2359     */
2360    void checkImplementations(JCClassDecl tree) {
2361        checkImplementations(tree, tree.sym, tree.sym);
2362    }
2363    //where
2364        /** Check that all methods which implement some
2365         *  method in `ic' conform to the method they implement.
2366         */
2367        void checkImplementations(JCTree tree, ClassSymbol origin, ClassSymbol ic) {
2368            for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) {
2369                ClassSymbol lc = (ClassSymbol)l.head.tsym;
2370                if ((lc.flags() & ABSTRACT) != 0) {
2371                    for (Symbol sym : lc.members().getSymbols(NON_RECURSIVE)) {
2372                        if (sym.kind == MTH &&
2373                            (sym.flags() & (STATIC|ABSTRACT)) == ABSTRACT) {
2374                            MethodSymbol absmeth = (MethodSymbol)sym;
2375                            MethodSymbol implmeth = absmeth.implementation(origin, types, false);
2376                            if (implmeth != null && implmeth != absmeth &&
2377                                (implmeth.owner.flags() & INTERFACE) ==
2378                                (origin.flags() & INTERFACE)) {
2379                                // don't check if implmeth is in a class, yet
2380                                // origin is an interface. This case arises only
2381                                // if implmeth is declared in Object. The reason is
2382                                // that interfaces really don't inherit from
2383                                // Object it's just that the compiler represents
2384                                // things that way.
2385                                checkOverride(tree, implmeth, absmeth, origin);
2386                            }
2387                        }
2388                    }
2389                }
2390            }
2391        }
2392
2393    /** Check that all abstract methods implemented by a class are
2394     *  mutually compatible.
2395     *  @param pos          Position to be used for error reporting.
2396     *  @param c            The class whose interfaces are checked.
2397     */
2398    void checkCompatibleSupertypes(DiagnosticPosition pos, Type c) {
2399        List<Type> supertypes = types.interfaces(c);
2400        Type supertype = types.supertype(c);
2401        if (supertype.hasTag(CLASS) &&
2402            (supertype.tsym.flags() & ABSTRACT) != 0)
2403            supertypes = supertypes.prepend(supertype);
2404        for (List<Type> l = supertypes; l.nonEmpty(); l = l.tail) {
2405            if (!l.head.getTypeArguments().isEmpty() &&
2406                !checkCompatibleAbstracts(pos, l.head, l.head, c))
2407                return;
2408            for (List<Type> m = supertypes; m != l; m = m.tail)
2409                if (!checkCompatibleAbstracts(pos, l.head, m.head, c))
2410                    return;
2411        }
2412        checkCompatibleConcretes(pos, c);
2413    }
2414
2415    void checkConflicts(DiagnosticPosition pos, Symbol sym, TypeSymbol c) {
2416        for (Type ct = c.type; ct != Type.noType ; ct = types.supertype(ct)) {
2417            for (Symbol sym2 : ct.tsym.members().getSymbolsByName(sym.name, NON_RECURSIVE)) {
2418                // VM allows methods and variables with differing types
2419                if (sym.kind == sym2.kind &&
2420                    types.isSameType(types.erasure(sym.type), types.erasure(sym2.type)) &&
2421                    sym != sym2 &&
2422                    (sym.flags() & Flags.SYNTHETIC) != (sym2.flags() & Flags.SYNTHETIC) &&
2423                    (sym.flags() & BRIDGE) == 0 && (sym2.flags() & BRIDGE) == 0) {
2424                    syntheticError(pos, (sym2.flags() & SYNTHETIC) == 0 ? sym2 : sym);
2425                    return;
2426                }
2427            }
2428        }
2429    }
2430
2431    /** Check that all non-override equivalent methods accessible from 'site'
2432     *  are mutually compatible (JLS 8.4.8/9.4.1).
2433     *
2434     *  @param pos  Position to be used for error reporting.
2435     *  @param site The class whose methods are checked.
2436     *  @param sym  The method symbol to be checked.
2437     */
2438    void checkOverrideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
2439         ClashFilter cf = new ClashFilter(site);
2440        //for each method m1 that is overridden (directly or indirectly)
2441        //by method 'sym' in 'site'...
2442
2443        List<MethodSymbol> potentiallyAmbiguousList = List.nil();
2444        boolean overridesAny = false;
2445        for (Symbol m1 : types.membersClosure(site, false).getSymbolsByName(sym.name, cf)) {
2446            if (!sym.overrides(m1, site.tsym, types, false)) {
2447                if (m1 == sym) {
2448                    continue;
2449                }
2450
2451                if (!overridesAny) {
2452                    potentiallyAmbiguousList = potentiallyAmbiguousList.prepend((MethodSymbol)m1);
2453                }
2454                continue;
2455            }
2456
2457            if (m1 != sym) {
2458                overridesAny = true;
2459                potentiallyAmbiguousList = List.nil();
2460            }
2461
2462            //...check each method m2 that is a member of 'site'
2463            for (Symbol m2 : types.membersClosure(site, false).getSymbolsByName(sym.name, cf)) {
2464                if (m2 == m1) continue;
2465                //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
2466                //a member of 'site') and (ii) m1 has the same erasure as m2, issue an error
2467                if (!types.isSubSignature(sym.type, types.memberType(site, m2), allowStrictMethodClashCheck) &&
2468                        types.hasSameArgs(m2.erasure(types), m1.erasure(types))) {
2469                    sym.flags_field |= CLASH;
2470                    if (m1 == sym) {
2471                        log.error(pos, Errors.NameClashSameErasureNoOverride(
2472                            m1.name, types.memberType(site, m1).asMethodType().getParameterTypes(), m1.location(),
2473                            m2.name, types.memberType(site, m2).asMethodType().getParameterTypes(), m2.location()));
2474                    } else {
2475                        ClassType ct = (ClassType)site;
2476                        String kind = ct.isInterface() ? "interface" : "class";
2477                        log.error(pos, Errors.NameClashSameErasureNoOverride1(
2478                            kind,
2479                            ct.tsym.name,
2480                            m1.name,
2481                            types.memberType(site, m1).asMethodType().getParameterTypes(),
2482                            m1.location(),
2483                            m2.name,
2484                            types.memberType(site, m2).asMethodType().getParameterTypes(),
2485                            m2.location()));
2486                    }
2487                    return;
2488                }
2489            }
2490        }
2491
2492        if (!overridesAny) {
2493            for (MethodSymbol m: potentiallyAmbiguousList) {
2494                checkPotentiallyAmbiguousOverloads(pos, site, sym, m);
2495            }
2496        }
2497    }
2498
2499    /** Check that all static methods accessible from 'site' are
2500     *  mutually compatible (JLS 8.4.8).
2501     *
2502     *  @param pos  Position to be used for error reporting.
2503     *  @param site The class whose methods are checked.
2504     *  @param sym  The method symbol to be checked.
2505     */
2506    void checkHideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
2507        ClashFilter cf = new ClashFilter(site);
2508        //for each method m1 that is a member of 'site'...
2509        for (Symbol s : types.membersClosure(site, true).getSymbolsByName(sym.name, cf)) {
2510            //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
2511            //a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error
2512            if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck)) {
2513                if (types.hasSameArgs(s.erasure(types), sym.erasure(types))) {
2514                    log.error(pos,
2515                              Errors.NameClashSameErasureNoHide(sym, sym.location(), s, s.location()));
2516                    return;
2517                } else {
2518                    checkPotentiallyAmbiguousOverloads(pos, site, sym, (MethodSymbol)s);
2519                }
2520            }
2521         }
2522     }
2523
2524     //where
2525     private class ClashFilter implements Filter<Symbol> {
2526
2527         Type site;
2528
2529         ClashFilter(Type site) {
2530             this.site = site;
2531         }
2532
2533         boolean shouldSkip(Symbol s) {
2534             return (s.flags() & CLASH) != 0 &&
2535                s.owner == site.tsym;
2536         }
2537
2538         public boolean accepts(Symbol s) {
2539             return s.kind == MTH &&
2540                     (s.flags() & SYNTHETIC) == 0 &&
2541                     !shouldSkip(s) &&
2542                     s.isInheritedIn(site.tsym, types) &&
2543                     !s.isConstructor();
2544         }
2545     }
2546
2547    void checkDefaultMethodClashes(DiagnosticPosition pos, Type site) {
2548        DefaultMethodClashFilter dcf = new DefaultMethodClashFilter(site);
2549        for (Symbol m : types.membersClosure(site, false).getSymbols(dcf)) {
2550            Assert.check(m.kind == MTH);
2551            List<MethodSymbol> prov = types.interfaceCandidates(site, (MethodSymbol)m);
2552            if (prov.size() > 1) {
2553                ListBuffer<Symbol> abstracts = new ListBuffer<>();
2554                ListBuffer<Symbol> defaults = new ListBuffer<>();
2555                for (MethodSymbol provSym : prov) {
2556                    if ((provSym.flags() & DEFAULT) != 0) {
2557                        defaults = defaults.append(provSym);
2558                    } else if ((provSym.flags() & ABSTRACT) != 0) {
2559                        abstracts = abstracts.append(provSym);
2560                    }
2561                    if (defaults.nonEmpty() && defaults.size() + abstracts.size() >= 2) {
2562                        //strong semantics - issue an error if two sibling interfaces
2563                        //have two override-equivalent defaults - or if one is abstract
2564                        //and the other is default
2565                        String errKey;
2566                        Symbol s1 = defaults.first();
2567                        Symbol s2;
2568                        if (defaults.size() > 1) {
2569                            errKey = "types.incompatible.unrelated.defaults";
2570                            s2 = defaults.toList().tail.head;
2571                        } else {
2572                            errKey = "types.incompatible.abstract.default";
2573                            s2 = abstracts.first();
2574                        }
2575                        log.error(pos, errKey,
2576                                Kinds.kindName(site.tsym), site,
2577                                m.name, types.memberType(site, m).getParameterTypes(),
2578                                s1.location(), s2.location());
2579                        break;
2580                    }
2581                }
2582            }
2583        }
2584    }
2585
2586    //where
2587     private class DefaultMethodClashFilter implements Filter<Symbol> {
2588
2589         Type site;
2590
2591         DefaultMethodClashFilter(Type site) {
2592             this.site = site;
2593         }
2594
2595         public boolean accepts(Symbol s) {
2596             return s.kind == MTH &&
2597                     (s.flags() & DEFAULT) != 0 &&
2598                     s.isInheritedIn(site.tsym, types) &&
2599                     !s.isConstructor();
2600         }
2601     }
2602
2603    /**
2604      * Report warnings for potentially ambiguous method declarations. Two declarations
2605      * are potentially ambiguous if they feature two unrelated functional interface
2606      * in same argument position (in which case, a call site passing an implicit
2607      * lambda would be ambiguous).
2608      */
2609    void checkPotentiallyAmbiguousOverloads(DiagnosticPosition pos, Type site,
2610            MethodSymbol msym1, MethodSymbol msym2) {
2611        if (msym1 != msym2 &&
2612                allowDefaultMethods &&
2613                lint.isEnabled(LintCategory.OVERLOADS) &&
2614                (msym1.flags() & POTENTIALLY_AMBIGUOUS) == 0 &&
2615                (msym2.flags() & POTENTIALLY_AMBIGUOUS) == 0) {
2616            Type mt1 = types.memberType(site, msym1);
2617            Type mt2 = types.memberType(site, msym2);
2618            //if both generic methods, adjust type variables
2619            if (mt1.hasTag(FORALL) && mt2.hasTag(FORALL) &&
2620                    types.hasSameBounds((ForAll)mt1, (ForAll)mt2)) {
2621                mt2 = types.subst(mt2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars);
2622            }
2623            //expand varargs methods if needed
2624            int maxLength = Math.max(mt1.getParameterTypes().length(), mt2.getParameterTypes().length());
2625            List<Type> args1 = rs.adjustArgs(mt1.getParameterTypes(), msym1, maxLength, true);
2626            List<Type> args2 = rs.adjustArgs(mt2.getParameterTypes(), msym2, maxLength, true);
2627            //if arities don't match, exit
2628            if (args1.length() != args2.length()) return;
2629            boolean potentiallyAmbiguous = false;
2630            while (args1.nonEmpty() && args2.nonEmpty()) {
2631                Type s = args1.head;
2632                Type t = args2.head;
2633                if (!types.isSubtype(t, s) && !types.isSubtype(s, t)) {
2634                    if (types.isFunctionalInterface(s) && types.isFunctionalInterface(t) &&
2635                            types.findDescriptorType(s).getParameterTypes().length() > 0 &&
2636                            types.findDescriptorType(s).getParameterTypes().length() ==
2637                            types.findDescriptorType(t).getParameterTypes().length()) {
2638                        potentiallyAmbiguous = true;
2639                    } else {
2640                        break;
2641                    }
2642                }
2643                args1 = args1.tail;
2644                args2 = args2.tail;
2645            }
2646            if (potentiallyAmbiguous) {
2647                //we found two incompatible functional interfaces with same arity
2648                //this means a call site passing an implicit lambda would be ambigiuous
2649                msym1.flags_field |= POTENTIALLY_AMBIGUOUS;
2650                msym2.flags_field |= POTENTIALLY_AMBIGUOUS;
2651                log.warning(LintCategory.OVERLOADS, pos,
2652                            Warnings.PotentiallyAmbiguousOverload(msym1, msym1.location(),
2653                                                                  msym2, msym2.location()));
2654                return;
2655            }
2656        }
2657    }
2658
2659    void checkAccessFromSerializableElement(final JCTree tree, boolean isLambda) {
2660        if (warnOnAnyAccessToMembers ||
2661            (lint.isEnabled(LintCategory.SERIAL) &&
2662            !lint.isSuppressed(LintCategory.SERIAL) &&
2663            isLambda)) {
2664            Symbol sym = TreeInfo.symbol(tree);
2665            if (!sym.kind.matches(KindSelector.VAL_MTH)) {
2666                return;
2667            }
2668
2669            if (sym.kind == VAR) {
2670                if ((sym.flags() & PARAMETER) != 0 ||
2671                    sym.isLocal() ||
2672                    sym.name == names._this ||
2673                    sym.name == names._super) {
2674                    return;
2675                }
2676            }
2677
2678            if (!types.isSubtype(sym.owner.type, syms.serializableType) &&
2679                isEffectivelyNonPublic(sym)) {
2680                if (isLambda) {
2681                    if (belongsToRestrictedPackage(sym)) {
2682                        log.warning(LintCategory.SERIAL, tree.pos(),
2683                                    Warnings.AccessToMemberFromSerializableLambda(sym));
2684                    }
2685                } else {
2686                    log.warning(tree.pos(),
2687                                Warnings.AccessToMemberFromSerializableElement(sym));
2688                }
2689            }
2690        }
2691    }
2692
2693    private boolean isEffectivelyNonPublic(Symbol sym) {
2694        if (sym.packge() == syms.rootPackage) {
2695            return false;
2696        }
2697
2698        while (sym.kind != PCK) {
2699            if ((sym.flags() & PUBLIC) == 0) {
2700                return true;
2701            }
2702            sym = sym.owner;
2703        }
2704        return false;
2705    }
2706
2707    private boolean belongsToRestrictedPackage(Symbol sym) {
2708        String fullName = sym.packge().fullname.toString();
2709        return fullName.startsWith("java.") ||
2710                fullName.startsWith("javax.") ||
2711                fullName.startsWith("sun.") ||
2712                fullName.contains(".internal.");
2713    }
2714
2715    /** Report a conflict between a user symbol and a synthetic symbol.
2716     */
2717    private void syntheticError(DiagnosticPosition pos, Symbol sym) {
2718        if (!sym.type.isErroneous()) {
2719            log.error(pos, Errors.SyntheticNameConflict(sym, sym.location()));
2720        }
2721    }
2722
2723    /** Check that class c does not implement directly or indirectly
2724     *  the same parameterized interface with two different argument lists.
2725     *  @param pos          Position to be used for error reporting.
2726     *  @param type         The type whose interfaces are checked.
2727     */
2728    void checkClassBounds(DiagnosticPosition pos, Type type) {
2729        checkClassBounds(pos, new HashMap<TypeSymbol,Type>(), type);
2730    }
2731//where
2732        /** Enter all interfaces of type `type' into the hash table `seensofar'
2733         *  with their class symbol as key and their type as value. Make
2734         *  sure no class is entered with two different types.
2735         */
2736        void checkClassBounds(DiagnosticPosition pos,
2737                              Map<TypeSymbol,Type> seensofar,
2738                              Type type) {
2739            if (type.isErroneous()) return;
2740            for (List<Type> l = types.interfaces(type); l.nonEmpty(); l = l.tail) {
2741                Type it = l.head;
2742                Type oldit = seensofar.put(it.tsym, it);
2743                if (oldit != null) {
2744                    List<Type> oldparams = oldit.allparams();
2745                    List<Type> newparams = it.allparams();
2746                    if (!types.containsTypeEquivalent(oldparams, newparams))
2747                        log.error(pos,
2748                                  Errors.CantInheritDiffArg(it.tsym,
2749                                                            Type.toString(oldparams),
2750                                                            Type.toString(newparams)));
2751                }
2752                checkClassBounds(pos, seensofar, it);
2753            }
2754            Type st = types.supertype(type);
2755            if (st != Type.noType) checkClassBounds(pos, seensofar, st);
2756        }
2757
2758    /** Enter interface into into set.
2759     *  If it existed already, issue a "repeated interface" error.
2760     */
2761    void checkNotRepeated(DiagnosticPosition pos, Type it, Set<Type> its) {
2762        if (its.contains(it))
2763            log.error(pos, Errors.RepeatedInterface);
2764        else {
2765            its.add(it);
2766        }
2767    }
2768
2769/* *************************************************************************
2770 * Check annotations
2771 **************************************************************************/
2772
2773    /**
2774     * Recursively validate annotations values
2775     */
2776    void validateAnnotationTree(JCTree tree) {
2777        class AnnotationValidator extends TreeScanner {
2778            @Override
2779            public void visitAnnotation(JCAnnotation tree) {
2780                if (!tree.type.isErroneous()) {
2781                    super.visitAnnotation(tree);
2782                    validateAnnotation(tree);
2783                }
2784            }
2785        }
2786        tree.accept(new AnnotationValidator());
2787    }
2788
2789    /**
2790     *  {@literal
2791     *  Annotation types are restricted to primitives, String, an
2792     *  enum, an annotation, Class, Class<?>, Class<? extends
2793     *  Anything>, arrays of the preceding.
2794     *  }
2795     */
2796    void validateAnnotationType(JCTree restype) {
2797        // restype may be null if an error occurred, so don't bother validating it
2798        if (restype != null) {
2799            validateAnnotationType(restype.pos(), restype.type);
2800        }
2801    }
2802
2803    void validateAnnotationType(DiagnosticPosition pos, Type type) {
2804        if (type.isPrimitive()) return;
2805        if (types.isSameType(type, syms.stringType)) return;
2806        if ((type.tsym.flags() & Flags.ENUM) != 0) return;
2807        if ((type.tsym.flags() & Flags.ANNOTATION) != 0) return;
2808        if (types.cvarLowerBound(type).tsym == syms.classType.tsym) return;
2809        if (types.isArray(type) && !types.isArray(types.elemtype(type))) {
2810            validateAnnotationType(pos, types.elemtype(type));
2811            return;
2812        }
2813        log.error(pos, Errors.InvalidAnnotationMemberType);
2814    }
2815
2816    /**
2817     * "It is also a compile-time error if any method declared in an
2818     * annotation type has a signature that is override-equivalent to
2819     * that of any public or protected method declared in class Object
2820     * or in the interface annotation.Annotation."
2821     *
2822     * @jls 9.6 Annotation Types
2823     */
2824    void validateAnnotationMethod(DiagnosticPosition pos, MethodSymbol m) {
2825        for (Type sup = syms.annotationType; sup.hasTag(CLASS); sup = types.supertype(sup)) {
2826            Scope s = sup.tsym.members();
2827            for (Symbol sym : s.getSymbolsByName(m.name)) {
2828                if (sym.kind == MTH &&
2829                    (sym.flags() & (PUBLIC | PROTECTED)) != 0 &&
2830                    types.overrideEquivalent(m.type, sym.type))
2831                    log.error(pos, Errors.IntfAnnotationMemberClash(sym, sup));
2832            }
2833        }
2834    }
2835
2836    /** Check the annotations of a symbol.
2837     */
2838    public void validateAnnotations(List<JCAnnotation> annotations, Symbol s) {
2839        for (JCAnnotation a : annotations)
2840            validateAnnotation(a, s);
2841    }
2842
2843    /** Check the type annotations.
2844     */
2845    public void validateTypeAnnotations(List<JCAnnotation> annotations, boolean isTypeParameter) {
2846        for (JCAnnotation a : annotations)
2847            validateTypeAnnotation(a, isTypeParameter);
2848    }
2849
2850    /** Check an annotation of a symbol.
2851     */
2852    private void validateAnnotation(JCAnnotation a, Symbol s) {
2853        validateAnnotationTree(a);
2854
2855        if (a.type.tsym.isAnnotationType() && !annotationApplicable(a, s))
2856            log.error(a.pos(), Errors.AnnotationTypeNotApplicable);
2857
2858        if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) {
2859            if (s.kind != TYP) {
2860                log.error(a.pos(), Errors.BadFunctionalIntfAnno);
2861            } else if (!s.isInterface() || (s.flags() & ANNOTATION) != 0) {
2862                log.error(a.pos(), Errors.BadFunctionalIntfAnno1(Fragments.NotAFunctionalIntf(s)));
2863            }
2864        }
2865    }
2866
2867    public void validateTypeAnnotation(JCAnnotation a, boolean isTypeParameter) {
2868        Assert.checkNonNull(a.type);
2869        validateAnnotationTree(a);
2870
2871        if (a.hasTag(TYPE_ANNOTATION) &&
2872                !a.annotationType.type.isErroneous() &&
2873                !isTypeAnnotation(a, isTypeParameter)) {
2874            log.error(a.pos(), Errors.AnnotationTypeNotApplicableToType(a.type));
2875        }
2876    }
2877
2878    /**
2879     * Validate the proposed container 'repeatable' on the
2880     * annotation type symbol 's'. Report errors at position
2881     * 'pos'.
2882     *
2883     * @param s The (annotation)type declaration annotated with a @Repeatable
2884     * @param repeatable the @Repeatable on 's'
2885     * @param pos where to report errors
2886     */
2887    public void validateRepeatable(TypeSymbol s, Attribute.Compound repeatable, DiagnosticPosition pos) {
2888        Assert.check(types.isSameType(repeatable.type, syms.repeatableType));
2889
2890        Type t = null;
2891        List<Pair<MethodSymbol,Attribute>> l = repeatable.values;
2892        if (!l.isEmpty()) {
2893            Assert.check(l.head.fst.name == names.value);
2894            t = ((Attribute.Class)l.head.snd).getValue();
2895        }
2896
2897        if (t == null) {
2898            // errors should already have been reported during Annotate
2899            return;
2900        }
2901
2902        validateValue(t.tsym, s, pos);
2903        validateRetention(t.tsym, s, pos);
2904        validateDocumented(t.tsym, s, pos);
2905        validateInherited(t.tsym, s, pos);
2906        validateTarget(t.tsym, s, pos);
2907        validateDefault(t.tsym, pos);
2908    }
2909
2910    private void validateValue(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
2911        Symbol sym = container.members().findFirst(names.value);
2912        if (sym != null && sym.kind == MTH) {
2913            MethodSymbol m = (MethodSymbol) sym;
2914            Type ret = m.getReturnType();
2915            if (!(ret.hasTag(ARRAY) && types.isSameType(((ArrayType)ret).elemtype, contained.type))) {
2916                log.error(pos,
2917                          Errors.InvalidRepeatableAnnotationValueReturn(container,
2918                                                                        ret,
2919                                                                        types.makeArrayType(contained.type)));
2920            }
2921        } else {
2922            log.error(pos, Errors.InvalidRepeatableAnnotationNoValue(container));
2923        }
2924    }
2925
2926    private void validateRetention(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
2927        Attribute.RetentionPolicy containerRetention = types.getRetention(container);
2928        Attribute.RetentionPolicy containedRetention = types.getRetention(contained);
2929
2930        boolean error = false;
2931        switch (containedRetention) {
2932        case RUNTIME:
2933            if (containerRetention != Attribute.RetentionPolicy.RUNTIME) {
2934                error = true;
2935            }
2936            break;
2937        case CLASS:
2938            if (containerRetention == Attribute.RetentionPolicy.SOURCE)  {
2939                error = true;
2940            }
2941        }
2942        if (error ) {
2943            log.error(pos,
2944                      Errors.InvalidRepeatableAnnotationRetention(container,
2945                                                                  containerRetention.name(),
2946                                                                  contained,
2947                                                                  containedRetention.name()));
2948        }
2949    }
2950
2951    private void validateDocumented(Symbol container, Symbol contained, DiagnosticPosition pos) {
2952        if (contained.attribute(syms.documentedType.tsym) != null) {
2953            if (container.attribute(syms.documentedType.tsym) == null) {
2954                log.error(pos, Errors.InvalidRepeatableAnnotationNotDocumented(container, contained));
2955            }
2956        }
2957    }
2958
2959    private void validateInherited(Symbol container, Symbol contained, DiagnosticPosition pos) {
2960        if (contained.attribute(syms.inheritedType.tsym) != null) {
2961            if (container.attribute(syms.inheritedType.tsym) == null) {
2962                log.error(pos, Errors.InvalidRepeatableAnnotationNotInherited(container, contained));
2963            }
2964        }
2965    }
2966
2967    private void validateTarget(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
2968        // The set of targets the container is applicable to must be a subset
2969        // (with respect to annotation target semantics) of the set of targets
2970        // the contained is applicable to. The target sets may be implicit or
2971        // explicit.
2972
2973        Set<Name> containerTargets;
2974        Attribute.Array containerTarget = getAttributeTargetAttribute(container);
2975        if (containerTarget == null) {
2976            containerTargets = getDefaultTargetSet();
2977        } else {
2978            containerTargets = new HashSet<>();
2979            for (Attribute app : containerTarget.values) {
2980                if (!(app instanceof Attribute.Enum)) {
2981                    continue; // recovery
2982                }
2983                Attribute.Enum e = (Attribute.Enum)app;
2984                containerTargets.add(e.value.name);
2985            }
2986        }
2987
2988        Set<Name> containedTargets;
2989        Attribute.Array containedTarget = getAttributeTargetAttribute(contained);
2990        if (containedTarget == null) {
2991            containedTargets = getDefaultTargetSet();
2992        } else {
2993            containedTargets = new HashSet<>();
2994            for (Attribute app : containedTarget.values) {
2995                if (!(app instanceof Attribute.Enum)) {
2996                    continue; // recovery
2997                }
2998                Attribute.Enum e = (Attribute.Enum)app;
2999                containedTargets.add(e.value.name);
3000            }
3001        }
3002
3003        if (!isTargetSubsetOf(containerTargets, containedTargets)) {
3004            log.error(pos, Errors.InvalidRepeatableAnnotationIncompatibleTarget(container, contained));
3005        }
3006    }
3007
3008    /* get a set of names for the default target */
3009    private Set<Name> getDefaultTargetSet() {
3010        if (defaultTargets == null) {
3011            Set<Name> targets = new HashSet<>();
3012            targets.add(names.ANNOTATION_TYPE);
3013            targets.add(names.CONSTRUCTOR);
3014            targets.add(names.FIELD);
3015            targets.add(names.LOCAL_VARIABLE);
3016            targets.add(names.METHOD);
3017            targets.add(names.PACKAGE);
3018            targets.add(names.PARAMETER);
3019            targets.add(names.TYPE);
3020
3021            defaultTargets = java.util.Collections.unmodifiableSet(targets);
3022        }
3023
3024        return defaultTargets;
3025    }
3026    private Set<Name> defaultTargets;
3027
3028
3029    /** Checks that s is a subset of t, with respect to ElementType
3030     * semantics, specifically {ANNOTATION_TYPE} is a subset of {TYPE},
3031     * and {TYPE_USE} covers the set {ANNOTATION_TYPE, TYPE, TYPE_USE,
3032     * TYPE_PARAMETER}.
3033     */
3034    private boolean isTargetSubsetOf(Set<Name> s, Set<Name> t) {
3035        // Check that all elements in s are present in t
3036        for (Name n2 : s) {
3037            boolean currentElementOk = false;
3038            for (Name n1 : t) {
3039                if (n1 == n2) {
3040                    currentElementOk = true;
3041                    break;
3042                } else if (n1 == names.TYPE && n2 == names.ANNOTATION_TYPE) {
3043                    currentElementOk = true;
3044                    break;
3045                } else if (n1 == names.TYPE_USE &&
3046                        (n2 == names.TYPE ||
3047                         n2 == names.ANNOTATION_TYPE ||
3048                         n2 == names.TYPE_PARAMETER)) {
3049                    currentElementOk = true;
3050                    break;
3051                }
3052            }
3053            if (!currentElementOk)
3054                return false;
3055        }
3056        return true;
3057    }
3058
3059    private void validateDefault(Symbol container, DiagnosticPosition pos) {
3060        // validate that all other elements of containing type has defaults
3061        Scope scope = container.members();
3062        for(Symbol elm : scope.getSymbols()) {
3063            if (elm.name != names.value &&
3064                elm.kind == MTH &&
3065                ((MethodSymbol)elm).defaultValue == null) {
3066                log.error(pos,
3067                          Errors.InvalidRepeatableAnnotationElemNondefault(container, elm));
3068            }
3069        }
3070    }
3071
3072    /** Is s a method symbol that overrides a method in a superclass? */
3073    boolean isOverrider(Symbol s) {
3074        if (s.kind != MTH || s.isStatic())
3075            return false;
3076        MethodSymbol m = (MethodSymbol)s;
3077        TypeSymbol owner = (TypeSymbol)m.owner;
3078        for (Type sup : types.closure(owner.type)) {
3079            if (sup == owner.type)
3080                continue; // skip "this"
3081            Scope scope = sup.tsym.members();
3082            for (Symbol sym : scope.getSymbolsByName(m.name)) {
3083                if (!sym.isStatic() && m.overrides(sym, owner, types, true))
3084                    return true;
3085            }
3086        }
3087        return false;
3088    }
3089
3090    /** Is the annotation applicable to types? */
3091    protected boolean isTypeAnnotation(JCAnnotation a, boolean isTypeParameter) {
3092        List<Attribute> targets = typeAnnotations.annotationTargets(a.annotationType.type.tsym);
3093        return (targets == null) ?
3094                false :
3095                targets.stream()
3096                        .anyMatch(attr -> isTypeAnnotation(attr, isTypeParameter));
3097    }
3098    //where
3099        boolean isTypeAnnotation(Attribute a, boolean isTypeParameter) {
3100            Attribute.Enum e = (Attribute.Enum)a;
3101            return (e.value.name == names.TYPE_USE ||
3102                    (isTypeParameter && e.value.name == names.TYPE_PARAMETER));
3103        }
3104
3105    /** Is the annotation applicable to the symbol? */
3106    boolean annotationApplicable(JCAnnotation a, Symbol s) {
3107        Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym);
3108        Name[] targets;
3109
3110        if (arr == null) {
3111            targets = defaultTargetMetaInfo(a, s);
3112        } else {
3113            // TODO: can we optimize this?
3114            targets = new Name[arr.values.length];
3115            for (int i=0; i<arr.values.length; ++i) {
3116                Attribute app = arr.values[i];
3117                if (!(app instanceof Attribute.Enum)) {
3118                    return true; // recovery
3119                }
3120                Attribute.Enum e = (Attribute.Enum) app;
3121                targets[i] = e.value.name;
3122            }
3123        }
3124        for (Name target : targets) {
3125            if (target == names.TYPE) {
3126                if (s.kind == TYP)
3127                    return true;
3128            } else if (target == names.FIELD) {
3129                if (s.kind == VAR && s.owner.kind != MTH)
3130                    return true;
3131            } else if (target == names.METHOD) {
3132                if (s.kind == MTH && !s.isConstructor())
3133                    return true;
3134            } else if (target == names.PARAMETER) {
3135                if (s.kind == VAR && s.owner.kind == MTH &&
3136                      (s.flags() & PARAMETER) != 0) {
3137                    return true;
3138                }
3139            } else if (target == names.CONSTRUCTOR) {
3140                if (s.kind == MTH && s.isConstructor())
3141                    return true;
3142            } else if (target == names.LOCAL_VARIABLE) {
3143                if (s.kind == VAR && s.owner.kind == MTH &&
3144                      (s.flags() & PARAMETER) == 0) {
3145                    return true;
3146                }
3147            } else if (target == names.ANNOTATION_TYPE) {
3148                if (s.kind == TYP && (s.flags() & ANNOTATION) != 0) {
3149                    return true;
3150                }
3151            } else if (target == names.PACKAGE) {
3152                if (s.kind == PCK)
3153                    return true;
3154            } else if (target == names.TYPE_USE) {
3155                if (s.kind == TYP || s.kind == VAR ||
3156                        (s.kind == MTH && !s.isConstructor() &&
3157                                !s.type.getReturnType().hasTag(VOID)) ||
3158                        (s.kind == MTH && s.isConstructor())) {
3159                    return true;
3160                }
3161            } else if (target == names.TYPE_PARAMETER) {
3162                if (s.kind == TYP && s.type.hasTag(TYPEVAR))
3163                    return true;
3164            } else
3165                return true; // Unknown ElementType. This should be an error at declaration site,
3166                             // assume applicable.
3167        }
3168        return false;
3169    }
3170
3171
3172    Attribute.Array getAttributeTargetAttribute(TypeSymbol s) {
3173        Attribute.Compound atTarget = s.getAnnotationTypeMetadata().getTarget();
3174        if (atTarget == null) return null; // ok, is applicable
3175        Attribute atValue = atTarget.member(names.value);
3176        if (!(atValue instanceof Attribute.Array)) return null; // error recovery
3177        return (Attribute.Array) atValue;
3178    }
3179
3180    private final Name[] dfltTargetMeta;
3181    private Name[] defaultTargetMetaInfo(JCAnnotation a, Symbol s) {
3182        return dfltTargetMeta;
3183    }
3184
3185    /** Check an annotation value.
3186     *
3187     * @param a The annotation tree to check
3188     * @return true if this annotation tree is valid, otherwise false
3189     */
3190    public boolean validateAnnotationDeferErrors(JCAnnotation a) {
3191        boolean res = false;
3192        final Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
3193        try {
3194            res = validateAnnotation(a);
3195        } finally {
3196            log.popDiagnosticHandler(diagHandler);
3197        }
3198        return res;
3199    }
3200
3201    private boolean validateAnnotation(JCAnnotation a) {
3202        boolean isValid = true;
3203        AnnotationTypeMetadata metadata = a.annotationType.type.tsym.getAnnotationTypeMetadata();
3204
3205        // collect an inventory of the annotation elements
3206        Set<MethodSymbol> elements = metadata.getAnnotationElements();
3207
3208        // remove the ones that are assigned values
3209        for (JCTree arg : a.args) {
3210            if (!arg.hasTag(ASSIGN)) continue; // recovery
3211            JCAssign assign = (JCAssign)arg;
3212            Symbol m = TreeInfo.symbol(assign.lhs);
3213            if (m == null || m.type.isErroneous()) continue;
3214            if (!elements.remove(m)) {
3215                isValid = false;
3216                log.error(assign.lhs.pos(),
3217                          Errors.DuplicateAnnotationMemberValue(m.name, a.type));
3218            }
3219        }
3220
3221        // all the remaining ones better have default values
3222        List<Name> missingDefaults = List.nil();
3223        Set<MethodSymbol> membersWithDefault = metadata.getAnnotationElementsWithDefault();
3224        for (MethodSymbol m : elements) {
3225            if (m.type.isErroneous())
3226                continue;
3227
3228            if (!membersWithDefault.contains(m))
3229                missingDefaults = missingDefaults.append(m.name);
3230        }
3231        missingDefaults = missingDefaults.reverse();
3232        if (missingDefaults.nonEmpty()) {
3233            isValid = false;
3234            String key = (missingDefaults.size() > 1)
3235                    ? "annotation.missing.default.value.1"
3236                    : "annotation.missing.default.value";
3237            log.error(a.pos(), key, a.type, missingDefaults);
3238        }
3239
3240        return isValid && validateTargetAnnotationValue(a);
3241    }
3242
3243    /* Validate the special java.lang.annotation.Target annotation */
3244    boolean validateTargetAnnotationValue(JCAnnotation a) {
3245        // special case: java.lang.annotation.Target must not have
3246        // repeated values in its value member
3247        if (a.annotationType.type.tsym != syms.annotationTargetType.tsym ||
3248                a.args.tail == null)
3249            return true;
3250
3251        boolean isValid = true;
3252        if (!a.args.head.hasTag(ASSIGN)) return false; // error recovery
3253        JCAssign assign = (JCAssign) a.args.head;
3254        Symbol m = TreeInfo.symbol(assign.lhs);
3255        if (m.name != names.value) return false;
3256        JCTree rhs = assign.rhs;
3257        if (!rhs.hasTag(NEWARRAY)) return false;
3258        JCNewArray na = (JCNewArray) rhs;
3259        Set<Symbol> targets = new HashSet<>();
3260        for (JCTree elem : na.elems) {
3261            if (!targets.add(TreeInfo.symbol(elem))) {
3262                isValid = false;
3263                log.error(elem.pos(), Errors.RepeatedAnnotationTarget);
3264            }
3265        }
3266        return isValid;
3267    }
3268
3269    void checkDeprecatedAnnotation(DiagnosticPosition pos, Symbol s) {
3270        if (lint.isEnabled(LintCategory.DEP_ANN) && s.isDeprecatableViaAnnotation() &&
3271            (s.flags() & DEPRECATED) != 0 &&
3272            !syms.deprecatedType.isErroneous() &&
3273            s.attribute(syms.deprecatedType.tsym) == null) {
3274            log.warning(LintCategory.DEP_ANN,
3275                    pos, Warnings.MissingDeprecatedAnnotation);
3276        }
3277        // Note: @Deprecated has no effect on local variables, parameters and package decls.
3278        if (lint.isEnabled(LintCategory.DEPRECATION) && !s.isDeprecatableViaAnnotation()) {
3279            if (!syms.deprecatedType.isErroneous() && s.attribute(syms.deprecatedType.tsym) != null) {
3280                log.warning(LintCategory.DEPRECATION, pos,
3281                            Warnings.DeprecatedAnnotationHasNoEffect(Kinds.kindName(s)));
3282            }
3283        }
3284    }
3285
3286    void checkDeprecated(final DiagnosticPosition pos, final Symbol other, final Symbol s) {
3287        if ( (s.isDeprecatedForRemoval()
3288                || s.isDeprecated() && !other.isDeprecated())
3289                && (s.outermostClass() != other.outermostClass() || s.outermostClass() == null)) {
3290            deferredLintHandler.report(() -> warnDeprecated(pos, s));
3291        }
3292    }
3293
3294    void checkSunAPI(final DiagnosticPosition pos, final Symbol s) {
3295        if ((s.flags() & PROPRIETARY) != 0) {
3296            deferredLintHandler.report(() -> {
3297                log.mandatoryWarning(pos, Warnings.SunProprietary(s));
3298            });
3299        }
3300    }
3301
3302    void checkProfile(final DiagnosticPosition pos, final Symbol s) {
3303        if (profile != Profile.DEFAULT && (s.flags() & NOT_IN_PROFILE) != 0) {
3304            log.error(pos, Errors.NotInProfile(s, profile));
3305        }
3306    }
3307
3308/* *************************************************************************
3309 * Check for recursive annotation elements.
3310 **************************************************************************/
3311
3312    /** Check for cycles in the graph of annotation elements.
3313     */
3314    void checkNonCyclicElements(JCClassDecl tree) {
3315        if ((tree.sym.flags_field & ANNOTATION) == 0) return;
3316        Assert.check((tree.sym.flags_field & LOCKED) == 0);
3317        try {
3318            tree.sym.flags_field |= LOCKED;
3319            for (JCTree def : tree.defs) {
3320                if (!def.hasTag(METHODDEF)) continue;
3321                JCMethodDecl meth = (JCMethodDecl)def;
3322                checkAnnotationResType(meth.pos(), meth.restype.type);
3323            }
3324        } finally {
3325            tree.sym.flags_field &= ~LOCKED;
3326            tree.sym.flags_field |= ACYCLIC_ANN;
3327        }
3328    }
3329
3330    void checkNonCyclicElementsInternal(DiagnosticPosition pos, TypeSymbol tsym) {
3331        if ((tsym.flags_field & ACYCLIC_ANN) != 0)
3332            return;
3333        if ((tsym.flags_field & LOCKED) != 0) {
3334            log.error(pos, Errors.CyclicAnnotationElement(tsym));
3335            return;
3336        }
3337        try {
3338            tsym.flags_field |= LOCKED;
3339            for (Symbol s : tsym.members().getSymbols(NON_RECURSIVE)) {
3340                if (s.kind != MTH)
3341                    continue;
3342                checkAnnotationResType(pos, ((MethodSymbol)s).type.getReturnType());
3343            }
3344        } finally {
3345            tsym.flags_field &= ~LOCKED;
3346            tsym.flags_field |= ACYCLIC_ANN;
3347        }
3348    }
3349
3350    void checkAnnotationResType(DiagnosticPosition pos, Type type) {
3351        switch (type.getTag()) {
3352        case CLASS:
3353            if ((type.tsym.flags() & ANNOTATION) != 0)
3354                checkNonCyclicElementsInternal(pos, type.tsym);
3355            break;
3356        case ARRAY:
3357            checkAnnotationResType(pos, types.elemtype(type));
3358            break;
3359        default:
3360            break; // int etc
3361        }
3362    }
3363
3364/* *************************************************************************
3365 * Check for cycles in the constructor call graph.
3366 **************************************************************************/
3367
3368    /** Check for cycles in the graph of constructors calling other
3369     *  constructors.
3370     */
3371    void checkCyclicConstructors(JCClassDecl tree) {
3372        Map<Symbol,Symbol> callMap = new HashMap<>();
3373
3374        // enter each constructor this-call into the map
3375        for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
3376            JCMethodInvocation app = TreeInfo.firstConstructorCall(l.head);
3377            if (app == null) continue;
3378            JCMethodDecl meth = (JCMethodDecl) l.head;
3379            if (TreeInfo.name(app.meth) == names._this) {
3380                callMap.put(meth.sym, TreeInfo.symbol(app.meth));
3381            } else {
3382                meth.sym.flags_field |= ACYCLIC;
3383            }
3384        }
3385
3386        // Check for cycles in the map
3387        Symbol[] ctors = new Symbol[0];
3388        ctors = callMap.keySet().toArray(ctors);
3389        for (Symbol caller : ctors) {
3390            checkCyclicConstructor(tree, caller, callMap);
3391        }
3392    }
3393
3394    /** Look in the map to see if the given constructor is part of a
3395     *  call cycle.
3396     */
3397    private void checkCyclicConstructor(JCClassDecl tree, Symbol ctor,
3398                                        Map<Symbol,Symbol> callMap) {
3399        if (ctor != null && (ctor.flags_field & ACYCLIC) == 0) {
3400            if ((ctor.flags_field & LOCKED) != 0) {
3401                log.error(TreeInfo.diagnosticPositionFor(ctor, tree),
3402                          Errors.RecursiveCtorInvocation);
3403            } else {
3404                ctor.flags_field |= LOCKED;
3405                checkCyclicConstructor(tree, callMap.remove(ctor), callMap);
3406                ctor.flags_field &= ~LOCKED;
3407            }
3408            ctor.flags_field |= ACYCLIC;
3409        }
3410    }
3411
3412/* *************************************************************************
3413 * Miscellaneous
3414 **************************************************************************/
3415
3416    /**
3417     *  Check for division by integer constant zero
3418     *  @param pos           Position for error reporting.
3419     *  @param operator      The operator for the expression
3420     *  @param operand       The right hand operand for the expression
3421     */
3422    void checkDivZero(final DiagnosticPosition pos, Symbol operator, Type operand) {
3423        if (operand.constValue() != null
3424            && operand.getTag().isSubRangeOf(LONG)
3425            && ((Number) (operand.constValue())).longValue() == 0) {
3426            int opc = ((OperatorSymbol)operator).opcode;
3427            if (opc == ByteCodes.idiv || opc == ByteCodes.imod
3428                || opc == ByteCodes.ldiv || opc == ByteCodes.lmod) {
3429                deferredLintHandler.report(() -> warnDivZero(pos));
3430            }
3431        }
3432    }
3433
3434    /**
3435     * Check for empty statements after if
3436     */
3437    void checkEmptyIf(JCIf tree) {
3438        if (tree.thenpart.hasTag(SKIP) && tree.elsepart == null &&
3439                lint.isEnabled(LintCategory.EMPTY))
3440            log.warning(LintCategory.EMPTY, tree.thenpart.pos(), Warnings.EmptyIf);
3441    }
3442
3443    /** Check that symbol is unique in given scope.
3444     *  @param pos           Position for error reporting.
3445     *  @param sym           The symbol.
3446     *  @param s             The scope.
3447     */
3448    boolean checkUnique(DiagnosticPosition pos, Symbol sym, Scope s) {
3449        if (sym.type.isErroneous())
3450            return true;
3451        if (sym.owner.name == names.any) return false;
3452        for (Symbol byName : s.getSymbolsByName(sym.name, NON_RECURSIVE)) {
3453            if (sym != byName &&
3454                    (byName.flags() & CLASH) == 0 &&
3455                    sym.kind == byName.kind &&
3456                    sym.name != names.error &&
3457                    (sym.kind != MTH ||
3458                     types.hasSameArgs(sym.type, byName.type) ||
3459                     types.hasSameArgs(types.erasure(sym.type), types.erasure(byName.type)))) {
3460                if ((sym.flags() & VARARGS) != (byName.flags() & VARARGS)) {
3461                    varargsDuplicateError(pos, sym, byName);
3462                    return true;
3463                } else if (sym.kind == MTH && !types.hasSameArgs(sym.type, byName.type, false)) {
3464                    duplicateErasureError(pos, sym, byName);
3465                    sym.flags_field |= CLASH;
3466                    return true;
3467                } else {
3468                    duplicateError(pos, byName);
3469                    return false;
3470                }
3471            }
3472        }
3473        return true;
3474    }
3475
3476    /** Report duplicate declaration error.
3477     */
3478    void duplicateErasureError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) {
3479        if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) {
3480            log.error(pos, Errors.NameClashSameErasure(sym1, sym2));
3481        }
3482    }
3483
3484    /**Check that types imported through the ordinary imports don't clash with types imported
3485     * by other (static or ordinary) imports. Note that two static imports may import two clashing
3486     * types without an error on the imports.
3487     * @param toplevel       The toplevel tree for which the test should be performed.
3488     */
3489    void checkImportsUnique(JCCompilationUnit toplevel) {
3490        WriteableScope ordinallyImportedSoFar = WriteableScope.create(toplevel.packge);
3491        WriteableScope staticallyImportedSoFar = WriteableScope.create(toplevel.packge);
3492        WriteableScope topLevelScope = toplevel.toplevelScope;
3493
3494        for (JCTree def : toplevel.defs) {
3495            if (!def.hasTag(IMPORT))
3496                continue;
3497
3498            JCImport imp = (JCImport) def;
3499
3500            if (imp.importScope == null)
3501                continue;
3502
3503            for (Symbol sym : imp.importScope.getSymbols(sym -> sym.kind == TYP)) {
3504                if (imp.isStatic()) {
3505                    checkUniqueImport(imp.pos(), ordinallyImportedSoFar, staticallyImportedSoFar, topLevelScope, sym, true);
3506                    staticallyImportedSoFar.enter(sym);
3507                } else {
3508                    checkUniqueImport(imp.pos(), ordinallyImportedSoFar, staticallyImportedSoFar, topLevelScope, sym, false);
3509                    ordinallyImportedSoFar.enter(sym);
3510                }
3511            }
3512
3513            imp.importScope = null;
3514        }
3515    }
3516
3517    /** Check that single-type import is not already imported or top-level defined,
3518     *  but make an exception for two single-type imports which denote the same type.
3519     *  @param pos                     Position for error reporting.
3520     *  @param ordinallyImportedSoFar  A Scope containing types imported so far through
3521     *                                 ordinary imports.
3522     *  @param staticallyImportedSoFar A Scope containing types imported so far through
3523     *                                 static imports.
3524     *  @param topLevelScope           The current file's top-level Scope
3525     *  @param sym                     The symbol.
3526     *  @param staticImport            Whether or not this was a static import
3527     */
3528    private boolean checkUniqueImport(DiagnosticPosition pos, Scope ordinallyImportedSoFar,
3529                                      Scope staticallyImportedSoFar, Scope topLevelScope,
3530                                      Symbol sym, boolean staticImport) {
3531        Filter<Symbol> duplicates = candidate -> candidate != sym && !candidate.type.isErroneous();
3532        Symbol clashing = ordinallyImportedSoFar.findFirst(sym.name, duplicates);
3533        if (clashing == null && !staticImport) {
3534            clashing = staticallyImportedSoFar.findFirst(sym.name, duplicates);
3535        }
3536        if (clashing != null) {
3537            if (staticImport)
3538                log.error(pos, Errors.AlreadyDefinedStaticSingleImport(clashing));
3539            else
3540                log.error(pos, Errors.AlreadyDefinedSingleImport(clashing));
3541            return false;
3542        }
3543        clashing = topLevelScope.findFirst(sym.name, duplicates);
3544        if (clashing != null) {
3545            log.error(pos, Errors.AlreadyDefinedThisUnit(clashing));
3546            return false;
3547        }
3548        return true;
3549    }
3550
3551    /** Check that a qualified name is in canonical form (for import decls).
3552     */
3553    public void checkCanonical(JCTree tree) {
3554        if (!isCanonical(tree))
3555            log.error(tree.pos(),
3556                      Errors.ImportRequiresCanonical(TreeInfo.symbol(tree)));
3557    }
3558        // where
3559        private boolean isCanonical(JCTree tree) {
3560            while (tree.hasTag(SELECT)) {
3561                JCFieldAccess s = (JCFieldAccess) tree;
3562                if (s.sym.owner.name != TreeInfo.symbol(s.selected).name)
3563                    return false;
3564                tree = s.selected;
3565            }
3566            return true;
3567        }
3568
3569    /** Check that an auxiliary class is not accessed from any other file than its own.
3570     */
3571    void checkForBadAuxiliaryClassAccess(DiagnosticPosition pos, Env<AttrContext> env, ClassSymbol c) {
3572        if (lint.isEnabled(Lint.LintCategory.AUXILIARYCLASS) &&
3573            (c.flags() & AUXILIARY) != 0 &&
3574            rs.isAccessible(env, c) &&
3575            !fileManager.isSameFile(c.sourcefile, env.toplevel.sourcefile))
3576        {
3577            log.warning(pos,
3578                        Warnings.AuxiliaryClassAccessedFromOutsideOfItsSourceFile(c, c.sourcefile));
3579        }
3580    }
3581
3582    private class ConversionWarner extends Warner {
3583        final String uncheckedKey;
3584        final Type found;
3585        final Type expected;
3586        public ConversionWarner(DiagnosticPosition pos, String uncheckedKey, Type found, Type expected) {
3587            super(pos);
3588            this.uncheckedKey = uncheckedKey;
3589            this.found = found;
3590            this.expected = expected;
3591        }
3592
3593        @Override
3594        public void warn(LintCategory lint) {
3595            boolean warned = this.warned;
3596            super.warn(lint);
3597            if (warned) return; // suppress redundant diagnostics
3598            switch (lint) {
3599                case UNCHECKED:
3600                    Check.this.warnUnchecked(pos(), "prob.found.req", diags.fragment(uncheckedKey), found, expected);
3601                    break;
3602                case VARARGS:
3603                    if (method != null &&
3604                            method.attribute(syms.trustMeType.tsym) != null &&
3605                            isTrustMeAllowedOnMethod(method) &&
3606                            !types.isReifiable(method.type.getParameterTypes().last())) {
3607                        Check.this.warnUnsafeVararg(pos(), "varargs.unsafe.use.varargs.param", method.params.last());
3608                    }
3609                    break;
3610                default:
3611                    throw new AssertionError("Unexpected lint: " + lint);
3612            }
3613        }
3614    }
3615
3616    public Warner castWarner(DiagnosticPosition pos, Type found, Type expected) {
3617        return new ConversionWarner(pos, "unchecked.cast.to.type", found, expected);
3618    }
3619
3620    public Warner convertWarner(DiagnosticPosition pos, Type found, Type expected) {
3621        return new ConversionWarner(pos, "unchecked.assign", found, expected);
3622    }
3623
3624    public void checkFunctionalInterface(JCClassDecl tree, ClassSymbol cs) {
3625        Compound functionalType = cs.attribute(syms.functionalInterfaceType.tsym);
3626
3627        if (functionalType != null) {
3628            try {
3629                types.findDescriptorSymbol((TypeSymbol)cs);
3630            } catch (Types.FunctionDescriptorLookupError ex) {
3631                DiagnosticPosition pos = tree.pos();
3632                for (JCAnnotation a : tree.getModifiers().annotations) {
3633                    if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) {
3634                        pos = a.pos();
3635                        break;
3636                    }
3637                }
3638                log.error(pos, Errors.BadFunctionalIntfAnno1(ex.getDiagnostic()));
3639            }
3640        }
3641    }
3642
3643    public void checkImportsResolvable(final JCCompilationUnit toplevel) {
3644        for (final JCImport imp : toplevel.getImports()) {
3645            if (!imp.staticImport || !imp.qualid.hasTag(SELECT))
3646                continue;
3647            final JCFieldAccess select = (JCFieldAccess) imp.qualid;
3648            final Symbol origin;
3649            if (select.name == names.asterisk || (origin = TreeInfo.symbol(select.selected)) == null || origin.kind != TYP)
3650                continue;
3651
3652            TypeSymbol site = (TypeSymbol) TreeInfo.symbol(select.selected);
3653            if (!checkTypeContainsImportableElement(site, site, toplevel.packge, select.name, new HashSet<Symbol>())) {
3654                log.error(imp.pos(),
3655                          Errors.CantResolveLocation(KindName.STATIC,
3656                                                     select.name,
3657                                                     null,
3658                                                     null,
3659                                                     Fragments.Location(kindName(site),
3660                                                                        site,
3661                                                                        null)));
3662            }
3663        }
3664    }
3665
3666    // Check that packages imported are in scope (JLS 7.4.3, 6.3, 6.5.3.1, 6.5.3.2)
3667    public void checkImportedPackagesObservable(final JCCompilationUnit toplevel) {
3668        OUTER: for (JCImport imp : toplevel.getImports()) {
3669            if (!imp.staticImport && TreeInfo.name(imp.qualid) == names.asterisk) {
3670                TypeSymbol tsym = ((JCFieldAccess)imp.qualid).selected.type.tsym;
3671                if (toplevel.modle.visiblePackages != null) {
3672                    //TODO - unclear: selects like javax.* will get resolved from the current module
3673                    //(as javax is not an exported package from any module). And as javax in the current
3674                    //module typically does not contain any classes or subpackages, we need to go through
3675                    //the visible packages to find a sub-package:
3676                    for (PackageSymbol known : toplevel.modle.visiblePackages.values()) {
3677                        if (Convert.packagePart(known.fullname) == tsym.flatName())
3678                            continue OUTER;
3679                    }
3680                }
3681                if (tsym.kind == PCK && tsym.members().isEmpty() && !tsym.exists()) {
3682                    log.error(DiagnosticFlag.RESOLVE_ERROR, imp.pos, Errors.DoesntExist(tsym));
3683                }
3684            }
3685        }
3686    }
3687
3688    private boolean checkTypeContainsImportableElement(TypeSymbol tsym, TypeSymbol origin, PackageSymbol packge, Name name, Set<Symbol> processed) {
3689        if (tsym == null || !processed.add(tsym))
3690            return false;
3691
3692            // also search through inherited names
3693        if (checkTypeContainsImportableElement(types.supertype(tsym.type).tsym, origin, packge, name, processed))
3694            return true;
3695
3696        for (Type t : types.interfaces(tsym.type))
3697            if (checkTypeContainsImportableElement(t.tsym, origin, packge, name, processed))
3698                return true;
3699
3700        for (Symbol sym : tsym.members().getSymbolsByName(name)) {
3701            if (sym.isStatic() &&
3702                importAccessible(sym, packge) &&
3703                sym.isMemberOf(origin, types)) {
3704                return true;
3705            }
3706        }
3707
3708        return false;
3709    }
3710
3711    // is the sym accessible everywhere in packge?
3712    public boolean importAccessible(Symbol sym, PackageSymbol packge) {
3713        try {
3714            int flags = (int)(sym.flags() & AccessFlags);
3715            switch (flags) {
3716            default:
3717            case PUBLIC:
3718                return true;
3719            case PRIVATE:
3720                return false;
3721            case 0:
3722            case PROTECTED:
3723                return sym.packge() == packge;
3724            }
3725        } catch (ClassFinder.BadClassFile err) {
3726            throw err;
3727        } catch (CompletionFailure ex) {
3728            return false;
3729        }
3730    }
3731
3732    public void checkLeaksNotAccessible(Env<AttrContext> env, JCClassDecl check) {
3733        JCCompilationUnit toplevel = env.toplevel;
3734
3735        if (   toplevel.modle == syms.unnamedModule
3736            || toplevel.modle == syms.noModule
3737            || (check.sym.flags() & COMPOUND) != 0) {
3738            return ;
3739        }
3740
3741        ExportsDirective currentExport = findExport(toplevel.packge);
3742
3743        if (   currentExport == null //not exported
3744            || currentExport.modules != null) //don't check classes in qualified export
3745            return ;
3746
3747        new TreeScanner() {
3748            Lint lint = env.info.lint;
3749            boolean inSuperType;
3750
3751            @Override
3752            public void visitBlock(JCBlock tree) {
3753            }
3754            @Override
3755            public void visitMethodDef(JCMethodDecl tree) {
3756                if (!isAPISymbol(tree.sym))
3757                    return;
3758                Lint prevLint = lint;
3759                try {
3760                    lint = lint.augment(tree.sym);
3761                    if (lint.isEnabled(LintCategory.EXPORTS)) {
3762                        super.visitMethodDef(tree);
3763                    }
3764                } finally {
3765                    lint = prevLint;
3766                }
3767            }
3768            @Override
3769            public void visitVarDef(JCVariableDecl tree) {
3770                if (!isAPISymbol(tree.sym) && tree.sym.owner.kind != MTH)
3771                    return;
3772                Lint prevLint = lint;
3773                try {
3774                    lint = lint.augment(tree.sym);
3775                    if (lint.isEnabled(LintCategory.EXPORTS)) {
3776                        scan(tree.mods);
3777                        scan(tree.vartype);
3778                    }
3779                } finally {
3780                    lint = prevLint;
3781                }
3782            }
3783            @Override
3784            public void visitClassDef(JCClassDecl tree) {
3785                if (tree != check)
3786                    return ;
3787
3788                if (!isAPISymbol(tree.sym))
3789                    return ;
3790
3791                Lint prevLint = lint;
3792                try {
3793                    lint = lint.augment(tree.sym);
3794                    if (lint.isEnabled(LintCategory.EXPORTS)) {
3795                        scan(tree.mods);
3796                        scan(tree.typarams);
3797                        try {
3798                            inSuperType = true;
3799                            scan(tree.extending);
3800                            scan(tree.implementing);
3801                        } finally {
3802                            inSuperType = false;
3803                        }
3804                        scan(tree.defs);
3805                    }
3806                } finally {
3807                    lint = prevLint;
3808                }
3809            }
3810            @Override
3811            public void visitTypeApply(JCTypeApply tree) {
3812                scan(tree.clazz);
3813                boolean oldInSuperType = inSuperType;
3814                try {
3815                    inSuperType = false;
3816                    scan(tree.arguments);
3817                } finally {
3818                    inSuperType = oldInSuperType;
3819                }
3820            }
3821            @Override
3822            public void visitIdent(JCIdent tree) {
3823                Symbol sym = TreeInfo.symbol(tree);
3824                if (sym.kind == TYP && !sym.type.hasTag(TYPEVAR)) {
3825                    checkVisible(tree.pos(), sym, toplevel.packge, inSuperType);
3826                }
3827            }
3828
3829            @Override
3830            public void visitSelect(JCFieldAccess tree) {
3831                Symbol sym = TreeInfo.symbol(tree);
3832                Symbol sitesym = TreeInfo.symbol(tree.selected);
3833                if (sym.kind == TYP && sitesym.kind == PCK) {
3834                    checkVisible(tree.pos(), sym, toplevel.packge, inSuperType);
3835                } else {
3836                    super.visitSelect(tree);
3837                }
3838            }
3839
3840            @Override
3841            public void visitAnnotation(JCAnnotation tree) {
3842                if (tree.attribute.type.tsym.getAnnotation(java.lang.annotation.Documented.class) != null)
3843                    super.visitAnnotation(tree);
3844            }
3845
3846        }.scan(check);
3847    }
3848        //where:
3849        private ExportsDirective findExport(PackageSymbol pack) {
3850            for (ExportsDirective d : pack.modle.exports) {
3851                if (d.packge == pack)
3852                    return d;
3853            }
3854
3855            return null;
3856        }
3857        private boolean isAPISymbol(Symbol sym) {
3858            while (sym.kind != PCK) {
3859                if ((sym.flags() & Flags.PUBLIC) == 0 && (sym.flags() & Flags.PROTECTED) == 0) {
3860                    return false;
3861                }
3862                sym = sym.owner;
3863            }
3864            return true;
3865        }
3866        private void checkVisible(DiagnosticPosition pos, Symbol what, PackageSymbol inPackage, boolean inSuperType) {
3867            if (!isAPISymbol(what) && !inSuperType) { //package private/private element
3868                log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessible(kindName(what), what, what.packge().modle));
3869                return ;
3870            }
3871
3872            PackageSymbol whatPackage = what.packge();
3873            ExportsDirective whatExport = findExport(whatPackage);
3874            ExportsDirective inExport = findExport(inPackage);
3875
3876            if (whatExport == null) { //package not exported:
3877                log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessibleUnexported(kindName(what), what, what.packge().modle));
3878                return ;
3879            }
3880
3881            if (whatExport.modules != null) {
3882                if (inExport.modules == null || !whatExport.modules.containsAll(inExport.modules)) {
3883                    log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessibleUnexportedQualified(kindName(what), what, what.packge().modle));
3884                }
3885            }
3886
3887            if (whatPackage.modle != inPackage.modle && whatPackage.modle != syms.java_base) {
3888                //check that relativeTo.modle requires transitive what.modle, somehow:
3889                List<ModuleSymbol> todo = List.of(inPackage.modle);
3890
3891                while (todo.nonEmpty()) {
3892                    ModuleSymbol current = todo.head;
3893                    todo = todo.tail;
3894                    if (current == whatPackage.modle)
3895                        return ; //OK
3896                    for (RequiresDirective req : current.requires) {
3897                        if (req.isTransitive()) {
3898                            todo = todo.prepend(req.module);
3899                        }
3900                    }
3901                }
3902
3903                log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessibleNotRequiredTransitive(kindName(what), what, what.packge().modle));
3904            }
3905        }
3906
3907    void checkModuleExists(final DiagnosticPosition pos, ModuleSymbol msym) {
3908        if (msym.kind != MDL) {
3909            deferredLintHandler.report(() -> {
3910                if (lint.isEnabled(LintCategory.MODULE))
3911                    log.warning(LintCategory.MODULE, pos, Warnings.ModuleNotFound(msym));
3912            });
3913        }
3914    }
3915
3916    void checkPackageExistsForOpens(final DiagnosticPosition pos, PackageSymbol packge) {
3917        if (packge.members().isEmpty() &&
3918            ((packge.flags() & Flags.HAS_RESOURCE) == 0)) {
3919            deferredLintHandler.report(() -> {
3920                if (lint.isEnabled(LintCategory.OPENS))
3921                    log.warning(pos, Warnings.PackageEmptyOrNotFound(packge));
3922            });
3923        }
3924    }
3925
3926    void checkModuleRequires(final DiagnosticPosition pos, final RequiresDirective rd) {
3927        if ((rd.module.flags() & Flags.AUTOMATIC_MODULE) != 0) {
3928            deferredLintHandler.report(() -> {
3929                if (rd.isTransitive() && lint.isEnabled(LintCategory.REQUIRES_TRANSITIVE_AUTOMATIC)) {
3930                    log.warning(pos, Warnings.RequiresTransitiveAutomatic);
3931                } else if (lint.isEnabled(LintCategory.REQUIRES_AUTOMATIC)) {
3932                    log.warning(pos, Warnings.RequiresAutomatic);
3933                }
3934            });
3935        }
3936    }
3937
3938}
3939