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