Check.java revision 3719:32c685715095
1/*
2 * Copyright (c) 1999, 2016, 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                removalHandler.report(pos, "has.been.deprecated.for.removal", sym, sym.location());
231            }
232        } else if (!lint.isSuppressed(LintCategory.DEPRECATION)) {
233            deprecationHandler.report(pos, "has.been.deprecated", sym, sym.location());
234        }
235    }
236
237    /** Warn about unchecked operation.
238     *  @param pos        Position to be used for error reporting.
239     *  @param msg        A string describing the problem.
240     */
241    public void warnUnchecked(DiagnosticPosition pos, String msg, Object... args) {
242        if (!lint.isSuppressed(LintCategory.UNCHECKED))
243            uncheckedHandler.report(pos, msg, args);
244    }
245
246    /** Warn about unsafe vararg method decl.
247     *  @param pos        Position to be used for error reporting.
248     */
249    void warnUnsafeVararg(DiagnosticPosition pos, String key, Object... args) {
250        if (lint.isEnabled(LintCategory.VARARGS) && allowSimplifiedVarargs)
251            log.warning(LintCategory.VARARGS, pos, key, args);
252    }
253
254    public void warnStatic(DiagnosticPosition pos, String msg, Object... args) {
255        if (lint.isEnabled(LintCategory.STATIC))
256            log.warning(LintCategory.STATIC, pos, msg, args);
257    }
258
259    /** Warn about division by integer constant zero.
260     *  @param pos        Position to be used for error reporting.
261     */
262    void warnDivZero(DiagnosticPosition pos) {
263        if (lint.isEnabled(LintCategory.DIVZERO))
264            log.warning(LintCategory.DIVZERO, pos, "div.zero");
265    }
266
267    /**
268     * Report any deferred diagnostics.
269     */
270    public void reportDeferredDiagnostics() {
271        deprecationHandler.reportDeferredDiagnostic();
272        removalHandler.reportDeferredDiagnostic();
273        uncheckedHandler.reportDeferredDiagnostic();
274        sunApiHandler.reportDeferredDiagnostic();
275    }
276
277
278    /** Report a failure to complete a class.
279     *  @param pos        Position to be used for error reporting.
280     *  @param ex         The failure to report.
281     */
282    public Type completionError(DiagnosticPosition pos, CompletionFailure ex) {
283        log.error(JCDiagnostic.DiagnosticFlag.NON_DEFERRABLE, pos, "cant.access", ex.sym, ex.getDetailValue());
284        if (ex instanceof ClassFinder.BadClassFile) throw new Abort();
285        else return syms.errType;
286    }
287
288    /** Report an error that wrong type tag was found.
289     *  @param pos        Position to be used for error reporting.
290     *  @param required   An internationalized string describing the type tag
291     *                    required.
292     *  @param found      The type that was found.
293     */
294    Type typeTagError(DiagnosticPosition pos, Object required, Object found) {
295        // this error used to be raised by the parser,
296        // but has been delayed to this point:
297        if (found instanceof Type && ((Type)found).hasTag(VOID)) {
298            log.error(pos, "illegal.start.of.type");
299            return syms.errType;
300        }
301        log.error(pos, "type.found.req", found, required);
302        return types.createErrorType(found instanceof Type ? (Type)found : syms.errType);
303    }
304
305    /** Report an error that symbol cannot be referenced before super
306     *  has been called.
307     *  @param pos        Position to be used for error reporting.
308     *  @param sym        The referenced symbol.
309     */
310    void earlyRefError(DiagnosticPosition pos, Symbol sym) {
311        log.error(pos, "cant.ref.before.ctor.called", sym);
312    }
313
314    /** Report duplicate declaration error.
315     */
316    void duplicateError(DiagnosticPosition pos, Symbol sym) {
317        if (!sym.type.isErroneous()) {
318            Symbol location = sym.location();
319            if (location.kind == MTH &&
320                    ((MethodSymbol)location).isStaticOrInstanceInit()) {
321                log.error(pos, "already.defined.in.clinit", kindName(sym), sym,
322                        kindName(sym.location()), kindName(sym.location().enclClass()),
323                        sym.location().enclClass());
324            } else {
325                log.error(pos, "already.defined", kindName(sym), sym,
326                        kindName(sym.location()), sym.location());
327            }
328        }
329    }
330
331    /** Report array/varargs duplicate declaration
332     */
333    void varargsDuplicateError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) {
334        if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) {
335            log.error(pos, "array.and.varargs", sym1, sym2, sym2.location());
336        }
337    }
338
339/* ************************************************************************
340 * duplicate declaration checking
341 *************************************************************************/
342
343    /** Check that variable does not hide variable with same name in
344     *  immediately enclosing local scope.
345     *  @param pos           Position for error reporting.
346     *  @param v             The symbol.
347     *  @param s             The scope.
348     */
349    void checkTransparentVar(DiagnosticPosition pos, VarSymbol v, Scope s) {
350        for (Symbol sym : s.getSymbolsByName(v.name)) {
351            if (sym.owner != v.owner) break;
352            if (sym.kind == VAR &&
353                sym.owner.kind.matches(KindSelector.VAL_MTH) &&
354                v.name != names.error) {
355                duplicateError(pos, sym);
356                return;
357            }
358        }
359    }
360
361    /** Check that a class or interface does not hide a class or
362     *  interface with same name in immediately enclosing local scope.
363     *  @param pos           Position for error reporting.
364     *  @param c             The symbol.
365     *  @param s             The scope.
366     */
367    void checkTransparentClass(DiagnosticPosition pos, ClassSymbol c, Scope s) {
368        for (Symbol sym : s.getSymbolsByName(c.name)) {
369            if (sym.owner != c.owner) break;
370            if (sym.kind == TYP && !sym.type.hasTag(TYPEVAR) &&
371                sym.owner.kind.matches(KindSelector.VAL_MTH) &&
372                c.name != names.error) {
373                duplicateError(pos, sym);
374                return;
375            }
376        }
377    }
378
379    /** Check that class does not have the same name as one of
380     *  its enclosing classes, or as a class defined in its enclosing scope.
381     *  return true if class is unique in its enclosing scope.
382     *  @param pos           Position for error reporting.
383     *  @param name          The class name.
384     *  @param s             The enclosing scope.
385     */
386    boolean checkUniqueClassName(DiagnosticPosition pos, Name name, Scope s) {
387        for (Symbol sym : s.getSymbolsByName(name, NON_RECURSIVE)) {
388            if (sym.kind == TYP && sym.name != names.error) {
389                duplicateError(pos, sym);
390                return false;
391            }
392        }
393        for (Symbol sym = s.owner; sym != null; sym = sym.owner) {
394            if (sym.kind == TYP && sym.name == name && sym.name != names.error) {
395                duplicateError(pos, sym);
396                return true;
397            }
398        }
399        return true;
400    }
401
402/* *************************************************************************
403 * Class name generation
404 **************************************************************************/
405
406
407    private Map<Pair<Name, Name>, Integer> localClassNameIndexes = new HashMap<>();
408
409    /** Return name of local class.
410     *  This is of the form   {@code <enclClass> $ n <classname> }
411     *  where
412     *    enclClass is the flat name of the enclosing class,
413     *    classname is the simple name of the local class
414     */
415    Name localClassName(ClassSymbol c) {
416        Name enclFlatname = c.owner.enclClass().flatname;
417        String enclFlatnameStr = enclFlatname.toString();
418        Pair<Name, Name> key = new Pair<>(enclFlatname, c.name);
419        Integer index = localClassNameIndexes.get(key);
420        for (int i = (index == null) ? 1 : index; ; i++) {
421            Name flatname = names.fromString(enclFlatnameStr
422                    + syntheticNameChar + i + c.name);
423            if (getCompiled(c.packge().modle, flatname) == null) {
424                localClassNameIndexes.put(key, i + 1);
425                return flatname;
426            }
427        }
428    }
429
430    void clearLocalClassNameIndexes(ClassSymbol c) {
431        localClassNameIndexes.remove(new Pair<>(
432                c.owner.enclClass().flatname, c.name));
433    }
434
435    public void newRound() {
436        compiled.clear();
437        localClassNameIndexes.clear();
438    }
439
440    public void putCompiled(ClassSymbol csym) {
441        compiled.put(Pair.of(csym.packge().modle, csym.flatname), csym);
442    }
443
444    public ClassSymbol getCompiled(ClassSymbol csym) {
445        return compiled.get(Pair.of(csym.packge().modle, csym.flatname));
446    }
447
448    public ClassSymbol getCompiled(ModuleSymbol msym, Name flatname) {
449        return compiled.get(Pair.of(msym, flatname));
450    }
451
452    public void removeCompiled(ClassSymbol csym) {
453        compiled.remove(Pair.of(csym.packge().modle, csym.flatname));
454    }
455
456/* *************************************************************************
457 * Type Checking
458 **************************************************************************/
459
460    /**
461     * A check context is an object that can be used to perform compatibility
462     * checks - depending on the check context, meaning of 'compatibility' might
463     * vary significantly.
464     */
465    public interface CheckContext {
466        /**
467         * Is type 'found' compatible with type 'req' in given context
468         */
469        boolean compatible(Type found, Type req, Warner warn);
470        /**
471         * Report a check error
472         */
473        void report(DiagnosticPosition pos, JCDiagnostic details);
474        /**
475         * Obtain a warner for this check context
476         */
477        public Warner checkWarner(DiagnosticPosition pos, Type found, Type req);
478
479        public InferenceContext inferenceContext();
480
481        public DeferredAttr.DeferredAttrContext deferredAttrContext();
482    }
483
484    /**
485     * This class represent a check context that is nested within another check
486     * context - useful to check sub-expressions. The default behavior simply
487     * redirects all method calls to the enclosing check context leveraging
488     * the forwarding pattern.
489     */
490    static class NestedCheckContext implements CheckContext {
491        CheckContext enclosingContext;
492
493        NestedCheckContext(CheckContext enclosingContext) {
494            this.enclosingContext = enclosingContext;
495        }
496
497        public boolean compatible(Type found, Type req, Warner warn) {
498            return enclosingContext.compatible(found, req, warn);
499        }
500
501        public void report(DiagnosticPosition pos, JCDiagnostic details) {
502            enclosingContext.report(pos, details);
503        }
504
505        public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
506            return enclosingContext.checkWarner(pos, found, req);
507        }
508
509        public InferenceContext inferenceContext() {
510            return enclosingContext.inferenceContext();
511        }
512
513        public DeferredAttrContext deferredAttrContext() {
514            return enclosingContext.deferredAttrContext();
515        }
516    }
517
518    /**
519     * Check context to be used when evaluating assignment/return statements
520     */
521    CheckContext basicHandler = new CheckContext() {
522        public void report(DiagnosticPosition pos, JCDiagnostic details) {
523            log.error(pos, "prob.found.req", details);
524        }
525        public boolean compatible(Type found, Type req, Warner warn) {
526            return types.isAssignable(found, req, warn);
527        }
528
529        public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
530            return convertWarner(pos, found, req);
531        }
532
533        public InferenceContext inferenceContext() {
534            return infer.emptyContext;
535        }
536
537        public DeferredAttrContext deferredAttrContext() {
538            return deferredAttr.emptyDeferredAttrContext;
539        }
540
541        @Override
542        public String toString() {
543            return "CheckContext: basicHandler";
544        }
545    };
546
547    /** Check that a given type is assignable to a given proto-type.
548     *  If it is, return the type, otherwise return errType.
549     *  @param pos        Position to be used for error reporting.
550     *  @param found      The type that was found.
551     *  @param req        The type that was required.
552     */
553    public Type checkType(DiagnosticPosition pos, Type found, Type req) {
554        return checkType(pos, found, req, basicHandler);
555    }
556
557    Type checkType(final DiagnosticPosition pos, final Type found, final Type req, final CheckContext checkContext) {
558        final InferenceContext inferenceContext = checkContext.inferenceContext();
559        if (inferenceContext.free(req) || inferenceContext.free(found)) {
560            inferenceContext.addFreeTypeListener(List.of(req, found), new FreeTypeListener() {
561                @Override
562                public void typesInferred(InferenceContext inferenceContext) {
563                    checkType(pos, inferenceContext.asInstType(found), inferenceContext.asInstType(req), checkContext);
564                }
565            });
566        }
567        if (req.hasTag(ERROR))
568            return req;
569        if (req.hasTag(NONE))
570            return found;
571        if (checkContext.compatible(found, req, checkContext.checkWarner(pos, found, req))) {
572            return found;
573        } else {
574            if (found.isNumeric() && req.isNumeric()) {
575                checkContext.report(pos, diags.fragment("possible.loss.of.precision", found, req));
576                return types.createErrorType(found);
577            }
578            checkContext.report(pos, diags.fragment("inconvertible.types", found, req));
579            return types.createErrorType(found);
580        }
581    }
582
583    /** Check that a given type can be cast to a given target type.
584     *  Return the result of the cast.
585     *  @param pos        Position to be used for error reporting.
586     *  @param found      The type that is being cast.
587     *  @param req        The target type of the cast.
588     */
589    Type checkCastable(DiagnosticPosition pos, Type found, Type req) {
590        return checkCastable(pos, found, req, basicHandler);
591    }
592    Type checkCastable(DiagnosticPosition pos, Type found, Type req, CheckContext checkContext) {
593        if (types.isCastable(found, req, castWarner(pos, found, req))) {
594            return req;
595        } else {
596            checkContext.report(pos, diags.fragment("inconvertible.types", found, req));
597            return types.createErrorType(found);
598        }
599    }
600
601    /** Check for redundant casts (i.e. where source type is a subtype of target type)
602     * The problem should only be reported for non-292 cast
603     */
604    public void checkRedundantCast(Env<AttrContext> env, final JCTypeCast tree) {
605        if (!tree.type.isErroneous()
606                && types.isSameType(tree.expr.type, tree.clazz.type)
607                && !(ignoreAnnotatedCasts && TreeInfo.containsTypeAnnotation(tree.clazz))
608                && !is292targetTypeCast(tree)) {
609            deferredLintHandler.report(new DeferredLintHandler.LintLogger() {
610                @Override
611                public void report() {
612                    if (lint.isEnabled(Lint.LintCategory.CAST))
613                        log.warning(Lint.LintCategory.CAST,
614                                tree.pos(), "redundant.cast", tree.clazz.type);
615                }
616            });
617        }
618    }
619    //where
620        private boolean is292targetTypeCast(JCTypeCast tree) {
621            boolean is292targetTypeCast = false;
622            JCExpression expr = TreeInfo.skipParens(tree.expr);
623            if (expr.hasTag(APPLY)) {
624                JCMethodInvocation apply = (JCMethodInvocation)expr;
625                Symbol sym = TreeInfo.symbol(apply.meth);
626                is292targetTypeCast = sym != null &&
627                    sym.kind == MTH &&
628                    (sym.flags() & HYPOTHETICAL) != 0;
629            }
630            return is292targetTypeCast;
631        }
632
633        private static final boolean ignoreAnnotatedCasts = true;
634
635    /** Check that a type is within some bounds.
636     *
637     *  Used in TypeApply to verify that, e.g., X in {@code V<X>} is a valid
638     *  type argument.
639     *  @param a             The type that should be bounded by bs.
640     *  @param bound         The bound.
641     */
642    private boolean checkExtends(Type a, Type bound) {
643         if (a.isUnbound()) {
644             return true;
645         } else if (!a.hasTag(WILDCARD)) {
646             a = types.cvarUpperBound(a);
647             return types.isSubtype(a, bound);
648         } else if (a.isExtendsBound()) {
649             return types.isCastable(bound, types.wildUpperBound(a), types.noWarnings);
650         } else if (a.isSuperBound()) {
651             return !types.notSoftSubtype(types.wildLowerBound(a), bound);
652         }
653         return true;
654     }
655
656    /** Check that type is different from 'void'.
657     *  @param pos           Position to be used for error reporting.
658     *  @param t             The type to be checked.
659     */
660    Type checkNonVoid(DiagnosticPosition pos, Type t) {
661        if (t.hasTag(VOID)) {
662            log.error(pos, "void.not.allowed.here");
663            return types.createErrorType(t);
664        } else {
665            return t;
666        }
667    }
668
669    Type checkClassOrArrayType(DiagnosticPosition pos, Type t) {
670        if (!t.hasTag(CLASS) && !t.hasTag(ARRAY) && !t.hasTag(ERROR)) {
671            return typeTagError(pos,
672                                diags.fragment("type.req.class.array"),
673                                asTypeParam(t));
674        } else {
675            return t;
676        }
677    }
678
679    /** Check that type is a class or interface type.
680     *  @param pos           Position to be used for error reporting.
681     *  @param t             The type to be checked.
682     */
683    Type checkClassType(DiagnosticPosition pos, Type t) {
684        if (!t.hasTag(CLASS) && !t.hasTag(ERROR)) {
685            return typeTagError(pos,
686                                diags.fragment("type.req.class"),
687                                asTypeParam(t));
688        } else {
689            return t;
690        }
691    }
692    //where
693        private Object asTypeParam(Type t) {
694            return (t.hasTag(TYPEVAR))
695                                    ? diags.fragment("type.parameter", t)
696                                    : t;
697        }
698
699    /** Check that type is a valid qualifier for a constructor reference expression
700     */
701    Type checkConstructorRefType(DiagnosticPosition pos, Type t) {
702        t = checkClassOrArrayType(pos, t);
703        if (t.hasTag(CLASS)) {
704            if ((t.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) {
705                log.error(pos, "abstract.cant.be.instantiated", t.tsym);
706                t = types.createErrorType(t);
707            } else if ((t.tsym.flags() & ENUM) != 0) {
708                log.error(pos, "enum.cant.be.instantiated");
709                t = types.createErrorType(t);
710            } else {
711                t = checkClassType(pos, t, true);
712            }
713        } else if (t.hasTag(ARRAY)) {
714            if (!types.isReifiable(((ArrayType)t).elemtype)) {
715                log.error(pos, "generic.array.creation");
716                t = types.createErrorType(t);
717            }
718        }
719        return t;
720    }
721
722    /** Check that type is a class or interface type.
723     *  @param pos           Position to be used for error reporting.
724     *  @param t             The type to be checked.
725     *  @param noBounds    True if type bounds are illegal here.
726     */
727    Type checkClassType(DiagnosticPosition pos, Type t, boolean noBounds) {
728        t = checkClassType(pos, t);
729        if (noBounds && t.isParameterized()) {
730            List<Type> args = t.getTypeArguments();
731            while (args.nonEmpty()) {
732                if (args.head.hasTag(WILDCARD))
733                    return typeTagError(pos,
734                                        diags.fragment("type.req.exact"),
735                                        args.head);
736                args = args.tail;
737            }
738        }
739        return t;
740    }
741
742    /** Check that type is a reference type, i.e. a class, interface or array type
743     *  or a type variable.
744     *  @param pos           Position to be used for error reporting.
745     *  @param t             The type to be checked.
746     */
747    Type checkRefType(DiagnosticPosition pos, Type t) {
748        if (t.isReference())
749            return t;
750        else
751            return typeTagError(pos,
752                                diags.fragment("type.req.ref"),
753                                t);
754    }
755
756    /** Check that each type is a reference type, i.e. a class, interface or array type
757     *  or a type variable.
758     *  @param trees         Original trees, used for error reporting.
759     *  @param types         The types to be checked.
760     */
761    List<Type> checkRefTypes(List<JCExpression> trees, List<Type> types) {
762        List<JCExpression> tl = trees;
763        for (List<Type> l = types; l.nonEmpty(); l = l.tail) {
764            l.head = checkRefType(tl.head.pos(), l.head);
765            tl = tl.tail;
766        }
767        return types;
768    }
769
770    /** Check that type is a null or reference type.
771     *  @param pos           Position to be used for error reporting.
772     *  @param t             The type to be checked.
773     */
774    Type checkNullOrRefType(DiagnosticPosition pos, Type t) {
775        if (t.isReference() || t.hasTag(BOT))
776            return t;
777        else
778            return typeTagError(pos,
779                                diags.fragment("type.req.ref"),
780                                t);
781    }
782
783    /** Check that flag set does not contain elements of two conflicting sets. s
784     *  Return true if it doesn't.
785     *  @param pos           Position to be used for error reporting.
786     *  @param flags         The set of flags to be checked.
787     *  @param set1          Conflicting flags set #1.
788     *  @param set2          Conflicting flags set #2.
789     */
790    boolean checkDisjoint(DiagnosticPosition pos, long flags, long set1, long set2) {
791        if ((flags & set1) != 0 && (flags & set2) != 0) {
792            log.error(pos,
793                      "illegal.combination.of.modifiers",
794                      asFlagSet(TreeInfo.firstFlag(flags & set1)),
795                      asFlagSet(TreeInfo.firstFlag(flags & set2)));
796            return false;
797        } else
798            return true;
799    }
800
801    /** Check that usage of diamond operator is correct (i.e. diamond should not
802     * be used with non-generic classes or in anonymous class creation expressions)
803     */
804    Type checkDiamond(JCNewClass tree, Type t) {
805        if (!TreeInfo.isDiamond(tree) ||
806                t.isErroneous()) {
807            return checkClassType(tree.clazz.pos(), t, true);
808        } else {
809            if (tree.def != null && !allowDiamondWithAnonymousClassCreation) {
810                log.error(DiagnosticFlag.SOURCE_LEVEL, tree.clazz.pos(),
811                        Errors.CantApplyDiamond1(t, Fragments.DiamondAndAnonClassNotSupportedInSource(source.name)));
812            }
813            if (t.tsym.type.getTypeArguments().isEmpty()) {
814                log.error(tree.clazz.pos(),
815                    "cant.apply.diamond.1",
816                    t, diags.fragment("diamond.non.generic", t));
817                return types.createErrorType(t);
818            } else if (tree.typeargs != null &&
819                    tree.typeargs.nonEmpty()) {
820                log.error(tree.clazz.pos(),
821                    "cant.apply.diamond.1",
822                    t, diags.fragment("diamond.and.explicit.params", t));
823                return types.createErrorType(t);
824            } else {
825                return t;
826            }
827        }
828    }
829
830    /** Check that the type inferred using the diamond operator does not contain
831     *  non-denotable types such as captured types or intersection types.
832     *  @param t the type inferred using the diamond operator
833     *  @return  the (possibly empty) list of non-denotable types.
834     */
835    List<Type> checkDiamondDenotable(ClassType t) {
836        ListBuffer<Type> buf = new ListBuffer<>();
837        for (Type arg : t.allparams()) {
838            if (!diamondTypeChecker.visit(arg, null)) {
839                buf.append(arg);
840            }
841        }
842        return buf.toList();
843    }
844        // where
845
846        /** diamondTypeChecker: A type visitor that descends down the given type looking for non-denotable
847         *  types. The visit methods return false as soon as a non-denotable type is encountered and true
848         *  otherwise.
849         */
850        private static final Types.SimpleVisitor<Boolean, Void> diamondTypeChecker = new Types.SimpleVisitor<Boolean, Void>() {
851            @Override
852            public Boolean visitType(Type t, Void s) {
853                return true;
854            }
855            @Override
856            public Boolean visitClassType(ClassType t, Void s) {
857                if (t.isCompound()) {
858                    return false;
859                }
860                for (Type targ : t.allparams()) {
861                    if (!visit(targ, s)) {
862                        return false;
863                    }
864                }
865                return true;
866            }
867
868            @Override
869            public Boolean visitTypeVar(TypeVar t, Void s) {
870                /* Any type variable mentioned in the inferred type must have been declared as a type parameter
871                  (i.e cannot have been produced by inference (18.4))
872                */
873                return t.tsym.owner.type.getTypeArguments().contains(t);
874            }
875
876            @Override
877            public Boolean visitCapturedType(CapturedType t, Void s) {
878                /* Any type variable mentioned in the inferred type must have been declared as a type parameter
879                  (i.e cannot have been produced by capture conversion (5.1.10))
880                */
881                return false;
882            }
883
884            @Override
885            public Boolean visitArrayType(ArrayType t, Void s) {
886                return visit(t.elemtype, s);
887            }
888
889            @Override
890            public Boolean visitWildcardType(WildcardType t, Void s) {
891                return visit(t.type, s);
892            }
893        };
894
895    void checkVarargsMethodDecl(Env<AttrContext> env, JCMethodDecl tree) {
896        MethodSymbol m = tree.sym;
897        if (!allowSimplifiedVarargs) return;
898        boolean hasTrustMeAnno = m.attribute(syms.trustMeType.tsym) != null;
899        Type varargElemType = null;
900        if (m.isVarArgs()) {
901            varargElemType = types.elemtype(tree.params.last().type);
902        }
903        if (hasTrustMeAnno && !isTrustMeAllowedOnMethod(m)) {
904            if (varargElemType != null) {
905                log.error(tree,
906                        "varargs.invalid.trustme.anno",
907                          syms.trustMeType.tsym,
908                          allowPrivateSafeVarargs ?
909                          diags.fragment("varargs.trustme.on.virtual.varargs", m) :
910                          diags.fragment("varargs.trustme.on.virtual.varargs.final.only", m));
911            } else {
912                log.error(tree,
913                            "varargs.invalid.trustme.anno",
914                            syms.trustMeType.tsym,
915                            diags.fragment("varargs.trustme.on.non.varargs.meth", m));
916            }
917        } else if (hasTrustMeAnno && varargElemType != null &&
918                            types.isReifiable(varargElemType)) {
919            warnUnsafeVararg(tree,
920                            "varargs.redundant.trustme.anno",
921                            syms.trustMeType.tsym,
922                            diags.fragment("varargs.trustme.on.reifiable.varargs", varargElemType));
923        }
924        else if (!hasTrustMeAnno && varargElemType != null &&
925                !types.isReifiable(varargElemType)) {
926            warnUnchecked(tree.params.head.pos(), "unchecked.varargs.non.reifiable.type", varargElemType);
927        }
928    }
929    //where
930        private boolean isTrustMeAllowedOnMethod(Symbol s) {
931            return (s.flags() & VARARGS) != 0 &&
932                (s.isConstructor() ||
933                    (s.flags() & (STATIC | FINAL |
934                                  (allowPrivateSafeVarargs ? PRIVATE : 0) )) != 0);
935        }
936
937    Type checkMethod(final Type mtype,
938            final Symbol sym,
939            final Env<AttrContext> env,
940            final List<JCExpression> argtrees,
941            final List<Type> argtypes,
942            final boolean useVarargs,
943            InferenceContext inferenceContext) {
944        // System.out.println("call   : " + env.tree);
945        // System.out.println("method : " + owntype);
946        // System.out.println("actuals: " + argtypes);
947        if (inferenceContext.free(mtype)) {
948            inferenceContext.addFreeTypeListener(List.of(mtype), new FreeTypeListener() {
949                public void typesInferred(InferenceContext inferenceContext) {
950                    checkMethod(inferenceContext.asInstType(mtype), sym, env, argtrees, argtypes, useVarargs, inferenceContext);
951                }
952            });
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 = new Filter<Symbol>() {
2066        public boolean accepts(Symbol s) {
2067            return MethodSymbol.implementation_filter.accepts(s) &&
2068                    (s.flags() & BAD_OVERRIDE) == 0;
2069
2070        }
2071    };
2072
2073    public void checkClassOverrideEqualsAndHashIfNeeded(DiagnosticPosition pos,
2074            ClassSymbol someClass) {
2075        /* At present, annotations cannot possibly have a method that is override
2076         * equivalent with Object.equals(Object) but in any case the condition is
2077         * fine for completeness.
2078         */
2079        if (someClass == (ClassSymbol)syms.objectType.tsym ||
2080            someClass.isInterface() || someClass.isEnum() ||
2081            (someClass.flags() & ANNOTATION) != 0 ||
2082            (someClass.flags() & ABSTRACT) != 0) return;
2083        //anonymous inner classes implementing interfaces need especial treatment
2084        if (someClass.isAnonymous()) {
2085            List<Type> interfaces =  types.interfaces(someClass.type);
2086            if (interfaces != null && !interfaces.isEmpty() &&
2087                interfaces.head.tsym == syms.comparatorType.tsym) return;
2088        }
2089        checkClassOverrideEqualsAndHash(pos, someClass);
2090    }
2091
2092    private void checkClassOverrideEqualsAndHash(DiagnosticPosition pos,
2093            ClassSymbol someClass) {
2094        if (lint.isEnabled(LintCategory.OVERRIDES)) {
2095            MethodSymbol equalsAtObject = (MethodSymbol)syms.objectType
2096                    .tsym.members().findFirst(names.equals);
2097            MethodSymbol hashCodeAtObject = (MethodSymbol)syms.objectType
2098                    .tsym.members().findFirst(names.hashCode);
2099            boolean overridesEquals = types.implementation(equalsAtObject,
2100                someClass, false, equalsHasCodeFilter).owner == someClass;
2101            boolean overridesHashCode = types.implementation(hashCodeAtObject,
2102                someClass, false, equalsHasCodeFilter) != hashCodeAtObject;
2103
2104            if (overridesEquals && !overridesHashCode) {
2105                log.warning(LintCategory.OVERRIDES, pos,
2106                        "override.equals.but.not.hashcode", someClass);
2107            }
2108        }
2109    }
2110
2111    private boolean checkNameClash(ClassSymbol origin, Symbol s1, Symbol s2) {
2112        ClashFilter cf = new ClashFilter(origin.type);
2113        return (cf.accepts(s1) &&
2114                cf.accepts(s2) &&
2115                types.hasSameArgs(s1.erasure(types), s2.erasure(types)));
2116    }
2117
2118
2119    /** Check that all abstract members of given class have definitions.
2120     *  @param pos          Position to be used for error reporting.
2121     *  @param c            The class.
2122     */
2123    void checkAllDefined(DiagnosticPosition pos, ClassSymbol c) {
2124        MethodSymbol undef = types.firstUnimplementedAbstract(c);
2125        if (undef != null) {
2126            MethodSymbol undef1 =
2127                new MethodSymbol(undef.flags(), undef.name,
2128                                 types.memberType(c.type, undef), undef.owner);
2129            log.error(pos, "does.not.override.abstract",
2130                      c, undef1, undef1.location());
2131        }
2132    }
2133
2134    void checkNonCyclicDecl(JCClassDecl tree) {
2135        CycleChecker cc = new CycleChecker();
2136        cc.scan(tree);
2137        if (!cc.errorFound && !cc.partialCheck) {
2138            tree.sym.flags_field |= ACYCLIC;
2139        }
2140    }
2141
2142    class CycleChecker extends TreeScanner {
2143
2144        List<Symbol> seenClasses = List.nil();
2145        boolean errorFound = false;
2146        boolean partialCheck = false;
2147
2148        private void checkSymbol(DiagnosticPosition pos, Symbol sym) {
2149            if (sym != null && sym.kind == TYP) {
2150                Env<AttrContext> classEnv = enter.getEnv((TypeSymbol)sym);
2151                if (classEnv != null) {
2152                    DiagnosticSource prevSource = log.currentSource();
2153                    try {
2154                        log.useSource(classEnv.toplevel.sourcefile);
2155                        scan(classEnv.tree);
2156                    }
2157                    finally {
2158                        log.useSource(prevSource.getFile());
2159                    }
2160                } else if (sym.kind == TYP) {
2161                    checkClass(pos, sym, List.<JCTree>nil());
2162                }
2163            } else {
2164                //not completed yet
2165                partialCheck = true;
2166            }
2167        }
2168
2169        @Override
2170        public void visitSelect(JCFieldAccess tree) {
2171            super.visitSelect(tree);
2172            checkSymbol(tree.pos(), tree.sym);
2173        }
2174
2175        @Override
2176        public void visitIdent(JCIdent tree) {
2177            checkSymbol(tree.pos(), tree.sym);
2178        }
2179
2180        @Override
2181        public void visitTypeApply(JCTypeApply tree) {
2182            scan(tree.clazz);
2183        }
2184
2185        @Override
2186        public void visitTypeArray(JCArrayTypeTree tree) {
2187            scan(tree.elemtype);
2188        }
2189
2190        @Override
2191        public void visitClassDef(JCClassDecl tree) {
2192            List<JCTree> supertypes = List.nil();
2193            if (tree.getExtendsClause() != null) {
2194                supertypes = supertypes.prepend(tree.getExtendsClause());
2195            }
2196            if (tree.getImplementsClause() != null) {
2197                for (JCTree intf : tree.getImplementsClause()) {
2198                    supertypes = supertypes.prepend(intf);
2199                }
2200            }
2201            checkClass(tree.pos(), tree.sym, supertypes);
2202        }
2203
2204        void checkClass(DiagnosticPosition pos, Symbol c, List<JCTree> supertypes) {
2205            if ((c.flags_field & ACYCLIC) != 0)
2206                return;
2207            if (seenClasses.contains(c)) {
2208                errorFound = true;
2209                noteCyclic(pos, (ClassSymbol)c);
2210            } else if (!c.type.isErroneous()) {
2211                try {
2212                    seenClasses = seenClasses.prepend(c);
2213                    if (c.type.hasTag(CLASS)) {
2214                        if (supertypes.nonEmpty()) {
2215                            scan(supertypes);
2216                        }
2217                        else {
2218                            ClassType ct = (ClassType)c.type;
2219                            if (ct.supertype_field == null ||
2220                                    ct.interfaces_field == null) {
2221                                //not completed yet
2222                                partialCheck = true;
2223                                return;
2224                            }
2225                            checkSymbol(pos, ct.supertype_field.tsym);
2226                            for (Type intf : ct.interfaces_field) {
2227                                checkSymbol(pos, intf.tsym);
2228                            }
2229                        }
2230                        if (c.owner.kind == TYP) {
2231                            checkSymbol(pos, c.owner);
2232                        }
2233                    }
2234                } finally {
2235                    seenClasses = seenClasses.tail;
2236                }
2237            }
2238        }
2239    }
2240
2241    /** Check for cyclic references. Issue an error if the
2242     *  symbol of the type referred to has a LOCKED flag set.
2243     *
2244     *  @param pos      Position to be used for error reporting.
2245     *  @param t        The type referred to.
2246     */
2247    void checkNonCyclic(DiagnosticPosition pos, Type t) {
2248        checkNonCyclicInternal(pos, t);
2249    }
2250
2251
2252    void checkNonCyclic(DiagnosticPosition pos, TypeVar t) {
2253        checkNonCyclic1(pos, t, List.<TypeVar>nil());
2254    }
2255
2256    private void checkNonCyclic1(DiagnosticPosition pos, Type t, List<TypeVar> seen) {
2257        final TypeVar tv;
2258        if  (t.hasTag(TYPEVAR) && (t.tsym.flags() & UNATTRIBUTED) != 0)
2259            return;
2260        if (seen.contains(t)) {
2261            tv = (TypeVar)t;
2262            tv.bound = types.createErrorType(t);
2263            log.error(pos, "cyclic.inheritance", t);
2264        } else if (t.hasTag(TYPEVAR)) {
2265            tv = (TypeVar)t;
2266            seen = seen.prepend(tv);
2267            for (Type b : types.getBounds(tv))
2268                checkNonCyclic1(pos, b, seen);
2269        }
2270    }
2271
2272    /** Check for cyclic references. Issue an error if the
2273     *  symbol of the type referred to has a LOCKED flag set.
2274     *
2275     *  @param pos      Position to be used for error reporting.
2276     *  @param t        The type referred to.
2277     *  @returns        True if the check completed on all attributed classes
2278     */
2279    private boolean checkNonCyclicInternal(DiagnosticPosition pos, Type t) {
2280        boolean complete = true; // was the check complete?
2281        //- System.err.println("checkNonCyclicInternal("+t+");");//DEBUG
2282        Symbol c = t.tsym;
2283        if ((c.flags_field & ACYCLIC) != 0) return true;
2284
2285        if ((c.flags_field & LOCKED) != 0) {
2286            noteCyclic(pos, (ClassSymbol)c);
2287        } else if (!c.type.isErroneous()) {
2288            try {
2289                c.flags_field |= LOCKED;
2290                if (c.type.hasTag(CLASS)) {
2291                    ClassType clazz = (ClassType)c.type;
2292                    if (clazz.interfaces_field != null)
2293                        for (List<Type> l=clazz.interfaces_field; l.nonEmpty(); l=l.tail)
2294                            complete &= checkNonCyclicInternal(pos, l.head);
2295                    if (clazz.supertype_field != null) {
2296                        Type st = clazz.supertype_field;
2297                        if (st != null && st.hasTag(CLASS))
2298                            complete &= checkNonCyclicInternal(pos, st);
2299                    }
2300                    if (c.owner.kind == TYP)
2301                        complete &= checkNonCyclicInternal(pos, c.owner.type);
2302                }
2303            } finally {
2304                c.flags_field &= ~LOCKED;
2305            }
2306        }
2307        if (complete)
2308            complete = ((c.flags_field & UNATTRIBUTED) == 0) && c.isCompleted();
2309        if (complete) c.flags_field |= ACYCLIC;
2310        return complete;
2311    }
2312
2313    /** Note that we found an inheritance cycle. */
2314    private void noteCyclic(DiagnosticPosition pos, ClassSymbol c) {
2315        log.error(pos, "cyclic.inheritance", c);
2316        for (List<Type> l=types.interfaces(c.type); l.nonEmpty(); l=l.tail)
2317            l.head = types.createErrorType((ClassSymbol)l.head.tsym, Type.noType);
2318        Type st = types.supertype(c.type);
2319        if (st.hasTag(CLASS))
2320            ((ClassType)c.type).supertype_field = types.createErrorType((ClassSymbol)st.tsym, Type.noType);
2321        c.type = types.createErrorType(c, c.type);
2322        c.flags_field |= ACYCLIC;
2323    }
2324
2325    /** Check that all methods which implement some
2326     *  method conform to the method they implement.
2327     *  @param tree         The class definition whose members are checked.
2328     */
2329    void checkImplementations(JCClassDecl tree) {
2330        checkImplementations(tree, tree.sym, tree.sym);
2331    }
2332    //where
2333        /** Check that all methods which implement some
2334         *  method in `ic' conform to the method they implement.
2335         */
2336        void checkImplementations(JCTree tree, ClassSymbol origin, ClassSymbol ic) {
2337            for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) {
2338                ClassSymbol lc = (ClassSymbol)l.head.tsym;
2339                if ((lc.flags() & ABSTRACT) != 0) {
2340                    for (Symbol sym : lc.members().getSymbols(NON_RECURSIVE)) {
2341                        if (sym.kind == MTH &&
2342                            (sym.flags() & (STATIC|ABSTRACT)) == ABSTRACT) {
2343                            MethodSymbol absmeth = (MethodSymbol)sym;
2344                            MethodSymbol implmeth = absmeth.implementation(origin, types, false);
2345                            if (implmeth != null && implmeth != absmeth &&
2346                                (implmeth.owner.flags() & INTERFACE) ==
2347                                (origin.flags() & INTERFACE)) {
2348                                // don't check if implmeth is in a class, yet
2349                                // origin is an interface. This case arises only
2350                                // if implmeth is declared in Object. The reason is
2351                                // that interfaces really don't inherit from
2352                                // Object it's just that the compiler represents
2353                                // things that way.
2354                                checkOverride(tree, implmeth, absmeth, origin);
2355                            }
2356                        }
2357                    }
2358                }
2359            }
2360        }
2361
2362    /** Check that all abstract methods implemented by a class are
2363     *  mutually compatible.
2364     *  @param pos          Position to be used for error reporting.
2365     *  @param c            The class whose interfaces are checked.
2366     */
2367    void checkCompatibleSupertypes(DiagnosticPosition pos, Type c) {
2368        List<Type> supertypes = types.interfaces(c);
2369        Type supertype = types.supertype(c);
2370        if (supertype.hasTag(CLASS) &&
2371            (supertype.tsym.flags() & ABSTRACT) != 0)
2372            supertypes = supertypes.prepend(supertype);
2373        for (List<Type> l = supertypes; l.nonEmpty(); l = l.tail) {
2374            if (!l.head.getTypeArguments().isEmpty() &&
2375                !checkCompatibleAbstracts(pos, l.head, l.head, c))
2376                return;
2377            for (List<Type> m = supertypes; m != l; m = m.tail)
2378                if (!checkCompatibleAbstracts(pos, l.head, m.head, c))
2379                    return;
2380        }
2381        checkCompatibleConcretes(pos, c);
2382    }
2383
2384    void checkConflicts(DiagnosticPosition pos, Symbol sym, TypeSymbol c) {
2385        for (Type ct = c.type; ct != Type.noType ; ct = types.supertype(ct)) {
2386            for (Symbol sym2 : ct.tsym.members().getSymbolsByName(sym.name, NON_RECURSIVE)) {
2387                // VM allows methods and variables with differing types
2388                if (sym.kind == sym2.kind &&
2389                    types.isSameType(types.erasure(sym.type), types.erasure(sym2.type)) &&
2390                    sym != sym2 &&
2391                    (sym.flags() & Flags.SYNTHETIC) != (sym2.flags() & Flags.SYNTHETIC) &&
2392                    (sym.flags() & BRIDGE) == 0 && (sym2.flags() & BRIDGE) == 0) {
2393                    syntheticError(pos, (sym2.flags() & SYNTHETIC) == 0 ? sym2 : sym);
2394                    return;
2395                }
2396            }
2397        }
2398    }
2399
2400    /** Check that all non-override equivalent methods accessible from 'site'
2401     *  are mutually compatible (JLS 8.4.8/9.4.1).
2402     *
2403     *  @param pos  Position to be used for error reporting.
2404     *  @param site The class whose methods are checked.
2405     *  @param sym  The method symbol to be checked.
2406     */
2407    void checkOverrideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
2408         ClashFilter cf = new ClashFilter(site);
2409        //for each method m1 that is overridden (directly or indirectly)
2410        //by method 'sym' in 'site'...
2411
2412        List<MethodSymbol> potentiallyAmbiguousList = List.nil();
2413        boolean overridesAny = false;
2414        for (Symbol m1 : types.membersClosure(site, false).getSymbolsByName(sym.name, cf)) {
2415            if (!sym.overrides(m1, site.tsym, types, false)) {
2416                if (m1 == sym) {
2417                    continue;
2418                }
2419
2420                if (!overridesAny) {
2421                    potentiallyAmbiguousList = potentiallyAmbiguousList.prepend((MethodSymbol)m1);
2422                }
2423                continue;
2424            }
2425
2426            if (m1 != sym) {
2427                overridesAny = true;
2428                potentiallyAmbiguousList = List.nil();
2429            }
2430
2431            //...check each method m2 that is a member of 'site'
2432            for (Symbol m2 : types.membersClosure(site, false).getSymbolsByName(sym.name, cf)) {
2433                if (m2 == m1) continue;
2434                //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
2435                //a member of 'site') and (ii) m1 has the same erasure as m2, issue an error
2436                if (!types.isSubSignature(sym.type, types.memberType(site, m2), allowStrictMethodClashCheck) &&
2437                        types.hasSameArgs(m2.erasure(types), m1.erasure(types))) {
2438                    sym.flags_field |= CLASH;
2439                    String key = m1 == sym ?
2440                            "name.clash.same.erasure.no.override" :
2441                            "name.clash.same.erasure.no.override.1";
2442                    log.error(pos,
2443                            key,
2444                            sym, sym.location(),
2445                            m2, m2.location(),
2446                            m1, m1.location());
2447                    return;
2448                }
2449            }
2450        }
2451
2452        if (!overridesAny) {
2453            for (MethodSymbol m: potentiallyAmbiguousList) {
2454                checkPotentiallyAmbiguousOverloads(pos, site, sym, m);
2455            }
2456        }
2457    }
2458
2459    /** Check that all static methods accessible from 'site' are
2460     *  mutually compatible (JLS 8.4.8).
2461     *
2462     *  @param pos  Position to be used for error reporting.
2463     *  @param site The class whose methods are checked.
2464     *  @param sym  The method symbol to be checked.
2465     */
2466    void checkHideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
2467        ClashFilter cf = new ClashFilter(site);
2468        //for each method m1 that is a member of 'site'...
2469        for (Symbol s : types.membersClosure(site, true).getSymbolsByName(sym.name, cf)) {
2470            //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
2471            //a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error
2472            if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck)) {
2473                if (types.hasSameArgs(s.erasure(types), sym.erasure(types))) {
2474                    log.error(pos,
2475                            "name.clash.same.erasure.no.hide",
2476                            sym, sym.location(),
2477                            s, s.location());
2478                    return;
2479                } else {
2480                    checkPotentiallyAmbiguousOverloads(pos, site, sym, (MethodSymbol)s);
2481                }
2482            }
2483         }
2484     }
2485
2486     //where
2487     private class ClashFilter implements Filter<Symbol> {
2488
2489         Type site;
2490
2491         ClashFilter(Type site) {
2492             this.site = site;
2493         }
2494
2495         boolean shouldSkip(Symbol s) {
2496             return (s.flags() & CLASH) != 0 &&
2497                s.owner == site.tsym;
2498         }
2499
2500         public boolean accepts(Symbol s) {
2501             return s.kind == MTH &&
2502                     (s.flags() & SYNTHETIC) == 0 &&
2503                     !shouldSkip(s) &&
2504                     s.isInheritedIn(site.tsym, types) &&
2505                     !s.isConstructor();
2506         }
2507     }
2508
2509    void checkDefaultMethodClashes(DiagnosticPosition pos, Type site) {
2510        DefaultMethodClashFilter dcf = new DefaultMethodClashFilter(site);
2511        for (Symbol m : types.membersClosure(site, false).getSymbols(dcf)) {
2512            Assert.check(m.kind == MTH);
2513            List<MethodSymbol> prov = types.interfaceCandidates(site, (MethodSymbol)m);
2514            if (prov.size() > 1) {
2515                ListBuffer<Symbol> abstracts = new ListBuffer<>();
2516                ListBuffer<Symbol> defaults = new ListBuffer<>();
2517                for (MethodSymbol provSym : prov) {
2518                    if ((provSym.flags() & DEFAULT) != 0) {
2519                        defaults = defaults.append(provSym);
2520                    } else if ((provSym.flags() & ABSTRACT) != 0) {
2521                        abstracts = abstracts.append(provSym);
2522                    }
2523                    if (defaults.nonEmpty() && defaults.size() + abstracts.size() >= 2) {
2524                        //strong semantics - issue an error if two sibling interfaces
2525                        //have two override-equivalent defaults - or if one is abstract
2526                        //and the other is default
2527                        String errKey;
2528                        Symbol s1 = defaults.first();
2529                        Symbol s2;
2530                        if (defaults.size() > 1) {
2531                            errKey = "types.incompatible.unrelated.defaults";
2532                            s2 = defaults.toList().tail.head;
2533                        } else {
2534                            errKey = "types.incompatible.abstract.default";
2535                            s2 = abstracts.first();
2536                        }
2537                        log.error(pos, errKey,
2538                                Kinds.kindName(site.tsym), site,
2539                                m.name, types.memberType(site, m).getParameterTypes(),
2540                                s1.location(), s2.location());
2541                        break;
2542                    }
2543                }
2544            }
2545        }
2546    }
2547
2548    //where
2549     private class DefaultMethodClashFilter implements Filter<Symbol> {
2550
2551         Type site;
2552
2553         DefaultMethodClashFilter(Type site) {
2554             this.site = site;
2555         }
2556
2557         public boolean accepts(Symbol s) {
2558             return s.kind == MTH &&
2559                     (s.flags() & DEFAULT) != 0 &&
2560                     s.isInheritedIn(site.tsym, types) &&
2561                     !s.isConstructor();
2562         }
2563     }
2564
2565    /**
2566      * Report warnings for potentially ambiguous method declarations. Two declarations
2567      * are potentially ambiguous if they feature two unrelated functional interface
2568      * in same argument position (in which case, a call site passing an implicit
2569      * lambda would be ambiguous).
2570      */
2571    void checkPotentiallyAmbiguousOverloads(DiagnosticPosition pos, Type site,
2572            MethodSymbol msym1, MethodSymbol msym2) {
2573        if (msym1 != msym2 &&
2574                allowDefaultMethods &&
2575                lint.isEnabled(LintCategory.OVERLOADS) &&
2576                (msym1.flags() & POTENTIALLY_AMBIGUOUS) == 0 &&
2577                (msym2.flags() & POTENTIALLY_AMBIGUOUS) == 0) {
2578            Type mt1 = types.memberType(site, msym1);
2579            Type mt2 = types.memberType(site, msym2);
2580            //if both generic methods, adjust type variables
2581            if (mt1.hasTag(FORALL) && mt2.hasTag(FORALL) &&
2582                    types.hasSameBounds((ForAll)mt1, (ForAll)mt2)) {
2583                mt2 = types.subst(mt2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars);
2584            }
2585            //expand varargs methods if needed
2586            int maxLength = Math.max(mt1.getParameterTypes().length(), mt2.getParameterTypes().length());
2587            List<Type> args1 = rs.adjustArgs(mt1.getParameterTypes(), msym1, maxLength, true);
2588            List<Type> args2 = rs.adjustArgs(mt2.getParameterTypes(), msym2, maxLength, true);
2589            //if arities don't match, exit
2590            if (args1.length() != args2.length()) return;
2591            boolean potentiallyAmbiguous = false;
2592            while (args1.nonEmpty() && args2.nonEmpty()) {
2593                Type s = args1.head;
2594                Type t = args2.head;
2595                if (!types.isSubtype(t, s) && !types.isSubtype(s, t)) {
2596                    if (types.isFunctionalInterface(s) && types.isFunctionalInterface(t) &&
2597                            types.findDescriptorType(s).getParameterTypes().length() > 0 &&
2598                            types.findDescriptorType(s).getParameterTypes().length() ==
2599                            types.findDescriptorType(t).getParameterTypes().length()) {
2600                        potentiallyAmbiguous = true;
2601                    } else {
2602                        break;
2603                    }
2604                }
2605                args1 = args1.tail;
2606                args2 = args2.tail;
2607            }
2608            if (potentiallyAmbiguous) {
2609                //we found two incompatible functional interfaces with same arity
2610                //this means a call site passing an implicit lambda would be ambigiuous
2611                msym1.flags_field |= POTENTIALLY_AMBIGUOUS;
2612                msym2.flags_field |= POTENTIALLY_AMBIGUOUS;
2613                log.warning(LintCategory.OVERLOADS, pos, "potentially.ambiguous.overload",
2614                            msym1, msym1.location(),
2615                            msym2, msym2.location());
2616                return;
2617            }
2618        }
2619    }
2620
2621    void checkAccessFromSerializableElement(final JCTree tree, boolean isLambda) {
2622        if (warnOnAnyAccessToMembers ||
2623            (lint.isEnabled(LintCategory.SERIAL) &&
2624            !lint.isSuppressed(LintCategory.SERIAL) &&
2625            isLambda)) {
2626            Symbol sym = TreeInfo.symbol(tree);
2627            if (!sym.kind.matches(KindSelector.VAL_MTH)) {
2628                return;
2629            }
2630
2631            if (sym.kind == VAR) {
2632                if ((sym.flags() & PARAMETER) != 0 ||
2633                    sym.isLocal() ||
2634                    sym.name == names._this ||
2635                    sym.name == names._super) {
2636                    return;
2637                }
2638            }
2639
2640            if (!types.isSubtype(sym.owner.type, syms.serializableType) &&
2641                isEffectivelyNonPublic(sym)) {
2642                if (isLambda) {
2643                    if (belongsToRestrictedPackage(sym)) {
2644                        log.warning(LintCategory.SERIAL, tree.pos(),
2645                            "access.to.member.from.serializable.lambda", sym);
2646                    }
2647                } else {
2648                    log.warning(tree.pos(),
2649                        "access.to.member.from.serializable.element", sym);
2650                }
2651            }
2652        }
2653    }
2654
2655    private boolean isEffectivelyNonPublic(Symbol sym) {
2656        if (sym.packge() == syms.rootPackage) {
2657            return false;
2658        }
2659
2660        while (sym.kind != PCK) {
2661            if ((sym.flags() & PUBLIC) == 0) {
2662                return true;
2663            }
2664            sym = sym.owner;
2665        }
2666        return false;
2667    }
2668
2669    private boolean belongsToRestrictedPackage(Symbol sym) {
2670        String fullName = sym.packge().fullname.toString();
2671        return fullName.startsWith("java.") ||
2672                fullName.startsWith("javax.") ||
2673                fullName.startsWith("sun.") ||
2674                fullName.contains(".internal.");
2675    }
2676
2677    /** Report a conflict between a user symbol and a synthetic symbol.
2678     */
2679    private void syntheticError(DiagnosticPosition pos, Symbol sym) {
2680        if (!sym.type.isErroneous()) {
2681            log.error(pos, "synthetic.name.conflict", sym, sym.location());
2682        }
2683    }
2684
2685    /** Check that class c does not implement directly or indirectly
2686     *  the same parameterized interface with two different argument lists.
2687     *  @param pos          Position to be used for error reporting.
2688     *  @param type         The type whose interfaces are checked.
2689     */
2690    void checkClassBounds(DiagnosticPosition pos, Type type) {
2691        checkClassBounds(pos, new HashMap<TypeSymbol,Type>(), type);
2692    }
2693//where
2694        /** Enter all interfaces of type `type' into the hash table `seensofar'
2695         *  with their class symbol as key and their type as value. Make
2696         *  sure no class is entered with two different types.
2697         */
2698        void checkClassBounds(DiagnosticPosition pos,
2699                              Map<TypeSymbol,Type> seensofar,
2700                              Type type) {
2701            if (type.isErroneous()) return;
2702            for (List<Type> l = types.interfaces(type); l.nonEmpty(); l = l.tail) {
2703                Type it = l.head;
2704                Type oldit = seensofar.put(it.tsym, it);
2705                if (oldit != null) {
2706                    List<Type> oldparams = oldit.allparams();
2707                    List<Type> newparams = it.allparams();
2708                    if (!types.containsTypeEquivalent(oldparams, newparams))
2709                        log.error(pos, "cant.inherit.diff.arg",
2710                                  it.tsym, Type.toString(oldparams),
2711                                  Type.toString(newparams));
2712                }
2713                checkClassBounds(pos, seensofar, it);
2714            }
2715            Type st = types.supertype(type);
2716            if (st != Type.noType) checkClassBounds(pos, seensofar, st);
2717        }
2718
2719    /** Enter interface into into set.
2720     *  If it existed already, issue a "repeated interface" error.
2721     */
2722    void checkNotRepeated(DiagnosticPosition pos, Type it, Set<Type> its) {
2723        if (its.contains(it))
2724            log.error(pos, "repeated.interface");
2725        else {
2726            its.add(it);
2727        }
2728    }
2729
2730/* *************************************************************************
2731 * Check annotations
2732 **************************************************************************/
2733
2734    /**
2735     * Recursively validate annotations values
2736     */
2737    void validateAnnotationTree(JCTree tree) {
2738        class AnnotationValidator extends TreeScanner {
2739            @Override
2740            public void visitAnnotation(JCAnnotation tree) {
2741                if (!tree.type.isErroneous()) {
2742                    super.visitAnnotation(tree);
2743                    validateAnnotation(tree);
2744                }
2745            }
2746        }
2747        tree.accept(new AnnotationValidator());
2748    }
2749
2750    /**
2751     *  {@literal
2752     *  Annotation types are restricted to primitives, String, an
2753     *  enum, an annotation, Class, Class<?>, Class<? extends
2754     *  Anything>, arrays of the preceding.
2755     *  }
2756     */
2757    void validateAnnotationType(JCTree restype) {
2758        // restype may be null if an error occurred, so don't bother validating it
2759        if (restype != null) {
2760            validateAnnotationType(restype.pos(), restype.type);
2761        }
2762    }
2763
2764    void validateAnnotationType(DiagnosticPosition pos, Type type) {
2765        if (type.isPrimitive()) return;
2766        if (types.isSameType(type, syms.stringType)) return;
2767        if ((type.tsym.flags() & Flags.ENUM) != 0) return;
2768        if ((type.tsym.flags() & Flags.ANNOTATION) != 0) return;
2769        if (types.cvarLowerBound(type).tsym == syms.classType.tsym) return;
2770        if (types.isArray(type) && !types.isArray(types.elemtype(type))) {
2771            validateAnnotationType(pos, types.elemtype(type));
2772            return;
2773        }
2774        log.error(pos, "invalid.annotation.member.type");
2775    }
2776
2777    /**
2778     * "It is also a compile-time error if any method declared in an
2779     * annotation type has a signature that is override-equivalent to
2780     * that of any public or protected method declared in class Object
2781     * or in the interface annotation.Annotation."
2782     *
2783     * @jls 9.6 Annotation Types
2784     */
2785    void validateAnnotationMethod(DiagnosticPosition pos, MethodSymbol m) {
2786        for (Type sup = syms.annotationType; sup.hasTag(CLASS); sup = types.supertype(sup)) {
2787            Scope s = sup.tsym.members();
2788            for (Symbol sym : s.getSymbolsByName(m.name)) {
2789                if (sym.kind == MTH &&
2790                    (sym.flags() & (PUBLIC | PROTECTED)) != 0 &&
2791                    types.overrideEquivalent(m.type, sym.type))
2792                    log.error(pos, "intf.annotation.member.clash", sym, sup);
2793            }
2794        }
2795    }
2796
2797    /** Check the annotations of a symbol.
2798     */
2799    public void validateAnnotations(List<JCAnnotation> annotations, Symbol s) {
2800        for (JCAnnotation a : annotations)
2801            validateAnnotation(a, s);
2802    }
2803
2804    /** Check the type annotations.
2805     */
2806    public void validateTypeAnnotations(List<JCAnnotation> annotations, boolean isTypeParameter) {
2807        for (JCAnnotation a : annotations)
2808            validateTypeAnnotation(a, isTypeParameter);
2809    }
2810
2811    /** Check an annotation of a symbol.
2812     */
2813    private void validateAnnotation(JCAnnotation a, Symbol s) {
2814        validateAnnotationTree(a);
2815
2816        if (!annotationApplicable(a, s))
2817            log.error(a.pos(), "annotation.type.not.applicable");
2818
2819        if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) {
2820            if (s.kind != TYP) {
2821                log.error(a.pos(), "bad.functional.intf.anno");
2822            } else if (!s.isInterface() || (s.flags() & ANNOTATION) != 0) {
2823                log.error(a.pos(), "bad.functional.intf.anno.1", diags.fragment("not.a.functional.intf", s));
2824            }
2825        }
2826    }
2827
2828    public void validateTypeAnnotation(JCAnnotation a, boolean isTypeParameter) {
2829        Assert.checkNonNull(a.type);
2830        validateAnnotationTree(a);
2831
2832        if (a.hasTag(TYPE_ANNOTATION) &&
2833                !a.annotationType.type.isErroneous() &&
2834                !isTypeAnnotation(a, isTypeParameter)) {
2835            log.error(a.pos(), Errors.AnnotationTypeNotApplicableToType(a.type));
2836        }
2837    }
2838
2839    /**
2840     * Validate the proposed container 'repeatable' on the
2841     * annotation type symbol 's'. Report errors at position
2842     * 'pos'.
2843     *
2844     * @param s The (annotation)type declaration annotated with a @Repeatable
2845     * @param repeatable the @Repeatable on 's'
2846     * @param pos where to report errors
2847     */
2848    public void validateRepeatable(TypeSymbol s, Attribute.Compound repeatable, DiagnosticPosition pos) {
2849        Assert.check(types.isSameType(repeatable.type, syms.repeatableType));
2850
2851        Type t = null;
2852        List<Pair<MethodSymbol,Attribute>> l = repeatable.values;
2853        if (!l.isEmpty()) {
2854            Assert.check(l.head.fst.name == names.value);
2855            t = ((Attribute.Class)l.head.snd).getValue();
2856        }
2857
2858        if (t == null) {
2859            // errors should already have been reported during Annotate
2860            return;
2861        }
2862
2863        validateValue(t.tsym, s, pos);
2864        validateRetention(t.tsym, s, pos);
2865        validateDocumented(t.tsym, s, pos);
2866        validateInherited(t.tsym, s, pos);
2867        validateTarget(t.tsym, s, pos);
2868        validateDefault(t.tsym, pos);
2869    }
2870
2871    private void validateValue(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
2872        Symbol sym = container.members().findFirst(names.value);
2873        if (sym != null && sym.kind == MTH) {
2874            MethodSymbol m = (MethodSymbol) sym;
2875            Type ret = m.getReturnType();
2876            if (!(ret.hasTag(ARRAY) && types.isSameType(((ArrayType)ret).elemtype, contained.type))) {
2877                log.error(pos, "invalid.repeatable.annotation.value.return",
2878                        container, ret, types.makeArrayType(contained.type));
2879            }
2880        } else {
2881            log.error(pos, "invalid.repeatable.annotation.no.value", container);
2882        }
2883    }
2884
2885    private void validateRetention(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
2886        Attribute.RetentionPolicy containerRetention = types.getRetention(container);
2887        Attribute.RetentionPolicy containedRetention = types.getRetention(contained);
2888
2889        boolean error = false;
2890        switch (containedRetention) {
2891        case RUNTIME:
2892            if (containerRetention != Attribute.RetentionPolicy.RUNTIME) {
2893                error = true;
2894            }
2895            break;
2896        case CLASS:
2897            if (containerRetention == Attribute.RetentionPolicy.SOURCE)  {
2898                error = true;
2899            }
2900        }
2901        if (error ) {
2902            log.error(pos, "invalid.repeatable.annotation.retention",
2903                      container, containerRetention,
2904                      contained, containedRetention);
2905        }
2906    }
2907
2908    private void validateDocumented(Symbol container, Symbol contained, DiagnosticPosition pos) {
2909        if (contained.attribute(syms.documentedType.tsym) != null) {
2910            if (container.attribute(syms.documentedType.tsym) == null) {
2911                log.error(pos, "invalid.repeatable.annotation.not.documented", container, contained);
2912            }
2913        }
2914    }
2915
2916    private void validateInherited(Symbol container, Symbol contained, DiagnosticPosition pos) {
2917        if (contained.attribute(syms.inheritedType.tsym) != null) {
2918            if (container.attribute(syms.inheritedType.tsym) == null) {
2919                log.error(pos, "invalid.repeatable.annotation.not.inherited", container, contained);
2920            }
2921        }
2922    }
2923
2924    private void validateTarget(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
2925        // The set of targets the container is applicable to must be a subset
2926        // (with respect to annotation target semantics) of the set of targets
2927        // the contained is applicable to. The target sets may be implicit or
2928        // explicit.
2929
2930        Set<Name> containerTargets;
2931        Attribute.Array containerTarget = getAttributeTargetAttribute(container);
2932        if (containerTarget == null) {
2933            containerTargets = getDefaultTargetSet();
2934        } else {
2935            containerTargets = new HashSet<>();
2936            for (Attribute app : containerTarget.values) {
2937                if (!(app instanceof Attribute.Enum)) {
2938                    continue; // recovery
2939                }
2940                Attribute.Enum e = (Attribute.Enum)app;
2941                containerTargets.add(e.value.name);
2942            }
2943        }
2944
2945        Set<Name> containedTargets;
2946        Attribute.Array containedTarget = getAttributeTargetAttribute(contained);
2947        if (containedTarget == null) {
2948            containedTargets = getDefaultTargetSet();
2949        } else {
2950            containedTargets = new HashSet<>();
2951            for (Attribute app : containedTarget.values) {
2952                if (!(app instanceof Attribute.Enum)) {
2953                    continue; // recovery
2954                }
2955                Attribute.Enum e = (Attribute.Enum)app;
2956                containedTargets.add(e.value.name);
2957            }
2958        }
2959
2960        if (!isTargetSubsetOf(containerTargets, containedTargets)) {
2961            log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained);
2962        }
2963    }
2964
2965    /* get a set of names for the default target */
2966    private Set<Name> getDefaultTargetSet() {
2967        if (defaultTargets == null) {
2968            Set<Name> targets = new HashSet<>();
2969            targets.add(names.ANNOTATION_TYPE);
2970            targets.add(names.CONSTRUCTOR);
2971            targets.add(names.FIELD);
2972            targets.add(names.LOCAL_VARIABLE);
2973            targets.add(names.METHOD);
2974            targets.add(names.PACKAGE);
2975            targets.add(names.PARAMETER);
2976            targets.add(names.TYPE);
2977
2978            defaultTargets = java.util.Collections.unmodifiableSet(targets);
2979        }
2980
2981        return defaultTargets;
2982    }
2983    private Set<Name> defaultTargets;
2984
2985
2986    /** Checks that s is a subset of t, with respect to ElementType
2987     * semantics, specifically {ANNOTATION_TYPE} is a subset of {TYPE},
2988     * and {TYPE_USE} covers the set {ANNOTATION_TYPE, TYPE, TYPE_USE,
2989     * TYPE_PARAMETER}.
2990     */
2991    private boolean isTargetSubsetOf(Set<Name> s, Set<Name> t) {
2992        // Check that all elements in s are present in t
2993        for (Name n2 : s) {
2994            boolean currentElementOk = false;
2995            for (Name n1 : t) {
2996                if (n1 == n2) {
2997                    currentElementOk = true;
2998                    break;
2999                } else if (n1 == names.TYPE && n2 == names.ANNOTATION_TYPE) {
3000                    currentElementOk = true;
3001                    break;
3002                } else if (n1 == names.TYPE_USE &&
3003                        (n2 == names.TYPE ||
3004                         n2 == names.ANNOTATION_TYPE ||
3005                         n2 == names.TYPE_PARAMETER)) {
3006                    currentElementOk = true;
3007                    break;
3008                }
3009            }
3010            if (!currentElementOk)
3011                return false;
3012        }
3013        return true;
3014    }
3015
3016    private void validateDefault(Symbol container, DiagnosticPosition pos) {
3017        // validate that all other elements of containing type has defaults
3018        Scope scope = container.members();
3019        for(Symbol elm : scope.getSymbols()) {
3020            if (elm.name != names.value &&
3021                elm.kind == MTH &&
3022                ((MethodSymbol)elm).defaultValue == null) {
3023                log.error(pos,
3024                          "invalid.repeatable.annotation.elem.nondefault",
3025                          container,
3026                          elm);
3027            }
3028        }
3029    }
3030
3031    /** Is s a method symbol that overrides a method in a superclass? */
3032    boolean isOverrider(Symbol s) {
3033        if (s.kind != MTH || s.isStatic())
3034            return false;
3035        MethodSymbol m = (MethodSymbol)s;
3036        TypeSymbol owner = (TypeSymbol)m.owner;
3037        for (Type sup : types.closure(owner.type)) {
3038            if (sup == owner.type)
3039                continue; // skip "this"
3040            Scope scope = sup.tsym.members();
3041            for (Symbol sym : scope.getSymbolsByName(m.name)) {
3042                if (!sym.isStatic() && m.overrides(sym, owner, types, true))
3043                    return true;
3044            }
3045        }
3046        return false;
3047    }
3048
3049    /** Is the annotation applicable to types? */
3050    protected boolean isTypeAnnotation(JCAnnotation a, boolean isTypeParameter) {
3051        List<Attribute> targets = typeAnnotations.annotationTargets(a.annotationType.type.tsym);
3052        return (targets == null) ?
3053                false :
3054                targets.stream()
3055                        .anyMatch(attr -> isTypeAnnotation(attr, isTypeParameter));
3056    }
3057    //where
3058        boolean isTypeAnnotation(Attribute a, boolean isTypeParameter) {
3059            Attribute.Enum e = (Attribute.Enum)a;
3060            return (e.value.name == names.TYPE_USE ||
3061                    (isTypeParameter && e.value.name == names.TYPE_PARAMETER));
3062        }
3063
3064    /** Is the annotation applicable to the symbol? */
3065    boolean annotationApplicable(JCAnnotation a, Symbol s) {
3066        Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym);
3067        Name[] targets;
3068
3069        if (arr == null) {
3070            targets = defaultTargetMetaInfo(a, s);
3071        } else {
3072            // TODO: can we optimize this?
3073            targets = new Name[arr.values.length];
3074            for (int i=0; i<arr.values.length; ++i) {
3075                Attribute app = arr.values[i];
3076                if (!(app instanceof Attribute.Enum)) {
3077                    return true; // recovery
3078                }
3079                Attribute.Enum e = (Attribute.Enum) app;
3080                targets[i] = e.value.name;
3081            }
3082        }
3083        for (Name target : targets) {
3084            if (target == names.TYPE) {
3085                if (s.kind == TYP)
3086                    return true;
3087            } else if (target == names.FIELD) {
3088                if (s.kind == VAR && s.owner.kind != MTH)
3089                    return true;
3090            } else if (target == names.METHOD) {
3091                if (s.kind == MTH && !s.isConstructor())
3092                    return true;
3093            } else if (target == names.PARAMETER) {
3094                if (s.kind == VAR && s.owner.kind == MTH &&
3095                      (s.flags() & PARAMETER) != 0) {
3096                    return true;
3097                }
3098            } else if (target == names.CONSTRUCTOR) {
3099                if (s.kind == MTH && s.isConstructor())
3100                    return true;
3101            } else if (target == names.LOCAL_VARIABLE) {
3102                if (s.kind == VAR && s.owner.kind == MTH &&
3103                      (s.flags() & PARAMETER) == 0) {
3104                    return true;
3105                }
3106            } else if (target == names.ANNOTATION_TYPE) {
3107                if (s.kind == TYP && (s.flags() & ANNOTATION) != 0) {
3108                    return true;
3109                }
3110            } else if (target == names.PACKAGE) {
3111                if (s.kind == PCK)
3112                    return true;
3113            } else if (target == names.TYPE_USE) {
3114                if (s.kind == TYP || s.kind == VAR ||
3115                        (s.kind == MTH && !s.isConstructor() &&
3116                                !s.type.getReturnType().hasTag(VOID)) ||
3117                        (s.kind == MTH && s.isConstructor())) {
3118                    return true;
3119                }
3120            } else if (target == names.TYPE_PARAMETER) {
3121                if (s.kind == TYP && s.type.hasTag(TYPEVAR))
3122                    return true;
3123            } else
3124                return true; // Unknown ElementType. This should be an error at declaration site,
3125                             // assume applicable.
3126        }
3127        return false;
3128    }
3129
3130
3131    Attribute.Array getAttributeTargetAttribute(TypeSymbol s) {
3132        Attribute.Compound atTarget = s.getAnnotationTypeMetadata().getTarget();
3133        if (atTarget == null) return null; // ok, is applicable
3134        Attribute atValue = atTarget.member(names.value);
3135        if (!(atValue instanceof Attribute.Array)) return null; // error recovery
3136        return (Attribute.Array) atValue;
3137    }
3138
3139    private final Name[] dfltTargetMeta;
3140    private Name[] defaultTargetMetaInfo(JCAnnotation a, Symbol s) {
3141        return dfltTargetMeta;
3142    }
3143
3144    /** Check an annotation value.
3145     *
3146     * @param a The annotation tree to check
3147     * @return true if this annotation tree is valid, otherwise false
3148     */
3149    public boolean validateAnnotationDeferErrors(JCAnnotation a) {
3150        boolean res = false;
3151        final Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
3152        try {
3153            res = validateAnnotation(a);
3154        } finally {
3155            log.popDiagnosticHandler(diagHandler);
3156        }
3157        return res;
3158    }
3159
3160    private boolean validateAnnotation(JCAnnotation a) {
3161        boolean isValid = true;
3162        AnnotationTypeMetadata metadata = a.annotationType.type.tsym.getAnnotationTypeMetadata();
3163
3164        // collect an inventory of the annotation elements
3165        Set<MethodSymbol> elements = metadata.getAnnotationElements();
3166
3167        // remove the ones that are assigned values
3168        for (JCTree arg : a.args) {
3169            if (!arg.hasTag(ASSIGN)) continue; // recovery
3170            JCAssign assign = (JCAssign)arg;
3171            Symbol m = TreeInfo.symbol(assign.lhs);
3172            if (m == null || m.type.isErroneous()) continue;
3173            if (!elements.remove(m)) {
3174                isValid = false;
3175                log.error(assign.lhs.pos(), "duplicate.annotation.member.value",
3176                        m.name, a.type);
3177            }
3178        }
3179
3180        // all the remaining ones better have default values
3181        List<Name> missingDefaults = List.nil();
3182        Set<MethodSymbol> membersWithDefault = metadata.getAnnotationElementsWithDefault();
3183        for (MethodSymbol m : elements) {
3184            if (m.type.isErroneous())
3185                continue;
3186
3187            if (!membersWithDefault.contains(m))
3188                missingDefaults = missingDefaults.append(m.name);
3189        }
3190        missingDefaults = missingDefaults.reverse();
3191        if (missingDefaults.nonEmpty()) {
3192            isValid = false;
3193            String key = (missingDefaults.size() > 1)
3194                    ? "annotation.missing.default.value.1"
3195                    : "annotation.missing.default.value";
3196            log.error(a.pos(), key, a.type, missingDefaults);
3197        }
3198
3199        return isValid && validateTargetAnnotationValue(a);
3200    }
3201
3202    /* Validate the special java.lang.annotation.Target annotation */
3203    boolean validateTargetAnnotationValue(JCAnnotation a) {
3204        // special case: java.lang.annotation.Target must not have
3205        // repeated values in its value member
3206        if (a.annotationType.type.tsym != syms.annotationTargetType.tsym ||
3207                a.args.tail == null)
3208            return true;
3209
3210        boolean isValid = true;
3211        if (!a.args.head.hasTag(ASSIGN)) return false; // error recovery
3212        JCAssign assign = (JCAssign) a.args.head;
3213        Symbol m = TreeInfo.symbol(assign.lhs);
3214        if (m.name != names.value) return false;
3215        JCTree rhs = assign.rhs;
3216        if (!rhs.hasTag(NEWARRAY)) return false;
3217        JCNewArray na = (JCNewArray) rhs;
3218        Set<Symbol> targets = new HashSet<>();
3219        for (JCTree elem : na.elems) {
3220            if (!targets.add(TreeInfo.symbol(elem))) {
3221                isValid = false;
3222                log.error(elem.pos(), "repeated.annotation.target");
3223            }
3224        }
3225        return isValid;
3226    }
3227
3228    void checkDeprecatedAnnotation(DiagnosticPosition pos, Symbol s) {
3229        if (lint.isEnabled(LintCategory.DEP_ANN) && s.isDeprecatableViaAnnotation() &&
3230            (s.flags() & DEPRECATED) != 0 &&
3231            !syms.deprecatedType.isErroneous() &&
3232            s.attribute(syms.deprecatedType.tsym) == null) {
3233            log.warning(LintCategory.DEP_ANN,
3234                    pos, "missing.deprecated.annotation");
3235        }
3236        // Note: @Deprecated has no effect on local variables, parameters and package decls.
3237        if (lint.isEnabled(LintCategory.DEPRECATION) && !s.isDeprecatableViaAnnotation()) {
3238            if (!syms.deprecatedType.isErroneous() && s.attribute(syms.deprecatedType.tsym) != null) {
3239                log.warning(LintCategory.DEPRECATION, pos,
3240                        "deprecated.annotation.has.no.effect", Kinds.kindName(s));
3241            }
3242        }
3243    }
3244
3245    void checkDeprecated(final DiagnosticPosition pos, final Symbol other, final Symbol s) {
3246        if ( (s.isDeprecatedForRemoval()
3247                || s.isDeprecated() && !other.isDeprecated())
3248              && s.outermostClass() != other.outermostClass()) {
3249            deferredLintHandler.report(new DeferredLintHandler.LintLogger() {
3250                @Override
3251                public void report() {
3252                    warnDeprecated(pos, s);
3253                }
3254            });
3255        }
3256    }
3257
3258    void checkSunAPI(final DiagnosticPosition pos, final Symbol s) {
3259        if ((s.flags() & PROPRIETARY) != 0) {
3260            deferredLintHandler.report(() -> {
3261                log.mandatoryWarning(pos, "sun.proprietary", s);
3262            });
3263        }
3264    }
3265
3266    void checkProfile(final DiagnosticPosition pos, final Symbol s) {
3267        if (profile != Profile.DEFAULT && (s.flags() & NOT_IN_PROFILE) != 0) {
3268            log.error(pos, "not.in.profile", s, profile);
3269        }
3270    }
3271
3272/* *************************************************************************
3273 * Check for recursive annotation elements.
3274 **************************************************************************/
3275
3276    /** Check for cycles in the graph of annotation elements.
3277     */
3278    void checkNonCyclicElements(JCClassDecl tree) {
3279        if ((tree.sym.flags_field & ANNOTATION) == 0) return;
3280        Assert.check((tree.sym.flags_field & LOCKED) == 0);
3281        try {
3282            tree.sym.flags_field |= LOCKED;
3283            for (JCTree def : tree.defs) {
3284                if (!def.hasTag(METHODDEF)) continue;
3285                JCMethodDecl meth = (JCMethodDecl)def;
3286                checkAnnotationResType(meth.pos(), meth.restype.type);
3287            }
3288        } finally {
3289            tree.sym.flags_field &= ~LOCKED;
3290            tree.sym.flags_field |= ACYCLIC_ANN;
3291        }
3292    }
3293
3294    void checkNonCyclicElementsInternal(DiagnosticPosition pos, TypeSymbol tsym) {
3295        if ((tsym.flags_field & ACYCLIC_ANN) != 0)
3296            return;
3297        if ((tsym.flags_field & LOCKED) != 0) {
3298            log.error(pos, "cyclic.annotation.element");
3299            return;
3300        }
3301        try {
3302            tsym.flags_field |= LOCKED;
3303            for (Symbol s : tsym.members().getSymbols(NON_RECURSIVE)) {
3304                if (s.kind != MTH)
3305                    continue;
3306                checkAnnotationResType(pos, ((MethodSymbol)s).type.getReturnType());
3307            }
3308        } finally {
3309            tsym.flags_field &= ~LOCKED;
3310            tsym.flags_field |= ACYCLIC_ANN;
3311        }
3312    }
3313
3314    void checkAnnotationResType(DiagnosticPosition pos, Type type) {
3315        switch (type.getTag()) {
3316        case CLASS:
3317            if ((type.tsym.flags() & ANNOTATION) != 0)
3318                checkNonCyclicElementsInternal(pos, type.tsym);
3319            break;
3320        case ARRAY:
3321            checkAnnotationResType(pos, types.elemtype(type));
3322            break;
3323        default:
3324            break; // int etc
3325        }
3326    }
3327
3328/* *************************************************************************
3329 * Check for cycles in the constructor call graph.
3330 **************************************************************************/
3331
3332    /** Check for cycles in the graph of constructors calling other
3333     *  constructors.
3334     */
3335    void checkCyclicConstructors(JCClassDecl tree) {
3336        Map<Symbol,Symbol> callMap = new HashMap<>();
3337
3338        // enter each constructor this-call into the map
3339        for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
3340            JCMethodInvocation app = TreeInfo.firstConstructorCall(l.head);
3341            if (app == null) continue;
3342            JCMethodDecl meth = (JCMethodDecl) l.head;
3343            if (TreeInfo.name(app.meth) == names._this) {
3344                callMap.put(meth.sym, TreeInfo.symbol(app.meth));
3345            } else {
3346                meth.sym.flags_field |= ACYCLIC;
3347            }
3348        }
3349
3350        // Check for cycles in the map
3351        Symbol[] ctors = new Symbol[0];
3352        ctors = callMap.keySet().toArray(ctors);
3353        for (Symbol caller : ctors) {
3354            checkCyclicConstructor(tree, caller, callMap);
3355        }
3356    }
3357
3358    /** Look in the map to see if the given constructor is part of a
3359     *  call cycle.
3360     */
3361    private void checkCyclicConstructor(JCClassDecl tree, Symbol ctor,
3362                                        Map<Symbol,Symbol> callMap) {
3363        if (ctor != null && (ctor.flags_field & ACYCLIC) == 0) {
3364            if ((ctor.flags_field & LOCKED) != 0) {
3365                log.error(TreeInfo.diagnosticPositionFor(ctor, tree),
3366                          "recursive.ctor.invocation");
3367            } else {
3368                ctor.flags_field |= LOCKED;
3369                checkCyclicConstructor(tree, callMap.remove(ctor), callMap);
3370                ctor.flags_field &= ~LOCKED;
3371            }
3372            ctor.flags_field |= ACYCLIC;
3373        }
3374    }
3375
3376/* *************************************************************************
3377 * Miscellaneous
3378 **************************************************************************/
3379
3380    /**
3381     *  Check for division by integer constant zero
3382     *  @param pos           Position for error reporting.
3383     *  @param operator      The operator for the expression
3384     *  @param operand       The right hand operand for the expression
3385     */
3386    void checkDivZero(final DiagnosticPosition pos, Symbol operator, Type operand) {
3387        if (operand.constValue() != null
3388            && operand.getTag().isSubRangeOf(LONG)
3389            && ((Number) (operand.constValue())).longValue() == 0) {
3390            int opc = ((OperatorSymbol)operator).opcode;
3391            if (opc == ByteCodes.idiv || opc == ByteCodes.imod
3392                || opc == ByteCodes.ldiv || opc == ByteCodes.lmod) {
3393                deferredLintHandler.report(new DeferredLintHandler.LintLogger() {
3394                    @Override
3395                    public void report() {
3396                        warnDivZero(pos);
3397                    }
3398                });
3399            }
3400        }
3401    }
3402
3403    /**
3404     * Check for empty statements after if
3405     */
3406    void checkEmptyIf(JCIf tree) {
3407        if (tree.thenpart.hasTag(SKIP) && tree.elsepart == null &&
3408                lint.isEnabled(LintCategory.EMPTY))
3409            log.warning(LintCategory.EMPTY, tree.thenpart.pos(), "empty.if");
3410    }
3411
3412    /** Check that symbol is unique in given scope.
3413     *  @param pos           Position for error reporting.
3414     *  @param sym           The symbol.
3415     *  @param s             The scope.
3416     */
3417    boolean checkUnique(DiagnosticPosition pos, Symbol sym, Scope s) {
3418        if (sym.type.isErroneous())
3419            return true;
3420        if (sym.owner.name == names.any) return false;
3421        for (Symbol byName : s.getSymbolsByName(sym.name, NON_RECURSIVE)) {
3422            if (sym != byName &&
3423                    (byName.flags() & CLASH) == 0 &&
3424                    sym.kind == byName.kind &&
3425                    sym.name != names.error &&
3426                    (sym.kind != MTH ||
3427                     types.hasSameArgs(sym.type, byName.type) ||
3428                     types.hasSameArgs(types.erasure(sym.type), types.erasure(byName.type)))) {
3429                if ((sym.flags() & VARARGS) != (byName.flags() & VARARGS)) {
3430                    varargsDuplicateError(pos, sym, byName);
3431                    return true;
3432                } else if (sym.kind == MTH && !types.hasSameArgs(sym.type, byName.type, false)) {
3433                    duplicateErasureError(pos, sym, byName);
3434                    sym.flags_field |= CLASH;
3435                    return true;
3436                } else {
3437                    duplicateError(pos, byName);
3438                    return false;
3439                }
3440            }
3441        }
3442        return true;
3443    }
3444
3445    /** Report duplicate declaration error.
3446     */
3447    void duplicateErasureError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) {
3448        if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) {
3449            log.error(pos, "name.clash.same.erasure", sym1, sym2);
3450        }
3451    }
3452
3453    /**Check that types imported through the ordinary imports don't clash with types imported
3454     * by other (static or ordinary) imports. Note that two static imports may import two clashing
3455     * types without an error on the imports.
3456     * @param toplevel       The toplevel tree for which the test should be performed.
3457     */
3458    void checkImportsUnique(JCCompilationUnit toplevel) {
3459        WriteableScope ordinallyImportedSoFar = WriteableScope.create(toplevel.packge);
3460        WriteableScope staticallyImportedSoFar = WriteableScope.create(toplevel.packge);
3461        WriteableScope topLevelScope = toplevel.toplevelScope;
3462
3463        for (JCTree def : toplevel.defs) {
3464            if (!def.hasTag(IMPORT))
3465                continue;
3466
3467            JCImport imp = (JCImport) def;
3468
3469            if (imp.importScope == null)
3470                continue;
3471
3472            for (Symbol sym : imp.importScope.getSymbols(sym -> sym.kind == TYP)) {
3473                if (imp.isStatic()) {
3474                    checkUniqueImport(imp.pos(), ordinallyImportedSoFar, staticallyImportedSoFar, topLevelScope, sym, true);
3475                    staticallyImportedSoFar.enter(sym);
3476                } else {
3477                    checkUniqueImport(imp.pos(), ordinallyImportedSoFar, staticallyImportedSoFar, topLevelScope, sym, false);
3478                    ordinallyImportedSoFar.enter(sym);
3479                }
3480            }
3481
3482            imp.importScope = null;
3483        }
3484    }
3485
3486    /** Check that single-type import is not already imported or top-level defined,
3487     *  but make an exception for two single-type imports which denote the same type.
3488     *  @param pos                     Position for error reporting.
3489     *  @param ordinallyImportedSoFar  A Scope containing types imported so far through
3490     *                                 ordinary imports.
3491     *  @param staticallyImportedSoFar A Scope containing types imported so far through
3492     *                                 static imports.
3493     *  @param topLevelScope           The current file's top-level Scope
3494     *  @param sym                     The symbol.
3495     *  @param staticImport            Whether or not this was a static import
3496     */
3497    private boolean checkUniqueImport(DiagnosticPosition pos, Scope ordinallyImportedSoFar,
3498                                      Scope staticallyImportedSoFar, Scope topLevelScope,
3499                                      Symbol sym, boolean staticImport) {
3500        Filter<Symbol> duplicates = candidate -> candidate != sym && !candidate.type.isErroneous();
3501        Symbol clashing = ordinallyImportedSoFar.findFirst(sym.name, duplicates);
3502        if (clashing == null && !staticImport) {
3503            clashing = staticallyImportedSoFar.findFirst(sym.name, duplicates);
3504        }
3505        if (clashing != null) {
3506            if (staticImport)
3507                log.error(pos, "already.defined.static.single.import", clashing);
3508            else
3509                log.error(pos, "already.defined.single.import", clashing);
3510            return false;
3511        }
3512        clashing = topLevelScope.findFirst(sym.name, duplicates);
3513        if (clashing != null) {
3514            log.error(pos, "already.defined.this.unit", clashing);
3515            return false;
3516        }
3517        return true;
3518    }
3519
3520    /** Check that a qualified name is in canonical form (for import decls).
3521     */
3522    public void checkCanonical(JCTree tree) {
3523        if (!isCanonical(tree))
3524            log.error(tree.pos(), "import.requires.canonical",
3525                      TreeInfo.symbol(tree));
3526    }
3527        // where
3528        private boolean isCanonical(JCTree tree) {
3529            while (tree.hasTag(SELECT)) {
3530                JCFieldAccess s = (JCFieldAccess) tree;
3531                if (s.sym.owner.name != TreeInfo.symbol(s.selected).name)
3532                    return false;
3533                tree = s.selected;
3534            }
3535            return true;
3536        }
3537
3538    /** Check that an auxiliary class is not accessed from any other file than its own.
3539     */
3540    void checkForBadAuxiliaryClassAccess(DiagnosticPosition pos, Env<AttrContext> env, ClassSymbol c) {
3541        if (lint.isEnabled(Lint.LintCategory.AUXILIARYCLASS) &&
3542            (c.flags() & AUXILIARY) != 0 &&
3543            rs.isAccessible(env, c) &&
3544            !fileManager.isSameFile(c.sourcefile, env.toplevel.sourcefile))
3545        {
3546            log.warning(pos, "auxiliary.class.accessed.from.outside.of.its.source.file",
3547                        c, c.sourcefile);
3548        }
3549    }
3550
3551    private class ConversionWarner extends Warner {
3552        final String uncheckedKey;
3553        final Type found;
3554        final Type expected;
3555        public ConversionWarner(DiagnosticPosition pos, String uncheckedKey, Type found, Type expected) {
3556            super(pos);
3557            this.uncheckedKey = uncheckedKey;
3558            this.found = found;
3559            this.expected = expected;
3560        }
3561
3562        @Override
3563        public void warn(LintCategory lint) {
3564            boolean warned = this.warned;
3565            super.warn(lint);
3566            if (warned) return; // suppress redundant diagnostics
3567            switch (lint) {
3568                case UNCHECKED:
3569                    Check.this.warnUnchecked(pos(), "prob.found.req", diags.fragment(uncheckedKey), found, expected);
3570                    break;
3571                case VARARGS:
3572                    if (method != null &&
3573                            method.attribute(syms.trustMeType.tsym) != null &&
3574                            isTrustMeAllowedOnMethod(method) &&
3575                            !types.isReifiable(method.type.getParameterTypes().last())) {
3576                        Check.this.warnUnsafeVararg(pos(), "varargs.unsafe.use.varargs.param", method.params.last());
3577                    }
3578                    break;
3579                default:
3580                    throw new AssertionError("Unexpected lint: " + lint);
3581            }
3582        }
3583    }
3584
3585    public Warner castWarner(DiagnosticPosition pos, Type found, Type expected) {
3586        return new ConversionWarner(pos, "unchecked.cast.to.type", found, expected);
3587    }
3588
3589    public Warner convertWarner(DiagnosticPosition pos, Type found, Type expected) {
3590        return new ConversionWarner(pos, "unchecked.assign", found, expected);
3591    }
3592
3593    public void checkFunctionalInterface(JCClassDecl tree, ClassSymbol cs) {
3594        Compound functionalType = cs.attribute(syms.functionalInterfaceType.tsym);
3595
3596        if (functionalType != null) {
3597            try {
3598                types.findDescriptorSymbol((TypeSymbol)cs);
3599            } catch (Types.FunctionDescriptorLookupError ex) {
3600                DiagnosticPosition pos = tree.pos();
3601                for (JCAnnotation a : tree.getModifiers().annotations) {
3602                    if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) {
3603                        pos = a.pos();
3604                        break;
3605                    }
3606                }
3607                log.error(pos, "bad.functional.intf.anno.1", ex.getDiagnostic());
3608            }
3609        }
3610    }
3611
3612    public void checkImportsResolvable(final JCCompilationUnit toplevel) {
3613        for (final JCImport imp : toplevel.getImports()) {
3614            if (!imp.staticImport || !imp.qualid.hasTag(SELECT))
3615                continue;
3616            final JCFieldAccess select = (JCFieldAccess) imp.qualid;
3617            final Symbol origin;
3618            if (select.name == names.asterisk || (origin = TreeInfo.symbol(select.selected)) == null || origin.kind != TYP)
3619                continue;
3620
3621            TypeSymbol site = (TypeSymbol) TreeInfo.symbol(select.selected);
3622            if (!checkTypeContainsImportableElement(site, site, toplevel.packge, select.name, new HashSet<Symbol>())) {
3623                log.error(imp.pos(), "cant.resolve.location",
3624                          KindName.STATIC,
3625                          select.name, List.<Type>nil(), List.<Type>nil(),
3626                          Kinds.typeKindName(TreeInfo.symbol(select.selected).type),
3627                          TreeInfo.symbol(select.selected).type);
3628            }
3629        }
3630    }
3631
3632    // Check that packages imported are in scope (JLS 7.4.3, 6.3, 6.5.3.1, 6.5.3.2)
3633    public void checkImportedPackagesObservable(final JCCompilationUnit toplevel) {
3634        OUTER: for (JCImport imp : toplevel.getImports()) {
3635            if (!imp.staticImport && TreeInfo.name(imp.qualid) == names.asterisk) {
3636                TypeSymbol tsym = ((JCFieldAccess)imp.qualid).selected.type.tsym;
3637                if (toplevel.modle.visiblePackages != null) {
3638                    //TODO - unclear: selects like javax.* will get resolved from the current module
3639                    //(as javax is not an exported package from any module). And as javax in the current
3640                    //module typically does not contain any classes or subpackages, we need to go through
3641                    //the visible packages to find a sub-package:
3642                    for (PackageSymbol known : toplevel.modle.visiblePackages.values()) {
3643                        if (Convert.packagePart(known.fullname) == tsym.flatName())
3644                            continue OUTER;
3645                    }
3646                }
3647                if (tsym.kind == PCK && tsym.members().isEmpty() && !tsym.exists()) {
3648                    log.error(DiagnosticFlag.RESOLVE_ERROR, imp.pos, "doesnt.exist", tsym);
3649                }
3650            }
3651        }
3652    }
3653
3654    private boolean checkTypeContainsImportableElement(TypeSymbol tsym, TypeSymbol origin, PackageSymbol packge, Name name, Set<Symbol> processed) {
3655        if (tsym == null || !processed.add(tsym))
3656            return false;
3657
3658            // also search through inherited names
3659        if (checkTypeContainsImportableElement(types.supertype(tsym.type).tsym, origin, packge, name, processed))
3660            return true;
3661
3662        for (Type t : types.interfaces(tsym.type))
3663            if (checkTypeContainsImportableElement(t.tsym, origin, packge, name, processed))
3664                return true;
3665
3666        for (Symbol sym : tsym.members().getSymbolsByName(name)) {
3667            if (sym.isStatic() &&
3668                importAccessible(sym, packge) &&
3669                sym.isMemberOf(origin, types)) {
3670                return true;
3671            }
3672        }
3673
3674        return false;
3675    }
3676
3677    // is the sym accessible everywhere in packge?
3678    public boolean importAccessible(Symbol sym, PackageSymbol packge) {
3679        try {
3680            int flags = (int)(sym.flags() & AccessFlags);
3681            switch (flags) {
3682            default:
3683            case PUBLIC:
3684                return true;
3685            case PRIVATE:
3686                return false;
3687            case 0:
3688            case PROTECTED:
3689                return sym.packge() == packge;
3690            }
3691        } catch (ClassFinder.BadClassFile err) {
3692            throw err;
3693        } catch (CompletionFailure ex) {
3694            return false;
3695        }
3696    }
3697
3698    public void checkLeaksNotAccessible(Env<AttrContext> env, JCClassDecl check) {
3699        JCCompilationUnit toplevel = env.toplevel;
3700
3701        if (   toplevel.modle == syms.unnamedModule
3702            || toplevel.modle == syms.noModule
3703            || (check.sym.flags() & COMPOUND) != 0) {
3704            return ;
3705        }
3706
3707        ExportsDirective currentExport = findExport(toplevel.packge);
3708
3709        if (   currentExport == null //not exported
3710            || currentExport.modules != null) //don't check classes in qualified export
3711            return ;
3712
3713        new TreeScanner() {
3714            Lint lint = env.info.lint;
3715            boolean inSuperType;
3716
3717            @Override
3718            public void visitBlock(JCBlock tree) {
3719            }
3720            @Override
3721            public void visitMethodDef(JCMethodDecl tree) {
3722                if (!isAPISymbol(tree.sym))
3723                    return;
3724                Lint prevLint = lint;
3725                try {
3726                    lint = lint.augment(tree.sym);
3727                    if (lint.isEnabled(LintCategory.EXPORTS)) {
3728                        super.visitMethodDef(tree);
3729                    }
3730                } finally {
3731                    lint = prevLint;
3732                }
3733            }
3734            @Override
3735            public void visitVarDef(JCVariableDecl tree) {
3736                if (!isAPISymbol(tree.sym) && tree.sym.owner.kind != MTH)
3737                    return;
3738                Lint prevLint = lint;
3739                try {
3740                    lint = lint.augment(tree.sym);
3741                    if (lint.isEnabled(LintCategory.EXPORTS)) {
3742                        scan(tree.mods);
3743                        scan(tree.vartype);
3744                    }
3745                } finally {
3746                    lint = prevLint;
3747                }
3748            }
3749            @Override
3750            public void visitClassDef(JCClassDecl tree) {
3751                if (tree != check)
3752                    return ;
3753
3754                if (!isAPISymbol(tree.sym))
3755                    return ;
3756
3757                Lint prevLint = lint;
3758                try {
3759                    lint = lint.augment(tree.sym);
3760                    if (lint.isEnabled(LintCategory.EXPORTS)) {
3761                        scan(tree.mods);
3762                        scan(tree.typarams);
3763                        try {
3764                            inSuperType = true;
3765                            scan(tree.extending);
3766                            scan(tree.implementing);
3767                        } finally {
3768                            inSuperType = false;
3769                        }
3770                        scan(tree.defs);
3771                    }
3772                } finally {
3773                    lint = prevLint;
3774                }
3775            }
3776            @Override
3777            public void visitTypeApply(JCTypeApply tree) {
3778                scan(tree.clazz);
3779                boolean oldInSuperType = inSuperType;
3780                try {
3781                    inSuperType = false;
3782                    scan(tree.arguments);
3783                } finally {
3784                    inSuperType = oldInSuperType;
3785                }
3786            }
3787            @Override
3788            public void visitIdent(JCIdent tree) {
3789                Symbol sym = TreeInfo.symbol(tree);
3790                if (sym.kind == TYP && !sym.type.hasTag(TYPEVAR)) {
3791                    checkVisible(tree.pos(), sym, toplevel.packge, inSuperType);
3792                }
3793            }
3794
3795            @Override
3796            public void visitSelect(JCFieldAccess tree) {
3797                Symbol sym = TreeInfo.symbol(tree);
3798                Symbol sitesym = TreeInfo.symbol(tree.selected);
3799                if (sym.kind == TYP && sitesym.kind == PCK) {
3800                    checkVisible(tree.pos(), sym, toplevel.packge, inSuperType);
3801                } else {
3802                    super.visitSelect(tree);
3803                }
3804            }
3805
3806            @Override
3807            public void visitAnnotation(JCAnnotation tree) {
3808                if (tree.attribute.type.tsym.getAnnotation(java.lang.annotation.Documented.class) != null)
3809                    super.visitAnnotation(tree);
3810            }
3811
3812        }.scan(check);
3813    }
3814        //where:
3815        private ExportsDirective findExport(PackageSymbol pack) {
3816            for (ExportsDirective d : pack.modle.exports) {
3817                if (d.packge == pack)
3818                    return d;
3819            }
3820
3821            return null;
3822        }
3823        private boolean isAPISymbol(Symbol sym) {
3824            while (sym.kind != PCK) {
3825                if ((sym.flags() & Flags.PUBLIC) == 0 && (sym.flags() & Flags.PROTECTED) == 0) {
3826                    return false;
3827                }
3828                sym = sym.owner;
3829            }
3830            return true;
3831        }
3832        private void checkVisible(DiagnosticPosition pos, Symbol what, PackageSymbol inPackage, boolean inSuperType) {
3833            if (!isAPISymbol(what) && !inSuperType) { //package private/private element
3834                log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessible(kindName(what), what, what.packge().modle));
3835                return ;
3836            }
3837
3838            PackageSymbol whatPackage = what.packge();
3839            ExportsDirective whatExport = findExport(whatPackage);
3840            ExportsDirective inExport = findExport(inPackage);
3841
3842            if (whatExport == null) { //package not exported:
3843                log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessibleUnexported(kindName(what), what, what.packge().modle));
3844                return ;
3845            }
3846
3847            if (whatExport.modules != null) {
3848                if (inExport.modules == null || !whatExport.modules.containsAll(inExport.modules)) {
3849                    log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessibleUnexportedQualified(kindName(what), what, what.packge().modle));
3850                }
3851            }
3852
3853            if (whatPackage.modle != inPackage.modle && whatPackage.modle != syms.java_base) {
3854                //check that relativeTo.modle requires public what.modle, somehow:
3855                List<ModuleSymbol> todo = List.of(inPackage.modle);
3856
3857                while (todo.nonEmpty()) {
3858                    ModuleSymbol current = todo.head;
3859                    todo = todo.tail;
3860                    if (current == whatPackage.modle)
3861                        return ; //OK
3862                    for (RequiresDirective req : current.requires) {
3863                        if (req.isPublic()) {
3864                            todo = todo.prepend(req.module);
3865                        }
3866                    }
3867                }
3868
3869                log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessibleNotRequiredPublic(kindName(what), what, what.packge().modle));
3870            }
3871        }
3872}
3873