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