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