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