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