Check.java revision 3876:9486f3eac5ad
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            String moduleNameString = moduleName.toString();
2111            int nameLength = moduleNameString.length();
2112            if (nameLength > 0 && Character.isDigit(moduleNameString.charAt(nameLength - 1))) {
2113                log.warning(Lint.LintCategory.MODULE, tree.qualId.pos(), Warnings.PoorChoiceForModuleName(moduleName));
2114            }
2115        }
2116    }
2117
2118    private boolean checkNameClash(ClassSymbol origin, Symbol s1, Symbol s2) {
2119        ClashFilter cf = new ClashFilter(origin.type);
2120        return (cf.accepts(s1) &&
2121                cf.accepts(s2) &&
2122                types.hasSameArgs(s1.erasure(types), s2.erasure(types)));
2123    }
2124
2125
2126    /** Check that all abstract members of given class have definitions.
2127     *  @param pos          Position to be used for error reporting.
2128     *  @param c            The class.
2129     */
2130    void checkAllDefined(DiagnosticPosition pos, ClassSymbol c) {
2131        MethodSymbol undef = types.firstUnimplementedAbstract(c);
2132        if (undef != null) {
2133            MethodSymbol undef1 =
2134                new MethodSymbol(undef.flags(), undef.name,
2135                                 types.memberType(c.type, undef), undef.owner);
2136            log.error(pos, "does.not.override.abstract",
2137                      c, undef1, undef1.location());
2138        }
2139    }
2140
2141    void checkNonCyclicDecl(JCClassDecl tree) {
2142        CycleChecker cc = new CycleChecker();
2143        cc.scan(tree);
2144        if (!cc.errorFound && !cc.partialCheck) {
2145            tree.sym.flags_field |= ACYCLIC;
2146        }
2147    }
2148
2149    class CycleChecker extends TreeScanner {
2150
2151        List<Symbol> seenClasses = List.nil();
2152        boolean errorFound = false;
2153        boolean partialCheck = false;
2154
2155        private void checkSymbol(DiagnosticPosition pos, Symbol sym) {
2156            if (sym != null && sym.kind == TYP) {
2157                Env<AttrContext> classEnv = enter.getEnv((TypeSymbol)sym);
2158                if (classEnv != null) {
2159                    DiagnosticSource prevSource = log.currentSource();
2160                    try {
2161                        log.useSource(classEnv.toplevel.sourcefile);
2162                        scan(classEnv.tree);
2163                    }
2164                    finally {
2165                        log.useSource(prevSource.getFile());
2166                    }
2167                } else if (sym.kind == TYP) {
2168                    checkClass(pos, sym, List.nil());
2169                }
2170            } else {
2171                //not completed yet
2172                partialCheck = true;
2173            }
2174        }
2175
2176        @Override
2177        public void visitSelect(JCFieldAccess tree) {
2178            super.visitSelect(tree);
2179            checkSymbol(tree.pos(), tree.sym);
2180        }
2181
2182        @Override
2183        public void visitIdent(JCIdent tree) {
2184            checkSymbol(tree.pos(), tree.sym);
2185        }
2186
2187        @Override
2188        public void visitTypeApply(JCTypeApply tree) {
2189            scan(tree.clazz);
2190        }
2191
2192        @Override
2193        public void visitTypeArray(JCArrayTypeTree tree) {
2194            scan(tree.elemtype);
2195        }
2196
2197        @Override
2198        public void visitClassDef(JCClassDecl tree) {
2199            List<JCTree> supertypes = List.nil();
2200            if (tree.getExtendsClause() != null) {
2201                supertypes = supertypes.prepend(tree.getExtendsClause());
2202            }
2203            if (tree.getImplementsClause() != null) {
2204                for (JCTree intf : tree.getImplementsClause()) {
2205                    supertypes = supertypes.prepend(intf);
2206                }
2207            }
2208            checkClass(tree.pos(), tree.sym, supertypes);
2209        }
2210
2211        void checkClass(DiagnosticPosition pos, Symbol c, List<JCTree> supertypes) {
2212            if ((c.flags_field & ACYCLIC) != 0)
2213                return;
2214            if (seenClasses.contains(c)) {
2215                errorFound = true;
2216                noteCyclic(pos, (ClassSymbol)c);
2217            } else if (!c.type.isErroneous()) {
2218                try {
2219                    seenClasses = seenClasses.prepend(c);
2220                    if (c.type.hasTag(CLASS)) {
2221                        if (supertypes.nonEmpty()) {
2222                            scan(supertypes);
2223                        }
2224                        else {
2225                            ClassType ct = (ClassType)c.type;
2226                            if (ct.supertype_field == null ||
2227                                    ct.interfaces_field == null) {
2228                                //not completed yet
2229                                partialCheck = true;
2230                                return;
2231                            }
2232                            checkSymbol(pos, ct.supertype_field.tsym);
2233                            for (Type intf : ct.interfaces_field) {
2234                                checkSymbol(pos, intf.tsym);
2235                            }
2236                        }
2237                        if (c.owner.kind == TYP) {
2238                            checkSymbol(pos, c.owner);
2239                        }
2240                    }
2241                } finally {
2242                    seenClasses = seenClasses.tail;
2243                }
2244            }
2245        }
2246    }
2247
2248    /** Check for cyclic references. Issue an error if the
2249     *  symbol of the type referred to has a LOCKED flag set.
2250     *
2251     *  @param pos      Position to be used for error reporting.
2252     *  @param t        The type referred to.
2253     */
2254    void checkNonCyclic(DiagnosticPosition pos, Type t) {
2255        checkNonCyclicInternal(pos, t);
2256    }
2257
2258
2259    void checkNonCyclic(DiagnosticPosition pos, TypeVar t) {
2260        checkNonCyclic1(pos, t, List.nil());
2261    }
2262
2263    private void checkNonCyclic1(DiagnosticPosition pos, Type t, List<TypeVar> seen) {
2264        final TypeVar tv;
2265        if  (t.hasTag(TYPEVAR) && (t.tsym.flags() & UNATTRIBUTED) != 0)
2266            return;
2267        if (seen.contains(t)) {
2268            tv = (TypeVar)t;
2269            tv.bound = types.createErrorType(t);
2270            log.error(pos, "cyclic.inheritance", t);
2271        } else if (t.hasTag(TYPEVAR)) {
2272            tv = (TypeVar)t;
2273            seen = seen.prepend(tv);
2274            for (Type b : types.getBounds(tv))
2275                checkNonCyclic1(pos, b, seen);
2276        }
2277    }
2278
2279    /** Check for cyclic references. Issue an error if the
2280     *  symbol of the type referred to has a LOCKED flag set.
2281     *
2282     *  @param pos      Position to be used for error reporting.
2283     *  @param t        The type referred to.
2284     *  @returns        True if the check completed on all attributed classes
2285     */
2286    private boolean checkNonCyclicInternal(DiagnosticPosition pos, Type t) {
2287        boolean complete = true; // was the check complete?
2288        //- System.err.println("checkNonCyclicInternal("+t+");");//DEBUG
2289        Symbol c = t.tsym;
2290        if ((c.flags_field & ACYCLIC) != 0) return true;
2291
2292        if ((c.flags_field & LOCKED) != 0) {
2293            noteCyclic(pos, (ClassSymbol)c);
2294        } else if (!c.type.isErroneous()) {
2295            try {
2296                c.flags_field |= LOCKED;
2297                if (c.type.hasTag(CLASS)) {
2298                    ClassType clazz = (ClassType)c.type;
2299                    if (clazz.interfaces_field != null)
2300                        for (List<Type> l=clazz.interfaces_field; l.nonEmpty(); l=l.tail)
2301                            complete &= checkNonCyclicInternal(pos, l.head);
2302                    if (clazz.supertype_field != null) {
2303                        Type st = clazz.supertype_field;
2304                        if (st != null && st.hasTag(CLASS))
2305                            complete &= checkNonCyclicInternal(pos, st);
2306                    }
2307                    if (c.owner.kind == TYP)
2308                        complete &= checkNonCyclicInternal(pos, c.owner.type);
2309                }
2310            } finally {
2311                c.flags_field &= ~LOCKED;
2312            }
2313        }
2314        if (complete)
2315            complete = ((c.flags_field & UNATTRIBUTED) == 0) && c.isCompleted();
2316        if (complete) c.flags_field |= ACYCLIC;
2317        return complete;
2318    }
2319
2320    /** Note that we found an inheritance cycle. */
2321    private void noteCyclic(DiagnosticPosition pos, ClassSymbol c) {
2322        log.error(pos, "cyclic.inheritance", c);
2323        for (List<Type> l=types.interfaces(c.type); l.nonEmpty(); l=l.tail)
2324            l.head = types.createErrorType((ClassSymbol)l.head.tsym, Type.noType);
2325        Type st = types.supertype(c.type);
2326        if (st.hasTag(CLASS))
2327            ((ClassType)c.type).supertype_field = types.createErrorType((ClassSymbol)st.tsym, Type.noType);
2328        c.type = types.createErrorType(c, c.type);
2329        c.flags_field |= ACYCLIC;
2330    }
2331
2332    /** Check that all methods which implement some
2333     *  method conform to the method they implement.
2334     *  @param tree         The class definition whose members are checked.
2335     */
2336    void checkImplementations(JCClassDecl tree) {
2337        checkImplementations(tree, tree.sym, tree.sym);
2338    }
2339    //where
2340        /** Check that all methods which implement some
2341         *  method in `ic' conform to the method they implement.
2342         */
2343        void checkImplementations(JCTree tree, ClassSymbol origin, ClassSymbol ic) {
2344            for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) {
2345                ClassSymbol lc = (ClassSymbol)l.head.tsym;
2346                if ((lc.flags() & ABSTRACT) != 0) {
2347                    for (Symbol sym : lc.members().getSymbols(NON_RECURSIVE)) {
2348                        if (sym.kind == MTH &&
2349                            (sym.flags() & (STATIC|ABSTRACT)) == ABSTRACT) {
2350                            MethodSymbol absmeth = (MethodSymbol)sym;
2351                            MethodSymbol implmeth = absmeth.implementation(origin, types, false);
2352                            if (implmeth != null && implmeth != absmeth &&
2353                                (implmeth.owner.flags() & INTERFACE) ==
2354                                (origin.flags() & INTERFACE)) {
2355                                // don't check if implmeth is in a class, yet
2356                                // origin is an interface. This case arises only
2357                                // if implmeth is declared in Object. The reason is
2358                                // that interfaces really don't inherit from
2359                                // Object it's just that the compiler represents
2360                                // things that way.
2361                                checkOverride(tree, implmeth, absmeth, origin);
2362                            }
2363                        }
2364                    }
2365                }
2366            }
2367        }
2368
2369    /** Check that all abstract methods implemented by a class are
2370     *  mutually compatible.
2371     *  @param pos          Position to be used for error reporting.
2372     *  @param c            The class whose interfaces are checked.
2373     */
2374    void checkCompatibleSupertypes(DiagnosticPosition pos, Type c) {
2375        List<Type> supertypes = types.interfaces(c);
2376        Type supertype = types.supertype(c);
2377        if (supertype.hasTag(CLASS) &&
2378            (supertype.tsym.flags() & ABSTRACT) != 0)
2379            supertypes = supertypes.prepend(supertype);
2380        for (List<Type> l = supertypes; l.nonEmpty(); l = l.tail) {
2381            if (!l.head.getTypeArguments().isEmpty() &&
2382                !checkCompatibleAbstracts(pos, l.head, l.head, c))
2383                return;
2384            for (List<Type> m = supertypes; m != l; m = m.tail)
2385                if (!checkCompatibleAbstracts(pos, l.head, m.head, c))
2386                    return;
2387        }
2388        checkCompatibleConcretes(pos, c);
2389    }
2390
2391    void checkConflicts(DiagnosticPosition pos, Symbol sym, TypeSymbol c) {
2392        for (Type ct = c.type; ct != Type.noType ; ct = types.supertype(ct)) {
2393            for (Symbol sym2 : ct.tsym.members().getSymbolsByName(sym.name, NON_RECURSIVE)) {
2394                // VM allows methods and variables with differing types
2395                if (sym.kind == sym2.kind &&
2396                    types.isSameType(types.erasure(sym.type), types.erasure(sym2.type)) &&
2397                    sym != sym2 &&
2398                    (sym.flags() & Flags.SYNTHETIC) != (sym2.flags() & Flags.SYNTHETIC) &&
2399                    (sym.flags() & BRIDGE) == 0 && (sym2.flags() & BRIDGE) == 0) {
2400                    syntheticError(pos, (sym2.flags() & SYNTHETIC) == 0 ? sym2 : sym);
2401                    return;
2402                }
2403            }
2404        }
2405    }
2406
2407    /** Check that all non-override equivalent methods accessible from 'site'
2408     *  are mutually compatible (JLS 8.4.8/9.4.1).
2409     *
2410     *  @param pos  Position to be used for error reporting.
2411     *  @param site The class whose methods are checked.
2412     *  @param sym  The method symbol to be checked.
2413     */
2414    void checkOverrideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
2415         ClashFilter cf = new ClashFilter(site);
2416        //for each method m1 that is overridden (directly or indirectly)
2417        //by method 'sym' in 'site'...
2418
2419        List<MethodSymbol> potentiallyAmbiguousList = List.nil();
2420        boolean overridesAny = false;
2421        for (Symbol m1 : types.membersClosure(site, false).getSymbolsByName(sym.name, cf)) {
2422            if (!sym.overrides(m1, site.tsym, types, false)) {
2423                if (m1 == sym) {
2424                    continue;
2425                }
2426
2427                if (!overridesAny) {
2428                    potentiallyAmbiguousList = potentiallyAmbiguousList.prepend((MethodSymbol)m1);
2429                }
2430                continue;
2431            }
2432
2433            if (m1 != sym) {
2434                overridesAny = true;
2435                potentiallyAmbiguousList = List.nil();
2436            }
2437
2438            //...check each method m2 that is a member of 'site'
2439            for (Symbol m2 : types.membersClosure(site, false).getSymbolsByName(sym.name, cf)) {
2440                if (m2 == m1) continue;
2441                //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
2442                //a member of 'site') and (ii) m1 has the same erasure as m2, issue an error
2443                if (!types.isSubSignature(sym.type, types.memberType(site, m2), allowStrictMethodClashCheck) &&
2444                        types.hasSameArgs(m2.erasure(types), m1.erasure(types))) {
2445                    sym.flags_field |= CLASH;
2446                    String key = m1 == sym ?
2447                            "name.clash.same.erasure.no.override" :
2448                            "name.clash.same.erasure.no.override.1";
2449                    log.error(pos,
2450                            key,
2451                            sym, sym.location(),
2452                            m2, m2.location(),
2453                            m1, m1.location());
2454                    return;
2455                }
2456            }
2457        }
2458
2459        if (!overridesAny) {
2460            for (MethodSymbol m: potentiallyAmbiguousList) {
2461                checkPotentiallyAmbiguousOverloads(pos, site, sym, m);
2462            }
2463        }
2464    }
2465
2466    /** Check that all static methods accessible from 'site' are
2467     *  mutually compatible (JLS 8.4.8).
2468     *
2469     *  @param pos  Position to be used for error reporting.
2470     *  @param site The class whose methods are checked.
2471     *  @param sym  The method symbol to be checked.
2472     */
2473    void checkHideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
2474        ClashFilter cf = new ClashFilter(site);
2475        //for each method m1 that is a member of 'site'...
2476        for (Symbol s : types.membersClosure(site, true).getSymbolsByName(sym.name, cf)) {
2477            //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
2478            //a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error
2479            if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck)) {
2480                if (types.hasSameArgs(s.erasure(types), sym.erasure(types))) {
2481                    log.error(pos,
2482                            "name.clash.same.erasure.no.hide",
2483                            sym, sym.location(),
2484                            s, s.location());
2485                    return;
2486                } else {
2487                    checkPotentiallyAmbiguousOverloads(pos, site, sym, (MethodSymbol)s);
2488                }
2489            }
2490         }
2491     }
2492
2493     //where
2494     private class ClashFilter implements Filter<Symbol> {
2495
2496         Type site;
2497
2498         ClashFilter(Type site) {
2499             this.site = site;
2500         }
2501
2502         boolean shouldSkip(Symbol s) {
2503             return (s.flags() & CLASH) != 0 &&
2504                s.owner == site.tsym;
2505         }
2506
2507         public boolean accepts(Symbol s) {
2508             return s.kind == MTH &&
2509                     (s.flags() & SYNTHETIC) == 0 &&
2510                     !shouldSkip(s) &&
2511                     s.isInheritedIn(site.tsym, types) &&
2512                     !s.isConstructor();
2513         }
2514     }
2515
2516    void checkDefaultMethodClashes(DiagnosticPosition pos, Type site) {
2517        DefaultMethodClashFilter dcf = new DefaultMethodClashFilter(site);
2518        for (Symbol m : types.membersClosure(site, false).getSymbols(dcf)) {
2519            Assert.check(m.kind == MTH);
2520            List<MethodSymbol> prov = types.interfaceCandidates(site, (MethodSymbol)m);
2521            if (prov.size() > 1) {
2522                ListBuffer<Symbol> abstracts = new ListBuffer<>();
2523                ListBuffer<Symbol> defaults = new ListBuffer<>();
2524                for (MethodSymbol provSym : prov) {
2525                    if ((provSym.flags() & DEFAULT) != 0) {
2526                        defaults = defaults.append(provSym);
2527                    } else if ((provSym.flags() & ABSTRACT) != 0) {
2528                        abstracts = abstracts.append(provSym);
2529                    }
2530                    if (defaults.nonEmpty() && defaults.size() + abstracts.size() >= 2) {
2531                        //strong semantics - issue an error if two sibling interfaces
2532                        //have two override-equivalent defaults - or if one is abstract
2533                        //and the other is default
2534                        String errKey;
2535                        Symbol s1 = defaults.first();
2536                        Symbol s2;
2537                        if (defaults.size() > 1) {
2538                            errKey = "types.incompatible.unrelated.defaults";
2539                            s2 = defaults.toList().tail.head;
2540                        } else {
2541                            errKey = "types.incompatible.abstract.default";
2542                            s2 = abstracts.first();
2543                        }
2544                        log.error(pos, errKey,
2545                                Kinds.kindName(site.tsym), site,
2546                                m.name, types.memberType(site, m).getParameterTypes(),
2547                                s1.location(), s2.location());
2548                        break;
2549                    }
2550                }
2551            }
2552        }
2553    }
2554
2555    //where
2556     private class DefaultMethodClashFilter implements Filter<Symbol> {
2557
2558         Type site;
2559
2560         DefaultMethodClashFilter(Type site) {
2561             this.site = site;
2562         }
2563
2564         public boolean accepts(Symbol s) {
2565             return s.kind == MTH &&
2566                     (s.flags() & DEFAULT) != 0 &&
2567                     s.isInheritedIn(site.tsym, types) &&
2568                     !s.isConstructor();
2569         }
2570     }
2571
2572    /**
2573      * Report warnings for potentially ambiguous method declarations. Two declarations
2574      * are potentially ambiguous if they feature two unrelated functional interface
2575      * in same argument position (in which case, a call site passing an implicit
2576      * lambda would be ambiguous).
2577      */
2578    void checkPotentiallyAmbiguousOverloads(DiagnosticPosition pos, Type site,
2579            MethodSymbol msym1, MethodSymbol msym2) {
2580        if (msym1 != msym2 &&
2581                allowDefaultMethods &&
2582                lint.isEnabled(LintCategory.OVERLOADS) &&
2583                (msym1.flags() & POTENTIALLY_AMBIGUOUS) == 0 &&
2584                (msym2.flags() & POTENTIALLY_AMBIGUOUS) == 0) {
2585            Type mt1 = types.memberType(site, msym1);
2586            Type mt2 = types.memberType(site, msym2);
2587            //if both generic methods, adjust type variables
2588            if (mt1.hasTag(FORALL) && mt2.hasTag(FORALL) &&
2589                    types.hasSameBounds((ForAll)mt1, (ForAll)mt2)) {
2590                mt2 = types.subst(mt2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars);
2591            }
2592            //expand varargs methods if needed
2593            int maxLength = Math.max(mt1.getParameterTypes().length(), mt2.getParameterTypes().length());
2594            List<Type> args1 = rs.adjustArgs(mt1.getParameterTypes(), msym1, maxLength, true);
2595            List<Type> args2 = rs.adjustArgs(mt2.getParameterTypes(), msym2, maxLength, true);
2596            //if arities don't match, exit
2597            if (args1.length() != args2.length()) return;
2598            boolean potentiallyAmbiguous = false;
2599            while (args1.nonEmpty() && args2.nonEmpty()) {
2600                Type s = args1.head;
2601                Type t = args2.head;
2602                if (!types.isSubtype(t, s) && !types.isSubtype(s, t)) {
2603                    if (types.isFunctionalInterface(s) && types.isFunctionalInterface(t) &&
2604                            types.findDescriptorType(s).getParameterTypes().length() > 0 &&
2605                            types.findDescriptorType(s).getParameterTypes().length() ==
2606                            types.findDescriptorType(t).getParameterTypes().length()) {
2607                        potentiallyAmbiguous = true;
2608                    } else {
2609                        break;
2610                    }
2611                }
2612                args1 = args1.tail;
2613                args2 = args2.tail;
2614            }
2615            if (potentiallyAmbiguous) {
2616                //we found two incompatible functional interfaces with same arity
2617                //this means a call site passing an implicit lambda would be ambigiuous
2618                msym1.flags_field |= POTENTIALLY_AMBIGUOUS;
2619                msym2.flags_field |= POTENTIALLY_AMBIGUOUS;
2620                log.warning(LintCategory.OVERLOADS, pos, "potentially.ambiguous.overload",
2621                            msym1, msym1.location(),
2622                            msym2, msym2.location());
2623                return;
2624            }
2625        }
2626    }
2627
2628    void checkAccessFromSerializableElement(final JCTree tree, boolean isLambda) {
2629        if (warnOnAnyAccessToMembers ||
2630            (lint.isEnabled(LintCategory.SERIAL) &&
2631            !lint.isSuppressed(LintCategory.SERIAL) &&
2632            isLambda)) {
2633            Symbol sym = TreeInfo.symbol(tree);
2634            if (!sym.kind.matches(KindSelector.VAL_MTH)) {
2635                return;
2636            }
2637
2638            if (sym.kind == VAR) {
2639                if ((sym.flags() & PARAMETER) != 0 ||
2640                    sym.isLocal() ||
2641                    sym.name == names._this ||
2642                    sym.name == names._super) {
2643                    return;
2644                }
2645            }
2646
2647            if (!types.isSubtype(sym.owner.type, syms.serializableType) &&
2648                isEffectivelyNonPublic(sym)) {
2649                if (isLambda) {
2650                    if (belongsToRestrictedPackage(sym)) {
2651                        log.warning(LintCategory.SERIAL, tree.pos(),
2652                            "access.to.member.from.serializable.lambda", sym);
2653                    }
2654                } else {
2655                    log.warning(tree.pos(),
2656                        "access.to.member.from.serializable.element", sym);
2657                }
2658            }
2659        }
2660    }
2661
2662    private boolean isEffectivelyNonPublic(Symbol sym) {
2663        if (sym.packge() == syms.rootPackage) {
2664            return false;
2665        }
2666
2667        while (sym.kind != PCK) {
2668            if ((sym.flags() & PUBLIC) == 0) {
2669                return true;
2670            }
2671            sym = sym.owner;
2672        }
2673        return false;
2674    }
2675
2676    private boolean belongsToRestrictedPackage(Symbol sym) {
2677        String fullName = sym.packge().fullname.toString();
2678        return fullName.startsWith("java.") ||
2679                fullName.startsWith("javax.") ||
2680                fullName.startsWith("sun.") ||
2681                fullName.contains(".internal.");
2682    }
2683
2684    /** Report a conflict between a user symbol and a synthetic symbol.
2685     */
2686    private void syntheticError(DiagnosticPosition pos, Symbol sym) {
2687        if (!sym.type.isErroneous()) {
2688            log.error(pos, "synthetic.name.conflict", sym, sym.location());
2689        }
2690    }
2691
2692    /** Check that class c does not implement directly or indirectly
2693     *  the same parameterized interface with two different argument lists.
2694     *  @param pos          Position to be used for error reporting.
2695     *  @param type         The type whose interfaces are checked.
2696     */
2697    void checkClassBounds(DiagnosticPosition pos, Type type) {
2698        checkClassBounds(pos, new HashMap<TypeSymbol,Type>(), type);
2699    }
2700//where
2701        /** Enter all interfaces of type `type' into the hash table `seensofar'
2702         *  with their class symbol as key and their type as value. Make
2703         *  sure no class is entered with two different types.
2704         */
2705        void checkClassBounds(DiagnosticPosition pos,
2706                              Map<TypeSymbol,Type> seensofar,
2707                              Type type) {
2708            if (type.isErroneous()) return;
2709            for (List<Type> l = types.interfaces(type); l.nonEmpty(); l = l.tail) {
2710                Type it = l.head;
2711                Type oldit = seensofar.put(it.tsym, it);
2712                if (oldit != null) {
2713                    List<Type> oldparams = oldit.allparams();
2714                    List<Type> newparams = it.allparams();
2715                    if (!types.containsTypeEquivalent(oldparams, newparams))
2716                        log.error(pos, "cant.inherit.diff.arg",
2717                                  it.tsym, Type.toString(oldparams),
2718                                  Type.toString(newparams));
2719                }
2720                checkClassBounds(pos, seensofar, it);
2721            }
2722            Type st = types.supertype(type);
2723            if (st != Type.noType) checkClassBounds(pos, seensofar, st);
2724        }
2725
2726    /** Enter interface into into set.
2727     *  If it existed already, issue a "repeated interface" error.
2728     */
2729    void checkNotRepeated(DiagnosticPosition pos, Type it, Set<Type> its) {
2730        if (its.contains(it))
2731            log.error(pos, "repeated.interface");
2732        else {
2733            its.add(it);
2734        }
2735    }
2736
2737/* *************************************************************************
2738 * Check annotations
2739 **************************************************************************/
2740
2741    /**
2742     * Recursively validate annotations values
2743     */
2744    void validateAnnotationTree(JCTree tree) {
2745        class AnnotationValidator extends TreeScanner {
2746            @Override
2747            public void visitAnnotation(JCAnnotation tree) {
2748                if (!tree.type.isErroneous()) {
2749                    super.visitAnnotation(tree);
2750                    validateAnnotation(tree);
2751                }
2752            }
2753        }
2754        tree.accept(new AnnotationValidator());
2755    }
2756
2757    /**
2758     *  {@literal
2759     *  Annotation types are restricted to primitives, String, an
2760     *  enum, an annotation, Class, Class<?>, Class<? extends
2761     *  Anything>, arrays of the preceding.
2762     *  }
2763     */
2764    void validateAnnotationType(JCTree restype) {
2765        // restype may be null if an error occurred, so don't bother validating it
2766        if (restype != null) {
2767            validateAnnotationType(restype.pos(), restype.type);
2768        }
2769    }
2770
2771    void validateAnnotationType(DiagnosticPosition pos, Type type) {
2772        if (type.isPrimitive()) return;
2773        if (types.isSameType(type, syms.stringType)) return;
2774        if ((type.tsym.flags() & Flags.ENUM) != 0) return;
2775        if ((type.tsym.flags() & Flags.ANNOTATION) != 0) return;
2776        if (types.cvarLowerBound(type).tsym == syms.classType.tsym) return;
2777        if (types.isArray(type) && !types.isArray(types.elemtype(type))) {
2778            validateAnnotationType(pos, types.elemtype(type));
2779            return;
2780        }
2781        log.error(pos, "invalid.annotation.member.type");
2782    }
2783
2784    /**
2785     * "It is also a compile-time error if any method declared in an
2786     * annotation type has a signature that is override-equivalent to
2787     * that of any public or protected method declared in class Object
2788     * or in the interface annotation.Annotation."
2789     *
2790     * @jls 9.6 Annotation Types
2791     */
2792    void validateAnnotationMethod(DiagnosticPosition pos, MethodSymbol m) {
2793        for (Type sup = syms.annotationType; sup.hasTag(CLASS); sup = types.supertype(sup)) {
2794            Scope s = sup.tsym.members();
2795            for (Symbol sym : s.getSymbolsByName(m.name)) {
2796                if (sym.kind == MTH &&
2797                    (sym.flags() & (PUBLIC | PROTECTED)) != 0 &&
2798                    types.overrideEquivalent(m.type, sym.type))
2799                    log.error(pos, "intf.annotation.member.clash", sym, sup);
2800            }
2801        }
2802    }
2803
2804    /** Check the annotations of a symbol.
2805     */
2806    public void validateAnnotations(List<JCAnnotation> annotations, Symbol s) {
2807        for (JCAnnotation a : annotations)
2808            validateAnnotation(a, s);
2809    }
2810
2811    /** Check the type annotations.
2812     */
2813    public void validateTypeAnnotations(List<JCAnnotation> annotations, boolean isTypeParameter) {
2814        for (JCAnnotation a : annotations)
2815            validateTypeAnnotation(a, isTypeParameter);
2816    }
2817
2818    /** Check an annotation of a symbol.
2819     */
2820    private void validateAnnotation(JCAnnotation a, Symbol s) {
2821        validateAnnotationTree(a);
2822
2823        if (!annotationApplicable(a, s))
2824            log.error(a.pos(), "annotation.type.not.applicable");
2825
2826        if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) {
2827            if (s.kind != TYP) {
2828                log.error(a.pos(), "bad.functional.intf.anno");
2829            } else if (!s.isInterface() || (s.flags() & ANNOTATION) != 0) {
2830                log.error(a.pos(), "bad.functional.intf.anno.1", diags.fragment("not.a.functional.intf", s));
2831            }
2832        }
2833    }
2834
2835    public void validateTypeAnnotation(JCAnnotation a, boolean isTypeParameter) {
2836        Assert.checkNonNull(a.type);
2837        validateAnnotationTree(a);
2838
2839        if (a.hasTag(TYPE_ANNOTATION) &&
2840                !a.annotationType.type.isErroneous() &&
2841                !isTypeAnnotation(a, isTypeParameter)) {
2842            log.error(a.pos(), Errors.AnnotationTypeNotApplicableToType(a.type));
2843        }
2844    }
2845
2846    /**
2847     * Validate the proposed container 'repeatable' on the
2848     * annotation type symbol 's'. Report errors at position
2849     * 'pos'.
2850     *
2851     * @param s The (annotation)type declaration annotated with a @Repeatable
2852     * @param repeatable the @Repeatable on 's'
2853     * @param pos where to report errors
2854     */
2855    public void validateRepeatable(TypeSymbol s, Attribute.Compound repeatable, DiagnosticPosition pos) {
2856        Assert.check(types.isSameType(repeatable.type, syms.repeatableType));
2857
2858        Type t = null;
2859        List<Pair<MethodSymbol,Attribute>> l = repeatable.values;
2860        if (!l.isEmpty()) {
2861            Assert.check(l.head.fst.name == names.value);
2862            t = ((Attribute.Class)l.head.snd).getValue();
2863        }
2864
2865        if (t == null) {
2866            // errors should already have been reported during Annotate
2867            return;
2868        }
2869
2870        validateValue(t.tsym, s, pos);
2871        validateRetention(t.tsym, s, pos);
2872        validateDocumented(t.tsym, s, pos);
2873        validateInherited(t.tsym, s, pos);
2874        validateTarget(t.tsym, s, pos);
2875        validateDefault(t.tsym, pos);
2876    }
2877
2878    private void validateValue(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
2879        Symbol sym = container.members().findFirst(names.value);
2880        if (sym != null && sym.kind == MTH) {
2881            MethodSymbol m = (MethodSymbol) sym;
2882            Type ret = m.getReturnType();
2883            if (!(ret.hasTag(ARRAY) && types.isSameType(((ArrayType)ret).elemtype, contained.type))) {
2884                log.error(pos, "invalid.repeatable.annotation.value.return",
2885                        container, ret, types.makeArrayType(contained.type));
2886            }
2887        } else {
2888            log.error(pos, "invalid.repeatable.annotation.no.value", container);
2889        }
2890    }
2891
2892    private void validateRetention(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
2893        Attribute.RetentionPolicy containerRetention = types.getRetention(container);
2894        Attribute.RetentionPolicy containedRetention = types.getRetention(contained);
2895
2896        boolean error = false;
2897        switch (containedRetention) {
2898        case RUNTIME:
2899            if (containerRetention != Attribute.RetentionPolicy.RUNTIME) {
2900                error = true;
2901            }
2902            break;
2903        case CLASS:
2904            if (containerRetention == Attribute.RetentionPolicy.SOURCE)  {
2905                error = true;
2906            }
2907        }
2908        if (error ) {
2909            log.error(pos, "invalid.repeatable.annotation.retention",
2910                      container, containerRetention,
2911                      contained, containedRetention);
2912        }
2913    }
2914
2915    private void validateDocumented(Symbol container, Symbol contained, DiagnosticPosition pos) {
2916        if (contained.attribute(syms.documentedType.tsym) != null) {
2917            if (container.attribute(syms.documentedType.tsym) == null) {
2918                log.error(pos, "invalid.repeatable.annotation.not.documented", container, contained);
2919            }
2920        }
2921    }
2922
2923    private void validateInherited(Symbol container, Symbol contained, DiagnosticPosition pos) {
2924        if (contained.attribute(syms.inheritedType.tsym) != null) {
2925            if (container.attribute(syms.inheritedType.tsym) == null) {
2926                log.error(pos, "invalid.repeatable.annotation.not.inherited", container, contained);
2927            }
2928        }
2929    }
2930
2931    private void validateTarget(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
2932        // The set of targets the container is applicable to must be a subset
2933        // (with respect to annotation target semantics) of the set of targets
2934        // the contained is applicable to. The target sets may be implicit or
2935        // explicit.
2936
2937        Set<Name> containerTargets;
2938        Attribute.Array containerTarget = getAttributeTargetAttribute(container);
2939        if (containerTarget == null) {
2940            containerTargets = getDefaultTargetSet();
2941        } else {
2942            containerTargets = new HashSet<>();
2943            for (Attribute app : containerTarget.values) {
2944                if (!(app instanceof Attribute.Enum)) {
2945                    continue; // recovery
2946                }
2947                Attribute.Enum e = (Attribute.Enum)app;
2948                containerTargets.add(e.value.name);
2949            }
2950        }
2951
2952        Set<Name> containedTargets;
2953        Attribute.Array containedTarget = getAttributeTargetAttribute(contained);
2954        if (containedTarget == null) {
2955            containedTargets = getDefaultTargetSet();
2956        } else {
2957            containedTargets = new HashSet<>();
2958            for (Attribute app : containedTarget.values) {
2959                if (!(app instanceof Attribute.Enum)) {
2960                    continue; // recovery
2961                }
2962                Attribute.Enum e = (Attribute.Enum)app;
2963                containedTargets.add(e.value.name);
2964            }
2965        }
2966
2967        if (!isTargetSubsetOf(containerTargets, containedTargets)) {
2968            log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained);
2969        }
2970    }
2971
2972    /* get a set of names for the default target */
2973    private Set<Name> getDefaultTargetSet() {
2974        if (defaultTargets == null) {
2975            Set<Name> targets = new HashSet<>();
2976            targets.add(names.ANNOTATION_TYPE);
2977            targets.add(names.CONSTRUCTOR);
2978            targets.add(names.FIELD);
2979            targets.add(names.LOCAL_VARIABLE);
2980            targets.add(names.METHOD);
2981            targets.add(names.PACKAGE);
2982            targets.add(names.PARAMETER);
2983            targets.add(names.TYPE);
2984
2985            defaultTargets = java.util.Collections.unmodifiableSet(targets);
2986        }
2987
2988        return defaultTargets;
2989    }
2990    private Set<Name> defaultTargets;
2991
2992
2993    /** Checks that s is a subset of t, with respect to ElementType
2994     * semantics, specifically {ANNOTATION_TYPE} is a subset of {TYPE},
2995     * and {TYPE_USE} covers the set {ANNOTATION_TYPE, TYPE, TYPE_USE,
2996     * TYPE_PARAMETER}.
2997     */
2998    private boolean isTargetSubsetOf(Set<Name> s, Set<Name> t) {
2999        // Check that all elements in s are present in t
3000        for (Name n2 : s) {
3001            boolean currentElementOk = false;
3002            for (Name n1 : t) {
3003                if (n1 == n2) {
3004                    currentElementOk = true;
3005                    break;
3006                } else if (n1 == names.TYPE && n2 == names.ANNOTATION_TYPE) {
3007                    currentElementOk = true;
3008                    break;
3009                } else if (n1 == names.TYPE_USE &&
3010                        (n2 == names.TYPE ||
3011                         n2 == names.ANNOTATION_TYPE ||
3012                         n2 == names.TYPE_PARAMETER)) {
3013                    currentElementOk = true;
3014                    break;
3015                }
3016            }
3017            if (!currentElementOk)
3018                return false;
3019        }
3020        return true;
3021    }
3022
3023    private void validateDefault(Symbol container, DiagnosticPosition pos) {
3024        // validate that all other elements of containing type has defaults
3025        Scope scope = container.members();
3026        for(Symbol elm : scope.getSymbols()) {
3027            if (elm.name != names.value &&
3028                elm.kind == MTH &&
3029                ((MethodSymbol)elm).defaultValue == null) {
3030                log.error(pos,
3031                          "invalid.repeatable.annotation.elem.nondefault",
3032                          container,
3033                          elm);
3034            }
3035        }
3036    }
3037
3038    /** Is s a method symbol that overrides a method in a superclass? */
3039    boolean isOverrider(Symbol s) {
3040        if (s.kind != MTH || s.isStatic())
3041            return false;
3042        MethodSymbol m = (MethodSymbol)s;
3043        TypeSymbol owner = (TypeSymbol)m.owner;
3044        for (Type sup : types.closure(owner.type)) {
3045            if (sup == owner.type)
3046                continue; // skip "this"
3047            Scope scope = sup.tsym.members();
3048            for (Symbol sym : scope.getSymbolsByName(m.name)) {
3049                if (!sym.isStatic() && m.overrides(sym, owner, types, true))
3050                    return true;
3051            }
3052        }
3053        return false;
3054    }
3055
3056    /** Is the annotation applicable to types? */
3057    protected boolean isTypeAnnotation(JCAnnotation a, boolean isTypeParameter) {
3058        List<Attribute> targets = typeAnnotations.annotationTargets(a.annotationType.type.tsym);
3059        return (targets == null) ?
3060                false :
3061                targets.stream()
3062                        .anyMatch(attr -> isTypeAnnotation(attr, isTypeParameter));
3063    }
3064    //where
3065        boolean isTypeAnnotation(Attribute a, boolean isTypeParameter) {
3066            Attribute.Enum e = (Attribute.Enum)a;
3067            return (e.value.name == names.TYPE_USE ||
3068                    (isTypeParameter && e.value.name == names.TYPE_PARAMETER));
3069        }
3070
3071    /** Is the annotation applicable to the symbol? */
3072    boolean annotationApplicable(JCAnnotation a, Symbol s) {
3073        Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym);
3074        Name[] targets;
3075
3076        if (arr == null) {
3077            targets = defaultTargetMetaInfo(a, s);
3078        } else {
3079            // TODO: can we optimize this?
3080            targets = new Name[arr.values.length];
3081            for (int i=0; i<arr.values.length; ++i) {
3082                Attribute app = arr.values[i];
3083                if (!(app instanceof Attribute.Enum)) {
3084                    return true; // recovery
3085                }
3086                Attribute.Enum e = (Attribute.Enum) app;
3087                targets[i] = e.value.name;
3088            }
3089        }
3090        for (Name target : targets) {
3091            if (target == names.TYPE) {
3092                if (s.kind == TYP)
3093                    return true;
3094            } else if (target == names.FIELD) {
3095                if (s.kind == VAR && s.owner.kind != MTH)
3096                    return true;
3097            } else if (target == names.METHOD) {
3098                if (s.kind == MTH && !s.isConstructor())
3099                    return true;
3100            } else if (target == names.PARAMETER) {
3101                if (s.kind == VAR && s.owner.kind == MTH &&
3102                      (s.flags() & PARAMETER) != 0) {
3103                    return true;
3104                }
3105            } else if (target == names.CONSTRUCTOR) {
3106                if (s.kind == MTH && s.isConstructor())
3107                    return true;
3108            } else if (target == names.LOCAL_VARIABLE) {
3109                if (s.kind == VAR && s.owner.kind == MTH &&
3110                      (s.flags() & PARAMETER) == 0) {
3111                    return true;
3112                }
3113            } else if (target == names.ANNOTATION_TYPE) {
3114                if (s.kind == TYP && (s.flags() & ANNOTATION) != 0) {
3115                    return true;
3116                }
3117            } else if (target == names.PACKAGE) {
3118                if (s.kind == PCK)
3119                    return true;
3120            } else if (target == names.TYPE_USE) {
3121                if (s.kind == TYP || s.kind == VAR ||
3122                        (s.kind == MTH && !s.isConstructor() &&
3123                                !s.type.getReturnType().hasTag(VOID)) ||
3124                        (s.kind == MTH && s.isConstructor())) {
3125                    return true;
3126                }
3127            } else if (target == names.TYPE_PARAMETER) {
3128                if (s.kind == TYP && s.type.hasTag(TYPEVAR))
3129                    return true;
3130            } else
3131                return true; // Unknown ElementType. This should be an error at declaration site,
3132                             // assume applicable.
3133        }
3134        return false;
3135    }
3136
3137
3138    Attribute.Array getAttributeTargetAttribute(TypeSymbol s) {
3139        Attribute.Compound atTarget = s.getAnnotationTypeMetadata().getTarget();
3140        if (atTarget == null) return null; // ok, is applicable
3141        Attribute atValue = atTarget.member(names.value);
3142        if (!(atValue instanceof Attribute.Array)) return null; // error recovery
3143        return (Attribute.Array) atValue;
3144    }
3145
3146    private final Name[] dfltTargetMeta;
3147    private Name[] defaultTargetMetaInfo(JCAnnotation a, Symbol s) {
3148        return dfltTargetMeta;
3149    }
3150
3151    /** Check an annotation value.
3152     *
3153     * @param a The annotation tree to check
3154     * @return true if this annotation tree is valid, otherwise false
3155     */
3156    public boolean validateAnnotationDeferErrors(JCAnnotation a) {
3157        boolean res = false;
3158        final Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
3159        try {
3160            res = validateAnnotation(a);
3161        } finally {
3162            log.popDiagnosticHandler(diagHandler);
3163        }
3164        return res;
3165    }
3166
3167    private boolean validateAnnotation(JCAnnotation a) {
3168        boolean isValid = true;
3169        AnnotationTypeMetadata metadata = a.annotationType.type.tsym.getAnnotationTypeMetadata();
3170
3171        // collect an inventory of the annotation elements
3172        Set<MethodSymbol> elements = metadata.getAnnotationElements();
3173
3174        // remove the ones that are assigned values
3175        for (JCTree arg : a.args) {
3176            if (!arg.hasTag(ASSIGN)) continue; // recovery
3177            JCAssign assign = (JCAssign)arg;
3178            Symbol m = TreeInfo.symbol(assign.lhs);
3179            if (m == null || m.type.isErroneous()) continue;
3180            if (!elements.remove(m)) {
3181                isValid = false;
3182                log.error(assign.lhs.pos(), "duplicate.annotation.member.value",
3183                        m.name, a.type);
3184            }
3185        }
3186
3187        // all the remaining ones better have default values
3188        List<Name> missingDefaults = List.nil();
3189        Set<MethodSymbol> membersWithDefault = metadata.getAnnotationElementsWithDefault();
3190        for (MethodSymbol m : elements) {
3191            if (m.type.isErroneous())
3192                continue;
3193
3194            if (!membersWithDefault.contains(m))
3195                missingDefaults = missingDefaults.append(m.name);
3196        }
3197        missingDefaults = missingDefaults.reverse();
3198        if (missingDefaults.nonEmpty()) {
3199            isValid = false;
3200            String key = (missingDefaults.size() > 1)
3201                    ? "annotation.missing.default.value.1"
3202                    : "annotation.missing.default.value";
3203            log.error(a.pos(), key, a.type, missingDefaults);
3204        }
3205
3206        return isValid && validateTargetAnnotationValue(a);
3207    }
3208
3209    /* Validate the special java.lang.annotation.Target annotation */
3210    boolean validateTargetAnnotationValue(JCAnnotation a) {
3211        // special case: java.lang.annotation.Target must not have
3212        // repeated values in its value member
3213        if (a.annotationType.type.tsym != syms.annotationTargetType.tsym ||
3214                a.args.tail == null)
3215            return true;
3216
3217        boolean isValid = true;
3218        if (!a.args.head.hasTag(ASSIGN)) return false; // error recovery
3219        JCAssign assign = (JCAssign) a.args.head;
3220        Symbol m = TreeInfo.symbol(assign.lhs);
3221        if (m.name != names.value) return false;
3222        JCTree rhs = assign.rhs;
3223        if (!rhs.hasTag(NEWARRAY)) return false;
3224        JCNewArray na = (JCNewArray) rhs;
3225        Set<Symbol> targets = new HashSet<>();
3226        for (JCTree elem : na.elems) {
3227            if (!targets.add(TreeInfo.symbol(elem))) {
3228                isValid = false;
3229                log.error(elem.pos(), "repeated.annotation.target");
3230            }
3231        }
3232        return isValid;
3233    }
3234
3235    void checkDeprecatedAnnotation(DiagnosticPosition pos, Symbol s) {
3236        if (lint.isEnabled(LintCategory.DEP_ANN) && s.isDeprecatableViaAnnotation() &&
3237            (s.flags() & DEPRECATED) != 0 &&
3238            !syms.deprecatedType.isErroneous() &&
3239            s.attribute(syms.deprecatedType.tsym) == null) {
3240            log.warning(LintCategory.DEP_ANN,
3241                    pos, "missing.deprecated.annotation");
3242        }
3243        // Note: @Deprecated has no effect on local variables, parameters and package decls.
3244        if (lint.isEnabled(LintCategory.DEPRECATION) && !s.isDeprecatableViaAnnotation()) {
3245            if (!syms.deprecatedType.isErroneous() && s.attribute(syms.deprecatedType.tsym) != null) {
3246                log.warning(LintCategory.DEPRECATION, pos,
3247                        "deprecated.annotation.has.no.effect", Kinds.kindName(s));
3248            }
3249        }
3250    }
3251
3252    void checkDeprecated(final DiagnosticPosition pos, final Symbol other, final Symbol s) {
3253        if ( (s.isDeprecatedForRemoval()
3254                || s.isDeprecated() && !other.isDeprecated())
3255                && (s.outermostClass() != other.outermostClass() || s.outermostClass() == null)) {
3256            deferredLintHandler.report(() -> warnDeprecated(pos, s));
3257        }
3258    }
3259
3260    void checkSunAPI(final DiagnosticPosition pos, final Symbol s) {
3261        if ((s.flags() & PROPRIETARY) != 0) {
3262            deferredLintHandler.report(() -> {
3263                log.mandatoryWarning(pos, "sun.proprietary", s);
3264            });
3265        }
3266    }
3267
3268    void checkProfile(final DiagnosticPosition pos, final Symbol s) {
3269        if (profile != Profile.DEFAULT && (s.flags() & NOT_IN_PROFILE) != 0) {
3270            log.error(pos, "not.in.profile", s, profile);
3271        }
3272    }
3273
3274/* *************************************************************************
3275 * Check for recursive annotation elements.
3276 **************************************************************************/
3277
3278    /** Check for cycles in the graph of annotation elements.
3279     */
3280    void checkNonCyclicElements(JCClassDecl tree) {
3281        if ((tree.sym.flags_field & ANNOTATION) == 0) return;
3282        Assert.check((tree.sym.flags_field & LOCKED) == 0);
3283        try {
3284            tree.sym.flags_field |= LOCKED;
3285            for (JCTree def : tree.defs) {
3286                if (!def.hasTag(METHODDEF)) continue;
3287                JCMethodDecl meth = (JCMethodDecl)def;
3288                checkAnnotationResType(meth.pos(), meth.restype.type);
3289            }
3290        } finally {
3291            tree.sym.flags_field &= ~LOCKED;
3292            tree.sym.flags_field |= ACYCLIC_ANN;
3293        }
3294    }
3295
3296    void checkNonCyclicElementsInternal(DiagnosticPosition pos, TypeSymbol tsym) {
3297        if ((tsym.flags_field & ACYCLIC_ANN) != 0)
3298            return;
3299        if ((tsym.flags_field & LOCKED) != 0) {
3300            log.error(pos, "cyclic.annotation.element");
3301            return;
3302        }
3303        try {
3304            tsym.flags_field |= LOCKED;
3305            for (Symbol s : tsym.members().getSymbols(NON_RECURSIVE)) {
3306                if (s.kind != MTH)
3307                    continue;
3308                checkAnnotationResType(pos, ((MethodSymbol)s).type.getReturnType());
3309            }
3310        } finally {
3311            tsym.flags_field &= ~LOCKED;
3312            tsym.flags_field |= ACYCLIC_ANN;
3313        }
3314    }
3315
3316    void checkAnnotationResType(DiagnosticPosition pos, Type type) {
3317        switch (type.getTag()) {
3318        case CLASS:
3319            if ((type.tsym.flags() & ANNOTATION) != 0)
3320                checkNonCyclicElementsInternal(pos, type.tsym);
3321            break;
3322        case ARRAY:
3323            checkAnnotationResType(pos, types.elemtype(type));
3324            break;
3325        default:
3326            break; // int etc
3327        }
3328    }
3329
3330/* *************************************************************************
3331 * Check for cycles in the constructor call graph.
3332 **************************************************************************/
3333
3334    /** Check for cycles in the graph of constructors calling other
3335     *  constructors.
3336     */
3337    void checkCyclicConstructors(JCClassDecl tree) {
3338        Map<Symbol,Symbol> callMap = new HashMap<>();
3339
3340        // enter each constructor this-call into the map
3341        for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
3342            JCMethodInvocation app = TreeInfo.firstConstructorCall(l.head);
3343            if (app == null) continue;
3344            JCMethodDecl meth = (JCMethodDecl) l.head;
3345            if (TreeInfo.name(app.meth) == names._this) {
3346                callMap.put(meth.sym, TreeInfo.symbol(app.meth));
3347            } else {
3348                meth.sym.flags_field |= ACYCLIC;
3349            }
3350        }
3351
3352        // Check for cycles in the map
3353        Symbol[] ctors = new Symbol[0];
3354        ctors = callMap.keySet().toArray(ctors);
3355        for (Symbol caller : ctors) {
3356            checkCyclicConstructor(tree, caller, callMap);
3357        }
3358    }
3359
3360    /** Look in the map to see if the given constructor is part of a
3361     *  call cycle.
3362     */
3363    private void checkCyclicConstructor(JCClassDecl tree, Symbol ctor,
3364                                        Map<Symbol,Symbol> callMap) {
3365        if (ctor != null && (ctor.flags_field & ACYCLIC) == 0) {
3366            if ((ctor.flags_field & LOCKED) != 0) {
3367                log.error(TreeInfo.diagnosticPositionFor(ctor, tree),
3368                          "recursive.ctor.invocation");
3369            } else {
3370                ctor.flags_field |= LOCKED;
3371                checkCyclicConstructor(tree, callMap.remove(ctor), callMap);
3372                ctor.flags_field &= ~LOCKED;
3373            }
3374            ctor.flags_field |= ACYCLIC;
3375        }
3376    }
3377
3378/* *************************************************************************
3379 * Miscellaneous
3380 **************************************************************************/
3381
3382    /**
3383     *  Check for division by integer constant zero
3384     *  @param pos           Position for error reporting.
3385     *  @param operator      The operator for the expression
3386     *  @param operand       The right hand operand for the expression
3387     */
3388    void checkDivZero(final DiagnosticPosition pos, Symbol operator, Type operand) {
3389        if (operand.constValue() != null
3390            && operand.getTag().isSubRangeOf(LONG)
3391            && ((Number) (operand.constValue())).longValue() == 0) {
3392            int opc = ((OperatorSymbol)operator).opcode;
3393            if (opc == ByteCodes.idiv || opc == ByteCodes.imod
3394                || opc == ByteCodes.ldiv || opc == ByteCodes.lmod) {
3395                deferredLintHandler.report(() -> warnDivZero(pos));
3396            }
3397        }
3398    }
3399
3400    /**
3401     * Check for empty statements after if
3402     */
3403    void checkEmptyIf(JCIf tree) {
3404        if (tree.thenpart.hasTag(SKIP) && tree.elsepart == null &&
3405                lint.isEnabled(LintCategory.EMPTY))
3406            log.warning(LintCategory.EMPTY, tree.thenpart.pos(), "empty.if");
3407    }
3408
3409    /** Check that symbol is unique in given scope.
3410     *  @param pos           Position for error reporting.
3411     *  @param sym           The symbol.
3412     *  @param s             The scope.
3413     */
3414    boolean checkUnique(DiagnosticPosition pos, Symbol sym, Scope s) {
3415        if (sym.type.isErroneous())
3416            return true;
3417        if (sym.owner.name == names.any) return false;
3418        for (Symbol byName : s.getSymbolsByName(sym.name, NON_RECURSIVE)) {
3419            if (sym != byName &&
3420                    (byName.flags() & CLASH) == 0 &&
3421                    sym.kind == byName.kind &&
3422                    sym.name != names.error &&
3423                    (sym.kind != MTH ||
3424                     types.hasSameArgs(sym.type, byName.type) ||
3425                     types.hasSameArgs(types.erasure(sym.type), types.erasure(byName.type)))) {
3426                if ((sym.flags() & VARARGS) != (byName.flags() & VARARGS)) {
3427                    varargsDuplicateError(pos, sym, byName);
3428                    return true;
3429                } else if (sym.kind == MTH && !types.hasSameArgs(sym.type, byName.type, false)) {
3430                    duplicateErasureError(pos, sym, byName);
3431                    sym.flags_field |= CLASH;
3432                    return true;
3433                } else {
3434                    duplicateError(pos, byName);
3435                    return false;
3436                }
3437            }
3438        }
3439        return true;
3440    }
3441
3442    /** Report duplicate declaration error.
3443     */
3444    void duplicateErasureError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) {
3445        if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) {
3446            log.error(pos, "name.clash.same.erasure", sym1, sym2);
3447        }
3448    }
3449
3450    /**Check that types imported through the ordinary imports don't clash with types imported
3451     * by other (static or ordinary) imports. Note that two static imports may import two clashing
3452     * types without an error on the imports.
3453     * @param toplevel       The toplevel tree for which the test should be performed.
3454     */
3455    void checkImportsUnique(JCCompilationUnit toplevel) {
3456        WriteableScope ordinallyImportedSoFar = WriteableScope.create(toplevel.packge);
3457        WriteableScope staticallyImportedSoFar = WriteableScope.create(toplevel.packge);
3458        WriteableScope topLevelScope = toplevel.toplevelScope;
3459
3460        for (JCTree def : toplevel.defs) {
3461            if (!def.hasTag(IMPORT))
3462                continue;
3463
3464            JCImport imp = (JCImport) def;
3465
3466            if (imp.importScope == null)
3467                continue;
3468
3469            for (Symbol sym : imp.importScope.getSymbols(sym -> sym.kind == TYP)) {
3470                if (imp.isStatic()) {
3471                    checkUniqueImport(imp.pos(), ordinallyImportedSoFar, staticallyImportedSoFar, topLevelScope, sym, true);
3472                    staticallyImportedSoFar.enter(sym);
3473                } else {
3474                    checkUniqueImport(imp.pos(), ordinallyImportedSoFar, staticallyImportedSoFar, topLevelScope, sym, false);
3475                    ordinallyImportedSoFar.enter(sym);
3476                }
3477            }
3478
3479            imp.importScope = null;
3480        }
3481    }
3482
3483    /** Check that single-type import is not already imported or top-level defined,
3484     *  but make an exception for two single-type imports which denote the same type.
3485     *  @param pos                     Position for error reporting.
3486     *  @param ordinallyImportedSoFar  A Scope containing types imported so far through
3487     *                                 ordinary imports.
3488     *  @param staticallyImportedSoFar A Scope containing types imported so far through
3489     *                                 static imports.
3490     *  @param topLevelScope           The current file's top-level Scope
3491     *  @param sym                     The symbol.
3492     *  @param staticImport            Whether or not this was a static import
3493     */
3494    private boolean checkUniqueImport(DiagnosticPosition pos, Scope ordinallyImportedSoFar,
3495                                      Scope staticallyImportedSoFar, Scope topLevelScope,
3496                                      Symbol sym, boolean staticImport) {
3497        Filter<Symbol> duplicates = candidate -> candidate != sym && !candidate.type.isErroneous();
3498        Symbol clashing = ordinallyImportedSoFar.findFirst(sym.name, duplicates);
3499        if (clashing == null && !staticImport) {
3500            clashing = staticallyImportedSoFar.findFirst(sym.name, duplicates);
3501        }
3502        if (clashing != null) {
3503            if (staticImport)
3504                log.error(pos, "already.defined.static.single.import", clashing);
3505            else
3506                log.error(pos, "already.defined.single.import", clashing);
3507            return false;
3508        }
3509        clashing = topLevelScope.findFirst(sym.name, duplicates);
3510        if (clashing != null) {
3511            log.error(pos, "already.defined.this.unit", clashing);
3512            return false;
3513        }
3514        return true;
3515    }
3516
3517    /** Check that a qualified name is in canonical form (for import decls).
3518     */
3519    public void checkCanonical(JCTree tree) {
3520        if (!isCanonical(tree))
3521            log.error(tree.pos(), "import.requires.canonical",
3522                      TreeInfo.symbol(tree));
3523    }
3524        // where
3525        private boolean isCanonical(JCTree tree) {
3526            while (tree.hasTag(SELECT)) {
3527                JCFieldAccess s = (JCFieldAccess) tree;
3528                if (s.sym.owner.name != TreeInfo.symbol(s.selected).name)
3529                    return false;
3530                tree = s.selected;
3531            }
3532            return true;
3533        }
3534
3535    /** Check that an auxiliary class is not accessed from any other file than its own.
3536     */
3537    void checkForBadAuxiliaryClassAccess(DiagnosticPosition pos, Env<AttrContext> env, ClassSymbol c) {
3538        if (lint.isEnabled(Lint.LintCategory.AUXILIARYCLASS) &&
3539            (c.flags() & AUXILIARY) != 0 &&
3540            rs.isAccessible(env, c) &&
3541            !fileManager.isSameFile(c.sourcefile, env.toplevel.sourcefile))
3542        {
3543            log.warning(pos, "auxiliary.class.accessed.from.outside.of.its.source.file",
3544                        c, c.sourcefile);
3545        }
3546    }
3547
3548    private class ConversionWarner extends Warner {
3549        final String uncheckedKey;
3550        final Type found;
3551        final Type expected;
3552        public ConversionWarner(DiagnosticPosition pos, String uncheckedKey, Type found, Type expected) {
3553            super(pos);
3554            this.uncheckedKey = uncheckedKey;
3555            this.found = found;
3556            this.expected = expected;
3557        }
3558
3559        @Override
3560        public void warn(LintCategory lint) {
3561            boolean warned = this.warned;
3562            super.warn(lint);
3563            if (warned) return; // suppress redundant diagnostics
3564            switch (lint) {
3565                case UNCHECKED:
3566                    Check.this.warnUnchecked(pos(), "prob.found.req", diags.fragment(uncheckedKey), found, expected);
3567                    break;
3568                case VARARGS:
3569                    if (method != null &&
3570                            method.attribute(syms.trustMeType.tsym) != null &&
3571                            isTrustMeAllowedOnMethod(method) &&
3572                            !types.isReifiable(method.type.getParameterTypes().last())) {
3573                        Check.this.warnUnsafeVararg(pos(), "varargs.unsafe.use.varargs.param", method.params.last());
3574                    }
3575                    break;
3576                default:
3577                    throw new AssertionError("Unexpected lint: " + lint);
3578            }
3579        }
3580    }
3581
3582    public Warner castWarner(DiagnosticPosition pos, Type found, Type expected) {
3583        return new ConversionWarner(pos, "unchecked.cast.to.type", found, expected);
3584    }
3585
3586    public Warner convertWarner(DiagnosticPosition pos, Type found, Type expected) {
3587        return new ConversionWarner(pos, "unchecked.assign", found, expected);
3588    }
3589
3590    public void checkFunctionalInterface(JCClassDecl tree, ClassSymbol cs) {
3591        Compound functionalType = cs.attribute(syms.functionalInterfaceType.tsym);
3592
3593        if (functionalType != null) {
3594            try {
3595                types.findDescriptorSymbol((TypeSymbol)cs);
3596            } catch (Types.FunctionDescriptorLookupError ex) {
3597                DiagnosticPosition pos = tree.pos();
3598                for (JCAnnotation a : tree.getModifiers().annotations) {
3599                    if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) {
3600                        pos = a.pos();
3601                        break;
3602                    }
3603                }
3604                log.error(pos, "bad.functional.intf.anno.1", ex.getDiagnostic());
3605            }
3606        }
3607    }
3608
3609    public void checkImportsResolvable(final JCCompilationUnit toplevel) {
3610        for (final JCImport imp : toplevel.getImports()) {
3611            if (!imp.staticImport || !imp.qualid.hasTag(SELECT))
3612                continue;
3613            final JCFieldAccess select = (JCFieldAccess) imp.qualid;
3614            final Symbol origin;
3615            if (select.name == names.asterisk || (origin = TreeInfo.symbol(select.selected)) == null || origin.kind != TYP)
3616                continue;
3617
3618            TypeSymbol site = (TypeSymbol) TreeInfo.symbol(select.selected);
3619            if (!checkTypeContainsImportableElement(site, site, toplevel.packge, select.name, new HashSet<Symbol>())) {
3620                log.error(imp.pos(), "cant.resolve.location",
3621                          KindName.STATIC,
3622                          select.name, List.<Type>nil(), List.<Type>nil(),
3623                          Kinds.typeKindName(TreeInfo.symbol(select.selected).type),
3624                          TreeInfo.symbol(select.selected).type);
3625            }
3626        }
3627    }
3628
3629    // Check that packages imported are in scope (JLS 7.4.3, 6.3, 6.5.3.1, 6.5.3.2)
3630    public void checkImportedPackagesObservable(final JCCompilationUnit toplevel) {
3631        OUTER: for (JCImport imp : toplevel.getImports()) {
3632            if (!imp.staticImport && TreeInfo.name(imp.qualid) == names.asterisk) {
3633                TypeSymbol tsym = ((JCFieldAccess)imp.qualid).selected.type.tsym;
3634                if (toplevel.modle.visiblePackages != null) {
3635                    //TODO - unclear: selects like javax.* will get resolved from the current module
3636                    //(as javax is not an exported package from any module). And as javax in the current
3637                    //module typically does not contain any classes or subpackages, we need to go through
3638                    //the visible packages to find a sub-package:
3639                    for (PackageSymbol known : toplevel.modle.visiblePackages.values()) {
3640                        if (Convert.packagePart(known.fullname) == tsym.flatName())
3641                            continue OUTER;
3642                    }
3643                }
3644                if (tsym.kind == PCK && tsym.members().isEmpty() && !tsym.exists()) {
3645                    log.error(DiagnosticFlag.RESOLVE_ERROR, imp.pos, "doesnt.exist", tsym);
3646                }
3647            }
3648        }
3649    }
3650
3651    private boolean checkTypeContainsImportableElement(TypeSymbol tsym, TypeSymbol origin, PackageSymbol packge, Name name, Set<Symbol> processed) {
3652        if (tsym == null || !processed.add(tsym))
3653            return false;
3654
3655            // also search through inherited names
3656        if (checkTypeContainsImportableElement(types.supertype(tsym.type).tsym, origin, packge, name, processed))
3657            return true;
3658
3659        for (Type t : types.interfaces(tsym.type))
3660            if (checkTypeContainsImportableElement(t.tsym, origin, packge, name, processed))
3661                return true;
3662
3663        for (Symbol sym : tsym.members().getSymbolsByName(name)) {
3664            if (sym.isStatic() &&
3665                importAccessible(sym, packge) &&
3666                sym.isMemberOf(origin, types)) {
3667                return true;
3668            }
3669        }
3670
3671        return false;
3672    }
3673
3674    // is the sym accessible everywhere in packge?
3675    public boolean importAccessible(Symbol sym, PackageSymbol packge) {
3676        try {
3677            int flags = (int)(sym.flags() & AccessFlags);
3678            switch (flags) {
3679            default:
3680            case PUBLIC:
3681                return true;
3682            case PRIVATE:
3683                return false;
3684            case 0:
3685            case PROTECTED:
3686                return sym.packge() == packge;
3687            }
3688        } catch (ClassFinder.BadClassFile err) {
3689            throw err;
3690        } catch (CompletionFailure ex) {
3691            return false;
3692        }
3693    }
3694
3695    public void checkLeaksNotAccessible(Env<AttrContext> env, JCClassDecl check) {
3696        JCCompilationUnit toplevel = env.toplevel;
3697
3698        if (   toplevel.modle == syms.unnamedModule
3699            || toplevel.modle == syms.noModule
3700            || (check.sym.flags() & COMPOUND) != 0) {
3701            return ;
3702        }
3703
3704        ExportsDirective currentExport = findExport(toplevel.packge);
3705
3706        if (   currentExport == null //not exported
3707            || currentExport.modules != null) //don't check classes in qualified export
3708            return ;
3709
3710        new TreeScanner() {
3711            Lint lint = env.info.lint;
3712            boolean inSuperType;
3713
3714            @Override
3715            public void visitBlock(JCBlock tree) {
3716            }
3717            @Override
3718            public void visitMethodDef(JCMethodDecl tree) {
3719                if (!isAPISymbol(tree.sym))
3720                    return;
3721                Lint prevLint = lint;
3722                try {
3723                    lint = lint.augment(tree.sym);
3724                    if (lint.isEnabled(LintCategory.EXPORTS)) {
3725                        super.visitMethodDef(tree);
3726                    }
3727                } finally {
3728                    lint = prevLint;
3729                }
3730            }
3731            @Override
3732            public void visitVarDef(JCVariableDecl tree) {
3733                if (!isAPISymbol(tree.sym) && tree.sym.owner.kind != MTH)
3734                    return;
3735                Lint prevLint = lint;
3736                try {
3737                    lint = lint.augment(tree.sym);
3738                    if (lint.isEnabled(LintCategory.EXPORTS)) {
3739                        scan(tree.mods);
3740                        scan(tree.vartype);
3741                    }
3742                } finally {
3743                    lint = prevLint;
3744                }
3745            }
3746            @Override
3747            public void visitClassDef(JCClassDecl tree) {
3748                if (tree != check)
3749                    return ;
3750
3751                if (!isAPISymbol(tree.sym))
3752                    return ;
3753
3754                Lint prevLint = lint;
3755                try {
3756                    lint = lint.augment(tree.sym);
3757                    if (lint.isEnabled(LintCategory.EXPORTS)) {
3758                        scan(tree.mods);
3759                        scan(tree.typarams);
3760                        try {
3761                            inSuperType = true;
3762                            scan(tree.extending);
3763                            scan(tree.implementing);
3764                        } finally {
3765                            inSuperType = false;
3766                        }
3767                        scan(tree.defs);
3768                    }
3769                } finally {
3770                    lint = prevLint;
3771                }
3772            }
3773            @Override
3774            public void visitTypeApply(JCTypeApply tree) {
3775                scan(tree.clazz);
3776                boolean oldInSuperType = inSuperType;
3777                try {
3778                    inSuperType = false;
3779                    scan(tree.arguments);
3780                } finally {
3781                    inSuperType = oldInSuperType;
3782                }
3783            }
3784            @Override
3785            public void visitIdent(JCIdent tree) {
3786                Symbol sym = TreeInfo.symbol(tree);
3787                if (sym.kind == TYP && !sym.type.hasTag(TYPEVAR)) {
3788                    checkVisible(tree.pos(), sym, toplevel.packge, inSuperType);
3789                }
3790            }
3791
3792            @Override
3793            public void visitSelect(JCFieldAccess tree) {
3794                Symbol sym = TreeInfo.symbol(tree);
3795                Symbol sitesym = TreeInfo.symbol(tree.selected);
3796                if (sym.kind == TYP && sitesym.kind == PCK) {
3797                    checkVisible(tree.pos(), sym, toplevel.packge, inSuperType);
3798                } else {
3799                    super.visitSelect(tree);
3800                }
3801            }
3802
3803            @Override
3804            public void visitAnnotation(JCAnnotation tree) {
3805                if (tree.attribute.type.tsym.getAnnotation(java.lang.annotation.Documented.class) != null)
3806                    super.visitAnnotation(tree);
3807            }
3808
3809        }.scan(check);
3810    }
3811        //where:
3812        private ExportsDirective findExport(PackageSymbol pack) {
3813            for (ExportsDirective d : pack.modle.exports) {
3814                if (d.packge == pack)
3815                    return d;
3816            }
3817
3818            return null;
3819        }
3820        private boolean isAPISymbol(Symbol sym) {
3821            while (sym.kind != PCK) {
3822                if ((sym.flags() & Flags.PUBLIC) == 0 && (sym.flags() & Flags.PROTECTED) == 0) {
3823                    return false;
3824                }
3825                sym = sym.owner;
3826            }
3827            return true;
3828        }
3829        private void checkVisible(DiagnosticPosition pos, Symbol what, PackageSymbol inPackage, boolean inSuperType) {
3830            if (!isAPISymbol(what) && !inSuperType) { //package private/private element
3831                log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessible(kindName(what), what, what.packge().modle));
3832                return ;
3833            }
3834
3835            PackageSymbol whatPackage = what.packge();
3836            ExportsDirective whatExport = findExport(whatPackage);
3837            ExportsDirective inExport = findExport(inPackage);
3838
3839            if (whatExport == null) { //package not exported:
3840                log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessibleUnexported(kindName(what), what, what.packge().modle));
3841                return ;
3842            }
3843
3844            if (whatExport.modules != null) {
3845                if (inExport.modules == null || !whatExport.modules.containsAll(inExport.modules)) {
3846                    log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessibleUnexportedQualified(kindName(what), what, what.packge().modle));
3847                }
3848            }
3849
3850            if (whatPackage.modle != inPackage.modle && whatPackage.modle != syms.java_base) {
3851                //check that relativeTo.modle requires transitive what.modle, somehow:
3852                List<ModuleSymbol> todo = List.of(inPackage.modle);
3853
3854                while (todo.nonEmpty()) {
3855                    ModuleSymbol current = todo.head;
3856                    todo = todo.tail;
3857                    if (current == whatPackage.modle)
3858                        return ; //OK
3859                    for (RequiresDirective req : current.requires) {
3860                        if (req.isTransitive()) {
3861                            todo = todo.prepend(req.module);
3862                        }
3863                    }
3864                }
3865
3866                log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessibleNotRequiredTransitive(kindName(what), what, what.packge().modle));
3867            }
3868        }
3869
3870    void checkModuleExists(final DiagnosticPosition pos, ModuleSymbol msym) {
3871        if (msym.kind != MDL) {
3872            deferredLintHandler.report(() -> {
3873                if (lint.isEnabled(LintCategory.MODULE))
3874                    log.warning(LintCategory.MODULE, pos, Warnings.ModuleNotFound(msym));
3875            });
3876        }
3877    }
3878
3879}
3880