Check.java revision 4099:3a05346a30cd
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.List;
46
47import com.sun.tools.javac.code.Lint;
48import com.sun.tools.javac.code.Lint.LintCategory;
49import com.sun.tools.javac.code.Scope.WriteableScope;
50import com.sun.tools.javac.code.Type.*;
51import com.sun.tools.javac.code.Symbol.*;
52import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
53import com.sun.tools.javac.comp.Infer.FreeTypeListener;
54import com.sun.tools.javac.tree.JCTree.*;
55
56import static com.sun.tools.javac.code.Flags.*;
57import static com.sun.tools.javac.code.Flags.ANNOTATION;
58import static com.sun.tools.javac.code.Flags.SYNCHRONIZED;
59import static com.sun.tools.javac.code.Kinds.*;
60import static com.sun.tools.javac.code.Kinds.Kind.*;
61import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
62import static com.sun.tools.javac.code.TypeTag.*;
63import static com.sun.tools.javac.code.TypeTag.WILDCARD;
64
65import static com.sun.tools.javac.tree.JCTree.Tag.*;
66
67/** Type checking helper class for the attribution phase.
68 *
69 *  <p><b>This is NOT part of any supported API.
70 *  If you write code that depends on this, you do so at your own risk.
71 *  This code and its internal interfaces are subject to change or
72 *  deletion without notice.</b>
73 */
74public class Check {
75    protected static final Context.Key<Check> checkKey = new Context.Key<>();
76
77    private final Names names;
78    private final Log log;
79    private final Resolve rs;
80    private final Symtab syms;
81    private final Enter enter;
82    private final DeferredAttr deferredAttr;
83    private final Infer infer;
84    private final Types types;
85    private final TypeAnnotations typeAnnotations;
86    private final JCDiagnostic.Factory diags;
87    private final JavaFileManager fileManager;
88    private final Source source;
89    private final Profile profile;
90    private final boolean warnOnAnyAccessToMembers;
91
92    // The set of lint options currently in effect. It is initialized
93    // from the context, and then is set/reset as needed by Attr as it
94    // visits all the various parts of the trees during attribution.
95    private Lint lint;
96
97    // The method being analyzed in Attr - it is set/reset as needed by
98    // Attr as it visits new method declarations.
99    private MethodSymbol method;
100
101    public static Check instance(Context context) {
102        Check instance = context.get(checkKey);
103        if (instance == null)
104            instance = new Check(context);
105        return instance;
106    }
107
108    protected Check(Context context) {
109        context.put(checkKey, this);
110
111        names = Names.instance(context);
112        dfltTargetMeta = new Name[] { names.PACKAGE, names.TYPE,
113            names.FIELD, names.METHOD, names.CONSTRUCTOR,
114            names.ANNOTATION_TYPE, names.LOCAL_VARIABLE, names.PARAMETER};
115        log = Log.instance(context);
116        rs = Resolve.instance(context);
117        syms = Symtab.instance(context);
118        enter = Enter.instance(context);
119        deferredAttr = DeferredAttr.instance(context);
120        infer = Infer.instance(context);
121        types = Types.instance(context);
122        typeAnnotations = TypeAnnotations.instance(context);
123        diags = JCDiagnostic.Factory.instance(context);
124        Options options = Options.instance(context);
125        lint = Lint.instance(context);
126        fileManager = context.get(JavaFileManager.class);
127
128        source = Source.instance(context);
129        allowSimplifiedVarargs = source.allowSimplifiedVarargs();
130        allowDefaultMethods = source.allowDefaultMethods();
131        allowStrictMethodClashCheck = source.allowStrictMethodClashCheck();
132        allowPrivateSafeVarargs = source.allowPrivateSafeVarargs();
133        allowDiamondWithAnonymousClassCreation = source.allowDiamondWithAnonymousClassCreation();
134        warnOnAnyAccessToMembers = options.isSet("warnOnAccessToMembers");
135
136        Target target = Target.instance(context);
137        syntheticNameChar = target.syntheticNameChar();
138
139        profile = Profile.instance(context);
140
141        boolean verboseDeprecated = lint.isEnabled(LintCategory.DEPRECATION);
142        boolean verboseRemoval = lint.isEnabled(LintCategory.REMOVAL);
143        boolean verboseUnchecked = lint.isEnabled(LintCategory.UNCHECKED);
144        boolean enforceMandatoryWarnings = true;
145
146        deprecationHandler = new MandatoryWarningHandler(log, verboseDeprecated,
147                enforceMandatoryWarnings, "deprecated", LintCategory.DEPRECATION);
148        removalHandler = new MandatoryWarningHandler(log, verboseRemoval,
149                enforceMandatoryWarnings, "removal", LintCategory.REMOVAL);
150        uncheckedHandler = new MandatoryWarningHandler(log, verboseUnchecked,
151                enforceMandatoryWarnings, "unchecked", LintCategory.UNCHECKED);
152        sunApiHandler = new MandatoryWarningHandler(log, false,
153                enforceMandatoryWarnings, "sunapi", null);
154
155        deferredLintHandler = DeferredLintHandler.instance(context);
156    }
157
158    /** Switch: simplified varargs enabled?
159     */
160    boolean allowSimplifiedVarargs;
161
162    /** Switch: default methods enabled?
163     */
164    boolean allowDefaultMethods;
165
166    /** Switch: should unrelated return types trigger a method clash?
167     */
168    boolean allowStrictMethodClashCheck;
169
170    /** Switch: can the @SafeVarargs annotation be applied to private methods?
171     */
172    boolean allowPrivateSafeVarargs;
173
174    /** Switch: can diamond inference be used in anonymous instance creation ?
175     */
176    boolean allowDiamondWithAnonymousClassCreation;
177
178    /** Character for synthetic names
179     */
180    char syntheticNameChar;
181
182    /** A table mapping flat names of all compiled classes for each module in this run
183     *  to their symbols; maintained from outside.
184     */
185    private Map<Pair<ModuleSymbol, Name>,ClassSymbol> compiled = new HashMap<>();
186
187    /** A handler for messages about deprecated usage.
188     */
189    private MandatoryWarningHandler deprecationHandler;
190
191    /** A handler for messages about deprecated-for-removal usage.
192     */
193    private MandatoryWarningHandler removalHandler;
194
195    /** A handler for messages about unchecked or unsafe usage.
196     */
197    private MandatoryWarningHandler uncheckedHandler;
198
199    /** A handler for messages about using proprietary API.
200     */
201    private MandatoryWarningHandler sunApiHandler;
202
203    /** A handler for deferred lint warnings.
204     */
205    private DeferredLintHandler deferredLintHandler;
206
207/* *************************************************************************
208 * Errors and Warnings
209 **************************************************************************/
210
211    Lint setLint(Lint newLint) {
212        Lint prev = lint;
213        lint = newLint;
214        return prev;
215    }
216
217    MethodSymbol setMethod(MethodSymbol newMethod) {
218        MethodSymbol prev = method;
219        method = newMethod;
220        return prev;
221    }
222
223    /** Warn about deprecated symbol.
224     *  @param pos        Position to be used for error reporting.
225     *  @param sym        The deprecated symbol.
226     */
227    void warnDeprecated(DiagnosticPosition pos, Symbol sym) {
228        if (sym.isDeprecatedForRemoval()) {
229            if (!lint.isSuppressed(LintCategory.REMOVAL)) {
230                if (sym.kind == MDL) {
231                    removalHandler.report(pos, "has.been.deprecated.for.removal.module", sym);
232                } else {
233                    removalHandler.report(pos, "has.been.deprecated.for.removal", sym, sym.location());
234                }
235            }
236        } else if (!lint.isSuppressed(LintCategory.DEPRECATION)) {
237            if (sym.kind == MDL) {
238                deprecationHandler.report(pos, "has.been.deprecated.module", sym);
239            } else {
240                deprecationHandler.report(pos, "has.been.deprecated", sym, sym.location());
241            }
242        }
243    }
244
245    /** Warn about unchecked operation.
246     *  @param pos        Position to be used for error reporting.
247     *  @param msg        A string describing the problem.
248     */
249    public void warnUnchecked(DiagnosticPosition pos, String msg, Object... args) {
250        if (!lint.isSuppressed(LintCategory.UNCHECKED))
251            uncheckedHandler.report(pos, msg, args);
252    }
253
254    /** Warn about unsafe vararg method decl.
255     *  @param pos        Position to be used for error reporting.
256     */
257    void warnUnsafeVararg(DiagnosticPosition pos, String key, Object... args) {
258        if (lint.isEnabled(LintCategory.VARARGS) && allowSimplifiedVarargs)
259            log.warning(LintCategory.VARARGS, pos, key, args);
260    }
261
262    public void warnStatic(DiagnosticPosition pos, String msg, Object... args) {
263        if (lint.isEnabled(LintCategory.STATIC))
264            log.warning(LintCategory.STATIC, pos, msg, args);
265    }
266
267    /** Warn about division by integer constant zero.
268     *  @param pos        Position to be used for error reporting.
269     */
270    void warnDivZero(DiagnosticPosition pos) {
271        if (lint.isEnabled(LintCategory.DIVZERO))
272            log.warning(LintCategory.DIVZERO, pos, "div.zero");
273    }
274
275    /**
276     * Report any deferred diagnostics.
277     */
278    public void reportDeferredDiagnostics() {
279        deprecationHandler.reportDeferredDiagnostic();
280        removalHandler.reportDeferredDiagnostic();
281        uncheckedHandler.reportDeferredDiagnostic();
282        sunApiHandler.reportDeferredDiagnostic();
283    }
284
285
286    /** Report a failure to complete a class.
287     *  @param pos        Position to be used for error reporting.
288     *  @param ex         The failure to report.
289     */
290    public Type completionError(DiagnosticPosition pos, CompletionFailure ex) {
291        log.error(JCDiagnostic.DiagnosticFlag.NON_DEFERRABLE, pos, "cant.access", ex.sym, ex.getDetailValue());
292        if (ex instanceof ClassFinder.BadClassFile) throw new Abort();
293        else return syms.errType;
294    }
295
296    /** Report an error that wrong type tag was found.
297     *  @param pos        Position to be used for error reporting.
298     *  @param required   An internationalized string describing the type tag
299     *                    required.
300     *  @param found      The type that was found.
301     */
302    Type typeTagError(DiagnosticPosition pos, Object required, Object found) {
303        // this error used to be raised by the parser,
304        // but has been delayed to this point:
305        if (found instanceof Type && ((Type)found).hasTag(VOID)) {
306            log.error(pos, "illegal.start.of.type");
307            return syms.errType;
308        }
309        log.error(pos, "type.found.req", found, required);
310        return types.createErrorType(found instanceof Type ? (Type)found : syms.errType);
311    }
312
313    /** Report an error that symbol cannot be referenced before super
314     *  has been called.
315     *  @param pos        Position to be used for error reporting.
316     *  @param sym        The referenced symbol.
317     */
318    void earlyRefError(DiagnosticPosition pos, Symbol sym) {
319        log.error(pos, "cant.ref.before.ctor.called", sym);
320    }
321
322    /** Report duplicate declaration error.
323     */
324    void duplicateError(DiagnosticPosition pos, Symbol sym) {
325        if (!sym.type.isErroneous()) {
326            Symbol location = sym.location();
327            if (location.kind == MTH &&
328                    ((MethodSymbol)location).isStaticOrInstanceInit()) {
329                log.error(pos, "already.defined.in.clinit", kindName(sym), sym,
330                        kindName(sym.location()), kindName(sym.location().enclClass()),
331                        sym.location().enclClass());
332            } else {
333                log.error(pos, "already.defined", kindName(sym), sym,
334                        kindName(sym.location()), sym.location());
335            }
336        }
337    }
338
339    /** Report array/varargs duplicate declaration
340     */
341    void varargsDuplicateError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) {
342        if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) {
343            log.error(pos, "array.and.varargs", sym1, sym2, sym2.location());
344        }
345    }
346
347/* ************************************************************************
348 * duplicate declaration checking
349 *************************************************************************/
350
351    /** Check that variable does not hide variable with same name in
352     *  immediately enclosing local scope.
353     *  @param pos           Position for error reporting.
354     *  @param v             The symbol.
355     *  @param s             The scope.
356     */
357    void checkTransparentVar(DiagnosticPosition pos, VarSymbol v, Scope s) {
358        for (Symbol sym : s.getSymbolsByName(v.name)) {
359            if (sym.owner != v.owner) break;
360            if (sym.kind == VAR &&
361                sym.owner.kind.matches(KindSelector.VAL_MTH) &&
362                v.name != names.error) {
363                duplicateError(pos, sym);
364                return;
365            }
366        }
367    }
368
369    /** Check that a class or interface does not hide a class or
370     *  interface with same name in immediately enclosing local scope.
371     *  @param pos           Position for error reporting.
372     *  @param c             The symbol.
373     *  @param s             The scope.
374     */
375    void checkTransparentClass(DiagnosticPosition pos, ClassSymbol c, Scope s) {
376        for (Symbol sym : s.getSymbolsByName(c.name)) {
377            if (sym.owner != c.owner) break;
378            if (sym.kind == TYP && !sym.type.hasTag(TYPEVAR) &&
379                sym.owner.kind.matches(KindSelector.VAL_MTH) &&
380                c.name != names.error) {
381                duplicateError(pos, sym);
382                return;
383            }
384        }
385    }
386
387    /** Check that class does not have the same name as one of
388     *  its enclosing classes, or as a class defined in its enclosing scope.
389     *  return true if class is unique in its enclosing scope.
390     *  @param pos           Position for error reporting.
391     *  @param name          The class name.
392     *  @param s             The enclosing scope.
393     */
394    boolean checkUniqueClassName(DiagnosticPosition pos, Name name, Scope s) {
395        for (Symbol sym : s.getSymbolsByName(name, NON_RECURSIVE)) {
396            if (sym.kind == TYP && sym.name != names.error) {
397                duplicateError(pos, sym);
398                return false;
399            }
400        }
401        for (Symbol sym = s.owner; sym != null; sym = sym.owner) {
402            if (sym.kind == TYP && sym.name == name && sym.name != names.error) {
403                duplicateError(pos, sym);
404                return true;
405            }
406        }
407        return true;
408    }
409
410/* *************************************************************************
411 * Class name generation
412 **************************************************************************/
413
414
415    private Map<Pair<Name, Name>, Integer> localClassNameIndexes = new HashMap<>();
416
417    /** Return name of local class.
418     *  This is of the form   {@code <enclClass> $ n <classname> }
419     *  where
420     *    enclClass is the flat name of the enclosing class,
421     *    classname is the simple name of the local class
422     */
423    Name localClassName(ClassSymbol c) {
424        Name enclFlatname = c.owner.enclClass().flatname;
425        String enclFlatnameStr = enclFlatname.toString();
426        Pair<Name, Name> key = new Pair<>(enclFlatname, c.name);
427        Integer index = localClassNameIndexes.get(key);
428        for (int i = (index == null) ? 1 : index; ; i++) {
429            Name flatname = names.fromString(enclFlatnameStr
430                    + syntheticNameChar + i + c.name);
431            if (getCompiled(c.packge().modle, flatname) == null) {
432                localClassNameIndexes.put(key, i + 1);
433                return flatname;
434            }
435        }
436    }
437
438    void clearLocalClassNameIndexes(ClassSymbol c) {
439        if (c.owner != null && c.owner.kind != NIL) {
440            localClassNameIndexes.remove(new Pair<>(
441                    c.owner.enclClass().flatname, c.name));
442        }
443    }
444
445    public void newRound() {
446        compiled.clear();
447        localClassNameIndexes.clear();
448    }
449
450    public void putCompiled(ClassSymbol csym) {
451        compiled.put(Pair.of(csym.packge().modle, csym.flatname), csym);
452    }
453
454    public ClassSymbol getCompiled(ClassSymbol csym) {
455        return compiled.get(Pair.of(csym.packge().modle, csym.flatname));
456    }
457
458    public ClassSymbol getCompiled(ModuleSymbol msym, Name flatname) {
459        return compiled.get(Pair.of(msym, flatname));
460    }
461
462    public void removeCompiled(ClassSymbol csym) {
463        compiled.remove(Pair.of(csym.packge().modle, csym.flatname));
464    }
465
466/* *************************************************************************
467 * Type Checking
468 **************************************************************************/
469
470    /**
471     * A check context is an object that can be used to perform compatibility
472     * checks - depending on the check context, meaning of 'compatibility' might
473     * vary significantly.
474     */
475    public interface CheckContext {
476        /**
477         * Is type 'found' compatible with type 'req' in given context
478         */
479        boolean compatible(Type found, Type req, Warner warn);
480        /**
481         * Report a check error
482         */
483        void report(DiagnosticPosition pos, JCDiagnostic details);
484        /**
485         * Obtain a warner for this check context
486         */
487        public Warner checkWarner(DiagnosticPosition pos, Type found, Type req);
488
489        public InferenceContext inferenceContext();
490
491        public DeferredAttr.DeferredAttrContext deferredAttrContext();
492    }
493
494    /**
495     * This class represent a check context that is nested within another check
496     * context - useful to check sub-expressions. The default behavior simply
497     * redirects all method calls to the enclosing check context leveraging
498     * the forwarding pattern.
499     */
500    static class NestedCheckContext implements CheckContext {
501        CheckContext enclosingContext;
502
503        NestedCheckContext(CheckContext enclosingContext) {
504            this.enclosingContext = enclosingContext;
505        }
506
507        public boolean compatible(Type found, Type req, Warner warn) {
508            return enclosingContext.compatible(found, req, warn);
509        }
510
511        public void report(DiagnosticPosition pos, JCDiagnostic details) {
512            enclosingContext.report(pos, details);
513        }
514
515        public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
516            return enclosingContext.checkWarner(pos, found, req);
517        }
518
519        public InferenceContext inferenceContext() {
520            return enclosingContext.inferenceContext();
521        }
522
523        public DeferredAttrContext deferredAttrContext() {
524            return enclosingContext.deferredAttrContext();
525        }
526    }
527
528    /**
529     * Check context to be used when evaluating assignment/return statements
530     */
531    CheckContext basicHandler = new CheckContext() {
532        public void report(DiagnosticPosition pos, JCDiagnostic details) {
533            log.error(pos, "prob.found.req", details);
534        }
535        public boolean compatible(Type found, Type req, Warner warn) {
536            return types.isAssignable(found, req, warn);
537        }
538
539        public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
540            return convertWarner(pos, found, req);
541        }
542
543        public InferenceContext inferenceContext() {
544            return infer.emptyContext;
545        }
546
547        public DeferredAttrContext deferredAttrContext() {
548            return deferredAttr.emptyDeferredAttrContext;
549        }
550
551        @Override
552        public String toString() {
553            return "CheckContext: basicHandler";
554        }
555    };
556
557    /** Check that a given type is assignable to a given proto-type.
558     *  If it is, return the type, otherwise return errType.
559     *  @param pos        Position to be used for error reporting.
560     *  @param found      The type that was found.
561     *  @param req        The type that was required.
562     */
563    public Type checkType(DiagnosticPosition pos, Type found, Type req) {
564        return checkType(pos, found, req, basicHandler);
565    }
566
567    Type checkType(final DiagnosticPosition pos, final Type found, final Type req, final CheckContext checkContext) {
568        final InferenceContext inferenceContext = checkContext.inferenceContext();
569        if (inferenceContext.free(req) || inferenceContext.free(found)) {
570            inferenceContext.addFreeTypeListener(List.of(req, found),
571                    solvedContext -> checkType(pos, solvedContext.asInstType(found), solvedContext.asInstType(req), checkContext));
572        }
573        if (req.hasTag(ERROR))
574            return req;
575        if (req.hasTag(NONE))
576            return found;
577        if (checkContext.compatible(found, req, checkContext.checkWarner(pos, found, req))) {
578            return found;
579        } else {
580            if (found.isNumeric() && req.isNumeric()) {
581                checkContext.report(pos, diags.fragment("possible.loss.of.precision", found, req));
582                return types.createErrorType(found);
583            }
584            checkContext.report(pos, diags.fragment("inconvertible.types", found, req));
585            return types.createErrorType(found);
586        }
587    }
588
589    /** Check that a given type can be cast to a given target type.
590     *  Return the result of the cast.
591     *  @param pos        Position to be used for error reporting.
592     *  @param found      The type that is being cast.
593     *  @param req        The target type of the cast.
594     */
595    Type checkCastable(DiagnosticPosition pos, Type found, Type req) {
596        return checkCastable(pos, found, req, basicHandler);
597    }
598    Type checkCastable(DiagnosticPosition pos, Type found, Type req, CheckContext checkContext) {
599        if (types.isCastable(found, req, castWarner(pos, found, req))) {
600            return req;
601        } else {
602            checkContext.report(pos, diags.fragment("inconvertible.types", found, req));
603            return types.createErrorType(found);
604        }
605    }
606
607    /** Check for redundant casts (i.e. where source type is a subtype of target type)
608     * The problem should only be reported for non-292 cast
609     */
610    public void checkRedundantCast(Env<AttrContext> env, final JCTypeCast tree) {
611        if (!tree.type.isErroneous()
612                && types.isSameType(tree.expr.type, tree.clazz.type)
613                && !(ignoreAnnotatedCasts && TreeInfo.containsTypeAnnotation(tree.clazz))
614                && !is292targetTypeCast(tree)) {
615            deferredLintHandler.report(() -> {
616                if (lint.isEnabled(LintCategory.CAST))
617                    log.warning(LintCategory.CAST,
618                            tree.pos(), "redundant.cast", tree.clazz.type);
619            });
620        }
621    }
622    //where
623        private boolean is292targetTypeCast(JCTypeCast tree) {
624            boolean is292targetTypeCast = false;
625            JCExpression expr = TreeInfo.skipParens(tree.expr);
626            if (expr.hasTag(APPLY)) {
627                JCMethodInvocation apply = (JCMethodInvocation)expr;
628                Symbol sym = TreeInfo.symbol(apply.meth);
629                is292targetTypeCast = sym != null &&
630                    sym.kind == MTH &&
631                    (sym.flags() & HYPOTHETICAL) != 0;
632            }
633            return is292targetTypeCast;
634        }
635
636        private static final boolean ignoreAnnotatedCasts = true;
637
638    /** Check that a type is within some bounds.
639     *
640     *  Used in TypeApply to verify that, e.g., X in {@code V<X>} is a valid
641     *  type argument.
642     *  @param a             The type that should be bounded by bs.
643     *  @param bound         The bound.
644     */
645    private boolean checkExtends(Type a, Type bound) {
646         if (a.isUnbound()) {
647             return true;
648         } else if (!a.hasTag(WILDCARD)) {
649             a = types.cvarUpperBound(a);
650             return types.isSubtype(a, bound);
651         } else if (a.isExtendsBound()) {
652             return types.isCastable(bound, types.wildUpperBound(a), types.noWarnings);
653         } else if (a.isSuperBound()) {
654             return !types.notSoftSubtype(types.wildLowerBound(a), bound);
655         }
656         return true;
657     }
658
659    /** Check that type is different from 'void'.
660     *  @param pos           Position to be used for error reporting.
661     *  @param t             The type to be checked.
662     */
663    Type checkNonVoid(DiagnosticPosition pos, Type t) {
664        if (t.hasTag(VOID)) {
665            log.error(pos, "void.not.allowed.here");
666            return types.createErrorType(t);
667        } else {
668            return t;
669        }
670    }
671
672    Type checkClassOrArrayType(DiagnosticPosition pos, Type t) {
673        if (!t.hasTag(CLASS) && !t.hasTag(ARRAY) && !t.hasTag(ERROR)) {
674            return typeTagError(pos,
675                                diags.fragment("type.req.class.array"),
676                                asTypeParam(t));
677        } else {
678            return t;
679        }
680    }
681
682    /** Check that type is a class or interface type.
683     *  @param pos           Position to be used for error reporting.
684     *  @param t             The type to be checked.
685     */
686    Type checkClassType(DiagnosticPosition pos, Type t) {
687        if (!t.hasTag(CLASS) && !t.hasTag(ERROR)) {
688            return typeTagError(pos,
689                                diags.fragment("type.req.class"),
690                                asTypeParam(t));
691        } else {
692            return t;
693        }
694    }
695    //where
696        private Object asTypeParam(Type t) {
697            return (t.hasTag(TYPEVAR))
698                                    ? diags.fragment("type.parameter", t)
699                                    : t;
700        }
701
702    /** Check that type is a valid qualifier for a constructor reference expression
703     */
704    Type checkConstructorRefType(DiagnosticPosition pos, Type t) {
705        t = checkClassOrArrayType(pos, t);
706        if (t.hasTag(CLASS)) {
707            if ((t.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) {
708                log.error(pos, "abstract.cant.be.instantiated", t.tsym);
709                t = types.createErrorType(t);
710            } else if ((t.tsym.flags() & ENUM) != 0) {
711                log.error(pos, "enum.cant.be.instantiated");
712                t = types.createErrorType(t);
713            } else {
714                t = checkClassType(pos, t, true);
715            }
716        } else if (t.hasTag(ARRAY)) {
717            if (!types.isReifiable(((ArrayType)t).elemtype)) {
718                log.error(pos, "generic.array.creation");
719                t = types.createErrorType(t);
720            }
721        }
722        return t;
723    }
724
725    /** Check that type is a class or interface type.
726     *  @param pos           Position to be used for error reporting.
727     *  @param t             The type to be checked.
728     *  @param noBounds    True if type bounds are illegal here.
729     */
730    Type checkClassType(DiagnosticPosition pos, Type t, boolean noBounds) {
731        t = checkClassType(pos, t);
732        if (noBounds && t.isParameterized()) {
733            List<Type> args = t.getTypeArguments();
734            while (args.nonEmpty()) {
735                if (args.head.hasTag(WILDCARD))
736                    return typeTagError(pos,
737                                        diags.fragment("type.req.exact"),
738                                        args.head);
739                args = args.tail;
740            }
741        }
742        return t;
743    }
744
745    /** Check that type is a reference type, i.e. a class, interface or array type
746     *  or a type variable.
747     *  @param pos           Position to be used for error reporting.
748     *  @param t             The type to be checked.
749     */
750    Type checkRefType(DiagnosticPosition pos, Type t) {
751        if (t.isReference())
752            return t;
753        else
754            return typeTagError(pos,
755                                diags.fragment("type.req.ref"),
756                                t);
757    }
758
759    /** Check that each type is a reference type, i.e. a class, interface or array type
760     *  or a type variable.
761     *  @param trees         Original trees, used for error reporting.
762     *  @param types         The types to be checked.
763     */
764    List<Type> checkRefTypes(List<JCExpression> trees, List<Type> types) {
765        List<JCExpression> tl = trees;
766        for (List<Type> l = types; l.nonEmpty(); l = l.tail) {
767            l.head = checkRefType(tl.head.pos(), l.head);
768            tl = tl.tail;
769        }
770        return types;
771    }
772
773    /** Check that type is a null or reference type.
774     *  @param pos           Position to be used for error reporting.
775     *  @param t             The type to be checked.
776     */
777    Type checkNullOrRefType(DiagnosticPosition pos, Type t) {
778        if (t.isReference() || t.hasTag(BOT))
779            return t;
780        else
781            return typeTagError(pos,
782                                diags.fragment("type.req.ref"),
783                                t);
784    }
785
786    /** Check that flag set does not contain elements of two conflicting sets. s
787     *  Return true if it doesn't.
788     *  @param pos           Position to be used for error reporting.
789     *  @param flags         The set of flags to be checked.
790     *  @param set1          Conflicting flags set #1.
791     *  @param set2          Conflicting flags set #2.
792     */
793    boolean checkDisjoint(DiagnosticPosition pos, long flags, long set1, long set2) {
794        if ((flags & set1) != 0 && (flags & set2) != 0) {
795            log.error(pos,
796                      "illegal.combination.of.modifiers",
797                      asFlagSet(TreeInfo.firstFlag(flags & set1)),
798                      asFlagSet(TreeInfo.firstFlag(flags & set2)));
799            return false;
800        } else
801            return true;
802    }
803
804    /** Check that usage of diamond operator is correct (i.e. diamond should not
805     * be used with non-generic classes or in anonymous class creation expressions)
806     */
807    Type checkDiamond(JCNewClass tree, Type t) {
808        if (!TreeInfo.isDiamond(tree) ||
809                t.isErroneous()) {
810            return checkClassType(tree.clazz.pos(), t, true);
811        } else {
812            if (tree.def != null && !allowDiamondWithAnonymousClassCreation) {
813                log.error(DiagnosticFlag.SOURCE_LEVEL, tree.clazz.pos(),
814                        Errors.CantApplyDiamond1(t, Fragments.DiamondAndAnonClassNotSupportedInSource(source.name)));
815            }
816            if (t.tsym.type.getTypeArguments().isEmpty()) {
817                log.error(tree.clazz.pos(),
818                    "cant.apply.diamond.1",
819                    t, diags.fragment("diamond.non.generic", t));
820                return types.createErrorType(t);
821            } else if (tree.typeargs != null &&
822                    tree.typeargs.nonEmpty()) {
823                log.error(tree.clazz.pos(),
824                    "cant.apply.diamond.1",
825                    t, diags.fragment("diamond.and.explicit.params", t));
826                return types.createErrorType(t);
827            } else {
828                return t;
829            }
830        }
831    }
832
833    /** Check that the type inferred using the diamond operator does not contain
834     *  non-denotable types such as captured types or intersection types.
835     *  @param t the type inferred using the diamond operator
836     *  @return  the (possibly empty) list of non-denotable types.
837     */
838    List<Type> checkDiamondDenotable(ClassType t) {
839        ListBuffer<Type> buf = new ListBuffer<>();
840        for (Type arg : t.allparams()) {
841            if (!diamondTypeChecker.visit(arg, null)) {
842                buf.append(arg);
843            }
844        }
845        return buf.toList();
846    }
847        // where
848
849        /** diamondTypeChecker: A type visitor that descends down the given type looking for non-denotable
850         *  types. The visit methods return false as soon as a non-denotable type is encountered and true
851         *  otherwise.
852         */
853        private static final Types.SimpleVisitor<Boolean, Void> diamondTypeChecker = new Types.SimpleVisitor<Boolean, Void>() {
854            @Override
855            public Boolean visitType(Type t, Void s) {
856                return true;
857            }
858            @Override
859            public Boolean visitClassType(ClassType t, Void s) {
860                if (t.isCompound()) {
861                    return false;
862                }
863                for (Type targ : t.allparams()) {
864                    if (!visit(targ, s)) {
865                        return false;
866                    }
867                }
868                return true;
869            }
870
871            @Override
872            public Boolean visitTypeVar(TypeVar t, Void s) {
873                /* Any type variable mentioned in the inferred type must have been declared as a type parameter
874                  (i.e cannot have been produced by inference (18.4))
875                */
876                return t.tsym.owner.type.getTypeArguments().contains(t);
877            }
878
879            @Override
880            public Boolean visitCapturedType(CapturedType t, Void s) {
881                /* Any type variable mentioned in the inferred type must have been declared as a type parameter
882                  (i.e cannot have been produced by capture conversion (5.1.10))
883                */
884                return false;
885            }
886
887            @Override
888            public Boolean visitArrayType(ArrayType t, Void s) {
889                return visit(t.elemtype, s);
890            }
891
892            @Override
893            public Boolean visitWildcardType(WildcardType t, Void s) {
894                return visit(t.type, s);
895            }
896        };
897
898    void checkVarargsMethodDecl(Env<AttrContext> env, JCMethodDecl tree) {
899        MethodSymbol m = tree.sym;
900        if (!allowSimplifiedVarargs) return;
901        boolean hasTrustMeAnno = m.attribute(syms.trustMeType.tsym) != null;
902        Type varargElemType = null;
903        if (m.isVarArgs()) {
904            varargElemType = types.elemtype(tree.params.last().type);
905        }
906        if (hasTrustMeAnno && !isTrustMeAllowedOnMethod(m)) {
907            if (varargElemType != null) {
908                log.error(tree,
909                        "varargs.invalid.trustme.anno",
910                          syms.trustMeType.tsym,
911                          allowPrivateSafeVarargs ?
912                          diags.fragment("varargs.trustme.on.virtual.varargs", m) :
913                          diags.fragment("varargs.trustme.on.virtual.varargs.final.only", m));
914            } else {
915                log.error(tree,
916                            "varargs.invalid.trustme.anno",
917                            syms.trustMeType.tsym,
918                            diags.fragment("varargs.trustme.on.non.varargs.meth", m));
919            }
920        } else if (hasTrustMeAnno && varargElemType != null &&
921                            types.isReifiable(varargElemType)) {
922            warnUnsafeVararg(tree,
923                            "varargs.redundant.trustme.anno",
924                            syms.trustMeType.tsym,
925                            diags.fragment("varargs.trustme.on.reifiable.varargs", varargElemType));
926        }
927        else if (!hasTrustMeAnno && varargElemType != null &&
928                !types.isReifiable(varargElemType)) {
929            warnUnchecked(tree.params.head.pos(), "unchecked.varargs.non.reifiable.type", varargElemType);
930        }
931    }
932    //where
933        private boolean isTrustMeAllowedOnMethod(Symbol s) {
934            return (s.flags() & VARARGS) != 0 &&
935                (s.isConstructor() ||
936                    (s.flags() & (STATIC | FINAL |
937                                  (allowPrivateSafeVarargs ? PRIVATE : 0) )) != 0);
938        }
939
940    Type checkMethod(final Type mtype,
941            final Symbol sym,
942            final Env<AttrContext> env,
943            final List<JCExpression> argtrees,
944            final List<Type> argtypes,
945            final boolean useVarargs,
946            InferenceContext inferenceContext) {
947        // System.out.println("call   : " + env.tree);
948        // System.out.println("method : " + owntype);
949        // System.out.println("actuals: " + argtypes);
950        if (inferenceContext.free(mtype)) {
951            inferenceContext.addFreeTypeListener(List.of(mtype),
952                    solvedContext -> checkMethod(solvedContext.asInstType(mtype), sym, env, argtrees, argtypes, useVarargs, solvedContext));
953            return mtype;
954        }
955        Type owntype = mtype;
956        List<Type> formals = owntype.getParameterTypes();
957        List<Type> nonInferred = sym.type.getParameterTypes();
958        if (nonInferred.length() != formals.length()) nonInferred = formals;
959        Type last = useVarargs ? formals.last() : null;
960        if (sym.name == names.init && sym.owner == syms.enumSym) {
961            formals = formals.tail.tail;
962            nonInferred = nonInferred.tail.tail;
963        }
964        List<JCExpression> args = argtrees;
965        if (args != null) {
966            //this is null when type-checking a method reference
967            while (formals.head != last) {
968                JCTree arg = args.head;
969                Warner warn = convertWarner(arg.pos(), arg.type, nonInferred.head);
970                assertConvertible(arg, arg.type, formals.head, warn);
971                args = args.tail;
972                formals = formals.tail;
973                nonInferred = nonInferred.tail;
974            }
975            if (useVarargs) {
976                Type varArg = types.elemtype(last);
977                while (args.tail != null) {
978                    JCTree arg = args.head;
979                    Warner warn = convertWarner(arg.pos(), arg.type, varArg);
980                    assertConvertible(arg, arg.type, varArg, warn);
981                    args = args.tail;
982                }
983            } else if ((sym.flags() & (VARARGS | SIGNATURE_POLYMORPHIC)) == VARARGS) {
984                // non-varargs call to varargs method
985                Type varParam = owntype.getParameterTypes().last();
986                Type lastArg = argtypes.last();
987                if (types.isSubtypeUnchecked(lastArg, types.elemtype(varParam)) &&
988                    !types.isSameType(types.erasure(varParam), types.erasure(lastArg)))
989                    log.warning(argtrees.last().pos(), "inexact.non-varargs.call",
990                                types.elemtype(varParam), varParam);
991            }
992        }
993        if (useVarargs) {
994            Type argtype = owntype.getParameterTypes().last();
995            if (!types.isReifiable(argtype) &&
996                (!allowSimplifiedVarargs ||
997                 sym.baseSymbol().attribute(syms.trustMeType.tsym) == null ||
998                 !isTrustMeAllowedOnMethod(sym))) {
999                warnUnchecked(env.tree.pos(),
1000                                  "unchecked.generic.array.creation",
1001                                  argtype);
1002            }
1003            if ((sym.baseSymbol().flags() & SIGNATURE_POLYMORPHIC) == 0) {
1004                TreeInfo.setVarargsElement(env.tree, types.elemtype(argtype));
1005            }
1006         }
1007         return owntype;
1008    }
1009    //where
1010    private void assertConvertible(JCTree tree, Type actual, Type formal, Warner warn) {
1011        if (types.isConvertible(actual, formal, warn))
1012            return;
1013
1014        if (formal.isCompound()
1015            && types.isSubtype(actual, types.supertype(formal))
1016            && types.isSubtypeUnchecked(actual, types.interfaces(formal), warn))
1017            return;
1018    }
1019
1020    /**
1021     * Check that type 't' is a valid instantiation of a generic class
1022     * (see JLS 4.5)
1023     *
1024     * @param t class type to be checked
1025     * @return true if 't' is well-formed
1026     */
1027    public boolean checkValidGenericType(Type t) {
1028        return firstIncompatibleTypeArg(t) == null;
1029    }
1030    //WHERE
1031        private Type firstIncompatibleTypeArg(Type type) {
1032            List<Type> formals = type.tsym.type.allparams();
1033            List<Type> actuals = type.allparams();
1034            List<Type> args = type.getTypeArguments();
1035            List<Type> forms = type.tsym.type.getTypeArguments();
1036            ListBuffer<Type> bounds_buf = new ListBuffer<>();
1037
1038            // For matching pairs of actual argument types `a' and
1039            // formal type parameters with declared bound `b' ...
1040            while (args.nonEmpty() && forms.nonEmpty()) {
1041                // exact type arguments needs to know their
1042                // bounds (for upper and lower bound
1043                // calculations).  So we create new bounds where
1044                // type-parameters are replaced with actuals argument types.
1045                bounds_buf.append(types.subst(forms.head.getUpperBound(), formals, actuals));
1046                args = args.tail;
1047                forms = forms.tail;
1048            }
1049
1050            args = type.getTypeArguments();
1051            List<Type> tvars_cap = types.substBounds(formals,
1052                                      formals,
1053                                      types.capture(type).allparams());
1054            while (args.nonEmpty() && tvars_cap.nonEmpty()) {
1055                // Let the actual arguments know their bound
1056                args.head.withTypeVar((TypeVar)tvars_cap.head);
1057                args = args.tail;
1058                tvars_cap = tvars_cap.tail;
1059            }
1060
1061            args = type.getTypeArguments();
1062            List<Type> bounds = bounds_buf.toList();
1063
1064            while (args.nonEmpty() && bounds.nonEmpty()) {
1065                Type actual = args.head;
1066                if (!isTypeArgErroneous(actual) &&
1067                        !bounds.head.isErroneous() &&
1068                        !checkExtends(actual, bounds.head)) {
1069                    return args.head;
1070                }
1071                args = args.tail;
1072                bounds = bounds.tail;
1073            }
1074
1075            args = type.getTypeArguments();
1076            bounds = bounds_buf.toList();
1077
1078            for (Type arg : types.capture(type).getTypeArguments()) {
1079                if (arg.hasTag(TYPEVAR) &&
1080                        arg.getUpperBound().isErroneous() &&
1081                        !bounds.head.isErroneous() &&
1082                        !isTypeArgErroneous(args.head)) {
1083                    return args.head;
1084                }
1085                bounds = bounds.tail;
1086                args = args.tail;
1087            }
1088
1089            return null;
1090        }
1091        //where
1092        boolean isTypeArgErroneous(Type t) {
1093            return isTypeArgErroneous.visit(t);
1094        }
1095
1096        Types.UnaryVisitor<Boolean> isTypeArgErroneous = new Types.UnaryVisitor<Boolean>() {
1097            public Boolean visitType(Type t, Void s) {
1098                return t.isErroneous();
1099            }
1100            @Override
1101            public Boolean visitTypeVar(TypeVar t, Void s) {
1102                return visit(t.getUpperBound());
1103            }
1104            @Override
1105            public Boolean visitCapturedType(CapturedType t, Void s) {
1106                return visit(t.getUpperBound()) ||
1107                        visit(t.getLowerBound());
1108            }
1109            @Override
1110            public Boolean visitWildcardType(WildcardType t, Void s) {
1111                return visit(t.type);
1112            }
1113        };
1114
1115    /** Check that given modifiers are legal for given symbol and
1116     *  return modifiers together with any implicit modifiers for that symbol.
1117     *  Warning: we can't use flags() here since this method
1118     *  is called during class enter, when flags() would cause a premature
1119     *  completion.
1120     *  @param pos           Position to be used for error reporting.
1121     *  @param flags         The set of modifiers given in a definition.
1122     *  @param sym           The defined symbol.
1123     */
1124    long checkFlags(DiagnosticPosition pos, long flags, Symbol sym, JCTree tree) {
1125        long mask;
1126        long implicit = 0;
1127
1128        switch (sym.kind) {
1129        case VAR:
1130            if (TreeInfo.isReceiverParam(tree))
1131                mask = ReceiverParamFlags;
1132            else if (sym.owner.kind != TYP)
1133                mask = LocalVarFlags;
1134            else if ((sym.owner.flags_field & INTERFACE) != 0)
1135                mask = implicit = InterfaceVarFlags;
1136            else
1137                mask = VarFlags;
1138            break;
1139        case MTH:
1140            if (sym.name == names.init) {
1141                if ((sym.owner.flags_field & ENUM) != 0) {
1142                    // enum constructors cannot be declared public or
1143                    // protected and must be implicitly or explicitly
1144                    // private
1145                    implicit = PRIVATE;
1146                    mask = PRIVATE;
1147                } else
1148                    mask = ConstructorFlags;
1149            }  else if ((sym.owner.flags_field & INTERFACE) != 0) {
1150                if ((sym.owner.flags_field & ANNOTATION) != 0) {
1151                    mask = AnnotationTypeElementMask;
1152                    implicit = PUBLIC | ABSTRACT;
1153                } else if ((flags & (DEFAULT | STATIC | PRIVATE)) != 0) {
1154                    mask = InterfaceMethodMask;
1155                    implicit = (flags & PRIVATE) != 0 ? 0 : PUBLIC;
1156                    if ((flags & DEFAULT) != 0) {
1157                        implicit |= ABSTRACT;
1158                    }
1159                } else {
1160                    mask = implicit = InterfaceMethodFlags;
1161                }
1162            } else {
1163                mask = MethodFlags;
1164            }
1165            // Imply STRICTFP if owner has STRICTFP set.
1166            if (((flags|implicit) & Flags.ABSTRACT) == 0 ||
1167                ((flags) & Flags.DEFAULT) != 0)
1168                implicit |= sym.owner.flags_field & STRICTFP;
1169            break;
1170        case TYP:
1171            if (sym.isLocal()) {
1172                mask = LocalClassFlags;
1173                if ((sym.owner.flags_field & STATIC) == 0 &&
1174                    (flags & ENUM) != 0)
1175                    log.error(pos, "enums.must.be.static");
1176            } else if (sym.owner.kind == TYP) {
1177                mask = MemberClassFlags;
1178                if (sym.owner.owner.kind == PCK ||
1179                    (sym.owner.flags_field & STATIC) != 0)
1180                    mask |= STATIC;
1181                else if ((flags & ENUM) != 0)
1182                    log.error(pos, "enums.must.be.static");
1183                // Nested interfaces and enums are always STATIC (Spec ???)
1184                if ((flags & (INTERFACE | ENUM)) != 0 ) implicit = STATIC;
1185            } else {
1186                mask = ClassFlags;
1187            }
1188            // Interfaces are always ABSTRACT
1189            if ((flags & INTERFACE) != 0) implicit |= ABSTRACT;
1190
1191            if ((flags & ENUM) != 0) {
1192                // enums can't be declared abstract or final
1193                mask &= ~(ABSTRACT | FINAL);
1194                implicit |= implicitEnumFinalFlag(tree);
1195            }
1196            // Imply STRICTFP if owner has STRICTFP set.
1197            implicit |= sym.owner.flags_field & STRICTFP;
1198            break;
1199        default:
1200            throw new AssertionError();
1201        }
1202        long illegal = flags & ExtendedStandardFlags & ~mask;
1203        if (illegal != 0) {
1204            if ((illegal & INTERFACE) != 0) {
1205                log.error(pos, "intf.not.allowed.here");
1206                mask |= INTERFACE;
1207            }
1208            else {
1209                log.error(pos,
1210                          "mod.not.allowed.here", asFlagSet(illegal));
1211            }
1212        }
1213        else if ((sym.kind == TYP ||
1214                  // ISSUE: Disallowing abstract&private is no longer appropriate
1215                  // in the presence of inner classes. Should it be deleted here?
1216                  checkDisjoint(pos, flags,
1217                                ABSTRACT,
1218                                PRIVATE | STATIC | DEFAULT))
1219                 &&
1220                 checkDisjoint(pos, flags,
1221                                STATIC | PRIVATE,
1222                                DEFAULT)
1223                 &&
1224                 checkDisjoint(pos, flags,
1225                               ABSTRACT | INTERFACE,
1226                               FINAL | NATIVE | SYNCHRONIZED)
1227                 &&
1228                 checkDisjoint(pos, flags,
1229                               PUBLIC,
1230                               PRIVATE | PROTECTED)
1231                 &&
1232                 checkDisjoint(pos, flags,
1233                               PRIVATE,
1234                               PUBLIC | PROTECTED)
1235                 &&
1236                 checkDisjoint(pos, flags,
1237                               FINAL,
1238                               VOLATILE)
1239                 &&
1240                 (sym.kind == TYP ||
1241                  checkDisjoint(pos, flags,
1242                                ABSTRACT | NATIVE,
1243                                STRICTFP))) {
1244            // skip
1245        }
1246        return flags & (mask | ~ExtendedStandardFlags) | implicit;
1247    }
1248
1249
1250    /** Determine if this enum should be implicitly final.
1251     *
1252     *  If the enum has no specialized enum contants, it is final.
1253     *
1254     *  If the enum does have specialized enum contants, it is
1255     *  <i>not</i> final.
1256     */
1257    private long implicitEnumFinalFlag(JCTree tree) {
1258        if (!tree.hasTag(CLASSDEF)) return 0;
1259        class SpecialTreeVisitor extends JCTree.Visitor {
1260            boolean specialized;
1261            SpecialTreeVisitor() {
1262                this.specialized = false;
1263            }
1264
1265            @Override
1266            public void visitTree(JCTree tree) { /* no-op */ }
1267
1268            @Override
1269            public void visitVarDef(JCVariableDecl tree) {
1270                if ((tree.mods.flags & ENUM) != 0) {
1271                    if (tree.init instanceof JCNewClass &&
1272                        ((JCNewClass) tree.init).def != null) {
1273                        specialized = true;
1274                    }
1275                }
1276            }
1277        }
1278
1279        SpecialTreeVisitor sts = new SpecialTreeVisitor();
1280        JCClassDecl cdef = (JCClassDecl) tree;
1281        for (JCTree defs: cdef.defs) {
1282            defs.accept(sts);
1283            if (sts.specialized) return 0;
1284        }
1285        return FINAL;
1286    }
1287
1288/* *************************************************************************
1289 * Type Validation
1290 **************************************************************************/
1291
1292    /** Validate a type expression. That is,
1293     *  check that all type arguments of a parametric type are within
1294     *  their bounds. This must be done in a second phase after type attribution
1295     *  since a class might have a subclass as type parameter bound. E.g:
1296     *
1297     *  <pre>{@code
1298     *  class B<A extends C> { ... }
1299     *  class C extends B<C> { ... }
1300     *  }</pre>
1301     *
1302     *  and we can't make sure that the bound is already attributed because
1303     *  of possible cycles.
1304     *
1305     * Visitor method: Validate a type expression, if it is not null, catching
1306     *  and reporting any completion failures.
1307     */
1308    void validate(JCTree tree, Env<AttrContext> env) {
1309        validate(tree, env, true);
1310    }
1311    void validate(JCTree tree, Env<AttrContext> env, boolean checkRaw) {
1312        new Validator(env).validateTree(tree, checkRaw, true);
1313    }
1314
1315    /** Visitor method: Validate a list of type expressions.
1316     */
1317    void validate(List<? extends JCTree> trees, Env<AttrContext> env) {
1318        for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail)
1319            validate(l.head, env);
1320    }
1321
1322    /** A visitor class for type validation.
1323     */
1324    class Validator extends JCTree.Visitor {
1325
1326        boolean checkRaw;
1327        boolean isOuter;
1328        Env<AttrContext> env;
1329
1330        Validator(Env<AttrContext> env) {
1331            this.env = env;
1332        }
1333
1334        @Override
1335        public void visitTypeArray(JCArrayTypeTree tree) {
1336            validateTree(tree.elemtype, checkRaw, isOuter);
1337        }
1338
1339        @Override
1340        public void visitTypeApply(JCTypeApply tree) {
1341            if (tree.type.hasTag(CLASS)) {
1342                List<JCExpression> args = tree.arguments;
1343                List<Type> forms = tree.type.tsym.type.getTypeArguments();
1344
1345                Type incompatibleArg = firstIncompatibleTypeArg(tree.type);
1346                if (incompatibleArg != null) {
1347                    for (JCTree arg : tree.arguments) {
1348                        if (arg.type == incompatibleArg) {
1349                            log.error(arg, "not.within.bounds", incompatibleArg, forms.head);
1350                        }
1351                        forms = forms.tail;
1352                     }
1353                 }
1354
1355                forms = tree.type.tsym.type.getTypeArguments();
1356
1357                boolean is_java_lang_Class = tree.type.tsym.flatName() == names.java_lang_Class;
1358
1359                // For matching pairs of actual argument types `a' and
1360                // formal type parameters with declared bound `b' ...
1361                while (args.nonEmpty() && forms.nonEmpty()) {
1362                    validateTree(args.head,
1363                            !(isOuter && is_java_lang_Class),
1364                            false);
1365                    args = args.tail;
1366                    forms = forms.tail;
1367                }
1368
1369                // Check that this type is either fully parameterized, or
1370                // not parameterized at all.
1371                if (tree.type.getEnclosingType().isRaw())
1372                    log.error(tree.pos(), "improperly.formed.type.inner.raw.param");
1373                if (tree.clazz.hasTag(SELECT))
1374                    visitSelectInternal((JCFieldAccess)tree.clazz);
1375            }
1376        }
1377
1378        @Override
1379        public void visitTypeParameter(JCTypeParameter tree) {
1380            validateTrees(tree.bounds, true, isOuter);
1381            checkClassBounds(tree.pos(), tree.type);
1382        }
1383
1384        @Override
1385        public void visitWildcard(JCWildcard tree) {
1386            if (tree.inner != null)
1387                validateTree(tree.inner, true, isOuter);
1388        }
1389
1390        @Override
1391        public void visitSelect(JCFieldAccess tree) {
1392            if (tree.type.hasTag(CLASS)) {
1393                visitSelectInternal(tree);
1394
1395                // Check that this type is either fully parameterized, or
1396                // not parameterized at all.
1397                if (tree.selected.type.isParameterized() && tree.type.tsym.type.getTypeArguments().nonEmpty())
1398                    log.error(tree.pos(), "improperly.formed.type.param.missing");
1399            }
1400        }
1401
1402        public void visitSelectInternal(JCFieldAccess tree) {
1403            if (tree.type.tsym.isStatic() &&
1404                tree.selected.type.isParameterized()) {
1405                // The enclosing type is not a class, so we are
1406                // looking at a static member type.  However, the
1407                // qualifying expression is parameterized.
1408                log.error(tree.pos(), "cant.select.static.class.from.param.type");
1409            } else {
1410                // otherwise validate the rest of the expression
1411                tree.selected.accept(this);
1412            }
1413        }
1414
1415        @Override
1416        public void visitAnnotatedType(JCAnnotatedType tree) {
1417            tree.underlyingType.accept(this);
1418        }
1419
1420        @Override
1421        public void visitTypeIdent(JCPrimitiveTypeTree that) {
1422            if (that.type.hasTag(TypeTag.VOID)) {
1423                log.error(that.pos(), "void.not.allowed.here");
1424            }
1425            super.visitTypeIdent(that);
1426        }
1427
1428        /** Default visitor method: do nothing.
1429         */
1430        @Override
1431        public void visitTree(JCTree tree) {
1432        }
1433
1434        public void validateTree(JCTree tree, boolean checkRaw, boolean isOuter) {
1435            if (tree != null) {
1436                boolean prevCheckRaw = this.checkRaw;
1437                this.checkRaw = checkRaw;
1438                this.isOuter = isOuter;
1439
1440                try {
1441                    tree.accept(this);
1442                    if (checkRaw)
1443                        checkRaw(tree, env);
1444                } catch (CompletionFailure ex) {
1445                    completionError(tree.pos(), ex);
1446                } finally {
1447                    this.checkRaw = prevCheckRaw;
1448                }
1449            }
1450        }
1451
1452        public void validateTrees(List<? extends JCTree> trees, boolean checkRaw, boolean isOuter) {
1453            for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail)
1454                validateTree(l.head, checkRaw, isOuter);
1455        }
1456    }
1457
1458    void checkRaw(JCTree tree, Env<AttrContext> env) {
1459        if (lint.isEnabled(LintCategory.RAW) &&
1460            tree.type.hasTag(CLASS) &&
1461            !TreeInfo.isDiamond(tree) &&
1462            !withinAnonConstr(env) &&
1463            tree.type.isRaw()) {
1464            log.warning(LintCategory.RAW,
1465                    tree.pos(), "raw.class.use", tree.type, tree.type.tsym.type);
1466        }
1467    }
1468    //where
1469        private boolean withinAnonConstr(Env<AttrContext> env) {
1470            return env.enclClass.name.isEmpty() &&
1471                    env.enclMethod != null && env.enclMethod.name == names.init;
1472        }
1473
1474/* *************************************************************************
1475 * Exception checking
1476 **************************************************************************/
1477
1478    /* The following methods treat classes as sets that contain
1479     * the class itself and all their subclasses
1480     */
1481
1482    /** Is given type a subtype of some of the types in given list?
1483     */
1484    boolean subset(Type t, List<Type> ts) {
1485        for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
1486            if (types.isSubtype(t, l.head)) return true;
1487        return false;
1488    }
1489
1490    /** Is given type a subtype or supertype of
1491     *  some of the types in given list?
1492     */
1493    boolean intersects(Type t, List<Type> ts) {
1494        for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
1495            if (types.isSubtype(t, l.head) || types.isSubtype(l.head, t)) return true;
1496        return false;
1497    }
1498
1499    /** Add type set to given type list, unless it is a subclass of some class
1500     *  in the list.
1501     */
1502    List<Type> incl(Type t, List<Type> ts) {
1503        return subset(t, ts) ? ts : excl(t, ts).prepend(t);
1504    }
1505
1506    /** Remove type set from type set list.
1507     */
1508    List<Type> excl(Type t, List<Type> ts) {
1509        if (ts.isEmpty()) {
1510            return ts;
1511        } else {
1512            List<Type> ts1 = excl(t, ts.tail);
1513            if (types.isSubtype(ts.head, t)) return ts1;
1514            else if (ts1 == ts.tail) return ts;
1515            else return ts1.prepend(ts.head);
1516        }
1517    }
1518
1519    /** Form the union of two type set lists.
1520     */
1521    List<Type> union(List<Type> ts1, List<Type> ts2) {
1522        List<Type> ts = ts1;
1523        for (List<Type> l = ts2; l.nonEmpty(); l = l.tail)
1524            ts = incl(l.head, ts);
1525        return ts;
1526    }
1527
1528    /** Form the difference of two type lists.
1529     */
1530    List<Type> diff(List<Type> ts1, List<Type> ts2) {
1531        List<Type> ts = ts1;
1532        for (List<Type> l = ts2; l.nonEmpty(); l = l.tail)
1533            ts = excl(l.head, ts);
1534        return ts;
1535    }
1536
1537    /** Form the intersection of two type lists.
1538     */
1539    public List<Type> intersect(List<Type> ts1, List<Type> ts2) {
1540        List<Type> ts = List.nil();
1541        for (List<Type> l = ts1; l.nonEmpty(); l = l.tail)
1542            if (subset(l.head, ts2)) ts = incl(l.head, ts);
1543        for (List<Type> l = ts2; l.nonEmpty(); l = l.tail)
1544            if (subset(l.head, ts1)) ts = incl(l.head, ts);
1545        return ts;
1546    }
1547
1548    /** Is exc an exception symbol that need not be declared?
1549     */
1550    boolean isUnchecked(ClassSymbol exc) {
1551        return
1552            exc.kind == ERR ||
1553            exc.isSubClass(syms.errorType.tsym, types) ||
1554            exc.isSubClass(syms.runtimeExceptionType.tsym, types);
1555    }
1556
1557    /** Is exc an exception type that need not be declared?
1558     */
1559    boolean isUnchecked(Type exc) {
1560        return
1561            (exc.hasTag(TYPEVAR)) ? isUnchecked(types.supertype(exc)) :
1562            (exc.hasTag(CLASS)) ? isUnchecked((ClassSymbol)exc.tsym) :
1563            exc.hasTag(BOT);
1564    }
1565
1566    /** Same, but handling completion failures.
1567     */
1568    boolean isUnchecked(DiagnosticPosition pos, Type exc) {
1569        try {
1570            return isUnchecked(exc);
1571        } catch (CompletionFailure ex) {
1572            completionError(pos, ex);
1573            return true;
1574        }
1575    }
1576
1577    /** Is exc handled by given exception list?
1578     */
1579    boolean isHandled(Type exc, List<Type> handled) {
1580        return isUnchecked(exc) || subset(exc, handled);
1581    }
1582
1583    /** Return all exceptions in thrown list that are not in handled list.
1584     *  @param thrown     The list of thrown exceptions.
1585     *  @param handled    The list of handled exceptions.
1586     */
1587    List<Type> unhandled(List<Type> thrown, List<Type> handled) {
1588        List<Type> unhandled = List.nil();
1589        for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
1590            if (!isHandled(l.head, handled)) unhandled = unhandled.prepend(l.head);
1591        return unhandled;
1592    }
1593
1594/* *************************************************************************
1595 * Overriding/Implementation checking
1596 **************************************************************************/
1597
1598    /** The level of access protection given by a flag set,
1599     *  where PRIVATE is highest and PUBLIC is lowest.
1600     */
1601    static int protection(long flags) {
1602        switch ((short)(flags & AccessFlags)) {
1603        case PRIVATE: return 3;
1604        case PROTECTED: return 1;
1605        default:
1606        case PUBLIC: return 0;
1607        case 0: return 2;
1608        }
1609    }
1610
1611    /** A customized "cannot override" error message.
1612     *  @param m      The overriding method.
1613     *  @param other  The overridden method.
1614     *  @return       An internationalized string.
1615     */
1616    Object cannotOverride(MethodSymbol m, MethodSymbol other) {
1617        String key;
1618        if ((other.owner.flags() & INTERFACE) == 0)
1619            key = "cant.override";
1620        else if ((m.owner.flags() & INTERFACE) == 0)
1621            key = "cant.implement";
1622        else
1623            key = "clashes.with";
1624        return diags.fragment(key, m, m.location(), other, other.location());
1625    }
1626
1627    /** A customized "override" warning message.
1628     *  @param m      The overriding method.
1629     *  @param other  The overridden method.
1630     *  @return       An internationalized string.
1631     */
1632    Object uncheckedOverrides(MethodSymbol m, MethodSymbol other) {
1633        String key;
1634        if ((other.owner.flags() & INTERFACE) == 0)
1635            key = "unchecked.override";
1636        else if ((m.owner.flags() & INTERFACE) == 0)
1637            key = "unchecked.implement";
1638        else
1639            key = "unchecked.clash.with";
1640        return diags.fragment(key, m, m.location(), other, other.location());
1641    }
1642
1643    /** A customized "override" warning message.
1644     *  @param m      The overriding method.
1645     *  @param other  The overridden method.
1646     *  @return       An internationalized string.
1647     */
1648    Object varargsOverrides(MethodSymbol m, MethodSymbol other) {
1649        String key;
1650        if ((other.owner.flags() & INTERFACE) == 0)
1651            key = "varargs.override";
1652        else  if ((m.owner.flags() & INTERFACE) == 0)
1653            key = "varargs.implement";
1654        else
1655            key = "varargs.clash.with";
1656        return diags.fragment(key, m, m.location(), other, other.location());
1657    }
1658
1659    /** Check that this method conforms with overridden method 'other'.
1660     *  where `origin' is the class where checking started.
1661     *  Complications:
1662     *  (1) Do not check overriding of synthetic methods
1663     *      (reason: they might be final).
1664     *      todo: check whether this is still necessary.
1665     *  (2) Admit the case where an interface proxy throws fewer exceptions
1666     *      than the method it implements. Augment the proxy methods with the
1667     *      undeclared exceptions in this case.
1668     *  (3) When generics are enabled, admit the case where an interface proxy
1669     *      has a result type
1670     *      extended by the result type of the method it implements.
1671     *      Change the proxies result type to the smaller type in this case.
1672     *
1673     *  @param tree         The tree from which positions
1674     *                      are extracted for errors.
1675     *  @param m            The overriding method.
1676     *  @param other        The overridden method.
1677     *  @param origin       The class of which the overriding method
1678     *                      is a member.
1679     */
1680    void checkOverride(JCTree tree,
1681                       MethodSymbol m,
1682                       MethodSymbol other,
1683                       ClassSymbol origin) {
1684        // Don't check overriding of synthetic methods or by bridge methods.
1685        if ((m.flags() & (SYNTHETIC|BRIDGE)) != 0 || (other.flags() & SYNTHETIC) != 0) {
1686            return;
1687        }
1688
1689        // Error if static method overrides instance method (JLS 8.4.6.2).
1690        if ((m.flags() & STATIC) != 0 &&
1691                   (other.flags() & STATIC) == 0) {
1692            log.error(TreeInfo.diagnosticPositionFor(m, tree), "override.static",
1693                      cannotOverride(m, other));
1694            m.flags_field |= BAD_OVERRIDE;
1695            return;
1696        }
1697
1698        // Error if instance method overrides static or final
1699        // method (JLS 8.4.6.1).
1700        if ((other.flags() & FINAL) != 0 ||
1701                 (m.flags() & STATIC) == 0 &&
1702                 (other.flags() & STATIC) != 0) {
1703            log.error(TreeInfo.diagnosticPositionFor(m, tree), "override.meth",
1704                      cannotOverride(m, other),
1705                      asFlagSet(other.flags() & (FINAL | STATIC)));
1706            m.flags_field |= BAD_OVERRIDE;
1707            return;
1708        }
1709
1710        if ((m.owner.flags() & ANNOTATION) != 0) {
1711            // handled in validateAnnotationMethod
1712            return;
1713        }
1714
1715        // Error if overriding method has weaker access (JLS 8.4.6.3).
1716        if (protection(m.flags()) > protection(other.flags())) {
1717            log.error(TreeInfo.diagnosticPositionFor(m, tree), "override.weaker.access",
1718                      cannotOverride(m, other),
1719                      (other.flags() & AccessFlags) == 0 ?
1720                          "package" :
1721                          asFlagSet(other.flags() & AccessFlags));
1722            m.flags_field |= BAD_OVERRIDE;
1723            return;
1724        }
1725
1726        Type mt = types.memberType(origin.type, m);
1727        Type ot = types.memberType(origin.type, other);
1728        // Error if overriding result type is different
1729        // (or, in the case of generics mode, not a subtype) of
1730        // overridden result type. We have to rename any type parameters
1731        // before comparing types.
1732        List<Type> mtvars = mt.getTypeArguments();
1733        List<Type> otvars = ot.getTypeArguments();
1734        Type mtres = mt.getReturnType();
1735        Type otres = types.subst(ot.getReturnType(), otvars, mtvars);
1736
1737        overrideWarner.clear();
1738        boolean resultTypesOK =
1739            types.returnTypeSubstitutable(mt, ot, otres, overrideWarner);
1740        if (!resultTypesOK) {
1741            if ((m.flags() & STATIC) != 0 && (other.flags() & STATIC) != 0) {
1742                log.error(TreeInfo.diagnosticPositionFor(m, tree),
1743                        Errors.OverrideIncompatibleRet(Fragments.CantHide(m, m.location(), other,
1744                                        other.location()), mtres, otres));
1745                m.flags_field |= BAD_OVERRIDE;
1746            } else {
1747                log.error(TreeInfo.diagnosticPositionFor(m, tree),
1748                        "override.incompatible.ret",
1749                        cannotOverride(m, other),
1750                        mtres, otres);
1751                m.flags_field |= BAD_OVERRIDE;
1752            }
1753            return;
1754        } else if (overrideWarner.hasNonSilentLint(LintCategory.UNCHECKED)) {
1755            warnUnchecked(TreeInfo.diagnosticPositionFor(m, tree),
1756                    "override.unchecked.ret",
1757                    uncheckedOverrides(m, other),
1758                    mtres, otres);
1759        }
1760
1761        // Error if overriding method throws an exception not reported
1762        // by overridden method.
1763        List<Type> otthrown = types.subst(ot.getThrownTypes(), otvars, mtvars);
1764        List<Type> unhandledErased = unhandled(mt.getThrownTypes(), types.erasure(otthrown));
1765        List<Type> unhandledUnerased = unhandled(mt.getThrownTypes(), otthrown);
1766        if (unhandledErased.nonEmpty()) {
1767            log.error(TreeInfo.diagnosticPositionFor(m, tree),
1768                      "override.meth.doesnt.throw",
1769                      cannotOverride(m, other),
1770                      unhandledUnerased.head);
1771            m.flags_field |= BAD_OVERRIDE;
1772            return;
1773        }
1774        else if (unhandledUnerased.nonEmpty()) {
1775            warnUnchecked(TreeInfo.diagnosticPositionFor(m, tree),
1776                          "override.unchecked.thrown",
1777                         cannotOverride(m, other),
1778                         unhandledUnerased.head);
1779            return;
1780        }
1781
1782        // Optional warning if varargs don't agree
1783        if ((((m.flags() ^ other.flags()) & Flags.VARARGS) != 0)
1784            && lint.isEnabled(LintCategory.OVERRIDES)) {
1785            log.warning(TreeInfo.diagnosticPositionFor(m, tree),
1786                        ((m.flags() & Flags.VARARGS) != 0)
1787                        ? "override.varargs.missing"
1788                        : "override.varargs.extra",
1789                        varargsOverrides(m, other));
1790        }
1791
1792        // Warn if instance method overrides bridge method (compiler spec ??)
1793        if ((other.flags() & BRIDGE) != 0) {
1794            log.warning(TreeInfo.diagnosticPositionFor(m, tree), "override.bridge",
1795                        uncheckedOverrides(m, other));
1796        }
1797
1798        // Warn if a deprecated method overridden by a non-deprecated one.
1799        if (!isDeprecatedOverrideIgnorable(other, origin)) {
1800            Lint prevLint = setLint(lint.augment(m));
1801            try {
1802                checkDeprecated(TreeInfo.diagnosticPositionFor(m, tree), m, other);
1803            } finally {
1804                setLint(prevLint);
1805            }
1806        }
1807    }
1808    // where
1809        private boolean isDeprecatedOverrideIgnorable(MethodSymbol m, ClassSymbol origin) {
1810            // If the method, m, is defined in an interface, then ignore the issue if the method
1811            // is only inherited via a supertype and also implemented in the supertype,
1812            // because in that case, we will rediscover the issue when examining the method
1813            // in the supertype.
1814            // If the method, m, is not defined in an interface, then the only time we need to
1815            // address the issue is when the method is the supertype implemementation: any other
1816            // case, we will have dealt with when examining the supertype classes
1817            ClassSymbol mc = m.enclClass();
1818            Type st = types.supertype(origin.type);
1819            if (!st.hasTag(CLASS))
1820                return true;
1821            MethodSymbol stimpl = m.implementation((ClassSymbol)st.tsym, types, false);
1822
1823            if (mc != null && ((mc.flags() & INTERFACE) != 0)) {
1824                List<Type> intfs = types.interfaces(origin.type);
1825                return (intfs.contains(mc.type) ? false : (stimpl != null));
1826            }
1827            else
1828                return (stimpl != m);
1829        }
1830
1831
1832    // used to check if there were any unchecked conversions
1833    Warner overrideWarner = new Warner();
1834
1835    /** Check that a class does not inherit two concrete methods
1836     *  with the same signature.
1837     *  @param pos          Position to be used for error reporting.
1838     *  @param site         The class type to be checked.
1839     */
1840    public void checkCompatibleConcretes(DiagnosticPosition pos, Type site) {
1841        Type sup = types.supertype(site);
1842        if (!sup.hasTag(CLASS)) return;
1843
1844        for (Type t1 = sup;
1845             t1.hasTag(CLASS) && t1.tsym.type.isParameterized();
1846             t1 = types.supertype(t1)) {
1847            for (Symbol s1 : t1.tsym.members().getSymbols(NON_RECURSIVE)) {
1848                if (s1.kind != MTH ||
1849                    (s1.flags() & (STATIC|SYNTHETIC|BRIDGE)) != 0 ||
1850                    !s1.isInheritedIn(site.tsym, types) ||
1851                    ((MethodSymbol)s1).implementation(site.tsym,
1852                                                      types,
1853                                                      true) != s1)
1854                    continue;
1855                Type st1 = types.memberType(t1, s1);
1856                int s1ArgsLength = st1.getParameterTypes().length();
1857                if (st1 == s1.type) continue;
1858
1859                for (Type t2 = sup;
1860                     t2.hasTag(CLASS);
1861                     t2 = types.supertype(t2)) {
1862                    for (Symbol s2 : t2.tsym.members().getSymbolsByName(s1.name)) {
1863                        if (s2 == s1 ||
1864                            s2.kind != MTH ||
1865                            (s2.flags() & (STATIC|SYNTHETIC|BRIDGE)) != 0 ||
1866                            s2.type.getParameterTypes().length() != s1ArgsLength ||
1867                            !s2.isInheritedIn(site.tsym, types) ||
1868                            ((MethodSymbol)s2).implementation(site.tsym,
1869                                                              types,
1870                                                              true) != s2)
1871                            continue;
1872                        Type st2 = types.memberType(t2, s2);
1873                        if (types.overrideEquivalent(st1, st2))
1874                            log.error(pos, "concrete.inheritance.conflict",
1875                                      s1, t1, s2, t2, sup);
1876                    }
1877                }
1878            }
1879        }
1880    }
1881
1882    /** Check that classes (or interfaces) do not each define an abstract
1883     *  method with same name and arguments but incompatible return types.
1884     *  @param pos          Position to be used for error reporting.
1885     *  @param t1           The first argument type.
1886     *  @param t2           The second argument type.
1887     */
1888    public boolean checkCompatibleAbstracts(DiagnosticPosition pos,
1889                                            Type t1,
1890                                            Type t2,
1891                                            Type site) {
1892        if ((site.tsym.flags() & COMPOUND) != 0) {
1893            // special case for intersections: need to eliminate wildcards in supertypes
1894            t1 = types.capture(t1);
1895            t2 = types.capture(t2);
1896        }
1897        return firstIncompatibility(pos, t1, t2, site) == null;
1898    }
1899
1900    /** Return the first method which is defined with same args
1901     *  but different return types in two given interfaces, or null if none
1902     *  exists.
1903     *  @param t1     The first type.
1904     *  @param t2     The second type.
1905     *  @param site   The most derived type.
1906     *  @returns symbol from t2 that conflicts with one in t1.
1907     */
1908    private Symbol firstIncompatibility(DiagnosticPosition pos, Type t1, Type t2, Type site) {
1909        Map<TypeSymbol,Type> interfaces1 = new HashMap<>();
1910        closure(t1, interfaces1);
1911        Map<TypeSymbol,Type> interfaces2;
1912        if (t1 == t2)
1913            interfaces2 = interfaces1;
1914        else
1915            closure(t2, interfaces1, interfaces2 = new HashMap<>());
1916
1917        for (Type t3 : interfaces1.values()) {
1918            for (Type t4 : interfaces2.values()) {
1919                Symbol s = firstDirectIncompatibility(pos, t3, t4, site);
1920                if (s != null) return s;
1921            }
1922        }
1923        return null;
1924    }
1925
1926    /** Compute all the supertypes of t, indexed by type symbol. */
1927    private void closure(Type t, Map<TypeSymbol,Type> typeMap) {
1928        if (!t.hasTag(CLASS)) return;
1929        if (typeMap.put(t.tsym, t) == null) {
1930            closure(types.supertype(t), typeMap);
1931            for (Type i : types.interfaces(t))
1932                closure(i, typeMap);
1933        }
1934    }
1935
1936    /** Compute all the supertypes of t, indexed by type symbol (except thise in typesSkip). */
1937    private void closure(Type t, Map<TypeSymbol,Type> typesSkip, Map<TypeSymbol,Type> typeMap) {
1938        if (!t.hasTag(CLASS)) return;
1939        if (typesSkip.get(t.tsym) != null) return;
1940        if (typeMap.put(t.tsym, t) == null) {
1941            closure(types.supertype(t), typesSkip, typeMap);
1942            for (Type i : types.interfaces(t))
1943                closure(i, typesSkip, typeMap);
1944        }
1945    }
1946
1947    /** Return the first method in t2 that conflicts with a method from t1. */
1948    private Symbol firstDirectIncompatibility(DiagnosticPosition pos, Type t1, Type t2, Type site) {
1949        for (Symbol s1 : t1.tsym.members().getSymbols(NON_RECURSIVE)) {
1950            Type st1 = null;
1951            if (s1.kind != MTH || !s1.isInheritedIn(site.tsym, types) ||
1952                    (s1.flags() & SYNTHETIC) != 0) continue;
1953            Symbol impl = ((MethodSymbol)s1).implementation(site.tsym, types, false);
1954            if (impl != null && (impl.flags() & ABSTRACT) == 0) continue;
1955            for (Symbol s2 : t2.tsym.members().getSymbolsByName(s1.name)) {
1956                if (s1 == s2) continue;
1957                if (s2.kind != MTH || !s2.isInheritedIn(site.tsym, types) ||
1958                        (s2.flags() & SYNTHETIC) != 0) continue;
1959                if (st1 == null) st1 = types.memberType(t1, s1);
1960                Type st2 = types.memberType(t2, s2);
1961                if (types.overrideEquivalent(st1, st2)) {
1962                    List<Type> tvars1 = st1.getTypeArguments();
1963                    List<Type> tvars2 = st2.getTypeArguments();
1964                    Type rt1 = st1.getReturnType();
1965                    Type rt2 = types.subst(st2.getReturnType(), tvars2, tvars1);
1966                    boolean compat =
1967                        types.isSameType(rt1, rt2) ||
1968                        !rt1.isPrimitiveOrVoid() &&
1969                        !rt2.isPrimitiveOrVoid() &&
1970                        (types.covariantReturnType(rt1, rt2, types.noWarnings) ||
1971                         types.covariantReturnType(rt2, rt1, types.noWarnings)) ||
1972                         checkCommonOverriderIn(s1,s2,site);
1973                    if (!compat) {
1974                        log.error(pos, "types.incompatible.diff.ret",
1975                            t1, t2, s2.name +
1976                            "(" + types.memberType(t2, s2).getParameterTypes() + ")");
1977                        return s2;
1978                    }
1979                } else if (checkNameClash((ClassSymbol)site.tsym, s1, s2) &&
1980                        !checkCommonOverriderIn(s1, s2, site)) {
1981                    log.error(pos,
1982                            "name.clash.same.erasure.no.override",
1983                            s1, s1.location(),
1984                            s2, s2.location());
1985                    return s2;
1986                }
1987            }
1988        }
1989        return null;
1990    }
1991    //WHERE
1992    boolean checkCommonOverriderIn(Symbol s1, Symbol s2, Type site) {
1993        Map<TypeSymbol,Type> supertypes = new HashMap<>();
1994        Type st1 = types.memberType(site, s1);
1995        Type st2 = types.memberType(site, s2);
1996        closure(site, supertypes);
1997        for (Type t : supertypes.values()) {
1998            for (Symbol s3 : t.tsym.members().getSymbolsByName(s1.name)) {
1999                if (s3 == s1 || s3 == s2 || s3.kind != MTH || (s3.flags() & (BRIDGE|SYNTHETIC)) != 0) continue;
2000                Type st3 = types.memberType(site,s3);
2001                if (types.overrideEquivalent(st3, st1) &&
2002                        types.overrideEquivalent(st3, st2) &&
2003                        types.returnTypeSubstitutable(st3, st1) &&
2004                        types.returnTypeSubstitutable(st3, st2)) {
2005                    return true;
2006                }
2007            }
2008        }
2009        return false;
2010    }
2011
2012    /** Check that a given method conforms with any method it overrides.
2013     *  @param tree         The tree from which positions are extracted
2014     *                      for errors.
2015     *  @param m            The overriding method.
2016     */
2017    void checkOverride(Env<AttrContext> env, JCMethodDecl tree, MethodSymbol m) {
2018        ClassSymbol origin = (ClassSymbol)m.owner;
2019        if ((origin.flags() & ENUM) != 0 && names.finalize.equals(m.name))
2020            if (m.overrides(syms.enumFinalFinalize, origin, types, false)) {
2021                log.error(tree.pos(), "enum.no.finalize");
2022                return;
2023            }
2024        for (Type t = origin.type; t.hasTag(CLASS);
2025             t = types.supertype(t)) {
2026            if (t != origin.type) {
2027                checkOverride(tree, t, origin, m);
2028            }
2029            for (Type t2 : types.interfaces(t)) {
2030                checkOverride(tree, t2, origin, m);
2031            }
2032        }
2033
2034        final boolean explicitOverride = m.attribute(syms.overrideType.tsym) != null;
2035        // Check if this method must override a super method due to being annotated with @Override
2036        // or by virtue of being a member of a diamond inferred anonymous class. Latter case is to
2037        // be treated "as if as they were annotated" with @Override.
2038        boolean mustOverride = explicitOverride ||
2039                (env.info.isAnonymousDiamond && !m.isConstructor() && !m.isPrivate());
2040        if (mustOverride && !isOverrider(m)) {
2041            DiagnosticPosition pos = tree.pos();
2042            for (JCAnnotation a : tree.getModifiers().annotations) {
2043                if (a.annotationType.type.tsym == syms.overrideType.tsym) {
2044                    pos = a.pos();
2045                    break;
2046                }
2047            }
2048            log.error(pos,
2049                      explicitOverride ? Errors.MethodDoesNotOverrideSuperclass :
2050                                Errors.AnonymousDiamondMethodDoesNotOverrideSuperclass(Fragments.DiamondAnonymousMethodsImplicitlyOverride));
2051        }
2052    }
2053
2054    void checkOverride(JCTree tree, Type site, ClassSymbol origin, MethodSymbol m) {
2055        TypeSymbol c = site.tsym;
2056        for (Symbol sym : c.members().getSymbolsByName(m.name)) {
2057            if (m.overrides(sym, origin, types, false)) {
2058                if ((sym.flags() & ABSTRACT) == 0) {
2059                    checkOverride(tree, m, (MethodSymbol)sym, origin);
2060                }
2061            }
2062        }
2063    }
2064
2065    private Filter<Symbol> equalsHasCodeFilter = s -> MethodSymbol.implementation_filter.accepts(s) &&
2066            (s.flags() & BAD_OVERRIDE) == 0;
2067
2068    public void checkClassOverrideEqualsAndHashIfNeeded(DiagnosticPosition pos,
2069            ClassSymbol someClass) {
2070        /* At present, annotations cannot possibly have a method that is override
2071         * equivalent with Object.equals(Object) but in any case the condition is
2072         * fine for completeness.
2073         */
2074        if (someClass == (ClassSymbol)syms.objectType.tsym ||
2075            someClass.isInterface() || someClass.isEnum() ||
2076            (someClass.flags() & ANNOTATION) != 0 ||
2077            (someClass.flags() & ABSTRACT) != 0) return;
2078        //anonymous inner classes implementing interfaces need especial treatment
2079        if (someClass.isAnonymous()) {
2080            List<Type> interfaces =  types.interfaces(someClass.type);
2081            if (interfaces != null && !interfaces.isEmpty() &&
2082                interfaces.head.tsym == syms.comparatorType.tsym) return;
2083        }
2084        checkClassOverrideEqualsAndHash(pos, someClass);
2085    }
2086
2087    private void checkClassOverrideEqualsAndHash(DiagnosticPosition pos,
2088            ClassSymbol someClass) {
2089        if (lint.isEnabled(LintCategory.OVERRIDES)) {
2090            MethodSymbol equalsAtObject = (MethodSymbol)syms.objectType
2091                    .tsym.members().findFirst(names.equals);
2092            MethodSymbol hashCodeAtObject = (MethodSymbol)syms.objectType
2093                    .tsym.members().findFirst(names.hashCode);
2094            boolean overridesEquals = types.implementation(equalsAtObject,
2095                someClass, false, equalsHasCodeFilter).owner == someClass;
2096            boolean overridesHashCode = types.implementation(hashCodeAtObject,
2097                someClass, false, equalsHasCodeFilter) != hashCodeAtObject;
2098
2099            if (overridesEquals && !overridesHashCode) {
2100                log.warning(LintCategory.OVERRIDES, pos,
2101                        "override.equals.but.not.hashcode", someClass);
2102            }
2103        }
2104    }
2105
2106    public void checkModuleName (JCModuleDecl tree) {
2107        Name moduleName = tree.sym.name;
2108        Assert.checkNonNull(moduleName);
2109        if (lint.isEnabled(LintCategory.MODULE)) {
2110            JCExpression qualId = tree.qualId;
2111            while (qualId != null) {
2112                Name componentName;
2113                DiagnosticPosition pos;
2114                switch (qualId.getTag()) {
2115                    case SELECT:
2116                        JCFieldAccess selectNode = ((JCFieldAccess) qualId);
2117                        componentName = selectNode.name;
2118                        pos = selectNode.pos();
2119                        qualId = selectNode.selected;
2120                        break;
2121                    case IDENT:
2122                        componentName = ((JCIdent) qualId).name;
2123                        pos = qualId.pos();
2124                        qualId = null;
2125                        break;
2126                    default:
2127                        throw new AssertionError("Unexpected qualified identifier: " + qualId.toString());
2128                }
2129                if (componentName != null) {
2130                    String moduleNameComponentString = componentName.toString();
2131                    int nameLength = moduleNameComponentString.length();
2132                    if (nameLength > 0 && Character.isDigit(moduleNameComponentString.charAt(nameLength - 1))) {
2133                        log.warning(Lint.LintCategory.MODULE, pos, Warnings.PoorChoiceForModuleName(componentName));
2134                    }
2135                }
2136            }
2137        }
2138    }
2139
2140    private boolean checkNameClash(ClassSymbol origin, Symbol s1, Symbol s2) {
2141        ClashFilter cf = new ClashFilter(origin.type);
2142        return (cf.accepts(s1) &&
2143                cf.accepts(s2) &&
2144                types.hasSameArgs(s1.erasure(types), s2.erasure(types)));
2145    }
2146
2147
2148    /** Check that all abstract members of given class have definitions.
2149     *  @param pos          Position to be used for error reporting.
2150     *  @param c            The class.
2151     */
2152    void checkAllDefined(DiagnosticPosition pos, ClassSymbol c) {
2153        MethodSymbol undef = types.firstUnimplementedAbstract(c);
2154        if (undef != null) {
2155            MethodSymbol undef1 =
2156                new MethodSymbol(undef.flags(), undef.name,
2157                                 types.memberType(c.type, undef), undef.owner);
2158            log.error(pos, "does.not.override.abstract",
2159                      c, undef1, undef1.location());
2160        }
2161    }
2162
2163    void checkNonCyclicDecl(JCClassDecl tree) {
2164        CycleChecker cc = new CycleChecker();
2165        cc.scan(tree);
2166        if (!cc.errorFound && !cc.partialCheck) {
2167            tree.sym.flags_field |= ACYCLIC;
2168        }
2169    }
2170
2171    class CycleChecker extends TreeScanner {
2172
2173        List<Symbol> seenClasses = List.nil();
2174        boolean errorFound = false;
2175        boolean partialCheck = false;
2176
2177        private void checkSymbol(DiagnosticPosition pos, Symbol sym) {
2178            if (sym != null && sym.kind == TYP) {
2179                Env<AttrContext> classEnv = enter.getEnv((TypeSymbol)sym);
2180                if (classEnv != null) {
2181                    DiagnosticSource prevSource = log.currentSource();
2182                    try {
2183                        log.useSource(classEnv.toplevel.sourcefile);
2184                        scan(classEnv.tree);
2185                    }
2186                    finally {
2187                        log.useSource(prevSource.getFile());
2188                    }
2189                } else if (sym.kind == TYP) {
2190                    checkClass(pos, sym, List.nil());
2191                }
2192            } else {
2193                //not completed yet
2194                partialCheck = true;
2195            }
2196        }
2197
2198        @Override
2199        public void visitSelect(JCFieldAccess tree) {
2200            super.visitSelect(tree);
2201            checkSymbol(tree.pos(), tree.sym);
2202        }
2203
2204        @Override
2205        public void visitIdent(JCIdent tree) {
2206            checkSymbol(tree.pos(), tree.sym);
2207        }
2208
2209        @Override
2210        public void visitTypeApply(JCTypeApply tree) {
2211            scan(tree.clazz);
2212        }
2213
2214        @Override
2215        public void visitTypeArray(JCArrayTypeTree tree) {
2216            scan(tree.elemtype);
2217        }
2218
2219        @Override
2220        public void visitClassDef(JCClassDecl tree) {
2221            List<JCTree> supertypes = List.nil();
2222            if (tree.getExtendsClause() != null) {
2223                supertypes = supertypes.prepend(tree.getExtendsClause());
2224            }
2225            if (tree.getImplementsClause() != null) {
2226                for (JCTree intf : tree.getImplementsClause()) {
2227                    supertypes = supertypes.prepend(intf);
2228                }
2229            }
2230            checkClass(tree.pos(), tree.sym, supertypes);
2231        }
2232
2233        void checkClass(DiagnosticPosition pos, Symbol c, List<JCTree> supertypes) {
2234            if ((c.flags_field & ACYCLIC) != 0)
2235                return;
2236            if (seenClasses.contains(c)) {
2237                errorFound = true;
2238                noteCyclic(pos, (ClassSymbol)c);
2239            } else if (!c.type.isErroneous()) {
2240                try {
2241                    seenClasses = seenClasses.prepend(c);
2242                    if (c.type.hasTag(CLASS)) {
2243                        if (supertypes.nonEmpty()) {
2244                            scan(supertypes);
2245                        }
2246                        else {
2247                            ClassType ct = (ClassType)c.type;
2248                            if (ct.supertype_field == null ||
2249                                    ct.interfaces_field == null) {
2250                                //not completed yet
2251                                partialCheck = true;
2252                                return;
2253                            }
2254                            checkSymbol(pos, ct.supertype_field.tsym);
2255                            for (Type intf : ct.interfaces_field) {
2256                                checkSymbol(pos, intf.tsym);
2257                            }
2258                        }
2259                        if (c.owner.kind == TYP) {
2260                            checkSymbol(pos, c.owner);
2261                        }
2262                    }
2263                } finally {
2264                    seenClasses = seenClasses.tail;
2265                }
2266            }
2267        }
2268    }
2269
2270    /** Check for cyclic references. Issue an error if the
2271     *  symbol of the type referred to has a LOCKED flag set.
2272     *
2273     *  @param pos      Position to be used for error reporting.
2274     *  @param t        The type referred to.
2275     */
2276    void checkNonCyclic(DiagnosticPosition pos, Type t) {
2277        checkNonCyclicInternal(pos, t);
2278    }
2279
2280
2281    void checkNonCyclic(DiagnosticPosition pos, TypeVar t) {
2282        checkNonCyclic1(pos, t, List.nil());
2283    }
2284
2285    private void checkNonCyclic1(DiagnosticPosition pos, Type t, List<TypeVar> seen) {
2286        final TypeVar tv;
2287        if  (t.hasTag(TYPEVAR) && (t.tsym.flags() & UNATTRIBUTED) != 0)
2288            return;
2289        if (seen.contains(t)) {
2290            tv = (TypeVar)t;
2291            tv.bound = types.createErrorType(t);
2292            log.error(pos, "cyclic.inheritance", t);
2293        } else if (t.hasTag(TYPEVAR)) {
2294            tv = (TypeVar)t;
2295            seen = seen.prepend(tv);
2296            for (Type b : types.getBounds(tv))
2297                checkNonCyclic1(pos, b, seen);
2298        }
2299    }
2300
2301    /** Check for cyclic references. Issue an error if the
2302     *  symbol of the type referred to has a LOCKED flag set.
2303     *
2304     *  @param pos      Position to be used for error reporting.
2305     *  @param t        The type referred to.
2306     *  @returns        True if the check completed on all attributed classes
2307     */
2308    private boolean checkNonCyclicInternal(DiagnosticPosition pos, Type t) {
2309        boolean complete = true; // was the check complete?
2310        //- System.err.println("checkNonCyclicInternal("+t+");");//DEBUG
2311        Symbol c = t.tsym;
2312        if ((c.flags_field & ACYCLIC) != 0) return true;
2313
2314        if ((c.flags_field & LOCKED) != 0) {
2315            noteCyclic(pos, (ClassSymbol)c);
2316        } else if (!c.type.isErroneous()) {
2317            try {
2318                c.flags_field |= LOCKED;
2319                if (c.type.hasTag(CLASS)) {
2320                    ClassType clazz = (ClassType)c.type;
2321                    if (clazz.interfaces_field != null)
2322                        for (List<Type> l=clazz.interfaces_field; l.nonEmpty(); l=l.tail)
2323                            complete &= checkNonCyclicInternal(pos, l.head);
2324                    if (clazz.supertype_field != null) {
2325                        Type st = clazz.supertype_field;
2326                        if (st != null && st.hasTag(CLASS))
2327                            complete &= checkNonCyclicInternal(pos, st);
2328                    }
2329                    if (c.owner.kind == TYP)
2330                        complete &= checkNonCyclicInternal(pos, c.owner.type);
2331                }
2332            } finally {
2333                c.flags_field &= ~LOCKED;
2334            }
2335        }
2336        if (complete)
2337            complete = ((c.flags_field & UNATTRIBUTED) == 0) && c.isCompleted();
2338        if (complete) c.flags_field |= ACYCLIC;
2339        return complete;
2340    }
2341
2342    /** Note that we found an inheritance cycle. */
2343    private void noteCyclic(DiagnosticPosition pos, ClassSymbol c) {
2344        log.error(pos, "cyclic.inheritance", c);
2345        for (List<Type> l=types.interfaces(c.type); l.nonEmpty(); l=l.tail)
2346            l.head = types.createErrorType((ClassSymbol)l.head.tsym, Type.noType);
2347        Type st = types.supertype(c.type);
2348        if (st.hasTag(CLASS))
2349            ((ClassType)c.type).supertype_field = types.createErrorType((ClassSymbol)st.tsym, Type.noType);
2350        c.type = types.createErrorType(c, c.type);
2351        c.flags_field |= ACYCLIC;
2352    }
2353
2354    /** Check that all methods which implement some
2355     *  method conform to the method they implement.
2356     *  @param tree         The class definition whose members are checked.
2357     */
2358    void checkImplementations(JCClassDecl tree) {
2359        checkImplementations(tree, tree.sym, tree.sym);
2360    }
2361    //where
2362        /** Check that all methods which implement some
2363         *  method in `ic' conform to the method they implement.
2364         */
2365        void checkImplementations(JCTree tree, ClassSymbol origin, ClassSymbol ic) {
2366            for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) {
2367                ClassSymbol lc = (ClassSymbol)l.head.tsym;
2368                if ((lc.flags() & ABSTRACT) != 0) {
2369                    for (Symbol sym : lc.members().getSymbols(NON_RECURSIVE)) {
2370                        if (sym.kind == MTH &&
2371                            (sym.flags() & (STATIC|ABSTRACT)) == ABSTRACT) {
2372                            MethodSymbol absmeth = (MethodSymbol)sym;
2373                            MethodSymbol implmeth = absmeth.implementation(origin, types, false);
2374                            if (implmeth != null && implmeth != absmeth &&
2375                                (implmeth.owner.flags() & INTERFACE) ==
2376                                (origin.flags() & INTERFACE)) {
2377                                // don't check if implmeth is in a class, yet
2378                                // origin is an interface. This case arises only
2379                                // if implmeth is declared in Object. The reason is
2380                                // that interfaces really don't inherit from
2381                                // Object it's just that the compiler represents
2382                                // things that way.
2383                                checkOverride(tree, implmeth, absmeth, origin);
2384                            }
2385                        }
2386                    }
2387                }
2388            }
2389        }
2390
2391    /** Check that all abstract methods implemented by a class are
2392     *  mutually compatible.
2393     *  @param pos          Position to be used for error reporting.
2394     *  @param c            The class whose interfaces are checked.
2395     */
2396    void checkCompatibleSupertypes(DiagnosticPosition pos, Type c) {
2397        List<Type> supertypes = types.interfaces(c);
2398        Type supertype = types.supertype(c);
2399        if (supertype.hasTag(CLASS) &&
2400            (supertype.tsym.flags() & ABSTRACT) != 0)
2401            supertypes = supertypes.prepend(supertype);
2402        for (List<Type> l = supertypes; l.nonEmpty(); l = l.tail) {
2403            if (!l.head.getTypeArguments().isEmpty() &&
2404                !checkCompatibleAbstracts(pos, l.head, l.head, c))
2405                return;
2406            for (List<Type> m = supertypes; m != l; m = m.tail)
2407                if (!checkCompatibleAbstracts(pos, l.head, m.head, c))
2408                    return;
2409        }
2410        checkCompatibleConcretes(pos, c);
2411    }
2412
2413    void checkConflicts(DiagnosticPosition pos, Symbol sym, TypeSymbol c) {
2414        for (Type ct = c.type; ct != Type.noType ; ct = types.supertype(ct)) {
2415            for (Symbol sym2 : ct.tsym.members().getSymbolsByName(sym.name, NON_RECURSIVE)) {
2416                // VM allows methods and variables with differing types
2417                if (sym.kind == sym2.kind &&
2418                    types.isSameType(types.erasure(sym.type), types.erasure(sym2.type)) &&
2419                    sym != sym2 &&
2420                    (sym.flags() & Flags.SYNTHETIC) != (sym2.flags() & Flags.SYNTHETIC) &&
2421                    (sym.flags() & BRIDGE) == 0 && (sym2.flags() & BRIDGE) == 0) {
2422                    syntheticError(pos, (sym2.flags() & SYNTHETIC) == 0 ? sym2 : sym);
2423                    return;
2424                }
2425            }
2426        }
2427    }
2428
2429    /** Check that all non-override equivalent methods accessible from 'site'
2430     *  are mutually compatible (JLS 8.4.8/9.4.1).
2431     *
2432     *  @param pos  Position to be used for error reporting.
2433     *  @param site The class whose methods are checked.
2434     *  @param sym  The method symbol to be checked.
2435     */
2436    void checkOverrideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
2437         ClashFilter cf = new ClashFilter(site);
2438        //for each method m1 that is overridden (directly or indirectly)
2439        //by method 'sym' in 'site'...
2440
2441        List<MethodSymbol> potentiallyAmbiguousList = List.nil();
2442        boolean overridesAny = false;
2443        for (Symbol m1 : types.membersClosure(site, false).getSymbolsByName(sym.name, cf)) {
2444            if (!sym.overrides(m1, site.tsym, types, false)) {
2445                if (m1 == sym) {
2446                    continue;
2447                }
2448
2449                if (!overridesAny) {
2450                    potentiallyAmbiguousList = potentiallyAmbiguousList.prepend((MethodSymbol)m1);
2451                }
2452                continue;
2453            }
2454
2455            if (m1 != sym) {
2456                overridesAny = true;
2457                potentiallyAmbiguousList = List.nil();
2458            }
2459
2460            //...check each method m2 that is a member of 'site'
2461            for (Symbol m2 : types.membersClosure(site, false).getSymbolsByName(sym.name, cf)) {
2462                if (m2 == m1) continue;
2463                //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
2464                //a member of 'site') and (ii) m1 has the same erasure as m2, issue an error
2465                if (!types.isSubSignature(sym.type, types.memberType(site, m2), allowStrictMethodClashCheck) &&
2466                        types.hasSameArgs(m2.erasure(types), m1.erasure(types))) {
2467                    sym.flags_field |= CLASH;
2468                    String key = m1 == sym ?
2469                            "name.clash.same.erasure.no.override" :
2470                            "name.clash.same.erasure.no.override.1";
2471                    log.error(pos,
2472                            key,
2473                            sym, sym.location(),
2474                            m2, m2.location(),
2475                            m1, m1.location());
2476                    return;
2477                }
2478            }
2479        }
2480
2481        if (!overridesAny) {
2482            for (MethodSymbol m: potentiallyAmbiguousList) {
2483                checkPotentiallyAmbiguousOverloads(pos, site, sym, m);
2484            }
2485        }
2486    }
2487
2488    /** Check that all static methods accessible from 'site' are
2489     *  mutually compatible (JLS 8.4.8).
2490     *
2491     *  @param pos  Position to be used for error reporting.
2492     *  @param site The class whose methods are checked.
2493     *  @param sym  The method symbol to be checked.
2494     */
2495    void checkHideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
2496        ClashFilter cf = new ClashFilter(site);
2497        //for each method m1 that is a member of 'site'...
2498        for (Symbol s : types.membersClosure(site, true).getSymbolsByName(sym.name, cf)) {
2499            //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
2500            //a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error
2501            if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck)) {
2502                if (types.hasSameArgs(s.erasure(types), sym.erasure(types))) {
2503                    log.error(pos,
2504                            "name.clash.same.erasure.no.hide",
2505                            sym, sym.location(),
2506                            s, s.location());
2507                    return;
2508                } else {
2509                    checkPotentiallyAmbiguousOverloads(pos, site, sym, (MethodSymbol)s);
2510                }
2511            }
2512         }
2513     }
2514
2515     //where
2516     private class ClashFilter implements Filter<Symbol> {
2517
2518         Type site;
2519
2520         ClashFilter(Type site) {
2521             this.site = site;
2522         }
2523
2524         boolean shouldSkip(Symbol s) {
2525             return (s.flags() & CLASH) != 0 &&
2526                s.owner == site.tsym;
2527         }
2528
2529         public boolean accepts(Symbol s) {
2530             return s.kind == MTH &&
2531                     (s.flags() & SYNTHETIC) == 0 &&
2532                     !shouldSkip(s) &&
2533                     s.isInheritedIn(site.tsym, types) &&
2534                     !s.isConstructor();
2535         }
2536     }
2537
2538    void checkDefaultMethodClashes(DiagnosticPosition pos, Type site) {
2539        DefaultMethodClashFilter dcf = new DefaultMethodClashFilter(site);
2540        for (Symbol m : types.membersClosure(site, false).getSymbols(dcf)) {
2541            Assert.check(m.kind == MTH);
2542            List<MethodSymbol> prov = types.interfaceCandidates(site, (MethodSymbol)m);
2543            if (prov.size() > 1) {
2544                ListBuffer<Symbol> abstracts = new ListBuffer<>();
2545                ListBuffer<Symbol> defaults = new ListBuffer<>();
2546                for (MethodSymbol provSym : prov) {
2547                    if ((provSym.flags() & DEFAULT) != 0) {
2548                        defaults = defaults.append(provSym);
2549                    } else if ((provSym.flags() & ABSTRACT) != 0) {
2550                        abstracts = abstracts.append(provSym);
2551                    }
2552                    if (defaults.nonEmpty() && defaults.size() + abstracts.size() >= 2) {
2553                        //strong semantics - issue an error if two sibling interfaces
2554                        //have two override-equivalent defaults - or if one is abstract
2555                        //and the other is default
2556                        String errKey;
2557                        Symbol s1 = defaults.first();
2558                        Symbol s2;
2559                        if (defaults.size() > 1) {
2560                            errKey = "types.incompatible.unrelated.defaults";
2561                            s2 = defaults.toList().tail.head;
2562                        } else {
2563                            errKey = "types.incompatible.abstract.default";
2564                            s2 = abstracts.first();
2565                        }
2566                        log.error(pos, errKey,
2567                                Kinds.kindName(site.tsym), site,
2568                                m.name, types.memberType(site, m).getParameterTypes(),
2569                                s1.location(), s2.location());
2570                        break;
2571                    }
2572                }
2573            }
2574        }
2575    }
2576
2577    //where
2578     private class DefaultMethodClashFilter implements Filter<Symbol> {
2579
2580         Type site;
2581
2582         DefaultMethodClashFilter(Type site) {
2583             this.site = site;
2584         }
2585
2586         public boolean accepts(Symbol s) {
2587             return s.kind == MTH &&
2588                     (s.flags() & DEFAULT) != 0 &&
2589                     s.isInheritedIn(site.tsym, types) &&
2590                     !s.isConstructor();
2591         }
2592     }
2593
2594    /**
2595      * Report warnings for potentially ambiguous method declarations. Two declarations
2596      * are potentially ambiguous if they feature two unrelated functional interface
2597      * in same argument position (in which case, a call site passing an implicit
2598      * lambda would be ambiguous).
2599      */
2600    void checkPotentiallyAmbiguousOverloads(DiagnosticPosition pos, Type site,
2601            MethodSymbol msym1, MethodSymbol msym2) {
2602        if (msym1 != msym2 &&
2603                allowDefaultMethods &&
2604                lint.isEnabled(LintCategory.OVERLOADS) &&
2605                (msym1.flags() & POTENTIALLY_AMBIGUOUS) == 0 &&
2606                (msym2.flags() & POTENTIALLY_AMBIGUOUS) == 0) {
2607            Type mt1 = types.memberType(site, msym1);
2608            Type mt2 = types.memberType(site, msym2);
2609            //if both generic methods, adjust type variables
2610            if (mt1.hasTag(FORALL) && mt2.hasTag(FORALL) &&
2611                    types.hasSameBounds((ForAll)mt1, (ForAll)mt2)) {
2612                mt2 = types.subst(mt2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars);
2613            }
2614            //expand varargs methods if needed
2615            int maxLength = Math.max(mt1.getParameterTypes().length(), mt2.getParameterTypes().length());
2616            List<Type> args1 = rs.adjustArgs(mt1.getParameterTypes(), msym1, maxLength, true);
2617            List<Type> args2 = rs.adjustArgs(mt2.getParameterTypes(), msym2, maxLength, true);
2618            //if arities don't match, exit
2619            if (args1.length() != args2.length()) return;
2620            boolean potentiallyAmbiguous = false;
2621            while (args1.nonEmpty() && args2.nonEmpty()) {
2622                Type s = args1.head;
2623                Type t = args2.head;
2624                if (!types.isSubtype(t, s) && !types.isSubtype(s, t)) {
2625                    if (types.isFunctionalInterface(s) && types.isFunctionalInterface(t) &&
2626                            types.findDescriptorType(s).getParameterTypes().length() > 0 &&
2627                            types.findDescriptorType(s).getParameterTypes().length() ==
2628                            types.findDescriptorType(t).getParameterTypes().length()) {
2629                        potentiallyAmbiguous = true;
2630                    } else {
2631                        break;
2632                    }
2633                }
2634                args1 = args1.tail;
2635                args2 = args2.tail;
2636            }
2637            if (potentiallyAmbiguous) {
2638                //we found two incompatible functional interfaces with same arity
2639                //this means a call site passing an implicit lambda would be ambigiuous
2640                msym1.flags_field |= POTENTIALLY_AMBIGUOUS;
2641                msym2.flags_field |= POTENTIALLY_AMBIGUOUS;
2642                log.warning(LintCategory.OVERLOADS, pos, "potentially.ambiguous.overload",
2643                            msym1, msym1.location(),
2644                            msym2, msym2.location());
2645                return;
2646            }
2647        }
2648    }
2649
2650    void checkAccessFromSerializableElement(final JCTree tree, boolean isLambda) {
2651        if (warnOnAnyAccessToMembers ||
2652            (lint.isEnabled(LintCategory.SERIAL) &&
2653            !lint.isSuppressed(LintCategory.SERIAL) &&
2654            isLambda)) {
2655            Symbol sym = TreeInfo.symbol(tree);
2656            if (!sym.kind.matches(KindSelector.VAL_MTH)) {
2657                return;
2658            }
2659
2660            if (sym.kind == VAR) {
2661                if ((sym.flags() & PARAMETER) != 0 ||
2662                    sym.isLocal() ||
2663                    sym.name == names._this ||
2664                    sym.name == names._super) {
2665                    return;
2666                }
2667            }
2668
2669            if (!types.isSubtype(sym.owner.type, syms.serializableType) &&
2670                isEffectivelyNonPublic(sym)) {
2671                if (isLambda) {
2672                    if (belongsToRestrictedPackage(sym)) {
2673                        log.warning(LintCategory.SERIAL, tree.pos(),
2674                            "access.to.member.from.serializable.lambda", sym);
2675                    }
2676                } else {
2677                    log.warning(tree.pos(),
2678                        "access.to.member.from.serializable.element", sym);
2679                }
2680            }
2681        }
2682    }
2683
2684    private boolean isEffectivelyNonPublic(Symbol sym) {
2685        if (sym.packge() == syms.rootPackage) {
2686            return false;
2687        }
2688
2689        while (sym.kind != PCK) {
2690            if ((sym.flags() & PUBLIC) == 0) {
2691                return true;
2692            }
2693            sym = sym.owner;
2694        }
2695        return false;
2696    }
2697
2698    private boolean belongsToRestrictedPackage(Symbol sym) {
2699        String fullName = sym.packge().fullname.toString();
2700        return fullName.startsWith("java.") ||
2701                fullName.startsWith("javax.") ||
2702                fullName.startsWith("sun.") ||
2703                fullName.contains(".internal.");
2704    }
2705
2706    /** Report a conflict between a user symbol and a synthetic symbol.
2707     */
2708    private void syntheticError(DiagnosticPosition pos, Symbol sym) {
2709        if (!sym.type.isErroneous()) {
2710            log.error(pos, "synthetic.name.conflict", sym, sym.location());
2711        }
2712    }
2713
2714    /** Check that class c does not implement directly or indirectly
2715     *  the same parameterized interface with two different argument lists.
2716     *  @param pos          Position to be used for error reporting.
2717     *  @param type         The type whose interfaces are checked.
2718     */
2719    void checkClassBounds(DiagnosticPosition pos, Type type) {
2720        checkClassBounds(pos, new HashMap<TypeSymbol,Type>(), type);
2721    }
2722//where
2723        /** Enter all interfaces of type `type' into the hash table `seensofar'
2724         *  with their class symbol as key and their type as value. Make
2725         *  sure no class is entered with two different types.
2726         */
2727        void checkClassBounds(DiagnosticPosition pos,
2728                              Map<TypeSymbol,Type> seensofar,
2729                              Type type) {
2730            if (type.isErroneous()) return;
2731            for (List<Type> l = types.interfaces(type); l.nonEmpty(); l = l.tail) {
2732                Type it = l.head;
2733                Type oldit = seensofar.put(it.tsym, it);
2734                if (oldit != null) {
2735                    List<Type> oldparams = oldit.allparams();
2736                    List<Type> newparams = it.allparams();
2737                    if (!types.containsTypeEquivalent(oldparams, newparams))
2738                        log.error(pos, "cant.inherit.diff.arg",
2739                                  it.tsym, Type.toString(oldparams),
2740                                  Type.toString(newparams));
2741                }
2742                checkClassBounds(pos, seensofar, it);
2743            }
2744            Type st = types.supertype(type);
2745            if (st != Type.noType) checkClassBounds(pos, seensofar, st);
2746        }
2747
2748    /** Enter interface into into set.
2749     *  If it existed already, issue a "repeated interface" error.
2750     */
2751    void checkNotRepeated(DiagnosticPosition pos, Type it, Set<Type> its) {
2752        if (its.contains(it))
2753            log.error(pos, "repeated.interface");
2754        else {
2755            its.add(it);
2756        }
2757    }
2758
2759/* *************************************************************************
2760 * Check annotations
2761 **************************************************************************/
2762
2763    /**
2764     * Recursively validate annotations values
2765     */
2766    void validateAnnotationTree(JCTree tree) {
2767        class AnnotationValidator extends TreeScanner {
2768            @Override
2769            public void visitAnnotation(JCAnnotation tree) {
2770                if (!tree.type.isErroneous()) {
2771                    super.visitAnnotation(tree);
2772                    validateAnnotation(tree);
2773                }
2774            }
2775        }
2776        tree.accept(new AnnotationValidator());
2777    }
2778
2779    /**
2780     *  {@literal
2781     *  Annotation types are restricted to primitives, String, an
2782     *  enum, an annotation, Class, Class<?>, Class<? extends
2783     *  Anything>, arrays of the preceding.
2784     *  }
2785     */
2786    void validateAnnotationType(JCTree restype) {
2787        // restype may be null if an error occurred, so don't bother validating it
2788        if (restype != null) {
2789            validateAnnotationType(restype.pos(), restype.type);
2790        }
2791    }
2792
2793    void validateAnnotationType(DiagnosticPosition pos, Type type) {
2794        if (type.isPrimitive()) return;
2795        if (types.isSameType(type, syms.stringType)) return;
2796        if ((type.tsym.flags() & Flags.ENUM) != 0) return;
2797        if ((type.tsym.flags() & Flags.ANNOTATION) != 0) return;
2798        if (types.cvarLowerBound(type).tsym == syms.classType.tsym) return;
2799        if (types.isArray(type) && !types.isArray(types.elemtype(type))) {
2800            validateAnnotationType(pos, types.elemtype(type));
2801            return;
2802        }
2803        log.error(pos, "invalid.annotation.member.type");
2804    }
2805
2806    /**
2807     * "It is also a compile-time error if any method declared in an
2808     * annotation type has a signature that is override-equivalent to
2809     * that of any public or protected method declared in class Object
2810     * or in the interface annotation.Annotation."
2811     *
2812     * @jls 9.6 Annotation Types
2813     */
2814    void validateAnnotationMethod(DiagnosticPosition pos, MethodSymbol m) {
2815        for (Type sup = syms.annotationType; sup.hasTag(CLASS); sup = types.supertype(sup)) {
2816            Scope s = sup.tsym.members();
2817            for (Symbol sym : s.getSymbolsByName(m.name)) {
2818                if (sym.kind == MTH &&
2819                    (sym.flags() & (PUBLIC | PROTECTED)) != 0 &&
2820                    types.overrideEquivalent(m.type, sym.type))
2821                    log.error(pos, "intf.annotation.member.clash", sym, sup);
2822            }
2823        }
2824    }
2825
2826    /** Check the annotations of a symbol.
2827     */
2828    public void validateAnnotations(List<JCAnnotation> annotations, Symbol s) {
2829        for (JCAnnotation a : annotations)
2830            validateAnnotation(a, s);
2831    }
2832
2833    /** Check the type annotations.
2834     */
2835    public void validateTypeAnnotations(List<JCAnnotation> annotations, boolean isTypeParameter) {
2836        for (JCAnnotation a : annotations)
2837            validateTypeAnnotation(a, isTypeParameter);
2838    }
2839
2840    /** Check an annotation of a symbol.
2841     */
2842    private void validateAnnotation(JCAnnotation a, Symbol s) {
2843        validateAnnotationTree(a);
2844
2845        if (a.type.tsym.isAnnotationType() && !annotationApplicable(a, s))
2846            log.error(a.pos(), "annotation.type.not.applicable");
2847
2848        if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) {
2849            if (s.kind != TYP) {
2850                log.error(a.pos(), "bad.functional.intf.anno");
2851            } else if (!s.isInterface() || (s.flags() & ANNOTATION) != 0) {
2852                log.error(a.pos(), "bad.functional.intf.anno.1", diags.fragment("not.a.functional.intf", s));
2853            }
2854        }
2855    }
2856
2857    public void validateTypeAnnotation(JCAnnotation a, boolean isTypeParameter) {
2858        Assert.checkNonNull(a.type);
2859        validateAnnotationTree(a);
2860
2861        if (a.hasTag(TYPE_ANNOTATION) &&
2862                !a.annotationType.type.isErroneous() &&
2863                !isTypeAnnotation(a, isTypeParameter)) {
2864            log.error(a.pos(), Errors.AnnotationTypeNotApplicableToType(a.type));
2865        }
2866    }
2867
2868    /**
2869     * Validate the proposed container 'repeatable' on the
2870     * annotation type symbol 's'. Report errors at position
2871     * 'pos'.
2872     *
2873     * @param s The (annotation)type declaration annotated with a @Repeatable
2874     * @param repeatable the @Repeatable on 's'
2875     * @param pos where to report errors
2876     */
2877    public void validateRepeatable(TypeSymbol s, Attribute.Compound repeatable, DiagnosticPosition pos) {
2878        Assert.check(types.isSameType(repeatable.type, syms.repeatableType));
2879
2880        Type t = null;
2881        List<Pair<MethodSymbol,Attribute>> l = repeatable.values;
2882        if (!l.isEmpty()) {
2883            Assert.check(l.head.fst.name == names.value);
2884            t = ((Attribute.Class)l.head.snd).getValue();
2885        }
2886
2887        if (t == null) {
2888            // errors should already have been reported during Annotate
2889            return;
2890        }
2891
2892        validateValue(t.tsym, s, pos);
2893        validateRetention(t.tsym, s, pos);
2894        validateDocumented(t.tsym, s, pos);
2895        validateInherited(t.tsym, s, pos);
2896        validateTarget(t.tsym, s, pos);
2897        validateDefault(t.tsym, pos);
2898    }
2899
2900    private void validateValue(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
2901        Symbol sym = container.members().findFirst(names.value);
2902        if (sym != null && sym.kind == MTH) {
2903            MethodSymbol m = (MethodSymbol) sym;
2904            Type ret = m.getReturnType();
2905            if (!(ret.hasTag(ARRAY) && types.isSameType(((ArrayType)ret).elemtype, contained.type))) {
2906                log.error(pos, "invalid.repeatable.annotation.value.return",
2907                        container, ret, types.makeArrayType(contained.type));
2908            }
2909        } else {
2910            log.error(pos, "invalid.repeatable.annotation.no.value", container);
2911        }
2912    }
2913
2914    private void validateRetention(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
2915        Attribute.RetentionPolicy containerRetention = types.getRetention(container);
2916        Attribute.RetentionPolicy containedRetention = types.getRetention(contained);
2917
2918        boolean error = false;
2919        switch (containedRetention) {
2920        case RUNTIME:
2921            if (containerRetention != Attribute.RetentionPolicy.RUNTIME) {
2922                error = true;
2923            }
2924            break;
2925        case CLASS:
2926            if (containerRetention == Attribute.RetentionPolicy.SOURCE)  {
2927                error = true;
2928            }
2929        }
2930        if (error ) {
2931            log.error(pos, "invalid.repeatable.annotation.retention",
2932                      container, containerRetention,
2933                      contained, containedRetention);
2934        }
2935    }
2936
2937    private void validateDocumented(Symbol container, Symbol contained, DiagnosticPosition pos) {
2938        if (contained.attribute(syms.documentedType.tsym) != null) {
2939            if (container.attribute(syms.documentedType.tsym) == null) {
2940                log.error(pos, "invalid.repeatable.annotation.not.documented", container, contained);
2941            }
2942        }
2943    }
2944
2945    private void validateInherited(Symbol container, Symbol contained, DiagnosticPosition pos) {
2946        if (contained.attribute(syms.inheritedType.tsym) != null) {
2947            if (container.attribute(syms.inheritedType.tsym) == null) {
2948                log.error(pos, "invalid.repeatable.annotation.not.inherited", container, contained);
2949            }
2950        }
2951    }
2952
2953    private void validateTarget(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
2954        // The set of targets the container is applicable to must be a subset
2955        // (with respect to annotation target semantics) of the set of targets
2956        // the contained is applicable to. The target sets may be implicit or
2957        // explicit.
2958
2959        Set<Name> containerTargets;
2960        Attribute.Array containerTarget = getAttributeTargetAttribute(container);
2961        if (containerTarget == null) {
2962            containerTargets = getDefaultTargetSet();
2963        } else {
2964            containerTargets = new HashSet<>();
2965            for (Attribute app : containerTarget.values) {
2966                if (!(app instanceof Attribute.Enum)) {
2967                    continue; // recovery
2968                }
2969                Attribute.Enum e = (Attribute.Enum)app;
2970                containerTargets.add(e.value.name);
2971            }
2972        }
2973
2974        Set<Name> containedTargets;
2975        Attribute.Array containedTarget = getAttributeTargetAttribute(contained);
2976        if (containedTarget == null) {
2977            containedTargets = getDefaultTargetSet();
2978        } else {
2979            containedTargets = new HashSet<>();
2980            for (Attribute app : containedTarget.values) {
2981                if (!(app instanceof Attribute.Enum)) {
2982                    continue; // recovery
2983                }
2984                Attribute.Enum e = (Attribute.Enum)app;
2985                containedTargets.add(e.value.name);
2986            }
2987        }
2988
2989        if (!isTargetSubsetOf(containerTargets, containedTargets)) {
2990            log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained);
2991        }
2992    }
2993
2994    /* get a set of names for the default target */
2995    private Set<Name> getDefaultTargetSet() {
2996        if (defaultTargets == null) {
2997            Set<Name> targets = new HashSet<>();
2998            targets.add(names.ANNOTATION_TYPE);
2999            targets.add(names.CONSTRUCTOR);
3000            targets.add(names.FIELD);
3001            targets.add(names.LOCAL_VARIABLE);
3002            targets.add(names.METHOD);
3003            targets.add(names.PACKAGE);
3004            targets.add(names.PARAMETER);
3005            targets.add(names.TYPE);
3006
3007            defaultTargets = java.util.Collections.unmodifiableSet(targets);
3008        }
3009
3010        return defaultTargets;
3011    }
3012    private Set<Name> defaultTargets;
3013
3014
3015    /** Checks that s is a subset of t, with respect to ElementType
3016     * semantics, specifically {ANNOTATION_TYPE} is a subset of {TYPE},
3017     * and {TYPE_USE} covers the set {ANNOTATION_TYPE, TYPE, TYPE_USE,
3018     * TYPE_PARAMETER}.
3019     */
3020    private boolean isTargetSubsetOf(Set<Name> s, Set<Name> t) {
3021        // Check that all elements in s are present in t
3022        for (Name n2 : s) {
3023            boolean currentElementOk = false;
3024            for (Name n1 : t) {
3025                if (n1 == n2) {
3026                    currentElementOk = true;
3027                    break;
3028                } else if (n1 == names.TYPE && n2 == names.ANNOTATION_TYPE) {
3029                    currentElementOk = true;
3030                    break;
3031                } else if (n1 == names.TYPE_USE &&
3032                        (n2 == names.TYPE ||
3033                         n2 == names.ANNOTATION_TYPE ||
3034                         n2 == names.TYPE_PARAMETER)) {
3035                    currentElementOk = true;
3036                    break;
3037                }
3038            }
3039            if (!currentElementOk)
3040                return false;
3041        }
3042        return true;
3043    }
3044
3045    private void validateDefault(Symbol container, DiagnosticPosition pos) {
3046        // validate that all other elements of containing type has defaults
3047        Scope scope = container.members();
3048        for(Symbol elm : scope.getSymbols()) {
3049            if (elm.name != names.value &&
3050                elm.kind == MTH &&
3051                ((MethodSymbol)elm).defaultValue == null) {
3052                log.error(pos,
3053                          "invalid.repeatable.annotation.elem.nondefault",
3054                          container,
3055                          elm);
3056            }
3057        }
3058    }
3059
3060    /** Is s a method symbol that overrides a method in a superclass? */
3061    boolean isOverrider(Symbol s) {
3062        if (s.kind != MTH || s.isStatic())
3063            return false;
3064        MethodSymbol m = (MethodSymbol)s;
3065        TypeSymbol owner = (TypeSymbol)m.owner;
3066        for (Type sup : types.closure(owner.type)) {
3067            if (sup == owner.type)
3068                continue; // skip "this"
3069            Scope scope = sup.tsym.members();
3070            for (Symbol sym : scope.getSymbolsByName(m.name)) {
3071                if (!sym.isStatic() && m.overrides(sym, owner, types, true))
3072                    return true;
3073            }
3074        }
3075        return false;
3076    }
3077
3078    /** Is the annotation applicable to types? */
3079    protected boolean isTypeAnnotation(JCAnnotation a, boolean isTypeParameter) {
3080        List<Attribute> targets = typeAnnotations.annotationTargets(a.annotationType.type.tsym);
3081        return (targets == null) ?
3082                false :
3083                targets.stream()
3084                        .anyMatch(attr -> isTypeAnnotation(attr, isTypeParameter));
3085    }
3086    //where
3087        boolean isTypeAnnotation(Attribute a, boolean isTypeParameter) {
3088            Attribute.Enum e = (Attribute.Enum)a;
3089            return (e.value.name == names.TYPE_USE ||
3090                    (isTypeParameter && e.value.name == names.TYPE_PARAMETER));
3091        }
3092
3093    /** Is the annotation applicable to the symbol? */
3094    boolean annotationApplicable(JCAnnotation a, Symbol s) {
3095        Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym);
3096        Name[] targets;
3097
3098        if (arr == null) {
3099            targets = defaultTargetMetaInfo(a, s);
3100        } else {
3101            // TODO: can we optimize this?
3102            targets = new Name[arr.values.length];
3103            for (int i=0; i<arr.values.length; ++i) {
3104                Attribute app = arr.values[i];
3105                if (!(app instanceof Attribute.Enum)) {
3106                    return true; // recovery
3107                }
3108                Attribute.Enum e = (Attribute.Enum) app;
3109                targets[i] = e.value.name;
3110            }
3111        }
3112        for (Name target : targets) {
3113            if (target == names.TYPE) {
3114                if (s.kind == TYP)
3115                    return true;
3116            } else if (target == names.FIELD) {
3117                if (s.kind == VAR && s.owner.kind != MTH)
3118                    return true;
3119            } else if (target == names.METHOD) {
3120                if (s.kind == MTH && !s.isConstructor())
3121                    return true;
3122            } else if (target == names.PARAMETER) {
3123                if (s.kind == VAR && s.owner.kind == MTH &&
3124                      (s.flags() & PARAMETER) != 0) {
3125                    return true;
3126                }
3127            } else if (target == names.CONSTRUCTOR) {
3128                if (s.kind == MTH && s.isConstructor())
3129                    return true;
3130            } else if (target == names.LOCAL_VARIABLE) {
3131                if (s.kind == VAR && s.owner.kind == MTH &&
3132                      (s.flags() & PARAMETER) == 0) {
3133                    return true;
3134                }
3135            } else if (target == names.ANNOTATION_TYPE) {
3136                if (s.kind == TYP && (s.flags() & ANNOTATION) != 0) {
3137                    return true;
3138                }
3139            } else if (target == names.PACKAGE) {
3140                if (s.kind == PCK)
3141                    return true;
3142            } else if (target == names.TYPE_USE) {
3143                if (s.kind == TYP || s.kind == VAR ||
3144                        (s.kind == MTH && !s.isConstructor() &&
3145                                !s.type.getReturnType().hasTag(VOID)) ||
3146                        (s.kind == MTH && s.isConstructor())) {
3147                    return true;
3148                }
3149            } else if (target == names.TYPE_PARAMETER) {
3150                if (s.kind == TYP && s.type.hasTag(TYPEVAR))
3151                    return true;
3152            } else
3153                return true; // Unknown ElementType. This should be an error at declaration site,
3154                             // assume applicable.
3155        }
3156        return false;
3157    }
3158
3159
3160    Attribute.Array getAttributeTargetAttribute(TypeSymbol s) {
3161        Attribute.Compound atTarget = s.getAnnotationTypeMetadata().getTarget();
3162        if (atTarget == null) return null; // ok, is applicable
3163        Attribute atValue = atTarget.member(names.value);
3164        if (!(atValue instanceof Attribute.Array)) return null; // error recovery
3165        return (Attribute.Array) atValue;
3166    }
3167
3168    private final Name[] dfltTargetMeta;
3169    private Name[] defaultTargetMetaInfo(JCAnnotation a, Symbol s) {
3170        return dfltTargetMeta;
3171    }
3172
3173    /** Check an annotation value.
3174     *
3175     * @param a The annotation tree to check
3176     * @return true if this annotation tree is valid, otherwise false
3177     */
3178    public boolean validateAnnotationDeferErrors(JCAnnotation a) {
3179        boolean res = false;
3180        final Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
3181        try {
3182            res = validateAnnotation(a);
3183        } finally {
3184            log.popDiagnosticHandler(diagHandler);
3185        }
3186        return res;
3187    }
3188
3189    private boolean validateAnnotation(JCAnnotation a) {
3190        boolean isValid = true;
3191        AnnotationTypeMetadata metadata = a.annotationType.type.tsym.getAnnotationTypeMetadata();
3192
3193        // collect an inventory of the annotation elements
3194        Set<MethodSymbol> elements = metadata.getAnnotationElements();
3195
3196        // remove the ones that are assigned values
3197        for (JCTree arg : a.args) {
3198            if (!arg.hasTag(ASSIGN)) continue; // recovery
3199            JCAssign assign = (JCAssign)arg;
3200            Symbol m = TreeInfo.symbol(assign.lhs);
3201            if (m == null || m.type.isErroneous()) continue;
3202            if (!elements.remove(m)) {
3203                isValid = false;
3204                log.error(assign.lhs.pos(), "duplicate.annotation.member.value",
3205                        m.name, a.type);
3206            }
3207        }
3208
3209        // all the remaining ones better have default values
3210        List<Name> missingDefaults = List.nil();
3211        Set<MethodSymbol> membersWithDefault = metadata.getAnnotationElementsWithDefault();
3212        for (MethodSymbol m : elements) {
3213            if (m.type.isErroneous())
3214                continue;
3215
3216            if (!membersWithDefault.contains(m))
3217                missingDefaults = missingDefaults.append(m.name);
3218        }
3219        missingDefaults = missingDefaults.reverse();
3220        if (missingDefaults.nonEmpty()) {
3221            isValid = false;
3222            String key = (missingDefaults.size() > 1)
3223                    ? "annotation.missing.default.value.1"
3224                    : "annotation.missing.default.value";
3225            log.error(a.pos(), key, a.type, missingDefaults);
3226        }
3227
3228        return isValid && validateTargetAnnotationValue(a);
3229    }
3230
3231    /* Validate the special java.lang.annotation.Target annotation */
3232    boolean validateTargetAnnotationValue(JCAnnotation a) {
3233        // special case: java.lang.annotation.Target must not have
3234        // repeated values in its value member
3235        if (a.annotationType.type.tsym != syms.annotationTargetType.tsym ||
3236                a.args.tail == null)
3237            return true;
3238
3239        boolean isValid = true;
3240        if (!a.args.head.hasTag(ASSIGN)) return false; // error recovery
3241        JCAssign assign = (JCAssign) a.args.head;
3242        Symbol m = TreeInfo.symbol(assign.lhs);
3243        if (m.name != names.value) return false;
3244        JCTree rhs = assign.rhs;
3245        if (!rhs.hasTag(NEWARRAY)) return false;
3246        JCNewArray na = (JCNewArray) rhs;
3247        Set<Symbol> targets = new HashSet<>();
3248        for (JCTree elem : na.elems) {
3249            if (!targets.add(TreeInfo.symbol(elem))) {
3250                isValid = false;
3251                log.error(elem.pos(), "repeated.annotation.target");
3252            }
3253        }
3254        return isValid;
3255    }
3256
3257    void checkDeprecatedAnnotation(DiagnosticPosition pos, Symbol s) {
3258        if (lint.isEnabled(LintCategory.DEP_ANN) && s.isDeprecatableViaAnnotation() &&
3259            (s.flags() & DEPRECATED) != 0 &&
3260            !syms.deprecatedType.isErroneous() &&
3261            s.attribute(syms.deprecatedType.tsym) == null) {
3262            log.warning(LintCategory.DEP_ANN,
3263                    pos, "missing.deprecated.annotation");
3264        }
3265        // Note: @Deprecated has no effect on local variables, parameters and package decls.
3266        if (lint.isEnabled(LintCategory.DEPRECATION) && !s.isDeprecatableViaAnnotation()) {
3267            if (!syms.deprecatedType.isErroneous() && s.attribute(syms.deprecatedType.tsym) != null) {
3268                log.warning(LintCategory.DEPRECATION, pos,
3269                        "deprecated.annotation.has.no.effect", Kinds.kindName(s));
3270            }
3271        }
3272    }
3273
3274    void checkDeprecated(final DiagnosticPosition pos, final Symbol other, final Symbol s) {
3275        if ( (s.isDeprecatedForRemoval()
3276                || s.isDeprecated() && !other.isDeprecated())
3277                && (s.outermostClass() != other.outermostClass() || s.outermostClass() == null)) {
3278            deferredLintHandler.report(() -> warnDeprecated(pos, s));
3279        }
3280    }
3281
3282    void checkSunAPI(final DiagnosticPosition pos, final Symbol s) {
3283        if ((s.flags() & PROPRIETARY) != 0) {
3284            deferredLintHandler.report(() -> {
3285                log.mandatoryWarning(pos, "sun.proprietary", s);
3286            });
3287        }
3288    }
3289
3290    void checkProfile(final DiagnosticPosition pos, final Symbol s) {
3291        if (profile != Profile.DEFAULT && (s.flags() & NOT_IN_PROFILE) != 0) {
3292            log.error(pos, "not.in.profile", s, profile);
3293        }
3294    }
3295
3296/* *************************************************************************
3297 * Check for recursive annotation elements.
3298 **************************************************************************/
3299
3300    /** Check for cycles in the graph of annotation elements.
3301     */
3302    void checkNonCyclicElements(JCClassDecl tree) {
3303        if ((tree.sym.flags_field & ANNOTATION) == 0) return;
3304        Assert.check((tree.sym.flags_field & LOCKED) == 0);
3305        try {
3306            tree.sym.flags_field |= LOCKED;
3307            for (JCTree def : tree.defs) {
3308                if (!def.hasTag(METHODDEF)) continue;
3309                JCMethodDecl meth = (JCMethodDecl)def;
3310                checkAnnotationResType(meth.pos(), meth.restype.type);
3311            }
3312        } finally {
3313            tree.sym.flags_field &= ~LOCKED;
3314            tree.sym.flags_field |= ACYCLIC_ANN;
3315        }
3316    }
3317
3318    void checkNonCyclicElementsInternal(DiagnosticPosition pos, TypeSymbol tsym) {
3319        if ((tsym.flags_field & ACYCLIC_ANN) != 0)
3320            return;
3321        if ((tsym.flags_field & LOCKED) != 0) {
3322            log.error(pos, "cyclic.annotation.element");
3323            return;
3324        }
3325        try {
3326            tsym.flags_field |= LOCKED;
3327            for (Symbol s : tsym.members().getSymbols(NON_RECURSIVE)) {
3328                if (s.kind != MTH)
3329                    continue;
3330                checkAnnotationResType(pos, ((MethodSymbol)s).type.getReturnType());
3331            }
3332        } finally {
3333            tsym.flags_field &= ~LOCKED;
3334            tsym.flags_field |= ACYCLIC_ANN;
3335        }
3336    }
3337
3338    void checkAnnotationResType(DiagnosticPosition pos, Type type) {
3339        switch (type.getTag()) {
3340        case CLASS:
3341            if ((type.tsym.flags() & ANNOTATION) != 0)
3342                checkNonCyclicElementsInternal(pos, type.tsym);
3343            break;
3344        case ARRAY:
3345            checkAnnotationResType(pos, types.elemtype(type));
3346            break;
3347        default:
3348            break; // int etc
3349        }
3350    }
3351
3352/* *************************************************************************
3353 * Check for cycles in the constructor call graph.
3354 **************************************************************************/
3355
3356    /** Check for cycles in the graph of constructors calling other
3357     *  constructors.
3358     */
3359    void checkCyclicConstructors(JCClassDecl tree) {
3360        Map<Symbol,Symbol> callMap = new HashMap<>();
3361
3362        // enter each constructor this-call into the map
3363        for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
3364            JCMethodInvocation app = TreeInfo.firstConstructorCall(l.head);
3365            if (app == null) continue;
3366            JCMethodDecl meth = (JCMethodDecl) l.head;
3367            if (TreeInfo.name(app.meth) == names._this) {
3368                callMap.put(meth.sym, TreeInfo.symbol(app.meth));
3369            } else {
3370                meth.sym.flags_field |= ACYCLIC;
3371            }
3372        }
3373
3374        // Check for cycles in the map
3375        Symbol[] ctors = new Symbol[0];
3376        ctors = callMap.keySet().toArray(ctors);
3377        for (Symbol caller : ctors) {
3378            checkCyclicConstructor(tree, caller, callMap);
3379        }
3380    }
3381
3382    /** Look in the map to see if the given constructor is part of a
3383     *  call cycle.
3384     */
3385    private void checkCyclicConstructor(JCClassDecl tree, Symbol ctor,
3386                                        Map<Symbol,Symbol> callMap) {
3387        if (ctor != null && (ctor.flags_field & ACYCLIC) == 0) {
3388            if ((ctor.flags_field & LOCKED) != 0) {
3389                log.error(TreeInfo.diagnosticPositionFor(ctor, tree),
3390                          "recursive.ctor.invocation");
3391            } else {
3392                ctor.flags_field |= LOCKED;
3393                checkCyclicConstructor(tree, callMap.remove(ctor), callMap);
3394                ctor.flags_field &= ~LOCKED;
3395            }
3396            ctor.flags_field |= ACYCLIC;
3397        }
3398    }
3399
3400/* *************************************************************************
3401 * Miscellaneous
3402 **************************************************************************/
3403
3404    /**
3405     *  Check for division by integer constant zero
3406     *  @param pos           Position for error reporting.
3407     *  @param operator      The operator for the expression
3408     *  @param operand       The right hand operand for the expression
3409     */
3410    void checkDivZero(final DiagnosticPosition pos, Symbol operator, Type operand) {
3411        if (operand.constValue() != null
3412            && operand.getTag().isSubRangeOf(LONG)
3413            && ((Number) (operand.constValue())).longValue() == 0) {
3414            int opc = ((OperatorSymbol)operator).opcode;
3415            if (opc == ByteCodes.idiv || opc == ByteCodes.imod
3416                || opc == ByteCodes.ldiv || opc == ByteCodes.lmod) {
3417                deferredLintHandler.report(() -> warnDivZero(pos));
3418            }
3419        }
3420    }
3421
3422    /**
3423     * Check for empty statements after if
3424     */
3425    void checkEmptyIf(JCIf tree) {
3426        if (tree.thenpart.hasTag(SKIP) && tree.elsepart == null &&
3427                lint.isEnabled(LintCategory.EMPTY))
3428            log.warning(LintCategory.EMPTY, tree.thenpart.pos(), "empty.if");
3429    }
3430
3431    /** Check that symbol is unique in given scope.
3432     *  @param pos           Position for error reporting.
3433     *  @param sym           The symbol.
3434     *  @param s             The scope.
3435     */
3436    boolean checkUnique(DiagnosticPosition pos, Symbol sym, Scope s) {
3437        if (sym.type.isErroneous())
3438            return true;
3439        if (sym.owner.name == names.any) return false;
3440        for (Symbol byName : s.getSymbolsByName(sym.name, NON_RECURSIVE)) {
3441            if (sym != byName &&
3442                    (byName.flags() & CLASH) == 0 &&
3443                    sym.kind == byName.kind &&
3444                    sym.name != names.error &&
3445                    (sym.kind != MTH ||
3446                     types.hasSameArgs(sym.type, byName.type) ||
3447                     types.hasSameArgs(types.erasure(sym.type), types.erasure(byName.type)))) {
3448                if ((sym.flags() & VARARGS) != (byName.flags() & VARARGS)) {
3449                    varargsDuplicateError(pos, sym, byName);
3450                    return true;
3451                } else if (sym.kind == MTH && !types.hasSameArgs(sym.type, byName.type, false)) {
3452                    duplicateErasureError(pos, sym, byName);
3453                    sym.flags_field |= CLASH;
3454                    return true;
3455                } else {
3456                    duplicateError(pos, byName);
3457                    return false;
3458                }
3459            }
3460        }
3461        return true;
3462    }
3463
3464    /** Report duplicate declaration error.
3465     */
3466    void duplicateErasureError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) {
3467        if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) {
3468            log.error(pos, "name.clash.same.erasure", sym1, sym2);
3469        }
3470    }
3471
3472    /**Check that types imported through the ordinary imports don't clash with types imported
3473     * by other (static or ordinary) imports. Note that two static imports may import two clashing
3474     * types without an error on the imports.
3475     * @param toplevel       The toplevel tree for which the test should be performed.
3476     */
3477    void checkImportsUnique(JCCompilationUnit toplevel) {
3478        WriteableScope ordinallyImportedSoFar = WriteableScope.create(toplevel.packge);
3479        WriteableScope staticallyImportedSoFar = WriteableScope.create(toplevel.packge);
3480        WriteableScope topLevelScope = toplevel.toplevelScope;
3481
3482        for (JCTree def : toplevel.defs) {
3483            if (!def.hasTag(IMPORT))
3484                continue;
3485
3486            JCImport imp = (JCImport) def;
3487
3488            if (imp.importScope == null)
3489                continue;
3490
3491            for (Symbol sym : imp.importScope.getSymbols(sym -> sym.kind == TYP)) {
3492                if (imp.isStatic()) {
3493                    checkUniqueImport(imp.pos(), ordinallyImportedSoFar, staticallyImportedSoFar, topLevelScope, sym, true);
3494                    staticallyImportedSoFar.enter(sym);
3495                } else {
3496                    checkUniqueImport(imp.pos(), ordinallyImportedSoFar, staticallyImportedSoFar, topLevelScope, sym, false);
3497                    ordinallyImportedSoFar.enter(sym);
3498                }
3499            }
3500
3501            imp.importScope = null;
3502        }
3503    }
3504
3505    /** Check that single-type import is not already imported or top-level defined,
3506     *  but make an exception for two single-type imports which denote the same type.
3507     *  @param pos                     Position for error reporting.
3508     *  @param ordinallyImportedSoFar  A Scope containing types imported so far through
3509     *                                 ordinary imports.
3510     *  @param staticallyImportedSoFar A Scope containing types imported so far through
3511     *                                 static imports.
3512     *  @param topLevelScope           The current file's top-level Scope
3513     *  @param sym                     The symbol.
3514     *  @param staticImport            Whether or not this was a static import
3515     */
3516    private boolean checkUniqueImport(DiagnosticPosition pos, Scope ordinallyImportedSoFar,
3517                                      Scope staticallyImportedSoFar, Scope topLevelScope,
3518                                      Symbol sym, boolean staticImport) {
3519        Filter<Symbol> duplicates = candidate -> candidate != sym && !candidate.type.isErroneous();
3520        Symbol clashing = ordinallyImportedSoFar.findFirst(sym.name, duplicates);
3521        if (clashing == null && !staticImport) {
3522            clashing = staticallyImportedSoFar.findFirst(sym.name, duplicates);
3523        }
3524        if (clashing != null) {
3525            if (staticImport)
3526                log.error(pos, "already.defined.static.single.import", clashing);
3527            else
3528                log.error(pos, "already.defined.single.import", clashing);
3529            return false;
3530        }
3531        clashing = topLevelScope.findFirst(sym.name, duplicates);
3532        if (clashing != null) {
3533            log.error(pos, "already.defined.this.unit", clashing);
3534            return false;
3535        }
3536        return true;
3537    }
3538
3539    /** Check that a qualified name is in canonical form (for import decls).
3540     */
3541    public void checkCanonical(JCTree tree) {
3542        if (!isCanonical(tree))
3543            log.error(tree.pos(), "import.requires.canonical",
3544                      TreeInfo.symbol(tree));
3545    }
3546        // where
3547        private boolean isCanonical(JCTree tree) {
3548            while (tree.hasTag(SELECT)) {
3549                JCFieldAccess s = (JCFieldAccess) tree;
3550                if (s.sym.owner.name != TreeInfo.symbol(s.selected).name)
3551                    return false;
3552                tree = s.selected;
3553            }
3554            return true;
3555        }
3556
3557    /** Check that an auxiliary class is not accessed from any other file than its own.
3558     */
3559    void checkForBadAuxiliaryClassAccess(DiagnosticPosition pos, Env<AttrContext> env, ClassSymbol c) {
3560        if (lint.isEnabled(Lint.LintCategory.AUXILIARYCLASS) &&
3561            (c.flags() & AUXILIARY) != 0 &&
3562            rs.isAccessible(env, c) &&
3563            !fileManager.isSameFile(c.sourcefile, env.toplevel.sourcefile))
3564        {
3565            log.warning(pos, "auxiliary.class.accessed.from.outside.of.its.source.file",
3566                        c, c.sourcefile);
3567        }
3568    }
3569
3570    private class ConversionWarner extends Warner {
3571        final String uncheckedKey;
3572        final Type found;
3573        final Type expected;
3574        public ConversionWarner(DiagnosticPosition pos, String uncheckedKey, Type found, Type expected) {
3575            super(pos);
3576            this.uncheckedKey = uncheckedKey;
3577            this.found = found;
3578            this.expected = expected;
3579        }
3580
3581        @Override
3582        public void warn(LintCategory lint) {
3583            boolean warned = this.warned;
3584            super.warn(lint);
3585            if (warned) return; // suppress redundant diagnostics
3586            switch (lint) {
3587                case UNCHECKED:
3588                    Check.this.warnUnchecked(pos(), "prob.found.req", diags.fragment(uncheckedKey), found, expected);
3589                    break;
3590                case VARARGS:
3591                    if (method != null &&
3592                            method.attribute(syms.trustMeType.tsym) != null &&
3593                            isTrustMeAllowedOnMethod(method) &&
3594                            !types.isReifiable(method.type.getParameterTypes().last())) {
3595                        Check.this.warnUnsafeVararg(pos(), "varargs.unsafe.use.varargs.param", method.params.last());
3596                    }
3597                    break;
3598                default:
3599                    throw new AssertionError("Unexpected lint: " + lint);
3600            }
3601        }
3602    }
3603
3604    public Warner castWarner(DiagnosticPosition pos, Type found, Type expected) {
3605        return new ConversionWarner(pos, "unchecked.cast.to.type", found, expected);
3606    }
3607
3608    public Warner convertWarner(DiagnosticPosition pos, Type found, Type expected) {
3609        return new ConversionWarner(pos, "unchecked.assign", found, expected);
3610    }
3611
3612    public void checkFunctionalInterface(JCClassDecl tree, ClassSymbol cs) {
3613        Compound functionalType = cs.attribute(syms.functionalInterfaceType.tsym);
3614
3615        if (functionalType != null) {
3616            try {
3617                types.findDescriptorSymbol((TypeSymbol)cs);
3618            } catch (Types.FunctionDescriptorLookupError ex) {
3619                DiagnosticPosition pos = tree.pos();
3620                for (JCAnnotation a : tree.getModifiers().annotations) {
3621                    if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) {
3622                        pos = a.pos();
3623                        break;
3624                    }
3625                }
3626                log.error(pos, "bad.functional.intf.anno.1", ex.getDiagnostic());
3627            }
3628        }
3629    }
3630
3631    public void checkImportsResolvable(final JCCompilationUnit toplevel) {
3632        for (final JCImport imp : toplevel.getImports()) {
3633            if (!imp.staticImport || !imp.qualid.hasTag(SELECT))
3634                continue;
3635            final JCFieldAccess select = (JCFieldAccess) imp.qualid;
3636            final Symbol origin;
3637            if (select.name == names.asterisk || (origin = TreeInfo.symbol(select.selected)) == null || origin.kind != TYP)
3638                continue;
3639
3640            TypeSymbol site = (TypeSymbol) TreeInfo.symbol(select.selected);
3641            if (!checkTypeContainsImportableElement(site, site, toplevel.packge, select.name, new HashSet<Symbol>())) {
3642                log.error(imp.pos(), "cant.resolve.location",
3643                          KindName.STATIC,
3644                          select.name, List.<Type>nil(), List.<Type>nil(),
3645                          Kinds.typeKindName(TreeInfo.symbol(select.selected).type),
3646                          TreeInfo.symbol(select.selected).type);
3647            }
3648        }
3649    }
3650
3651    // Check that packages imported are in scope (JLS 7.4.3, 6.3, 6.5.3.1, 6.5.3.2)
3652    public void checkImportedPackagesObservable(final JCCompilationUnit toplevel) {
3653        OUTER: for (JCImport imp : toplevel.getImports()) {
3654            if (!imp.staticImport && TreeInfo.name(imp.qualid) == names.asterisk) {
3655                TypeSymbol tsym = ((JCFieldAccess)imp.qualid).selected.type.tsym;
3656                if (toplevel.modle.visiblePackages != null) {
3657                    //TODO - unclear: selects like javax.* will get resolved from the current module
3658                    //(as javax is not an exported package from any module). And as javax in the current
3659                    //module typically does not contain any classes or subpackages, we need to go through
3660                    //the visible packages to find a sub-package:
3661                    for (PackageSymbol known : toplevel.modle.visiblePackages.values()) {
3662                        if (Convert.packagePart(known.fullname) == tsym.flatName())
3663                            continue OUTER;
3664                    }
3665                }
3666                if (tsym.kind == PCK && tsym.members().isEmpty() && !tsym.exists()) {
3667                    log.error(DiagnosticFlag.RESOLVE_ERROR, imp.pos, "doesnt.exist", tsym);
3668                }
3669            }
3670        }
3671    }
3672
3673    private boolean checkTypeContainsImportableElement(TypeSymbol tsym, TypeSymbol origin, PackageSymbol packge, Name name, Set<Symbol> processed) {
3674        if (tsym == null || !processed.add(tsym))
3675            return false;
3676
3677            // also search through inherited names
3678        if (checkTypeContainsImportableElement(types.supertype(tsym.type).tsym, origin, packge, name, processed))
3679            return true;
3680
3681        for (Type t : types.interfaces(tsym.type))
3682            if (checkTypeContainsImportableElement(t.tsym, origin, packge, name, processed))
3683                return true;
3684
3685        for (Symbol sym : tsym.members().getSymbolsByName(name)) {
3686            if (sym.isStatic() &&
3687                importAccessible(sym, packge) &&
3688                sym.isMemberOf(origin, types)) {
3689                return true;
3690            }
3691        }
3692
3693        return false;
3694    }
3695
3696    // is the sym accessible everywhere in packge?
3697    public boolean importAccessible(Symbol sym, PackageSymbol packge) {
3698        try {
3699            int flags = (int)(sym.flags() & AccessFlags);
3700            switch (flags) {
3701            default:
3702            case PUBLIC:
3703                return true;
3704            case PRIVATE:
3705                return false;
3706            case 0:
3707            case PROTECTED:
3708                return sym.packge() == packge;
3709            }
3710        } catch (ClassFinder.BadClassFile err) {
3711            throw err;
3712        } catch (CompletionFailure ex) {
3713            return false;
3714        }
3715    }
3716
3717    public void checkLeaksNotAccessible(Env<AttrContext> env, JCClassDecl check) {
3718        JCCompilationUnit toplevel = env.toplevel;
3719
3720        if (   toplevel.modle == syms.unnamedModule
3721            || toplevel.modle == syms.noModule
3722            || (check.sym.flags() & COMPOUND) != 0) {
3723            return ;
3724        }
3725
3726        ExportsDirective currentExport = findExport(toplevel.packge);
3727
3728        if (   currentExport == null //not exported
3729            || currentExport.modules != null) //don't check classes in qualified export
3730            return ;
3731
3732        new TreeScanner() {
3733            Lint lint = env.info.lint;
3734            boolean inSuperType;
3735
3736            @Override
3737            public void visitBlock(JCBlock tree) {
3738            }
3739            @Override
3740            public void visitMethodDef(JCMethodDecl tree) {
3741                if (!isAPISymbol(tree.sym))
3742                    return;
3743                Lint prevLint = lint;
3744                try {
3745                    lint = lint.augment(tree.sym);
3746                    if (lint.isEnabled(LintCategory.EXPORTS)) {
3747                        super.visitMethodDef(tree);
3748                    }
3749                } finally {
3750                    lint = prevLint;
3751                }
3752            }
3753            @Override
3754            public void visitVarDef(JCVariableDecl tree) {
3755                if (!isAPISymbol(tree.sym) && tree.sym.owner.kind != MTH)
3756                    return;
3757                Lint prevLint = lint;
3758                try {
3759                    lint = lint.augment(tree.sym);
3760                    if (lint.isEnabled(LintCategory.EXPORTS)) {
3761                        scan(tree.mods);
3762                        scan(tree.vartype);
3763                    }
3764                } finally {
3765                    lint = prevLint;
3766                }
3767            }
3768            @Override
3769            public void visitClassDef(JCClassDecl tree) {
3770                if (tree != check)
3771                    return ;
3772
3773                if (!isAPISymbol(tree.sym))
3774                    return ;
3775
3776                Lint prevLint = lint;
3777                try {
3778                    lint = lint.augment(tree.sym);
3779                    if (lint.isEnabled(LintCategory.EXPORTS)) {
3780                        scan(tree.mods);
3781                        scan(tree.typarams);
3782                        try {
3783                            inSuperType = true;
3784                            scan(tree.extending);
3785                            scan(tree.implementing);
3786                        } finally {
3787                            inSuperType = false;
3788                        }
3789                        scan(tree.defs);
3790                    }
3791                } finally {
3792                    lint = prevLint;
3793                }
3794            }
3795            @Override
3796            public void visitTypeApply(JCTypeApply tree) {
3797                scan(tree.clazz);
3798                boolean oldInSuperType = inSuperType;
3799                try {
3800                    inSuperType = false;
3801                    scan(tree.arguments);
3802                } finally {
3803                    inSuperType = oldInSuperType;
3804                }
3805            }
3806            @Override
3807            public void visitIdent(JCIdent tree) {
3808                Symbol sym = TreeInfo.symbol(tree);
3809                if (sym.kind == TYP && !sym.type.hasTag(TYPEVAR)) {
3810                    checkVisible(tree.pos(), sym, toplevel.packge, inSuperType);
3811                }
3812            }
3813
3814            @Override
3815            public void visitSelect(JCFieldAccess tree) {
3816                Symbol sym = TreeInfo.symbol(tree);
3817                Symbol sitesym = TreeInfo.symbol(tree.selected);
3818                if (sym.kind == TYP && sitesym.kind == PCK) {
3819                    checkVisible(tree.pos(), sym, toplevel.packge, inSuperType);
3820                } else {
3821                    super.visitSelect(tree);
3822                }
3823            }
3824
3825            @Override
3826            public void visitAnnotation(JCAnnotation tree) {
3827                if (tree.attribute.type.tsym.getAnnotation(java.lang.annotation.Documented.class) != null)
3828                    super.visitAnnotation(tree);
3829            }
3830
3831        }.scan(check);
3832    }
3833        //where:
3834        private ExportsDirective findExport(PackageSymbol pack) {
3835            for (ExportsDirective d : pack.modle.exports) {
3836                if (d.packge == pack)
3837                    return d;
3838            }
3839
3840            return null;
3841        }
3842        private boolean isAPISymbol(Symbol sym) {
3843            while (sym.kind != PCK) {
3844                if ((sym.flags() & Flags.PUBLIC) == 0 && (sym.flags() & Flags.PROTECTED) == 0) {
3845                    return false;
3846                }
3847                sym = sym.owner;
3848            }
3849            return true;
3850        }
3851        private void checkVisible(DiagnosticPosition pos, Symbol what, PackageSymbol inPackage, boolean inSuperType) {
3852            if (!isAPISymbol(what) && !inSuperType) { //package private/private element
3853                log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessible(kindName(what), what, what.packge().modle));
3854                return ;
3855            }
3856
3857            PackageSymbol whatPackage = what.packge();
3858            ExportsDirective whatExport = findExport(whatPackage);
3859            ExportsDirective inExport = findExport(inPackage);
3860
3861            if (whatExport == null) { //package not exported:
3862                log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessibleUnexported(kindName(what), what, what.packge().modle));
3863                return ;
3864            }
3865
3866            if (whatExport.modules != null) {
3867                if (inExport.modules == null || !whatExport.modules.containsAll(inExport.modules)) {
3868                    log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessibleUnexportedQualified(kindName(what), what, what.packge().modle));
3869                }
3870            }
3871
3872            if (whatPackage.modle != inPackage.modle && whatPackage.modle != syms.java_base) {
3873                //check that relativeTo.modle requires transitive what.modle, somehow:
3874                List<ModuleSymbol> todo = List.of(inPackage.modle);
3875
3876                while (todo.nonEmpty()) {
3877                    ModuleSymbol current = todo.head;
3878                    todo = todo.tail;
3879                    if (current == whatPackage.modle)
3880                        return ; //OK
3881                    for (RequiresDirective req : current.requires) {
3882                        if (req.isTransitive()) {
3883                            todo = todo.prepend(req.module);
3884                        }
3885                    }
3886                }
3887
3888                log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessibleNotRequiredTransitive(kindName(what), what, what.packge().modle));
3889            }
3890        }
3891
3892    void checkModuleExists(final DiagnosticPosition pos, ModuleSymbol msym) {
3893        if (msym.kind != MDL) {
3894            deferredLintHandler.report(() -> {
3895                if (lint.isEnabled(LintCategory.MODULE))
3896                    log.warning(LintCategory.MODULE, pos, Warnings.ModuleNotFound(msym));
3897            });
3898        }
3899    }
3900
3901    void checkPackageExistsForOpens(final DiagnosticPosition pos, PackageSymbol packge) {
3902        if (packge.members().isEmpty() &&
3903            ((packge.flags() & Flags.HAS_RESOURCE) == 0)) {
3904            deferredLintHandler.report(() -> {
3905                if (lint.isEnabled(LintCategory.OPENS))
3906                    log.warning(pos, Warnings.PackageEmptyOrNotFound(packge));
3907            });
3908        }
3909    }
3910
3911}
3912