1 /*
   2  * Copyright (c) 1999, 2026, 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 import java.util.function.BiConsumer;
  30 import java.util.function.Consumer;
  31 import java.util.stream.Stream;
  32 
  33 import javax.lang.model.element.ElementKind;
  34 import javax.tools.JavaFileObject;
  35 
  36 import com.sun.source.tree.CaseTree;
  37 import com.sun.source.tree.IdentifierTree;
  38 import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
  39 import com.sun.source.tree.MemberSelectTree;
  40 import com.sun.source.tree.TreeVisitor;
  41 import com.sun.source.util.SimpleTreeVisitor;
  42 import com.sun.tools.javac.code.*;
  43 import com.sun.tools.javac.code.Lint.LintCategory;
  44 import com.sun.tools.javac.code.LintMapper;
  45 import com.sun.tools.javac.code.Scope.WriteableScope;
  46 import com.sun.tools.javac.code.Source.Feature;
  47 import com.sun.tools.javac.code.Symbol.*;
  48 import com.sun.tools.javac.code.Type.*;
  49 import com.sun.tools.javac.code.Types.FunctionDescriptorLookupError;
  50 import com.sun.tools.javac.comp.ArgumentAttr.LocalCacheContext;
  51 import com.sun.tools.javac.comp.Check.CheckContext;
  52 import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
  53 import com.sun.tools.javac.comp.MatchBindingsComputer.MatchBindings;
  54 import com.sun.tools.javac.jvm.*;
  55 
  56 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.Diamond;
  57 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.DiamondInvalidArg;
  58 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.DiamondInvalidArgs;
  59 
  60 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  61 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  62 import com.sun.tools.javac.resources.CompilerProperties.LintWarnings;
  63 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
  64 import com.sun.tools.javac.tree.*;
  65 import com.sun.tools.javac.tree.JCTree.*;
  66 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
  67 import com.sun.tools.javac.util.*;
  68 import com.sun.tools.javac.util.DefinedBy.Api;
  69 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  70 import com.sun.tools.javac.util.JCDiagnostic.Error;
  71 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
  72 import com.sun.tools.javac.util.JCDiagnostic.Warning;
  73 import com.sun.tools.javac.util.List;
  74 
  75 import static com.sun.tools.javac.code.Flags.*;
  76 import static com.sun.tools.javac.code.Flags.ANNOTATION;
  77 import static com.sun.tools.javac.code.Flags.BLOCK;
  78 import static com.sun.tools.javac.code.Kinds.*;
  79 import static com.sun.tools.javac.code.Kinds.Kind.*;
  80 import static com.sun.tools.javac.code.TypeTag.*;
  81 import static com.sun.tools.javac.code.TypeTag.WILDCARD;
  82 import static com.sun.tools.javac.tree.JCTree.Tag.*;
  83 
  84 /** This is the main context-dependent analysis phase in GJC. It
  85  *  encompasses name resolution, type checking and constant folding as
  86  *  subtasks. Some subtasks involve auxiliary classes.
  87  *  @see Check
  88  *  @see Resolve
  89  *  @see ConstFold
  90  *  @see Infer
  91  *
  92  *  <p><b>This is NOT part of any supported API.
  93  *  If you write code that depends on this, you do so at your own risk.
  94  *  This code and its internal interfaces are subject to change or
  95  *  deletion without notice.</b>
  96  */
  97 public class Attr extends JCTree.Visitor {
  98     protected static final Context.Key<Attr> attrKey = new Context.Key<>();
  99 
 100     final Names names;
 101     final Log log;
 102     final LintMapper lintMapper;
 103     final Symtab syms;
 104     final Resolve rs;
 105     final Operators operators;
 106     final Infer infer;
 107     final Analyzer analyzer;
 108     final DeferredAttr deferredAttr;
 109     final Check chk;
 110     final Flow flow;
 111     final MemberEnter memberEnter;
 112     final TypeEnter typeEnter;
 113     final TreeMaker make;
 114     final ConstFold cfolder;
 115     final Enter enter;
 116     final Target target;
 117     final Types types;
 118     final Preview preview;
 119     final JCDiagnostic.Factory diags;
 120     final TypeAnnotations typeAnnotations;
 121     final TypeEnvs typeEnvs;
 122     final Dependencies dependencies;
 123     final Annotate annotate;
 124     final ArgumentAttr argumentAttr;
 125     final MatchBindingsComputer matchBindingsComputer;
 126     final AttrRecover attrRecover;
 127     final boolean captureMRefReturnType;
 128 
 129     public static Attr instance(Context context) {
 130         Attr instance = context.get(attrKey);
 131         if (instance == null)
 132             instance = new Attr(context);
 133         return instance;
 134     }
 135 
 136     @SuppressWarnings("this-escape")
 137     protected Attr(Context context) {
 138         context.put(attrKey, this);
 139 
 140         names = Names.instance(context);
 141         log = Log.instance(context);
 142         lintMapper = LintMapper.instance(context);
 143         syms = Symtab.instance(context);
 144         rs = Resolve.instance(context);
 145         operators = Operators.instance(context);
 146         chk = Check.instance(context);
 147         flow = Flow.instance(context);
 148         memberEnter = MemberEnter.instance(context);
 149         typeEnter = TypeEnter.instance(context);
 150         make = TreeMaker.instance(context);
 151         enter = Enter.instance(context);
 152         infer = Infer.instance(context);
 153         analyzer = Analyzer.instance(context);
 154         deferredAttr = DeferredAttr.instance(context);
 155         cfolder = ConstFold.instance(context);
 156         target = Target.instance(context);
 157         types = Types.instance(context);
 158         preview = Preview.instance(context);
 159         diags = JCDiagnostic.Factory.instance(context);
 160         annotate = Annotate.instance(context);
 161         typeAnnotations = TypeAnnotations.instance(context);
 162         typeEnvs = TypeEnvs.instance(context);
 163         dependencies = Dependencies.instance(context);
 164         argumentAttr = ArgumentAttr.instance(context);
 165         matchBindingsComputer = MatchBindingsComputer.instance(context);
 166         attrRecover = AttrRecover.instance(context);
 167 
 168         Options options = Options.instance(context);
 169 
 170         Source source = Source.instance(context);
 171         allowReifiableTypesInInstanceof = Feature.REIFIABLE_TYPES_INSTANCEOF.allowedInSource(source);
 172         allowRecords = Feature.RECORDS.allowedInSource(source);
 173         allowPatternSwitch = (preview.isEnabled() || !preview.isPreview(Feature.PATTERN_SWITCH)) &&
 174                              Feature.PATTERN_SWITCH.allowedInSource(source);
 175         allowUnconditionalPatternsInstanceOf =
 176                              Feature.UNCONDITIONAL_PATTERN_IN_INSTANCEOF.allowedInSource(source);
 177         sourceName = source.name;
 178         useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning");
 179         captureMRefReturnType = Source.Feature.CAPTURE_MREF_RETURN_TYPE.allowedInSource(source);
 180 
 181         statInfo = new ResultInfo(KindSelector.NIL, Type.noType);
 182         varAssignmentInfo = new ResultInfo(KindSelector.ASG, Type.noType);
 183         varAssignmentOpInfo = new ResultInfo(KindSelector.ASG_OP, Type.noType);
 184         unknownExprInfo = new ResultInfo(KindSelector.VAL, Type.noType);
 185         methodAttrInfo = new MethodAttrInfo();
 186         unknownTypeInfo = new ResultInfo(KindSelector.TYP, Type.noType);
 187         unknownTypeExprInfo = new ResultInfo(KindSelector.VAL_TYP, Type.noType);
 188         recoveryInfo = new RecoveryInfo(deferredAttr.emptyDeferredAttrContext);
 189         initBlockType = new MethodType(List.nil(), syms.voidType, List.nil(), syms.methodClass);
 190         allowValueClasses = preview.isEnabled() && Feature.VALUE_CLASSES.allowedInSource(source);
 191     }
 192 
 193     /** Switch: reifiable types in instanceof enabled?
 194      */
 195     boolean allowReifiableTypesInInstanceof;
 196 
 197     /** Are records allowed
 198      */
 199     private final boolean allowRecords;
 200 
 201     /** Are patterns in switch allowed
 202      */
 203     private final boolean allowPatternSwitch;
 204 
 205     /** Are unconditional patterns in instanceof allowed
 206      */
 207     private final boolean allowUnconditionalPatternsInstanceOf;
 208 
 209     /** Are value classes allowed
 210      */
 211     private final boolean allowValueClasses;
 212 
 213     /**
 214      * Switch: warn about use of variable before declaration?
 215      * RFE: 6425594
 216      */
 217     boolean useBeforeDeclarationWarning;
 218 
 219     /**
 220      * Switch: name of source level; used for error reporting.
 221      */
 222     String sourceName;
 223 
 224     /** Check kind and type of given tree against protokind and prototype.
 225      *  If check succeeds, store type in tree and return it.
 226      *  If check fails, store errType in tree and return it.
 227      *  No checks are performed if the prototype is a method type.
 228      *  It is not necessary in this case since we know that kind and type
 229      *  are correct.
 230      *
 231      *  @param tree     The tree whose kind and type is checked
 232      *  @param found    The computed type of the tree
 233      *  @param ownkind  The computed kind of the tree
 234      *  @param resultInfo  The expected result of the tree
 235      */
 236     Type check(final JCTree tree,
 237                final Type found,
 238                final KindSelector ownkind,
 239                final ResultInfo resultInfo) {
 240         InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext();
 241         Type owntype;
 242         boolean shouldCheck = !found.hasTag(ERROR) &&
 243                 !resultInfo.pt.hasTag(METHOD) &&
 244                 !resultInfo.pt.hasTag(FORALL);
 245         if (shouldCheck && !ownkind.subset(resultInfo.pkind)) {
 246             log.error(tree.pos(),
 247                       Errors.UnexpectedType(resultInfo.pkind.kindNames(),
 248                                             ownkind.kindNames()));
 249             owntype = types.createErrorType(found);
 250         } else if (inferenceContext.free(found)) {
 251             //delay the check if there are inference variables in the found type
 252             //this means we are dealing with a partially inferred poly expression
 253             owntype = shouldCheck ? resultInfo.pt : found;
 254             if (resultInfo.checkMode.installPostInferenceHook()) {
 255                 inferenceContext.addFreeTypeListener(List.of(found),
 256                         instantiatedContext -> {
 257                             ResultInfo pendingResult =
 258                                     resultInfo.dup(inferenceContext.asInstType(resultInfo.pt));
 259                             check(tree, inferenceContext.asInstType(found), ownkind, pendingResult);
 260                         });
 261             }
 262         } else {
 263             owntype = shouldCheck ?
 264             resultInfo.check(tree, found) :
 265             found;
 266         }
 267         if (resultInfo.checkMode.updateTreeType()) {
 268             tree.type = owntype;
 269         }
 270         return owntype;
 271     }
 272 
 273     /** Is given blank final variable assignable, i.e. in a scope where it
 274      *  may be assigned to even though it is final?
 275      *  @param v      The blank final variable.
 276      *  @param env    The current environment.
 277      */
 278     boolean isAssignableAsBlankFinal(VarSymbol v, Env<AttrContext> env) {
 279         Symbol owner = env.info.scope.owner;
 280            // owner refers to the innermost variable, method or
 281            // initializer block declaration at this point.
 282         boolean isAssignable =
 283             v.owner == owner
 284             ||
 285             ((owner.name == names.init ||    // i.e. we are in a constructor
 286               owner.kind == VAR ||           // i.e. we are in a variable initializer
 287               (owner.flags() & BLOCK) != 0)  // i.e. we are in an initializer block
 288              &&
 289              v.owner == owner.owner
 290              &&
 291              ((v.flags() & STATIC) != 0) == Resolve.isStatic(env));
 292         boolean insideCompactConstructor = env.enclMethod != null && TreeInfo.isCompactConstructor(env.enclMethod);
 293         boolean assigningRecordField = (v.flags() & RECORD) != 0;
 294         // Only record component fields are non-assignable in a compact constructor.
 295         return isAssignable && (!insideCompactConstructor || !assigningRecordField);
 296     }
 297 
 298     /** Check that variable can be assigned to.
 299      *  @param pos    The current source code position.
 300      *  @param v      The assigned variable
 301      *  @param base   If the variable is referred to in a Select, the part
 302      *                to the left of the `.', null otherwise.
 303      *  @param env    The current environment.
 304      */
 305     void checkAssignable(DiagnosticPosition pos, VarSymbol v, JCTree base, Env<AttrContext> env) {
 306         if (v.name == names._this) {
 307             log.error(pos, Errors.CantAssignValToThis);
 308             return;
 309         }
 310         if ((v.flags() & FINAL) != 0 &&
 311             ((v.flags() & HASINIT) != 0
 312              ||
 313              !((base == null ||
 314                TreeInfo.isThisQualifier(base)) &&
 315                isAssignableAsBlankFinal(v, env)))) {
 316             if (v.isResourceVariable()) { //TWR resource
 317                 log.error(pos, Errors.TryResourceMayNotBeAssigned(v));
 318             } else {
 319                 log.error(pos, Errors.CantAssignValToVar(Flags.toSource(v.flags() & (STATIC | FINAL)), v));
 320             }
 321             return;
 322         }
 323     }
 324 
 325     /** Does tree represent a static reference to an identifier?
 326      *  It is assumed that tree is either a SELECT or an IDENT.
 327      *  We have to weed out selects from non-type names here.
 328      *  @param tree    The candidate tree.
 329      */
 330     boolean isStaticReference(JCTree tree) {
 331         if (tree.hasTag(SELECT)) {
 332             Symbol lsym = TreeInfo.symbol(((JCFieldAccess) tree).selected);
 333             if (lsym == null || lsym.kind != TYP) {
 334                 return false;
 335             }
 336         }
 337         return true;
 338     }
 339 
 340     /** Is this symbol a type?
 341      */
 342     static boolean isType(Symbol sym) {
 343         return sym != null && sym.kind == TYP;
 344     }
 345 
 346     /** Attribute a parsed identifier.
 347      * @param tree Parsed identifier name
 348      * @param topLevel The toplevel to use
 349      */
 350     public Symbol attribIdent(JCTree tree, JCCompilationUnit topLevel) {
 351         Env<AttrContext> localEnv = enter.topLevelEnv(topLevel);
 352         localEnv.enclClass = make.ClassDef(make.Modifiers(0),
 353                                            syms.errSymbol.name,
 354                                            null, null, null, null);
 355         localEnv.enclClass.sym = syms.errSymbol;
 356         return attribIdent(tree, localEnv);
 357     }
 358 
 359     /** Attribute a parsed identifier.
 360      * @param tree Parsed identifier name
 361      * @param env The env to use
 362      */
 363     public Symbol attribIdent(JCTree tree, Env<AttrContext> env) {
 364         return tree.accept(identAttributer, env);
 365     }
 366     // where
 367         private TreeVisitor<Symbol,Env<AttrContext>> identAttributer = new IdentAttributer();
 368         private class IdentAttributer extends SimpleTreeVisitor<Symbol,Env<AttrContext>> {
 369             @Override @DefinedBy(Api.COMPILER_TREE)
 370             public Symbol visitMemberSelect(MemberSelectTree node, Env<AttrContext> env) {
 371                 Symbol site = visit(node.getExpression(), env);
 372                 if (site == null || site.kind == ERR || site.kind == ABSENT_TYP || site.kind == HIDDEN)
 373                     return site;
 374                 Name name = (Name)node.getIdentifier();
 375                 if (site.kind == PCK) {
 376                     env.toplevel.packge = (PackageSymbol)site;
 377                     return rs.findIdentInPackage(null, env, (TypeSymbol)site, name,
 378                             KindSelector.TYP_PCK);
 379                 } else {
 380                     env.enclClass.sym = (ClassSymbol)site;
 381                     return rs.findMemberType(env, site.asType(), name, (TypeSymbol)site);
 382                 }
 383             }
 384 
 385             @Override @DefinedBy(Api.COMPILER_TREE)
 386             public Symbol visitIdentifier(IdentifierTree node, Env<AttrContext> env) {
 387                 return rs.findIdent(null, env, (Name)node.getName(), KindSelector.TYP_PCK);
 388             }
 389         }
 390 
 391     public Type coerce(Type etype, Type ttype) {
 392         return cfolder.coerce(etype, ttype);
 393     }
 394 
 395     public Type attribType(JCTree node, TypeSymbol sym) {
 396         Env<AttrContext> env = typeEnvs.get(sym);
 397         Env<AttrContext> localEnv = env.dup(node, env.info.dup());
 398         return attribTree(node, localEnv, unknownTypeInfo);
 399     }
 400 
 401     public Type attribImportQualifier(JCImport tree, Env<AttrContext> env) {
 402         // Attribute qualifying package or class.
 403         JCFieldAccess s = tree.qualid;
 404         return attribTree(s.selected, env,
 405                           new ResultInfo(tree.staticImport ?
 406                                          KindSelector.TYP : KindSelector.TYP_PCK,
 407                        Type.noType));
 408     }
 409 
 410     public Env<AttrContext> attribExprToTree(JCTree expr, Env<AttrContext> env, JCTree tree) {
 411         return attribToTree(expr, env, tree, unknownExprInfo);
 412     }
 413 
 414     public Env<AttrContext> attribStatToTree(JCTree stmt, Env<AttrContext> env, JCTree tree) {
 415         return attribToTree(stmt, env, tree, statInfo);
 416     }
 417 
 418     private Env<AttrContext> attribToTree(JCTree root, Env<AttrContext> env, JCTree tree, ResultInfo resultInfo) {
 419         breakTree = tree;
 420         JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
 421         try {
 422             deferredAttr.attribSpeculative(root, env, resultInfo,
 423                     null, DeferredAttr.AttributionMode.ATTRIB_TO_TREE,
 424                     argumentAttr.withLocalCacheContext());
 425             attrRecover.doRecovery();
 426         } catch (BreakAttr b) {
 427             return b.env;
 428         } catch (AssertionError ae) {
 429             if (ae.getCause() instanceof BreakAttr breakAttr) {
 430                 return breakAttr.env;
 431             } else {
 432                 throw ae;
 433             }
 434         } finally {
 435             breakTree = null;
 436             log.useSource(prev);
 437         }
 438         return env;
 439     }
 440 
 441     private JCTree breakTree = null;
 442 
 443     private static class BreakAttr extends RuntimeException {
 444         static final long serialVersionUID = -6924771130405446405L;
 445         private transient Env<AttrContext> env;
 446         private BreakAttr(Env<AttrContext> env) {
 447             this.env = env;
 448         }
 449     }
 450 
 451     /**
 452      * Mode controlling behavior of Attr.Check
 453      */
 454     enum CheckMode {
 455 
 456         NORMAL,
 457 
 458         /**
 459          * Mode signalling 'fake check' - skip tree update. A side-effect of this mode is
 460          * that the captured var cache in {@code InferenceContext} will be used in read-only
 461          * mode when performing inference checks.
 462          */
 463         NO_TREE_UPDATE {
 464             @Override
 465             public boolean updateTreeType() {
 466                 return false;
 467             }
 468         },
 469         /**
 470          * Mode signalling that caller will manage free types in tree decorations.
 471          */
 472         NO_INFERENCE_HOOK {
 473             @Override
 474             public boolean installPostInferenceHook() {
 475                 return false;
 476             }
 477         };
 478 
 479         public boolean updateTreeType() {
 480             return true;
 481         }
 482         public boolean installPostInferenceHook() {
 483             return true;
 484         }
 485     }
 486 
 487 
 488     class ResultInfo {
 489         final KindSelector pkind;
 490         final Type pt;
 491         final CheckContext checkContext;
 492         final CheckMode checkMode;
 493 
 494         ResultInfo(KindSelector pkind, Type pt) {
 495             this(pkind, pt, chk.basicHandler, CheckMode.NORMAL);
 496         }
 497 
 498         ResultInfo(KindSelector pkind, Type pt, CheckMode checkMode) {
 499             this(pkind, pt, chk.basicHandler, checkMode);
 500         }
 501 
 502         protected ResultInfo(KindSelector pkind,
 503                              Type pt, CheckContext checkContext) {
 504             this(pkind, pt, checkContext, CheckMode.NORMAL);
 505         }
 506 
 507         protected ResultInfo(KindSelector pkind,
 508                              Type pt, CheckContext checkContext, CheckMode checkMode) {
 509             this.pkind = pkind;
 510             this.pt = pt;
 511             this.checkContext = checkContext;
 512             this.checkMode = checkMode;
 513         }
 514 
 515         /**
 516          * Should {@link Attr#attribTree} use the {@code ArgumentAttr} visitor instead of this one?
 517          * @param tree The tree to be type-checked.
 518          * @return true if {@code ArgumentAttr} should be used.
 519          */
 520         protected boolean needsArgumentAttr(JCTree tree) { return false; }
 521 
 522         protected Type check(final DiagnosticPosition pos, final Type found) {
 523             return chk.checkType(pos, found, pt, checkContext);
 524         }
 525 
 526         protected ResultInfo dup(Type newPt) {
 527             return new ResultInfo(pkind, newPt, checkContext, checkMode);
 528         }
 529 
 530         protected ResultInfo dup(CheckContext newContext) {
 531             return new ResultInfo(pkind, pt, newContext, checkMode);
 532         }
 533 
 534         protected ResultInfo dup(Type newPt, CheckContext newContext) {
 535             return new ResultInfo(pkind, newPt, newContext, checkMode);
 536         }
 537 
 538         protected ResultInfo dup(Type newPt, CheckContext newContext, CheckMode newMode) {
 539             return new ResultInfo(pkind, newPt, newContext, newMode);
 540         }
 541 
 542         protected ResultInfo dup(CheckMode newMode) {
 543             return new ResultInfo(pkind, pt, checkContext, newMode);
 544         }
 545 
 546         @Override
 547         public String toString() {
 548             if (pt != null) {
 549                 return pt.toString();
 550             } else {
 551                 return "";
 552             }
 553         }
 554     }
 555 
 556     class MethodAttrInfo extends ResultInfo {
 557         public MethodAttrInfo() {
 558             this(chk.basicHandler);
 559         }
 560 
 561         public MethodAttrInfo(CheckContext checkContext) {
 562             super(KindSelector.VAL, Infer.anyPoly, checkContext);
 563         }
 564 
 565         @Override
 566         protected boolean needsArgumentAttr(JCTree tree) {
 567             return true;
 568         }
 569 
 570         protected ResultInfo dup(Type newPt) {
 571             throw new IllegalStateException();
 572         }
 573 
 574         protected ResultInfo dup(CheckContext newContext) {
 575             return new MethodAttrInfo(newContext);
 576         }
 577 
 578         protected ResultInfo dup(Type newPt, CheckContext newContext) {
 579             throw new IllegalStateException();
 580         }
 581 
 582         protected ResultInfo dup(Type newPt, CheckContext newContext, CheckMode newMode) {
 583             throw new IllegalStateException();
 584         }
 585 
 586         protected ResultInfo dup(CheckMode newMode) {
 587             throw new IllegalStateException();
 588         }
 589     }
 590 
 591     class RecoveryInfo extends ResultInfo {
 592 
 593         public RecoveryInfo(final DeferredAttr.DeferredAttrContext deferredAttrContext) {
 594             this(deferredAttrContext, Type.recoveryType);
 595         }
 596 
 597         public RecoveryInfo(final DeferredAttr.DeferredAttrContext deferredAttrContext, Type pt) {
 598             super(KindSelector.VAL, pt, new Check.NestedCheckContext(chk.basicHandler) {
 599                 @Override
 600                 public DeferredAttr.DeferredAttrContext deferredAttrContext() {
 601                     return deferredAttrContext;
 602                 }
 603                 @Override
 604                 public boolean compatible(Type found, Type req, Warner warn) {
 605                     return true;
 606                 }
 607                 @Override
 608                 public void report(DiagnosticPosition pos, JCDiagnostic details) {
 609                     boolean needsReport = pt == Type.recoveryType ||
 610                             (details.getDiagnosticPosition() != null &&
 611                             details.getDiagnosticPosition().getTree().hasTag(LAMBDA));
 612                     if (needsReport) {
 613                         chk.basicHandler.report(pos, details);
 614                     }
 615                 }
 616             });
 617         }
 618     }
 619 
 620     final ResultInfo statInfo;
 621     final ResultInfo varAssignmentInfo;
 622     final ResultInfo varAssignmentOpInfo;
 623     final ResultInfo methodAttrInfo;
 624     final ResultInfo unknownExprInfo;
 625     final ResultInfo unknownTypeInfo;
 626     final ResultInfo unknownTypeExprInfo;
 627     final ResultInfo recoveryInfo;
 628     final MethodType initBlockType;
 629 
 630     Type pt() {
 631         return resultInfo.pt;
 632     }
 633 
 634     KindSelector pkind() {
 635         return resultInfo.pkind;
 636     }
 637 
 638 /* ************************************************************************
 639  * Visitor methods
 640  *************************************************************************/
 641 
 642     /** Visitor argument: the current environment.
 643      */
 644     Env<AttrContext> env;
 645 
 646     /** Visitor argument: the currently expected attribution result.
 647      */
 648     ResultInfo resultInfo;
 649 
 650     /** Visitor result: the computed type.
 651      */
 652     Type result;
 653 
 654     MatchBindings matchBindings = MatchBindingsComputer.EMPTY;
 655 
 656     /** Visitor method: attribute a tree, catching any completion failure
 657      *  exceptions. Return the tree's type.
 658      *
 659      *  @param tree    The tree to be visited.
 660      *  @param env     The environment visitor argument.
 661      *  @param resultInfo   The result info visitor argument.
 662      */
 663     Type attribTree(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) {
 664         Env<AttrContext> prevEnv = this.env;
 665         ResultInfo prevResult = this.resultInfo;
 666         try {
 667             this.env = env;
 668             this.resultInfo = resultInfo;
 669             if (resultInfo.needsArgumentAttr(tree)) {
 670                 result = argumentAttr.attribArg(tree, env);
 671             } else {
 672                 tree.accept(this);
 673             }
 674             matchBindings = matchBindingsComputer.finishBindings(tree,
 675                                                                  matchBindings);
 676             checkBreakTree(tree, env);
 677             return result;
 678         } catch (CompletionFailure ex) {
 679             tree.type = syms.errType;
 680             return chk.completionError(tree.pos(), ex);
 681         } finally {
 682             this.env = prevEnv;
 683             this.resultInfo = prevResult;
 684         }
 685     }
 686 
 687     private void checkBreakTree(JCTree tree, Env<AttrContext> env) {
 688         if (tree == breakTree &&
 689                 resultInfo.checkContext.deferredAttrContext().mode == AttrMode.CHECK) {
 690             breakTreeFound(copyEnv(env));
 691         }
 692     }
 693 
 694     protected void breakTreeFound(Env<AttrContext> env) {
 695         throw new BreakAttr(env);
 696     }
 697 
 698     Env<AttrContext> copyEnv(Env<AttrContext> env) {
 699         Env<AttrContext> newEnv =
 700                 env.dup(env.tree, env.info.dup(copyScope(env.info.scope)));
 701         if (newEnv.outer != null) {
 702             newEnv.outer = copyEnv(newEnv.outer);
 703         }
 704         return newEnv;
 705     }
 706 
 707     WriteableScope copyScope(WriteableScope sc) {
 708         WriteableScope newScope = WriteableScope.create(sc.owner);
 709         List<Symbol> elemsList = List.nil();
 710         for (Symbol sym : sc.getSymbols()) {
 711             elemsList = elemsList.prepend(sym);
 712         }
 713         for (Symbol s : elemsList) {
 714             newScope.enter(s);
 715         }
 716         return newScope;
 717     }
 718 
 719     /** Derived visitor method: attribute an expression tree.
 720      */
 721     public Type attribExpr(JCTree tree, Env<AttrContext> env, Type pt) {
 722         return attribTree(tree, env, new ResultInfo(KindSelector.VAL, !pt.hasTag(ERROR) ? pt : Type.noType));
 723     }
 724 
 725     /** Derived visitor method: attribute an expression tree with
 726      *  no constraints on the computed type.
 727      */
 728     public Type attribExpr(JCTree tree, Env<AttrContext> env) {
 729         return attribTree(tree, env, unknownExprInfo);
 730     }
 731 
 732     /** Derived visitor method: attribute a type tree.
 733      */
 734     public Type attribType(JCTree tree, Env<AttrContext> env) {
 735         Type result = attribType(tree, env, Type.noType);
 736         return result;
 737     }
 738 
 739     /** Derived visitor method: attribute a type tree.
 740      */
 741     Type attribType(JCTree tree, Env<AttrContext> env, Type pt) {
 742         Type result = attribTree(tree, env, new ResultInfo(KindSelector.TYP, pt));
 743         return result;
 744     }
 745 
 746     /** Derived visitor method: attribute a statement or definition tree.
 747      */
 748     public Type attribStat(JCTree tree, Env<AttrContext> env) {
 749         Env<AttrContext> analyzeEnv = analyzer.copyEnvIfNeeded(tree, env);
 750         Type result = attribTree(tree, env, statInfo);
 751         analyzer.analyzeIfNeeded(tree, analyzeEnv);
 752         attrRecover.doRecovery();
 753         return result;
 754     }
 755 
 756     /** Attribute a list of expressions, returning a list of types.
 757      */
 758     List<Type> attribExprs(List<JCExpression> trees, Env<AttrContext> env, Type pt) {
 759         ListBuffer<Type> ts = new ListBuffer<>();
 760         for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail)
 761             ts.append(attribExpr(l.head, env, pt));
 762         return ts.toList();
 763     }
 764 
 765     /** Attribute a list of statements, returning nothing.
 766      */
 767     <T extends JCTree> void attribStats(List<T> trees, Env<AttrContext> env) {
 768         for (List<T> l = trees; l.nonEmpty(); l = l.tail)
 769             attribStat(l.head, env);
 770     }
 771 
 772     /** Attribute the arguments in a method call, returning the method kind.
 773      */
 774     KindSelector attribArgs(KindSelector initialKind, List<JCExpression> trees, Env<AttrContext> env, ListBuffer<Type> argtypes) {
 775         KindSelector kind = initialKind;
 776         for (JCExpression arg : trees) {
 777             Type argtype = chk.checkNonVoid(arg, attribTree(arg, env, methodAttrInfo));
 778             if (argtype.hasTag(DEFERRED)) {
 779                 kind = KindSelector.of(KindSelector.POLY, kind);
 780             }
 781             argtypes.append(argtype);
 782         }
 783         return kind;
 784     }
 785 
 786     /** Attribute a type argument list, returning a list of types.
 787      *  Caller is responsible for calling checkRefTypes.
 788      */
 789     List<Type> attribAnyTypes(List<JCExpression> trees, Env<AttrContext> env) {
 790         ListBuffer<Type> argtypes = new ListBuffer<>();
 791         for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail)
 792             argtypes.append(attribType(l.head, env));
 793         return argtypes.toList();
 794     }
 795 
 796     /** Attribute a type argument list, returning a list of types.
 797      *  Check that all the types are references.
 798      */
 799     List<Type> attribTypes(List<JCExpression> trees, Env<AttrContext> env) {
 800         List<Type> types = attribAnyTypes(trees, env);
 801         return chk.checkRefTypes(trees, types);
 802     }
 803 
 804     /**
 805      * Attribute type variables (of generic classes or methods).
 806      * Compound types are attributed later in attribBounds.
 807      * @param typarams the type variables to enter
 808      * @param env      the current environment
 809      */
 810     void attribTypeVariables(List<JCTypeParameter> typarams, Env<AttrContext> env, boolean checkCyclic) {
 811         for (JCTypeParameter tvar : typarams) {
 812             TypeVar a = (TypeVar)tvar.type;
 813             a.tsym.flags_field |= UNATTRIBUTED;
 814             a.setUpperBound(Type.noType);
 815             if (!tvar.bounds.isEmpty()) {
 816                 List<Type> bounds = List.of(attribType(tvar.bounds.head, env));
 817                 for (JCExpression bound : tvar.bounds.tail)
 818                     bounds = bounds.prepend(attribType(bound, env));
 819                 bounds = bounds.reverse();
 820                 if (bounds.head.hasTag(ARRAY)) {
 821                     /* A single bound that is an array type may structurally reference
 822                      * this same type variable, as in `<T extends T[]>`, setting the bound to
 823                      * Object as a recovery strategy
 824                      */
 825                     types.setBounds(a, List.of(syms.objectType));
 826                 } else {
 827                     types.setBounds(a, bounds);
 828                 }
 829             } else {
 830                 // if no bounds are given, assume a single bound of
 831                 // java.lang.Object.
 832                 types.setBounds(a, List.of(syms.objectType));
 833             }
 834             a.tsym.flags_field &= ~UNATTRIBUTED;
 835         }
 836         if (checkCyclic) {
 837             for (JCTypeParameter tvar : typarams) {
 838                 chk.checkNonCyclic(tvar.pos(), (TypeVar)tvar.type);
 839             }
 840         }
 841     }
 842 
 843     /**
 844      * Attribute the type references in a list of annotations.
 845      */
 846     void attribAnnotationTypes(List<JCAnnotation> annotations,
 847                                Env<AttrContext> env) {
 848         for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
 849             JCAnnotation a = al.head;
 850             attribType(a.annotationType, env);
 851         }
 852     }
 853 
 854     /**
 855      * Attribute a "lazy constant value".
 856      *  @param env         The env for the const value
 857      *  @param variable    The initializer for the const value
 858      *  @param type        The expected type, or null
 859      *  @see VarSymbol#setLazyConstValue
 860      */
 861     public Object attribLazyConstantValue(Env<AttrContext> env,
 862                                       Env<AttrContext> enclosingEnv,
 863                                       JCVariableDecl variable,
 864                                       Type type) {
 865         final JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
 866         try {
 867             doQueueScanTreeAndTypeAnnotateForVarInit(variable, enclosingEnv);
 868             Type itype = attribExpr(variable.init, env, type);
 869             if (variable.isImplicitlyTyped()) {
 870                 //fixup local variable type
 871                 type = variable.type = variable.sym.type = chk.checkLocalVarType(variable, itype, variable.name);
 872             }
 873             if (itype.constValue() != null) {
 874                 return coerce(itype, type).constValue();
 875             } else {
 876                 return null;
 877             }
 878         } finally {
 879             log.useSource(prevSource);
 880         }
 881     }
 882 
 883     /** Attribute type reference in an `extends', `implements', or 'permits' clause.
 884      *  Supertypes of anonymous inner classes are usually already attributed.
 885      *
 886      *  @param tree              The tree making up the type reference.
 887      *  @param env               The environment current at the reference.
 888      *  @param classExpected     true if only a class is expected here.
 889      *  @param interfaceExpected true if only an interface is expected here.
 890      */
 891     Type attribBase(JCTree tree,
 892                     Env<AttrContext> env,
 893                     boolean classExpected,
 894                     boolean interfaceExpected,
 895                     boolean checkExtensible) {
 896         Type t = tree.type != null ?
 897             tree.type :
 898             attribType(tree, env);
 899         try {
 900             return tree.type = checkBase(t, tree, env, classExpected, interfaceExpected, checkExtensible);
 901         } catch (CompletionFailure ex) {
 902             chk.completionError(tree.pos(), ex);
 903             return t;
 904         }
 905     }
 906     Type checkBase(Type t,
 907                    JCTree tree,
 908                    Env<AttrContext> env,
 909                    boolean classExpected,
 910                    boolean interfaceExpected,
 911                    boolean checkExtensible) {
 912         final DiagnosticPosition pos = tree.hasTag(TYPEAPPLY) ?
 913                 (((JCTypeApply) tree).clazz).pos() : tree.pos();
 914         if (t.tsym.isAnonymous()) {
 915             log.error(pos, Errors.CantInheritFromAnon);
 916             return types.createErrorType(t);
 917         }
 918         if (t.isErroneous())
 919             return t;
 920         if (t.hasTag(TYPEVAR) && !classExpected && !interfaceExpected) {
 921             // check that type variable is already visible
 922             if (t.getUpperBound() == null) {
 923                 log.error(pos, Errors.IllegalForwardRef);
 924                 return types.createErrorType(t);
 925             }
 926         } else {
 927             t = chk.checkClassType(pos, t, checkExtensible);
 928         }
 929         if (interfaceExpected && (t.tsym.flags() & INTERFACE) == 0) {
 930             log.error(pos, Errors.IntfExpectedHere);
 931             // return errType is necessary since otherwise there might
 932             // be undetected cycles which cause attribution to loop
 933             return types.createErrorType(t);
 934         } else if (checkExtensible &&
 935                    classExpected &&
 936                    (t.tsym.flags() & INTERFACE) != 0) {
 937             log.error(pos, Errors.NoIntfExpectedHere);
 938             return types.createErrorType(t);
 939         }
 940         if (checkExtensible &&
 941             ((t.tsym.flags() & FINAL) != 0)) {
 942             log.error(pos,
 943                       Errors.CantInheritFromFinal(t.tsym));
 944         }
 945         chk.checkNonCyclic(pos, t);
 946         return t;
 947     }
 948 
 949     Type attribIdentAsEnumType(Env<AttrContext> env, JCIdent id) {
 950         Assert.check((env.enclClass.sym.flags() & ENUM) != 0);
 951         id.type = env.info.scope.owner.enclClass().type;
 952         id.sym = env.info.scope.owner.enclClass();
 953         return id.type;
 954     }
 955 
 956     public void visitClassDef(JCClassDecl tree) {
 957         Optional<ArgumentAttr.LocalCacheContext> localCacheContext =
 958                 Optional.ofNullable(env.info.attributionMode.isSpeculative ?
 959                         argumentAttr.withLocalCacheContext() : null);
 960         EarlyConstructionContext earlyConstructionPrev = env.info.earlyContext;
 961         try {
 962             env.info.earlyContext = earlyConstructionPrev.nested(true);
 963             // Local and anonymous classes have not been entered yet, so we need to
 964             // do it now.
 965             if (env.info.scope.owner.kind.matches(KindSelector.VAL_MTH)) {
 966                 enter.classEnter(tree, env);
 967             } else {
 968                 // If this class declaration is part of a class level annotation,
 969                 // as in @MyAnno(new Object() {}) class MyClass {}, enter it in
 970                 // order to simplify later steps and allow for sensible error
 971                 // messages.
 972                 if (env.tree.hasTag(NEWCLASS) && TreeInfo.isInAnnotation(env, tree))
 973                     enter.classEnter(tree, env);
 974             }
 975 
 976             ClassSymbol c = tree.sym;
 977             if (c == null) {
 978                 // exit in case something drastic went wrong during enter.
 979                 result = null;
 980             } else {
 981                 // make sure class has been completed:
 982                 c.complete();
 983 
 984                 // If a class declaration appears in a constructor prologue,
 985                 // that means it's either a local class or an anonymous class.
 986                 // Either way, there is no immediately enclosing instance.
 987                 if (earlyConstructionPrev.ctorPrologue()) {
 988                     c.flags_field |= NOOUTERTHIS;
 989                 }
 990                 attribClass(tree.pos(), c);
 991                 result = tree.type = c.type;
 992             }
 993         } finally {
 994             localCacheContext.ifPresent(LocalCacheContext::leave);
 995             env.info.earlyContext = earlyConstructionPrev;
 996         }
 997     }
 998 
 999     public void visitMethodDef(JCMethodDecl tree) {
1000         MethodSymbol m = tree.sym;
1001         boolean isDefaultMethod = (m.flags() & DEFAULT) != 0;
1002 
1003         Lint lint = env.info.lint.augment(m);
1004         Lint prevLint = chk.setLint(lint);
1005         EarlyConstructionContext earlyConstructionPrev = env.info.earlyContext;
1006         Assert.check(!earlyConstructionPrev.ctorPrologue());
1007         MethodSymbol prevMethod = chk.setMethod(m);
1008         try {
1009             chk.checkDeprecatedAnnotation(tree.pos(), m);
1010 
1011 
1012             // Create a new environment with local scope
1013             // for attributing the method.
1014             Env<AttrContext> localEnv = memberEnter.methodEnv(tree, env);
1015             localEnv.info.lint = lint;
1016 
1017             attribStats(tree.typarams, localEnv);
1018 
1019             // If we override any other methods, check that we do so properly.
1020             // JLS ???
1021             if (m.isStatic()) {
1022                 chk.checkHideClashes(tree.pos(), env.enclClass.type, m);
1023             } else {
1024                 chk.checkOverrideClashes(tree.pos(), env.enclClass.type, m);
1025             }
1026             chk.checkOverride(env, tree, m);
1027 
1028             if (isDefaultMethod && types.overridesObjectMethod(m.enclClass(), m)) {
1029                 log.error(tree, Errors.DefaultOverridesObjectMember(m.name, Kinds.kindName(m.location()), m.location()));
1030             }
1031 
1032             // Enter all type parameters into the local method scope.
1033             for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail)
1034                 localEnv.info.scope.enterIfAbsent(l.head.type.tsym);
1035 
1036             ClassSymbol owner = env.enclClass.sym;
1037             if ((owner.flags() & ANNOTATION) != 0 &&
1038                     (tree.params.nonEmpty() ||
1039                     tree.recvparam != null))
1040                 log.error(tree.params.nonEmpty() ?
1041                         tree.params.head.pos() :
1042                         tree.recvparam.pos(),
1043                         Errors.IntfAnnotationMembersCantHaveParams);
1044 
1045             // Attribute all value parameters.
1046             for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
1047                 attribStat(l.head, localEnv);
1048             }
1049 
1050             chk.checkVarargsMethodDecl(localEnv, tree);
1051 
1052             // Check that type parameters are well-formed.
1053             chk.validate(tree.typarams, localEnv);
1054 
1055             // Check that result type is well-formed.
1056             if (tree.restype != null && !tree.restype.type.hasTag(VOID)) {
1057                 chk.validate(tree.restype, localEnv);
1058             }
1059             chk.checkRequiresIdentity(tree, env.info.lint);
1060 
1061             // Check that receiver type is well-formed.
1062             if (tree.recvparam != null) {
1063                 // Use a new environment to check the receiver parameter.
1064                 // Otherwise I get "might not have been initialized" errors.
1065                 // Is there a better way?
1066                 Env<AttrContext> newEnv = memberEnter.methodEnv(tree, env);
1067                 attribType(tree.recvparam, newEnv);
1068                 chk.validate(tree.recvparam, newEnv);
1069             }
1070 
1071             // Is this method a constructor?
1072             boolean isConstructor = TreeInfo.isConstructor(tree);
1073 
1074             if (env.enclClass.sym.isRecord() && tree.sym.owner.kind == TYP) {
1075                 // lets find if this method is an accessor
1076                 Optional<? extends RecordComponent> recordComponent = env.enclClass.sym.getRecordComponents().stream()
1077                         .filter(rc -> rc.accessor == tree.sym && (rc.accessor.flags_field & GENERATED_MEMBER) == 0).findFirst();
1078                 if (recordComponent.isPresent()) {
1079                     // the method is a user defined accessor lets check that everything is fine
1080                     if (!tree.sym.isPublic()) {
1081                         log.error(tree, Errors.InvalidAccessorMethodInRecord(env.enclClass.sym, Fragments.MethodMustBePublic));
1082                     }
1083                     if (!types.isSameType(tree.sym.type.getReturnType(), recordComponent.get().type)) {
1084                         log.error(tree, Errors.InvalidAccessorMethodInRecord(env.enclClass.sym,
1085                                 Fragments.AccessorReturnTypeDoesntMatch(tree.sym, recordComponent.get())));
1086                     }
1087                     if (tree.sym.type.asMethodType().thrown != null && !tree.sym.type.asMethodType().thrown.isEmpty()) {
1088                         log.error(tree,
1089                                 Errors.InvalidAccessorMethodInRecord(env.enclClass.sym, Fragments.AccessorMethodCantThrowException));
1090                     }
1091                     if (!tree.typarams.isEmpty()) {
1092                         log.error(tree,
1093                                 Errors.InvalidAccessorMethodInRecord(env.enclClass.sym, Fragments.AccessorMethodMustNotBeGeneric));
1094                     }
1095                     if (tree.sym.isStatic()) {
1096                         log.error(tree,
1097                                 Errors.InvalidAccessorMethodInRecord(env.enclClass.sym, Fragments.AccessorMethodMustNotBeStatic));
1098                     }
1099                 }
1100 
1101                 if (isConstructor) {
1102                     // if this a constructor other than the canonical one
1103                     if ((tree.sym.flags_field & RECORD) == 0) {
1104                         if (!TreeInfo.hasConstructorCall(tree, names._this)) {
1105                             log.error(tree, Errors.NonCanonicalConstructorInvokeAnotherConstructor(env.enclClass.sym));
1106                         }
1107                     } else {
1108                         // but if it is the canonical:
1109 
1110                         /* if user generated, then it shouldn't:
1111                          *     - have an accessibility stricter than that of the record type
1112                          *     - explicitly invoke any other constructor
1113                          */
1114                         if ((tree.sym.flags_field & GENERATEDCONSTR) == 0) {
1115                             if (Check.protection(m.flags()) > Check.protection(env.enclClass.sym.flags())) {
1116                                 log.error(tree,
1117                                         (env.enclClass.sym.flags() & AccessFlags) == 0 ?
1118                                             Errors.InvalidCanonicalConstructorInRecord(
1119                                                 Fragments.Canonical,
1120                                                 env.enclClass.sym.name,
1121                                                 Fragments.CanonicalMustNotHaveStrongerAccess("package")
1122                                             ) :
1123                                             Errors.InvalidCanonicalConstructorInRecord(
1124                                                     Fragments.Canonical,
1125                                                     env.enclClass.sym.name,
1126                                                     Fragments.CanonicalMustNotHaveStrongerAccess(asFlagSet(env.enclClass.sym.flags() & AccessFlags))
1127                                             )
1128                                 );
1129                             }
1130 
1131                             if ((!allowValueClasses || TreeInfo.isCompactConstructor(tree)) &&
1132                                     TreeInfo.hasAnyConstructorCall(tree)) {
1133                                 log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1134                                         Fragments.Canonical, env.enclClass.sym.name,
1135                                         Fragments.CanonicalMustNotContainExplicitConstructorInvocation));
1136                             }
1137                         }
1138 
1139                         // also we want to check that no type variables have been defined
1140                         if (!tree.typarams.isEmpty()) {
1141                             log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1142                                     Fragments.Canonical, env.enclClass.sym.name, Fragments.CanonicalMustNotDeclareTypeVariables));
1143                         }
1144 
1145                         /* and now we need to check that the constructor's arguments are exactly the same as those of the
1146                          * record components
1147                          */
1148                         List<? extends RecordComponent> recordComponents = env.enclClass.sym.getRecordComponents();
1149                         List<Type> recordFieldTypes = TreeInfo.recordFields(env.enclClass).map(vd -> vd.sym.type);
1150                         for (JCVariableDecl param: tree.params) {
1151                             boolean paramIsVarArgs = (param.sym.flags_field & VARARGS) != 0;
1152                             if (!types.isSameType(param.type, recordFieldTypes.head) ||
1153                                     (recordComponents.head.isVarargs() != paramIsVarArgs)) {
1154                                 log.error(param, Errors.InvalidCanonicalConstructorInRecord(
1155                                         Fragments.Canonical, env.enclClass.sym.name,
1156                                         Fragments.TypeMustBeIdenticalToCorrespondingRecordComponentType));
1157                             }
1158                             recordComponents = recordComponents.tail;
1159                             recordFieldTypes = recordFieldTypes.tail;
1160                         }
1161                     }
1162                 }
1163             }
1164 
1165             // annotation method checks
1166             if ((owner.flags() & ANNOTATION) != 0) {
1167                 // annotation method cannot have throws clause
1168                 if (tree.thrown.nonEmpty()) {
1169                     log.error(tree.thrown.head.pos(),
1170                               Errors.ThrowsNotAllowedInIntfAnnotation);
1171                 }
1172                 // annotation method cannot declare type-parameters
1173                 if (tree.typarams.nonEmpty()) {
1174                     log.error(tree.typarams.head.pos(),
1175                               Errors.IntfAnnotationMembersCantHaveTypeParams);
1176                 }
1177                 // validate annotation method's return type (could be an annotation type)
1178                 chk.validateAnnotationType(tree.restype);
1179                 // ensure that annotation method does not clash with members of Object/Annotation
1180                 chk.validateAnnotationMethod(tree.pos(), m);
1181             }
1182 
1183             for (List<JCExpression> l = tree.thrown; l.nonEmpty(); l = l.tail)
1184                 chk.checkType(l.head.pos(), l.head.type, syms.throwableType, chk.subtypeHandler);
1185 
1186             if (tree.body == null) {
1187                 // Empty bodies are only allowed for
1188                 // abstract, native, or interface methods, or for methods
1189                 // in a retrofit signature class.
1190                 if (tree.defaultValue != null) {
1191                     if ((owner.flags() & ANNOTATION) == 0)
1192                         log.error(tree.pos(),
1193                                   Errors.DefaultAllowedInIntfAnnotationMember);
1194                 }
1195                 if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0)
1196                     log.error(tree.pos(), Errors.MissingMethBodyOrDeclAbstract(tree.sym, owner));
1197             } else {
1198                 if ((tree.sym.flags() & (ABSTRACT|DEFAULT|PRIVATE)) == ABSTRACT) {
1199                     if ((owner.flags() & INTERFACE) != 0) {
1200                         log.error(tree.body.pos(), Errors.IntfMethCantHaveBody);
1201                     } else {
1202                         log.error(tree.pos(), Errors.AbstractMethCantHaveBody);
1203                     }
1204                 } else if ((tree.mods.flags & NATIVE) != 0) {
1205                     log.error(tree.pos(), Errors.NativeMethCantHaveBody);
1206                 }
1207                 // Add an implicit super() call unless an explicit call to
1208                 // super(...) or this(...) is given
1209                 // or we are compiling class java.lang.Object.
1210                 if (isConstructor && owner.type != syms.objectType) {
1211                     if (!TreeInfo.hasAnyConstructorCall(tree)) {
1212                         JCStatement supCall = make.at(tree.body.pos).Exec(make.Apply(List.nil(),
1213                                 make.Ident(names._super), make.Idents(List.nil())));
1214                         if (allowValueClasses && (owner.isValueClass() || owner.isRecord())) {
1215                             tree.body.stats = tree.body.stats.append(supCall);
1216                         } else {
1217                             tree.body.stats = tree.body.stats.prepend(supCall);
1218                         }
1219                     } else if ((env.enclClass.sym.flags() & ENUM) != 0 &&
1220                             (tree.mods.flags & GENERATEDCONSTR) == 0 &&
1221                             TreeInfo.hasConstructorCall(tree, names._super)) {
1222                         // enum constructors are not allowed to call super
1223                         // directly, so make sure there aren't any super calls
1224                         // in enum constructors, except in the compiler
1225                         // generated one.
1226                         log.error(tree.body.stats.head.pos(),
1227                                   Errors.CallToSuperNotAllowedInEnumCtor(env.enclClass.sym));
1228                     }
1229                     if (env.enclClass.sym.isRecord() && (tree.sym.flags_field & RECORD) != 0) { // we are seeing the canonical constructor
1230                         List<Name> recordComponentNames = TreeInfo.recordFields(env.enclClass).map(vd -> vd.sym.name);
1231                         List<Name> initParamNames = tree.sym.params.map(p -> p.name);
1232                         if (!initParamNames.equals(recordComponentNames)) {
1233                             log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1234                                     Fragments.Canonical, env.enclClass.sym.name, Fragments.CanonicalWithNameMismatch));
1235                         }
1236                         if (tree.sym.type.asMethodType().thrown != null && !tree.sym.type.asMethodType().thrown.isEmpty()) {
1237                             log.error(tree,
1238                                     Errors.InvalidCanonicalConstructorInRecord(
1239                                             TreeInfo.isCompactConstructor(tree) ? Fragments.Compact : Fragments.Canonical,
1240                                             env.enclClass.sym.name,
1241                                             Fragments.ThrowsClauseNotAllowedForCanonicalConstructor(
1242                                                     TreeInfo.isCompactConstructor(tree) ? Fragments.Compact : Fragments.Canonical)));
1243                         }
1244                     }
1245                 }
1246 
1247                 // Attribute all type annotations in the body
1248                 annotate.queueScanTreeAndTypeAnnotate(tree.body, localEnv, m);
1249                 annotate.flush();
1250 
1251                 // Start of constructor prologue (if not in java.lang.Object constructor)
1252                 if (isConstructor && owner.type != syms.objectType) {
1253                     boolean hasThisConstructorCall = TreeInfo.hasConstructorCall(tree, names._this);
1254                     localEnv.info.earlyContext = EarlyConstructionContext.of(owner,
1255                             hasThisConstructorCall && allowValueClasses);
1256                 }
1257 
1258                 // Attribute method body.
1259                 attribStat(tree.body, localEnv);
1260             }
1261 
1262             localEnv.info.scope.leave();
1263             result = tree.type = m.type;
1264         } finally {
1265             chk.setLint(prevLint);
1266             chk.setMethod(prevMethod);
1267             env.info.earlyContext = earlyConstructionPrev;
1268         }
1269     }
1270 
1271     public void visitVarDef(JCVariableDecl tree) {
1272         // Local variables have not been entered yet, so we need to do it now:
1273         if (env.info.scope.owner.kind == MTH || env.info.scope.owner.kind == VAR) {
1274             if (tree.sym != null) {
1275                 // parameters have already been entered
1276                 env.info.scope.enter(tree.sym);
1277             } else {
1278                 if (tree.isImplicitlyTyped() && (tree.getModifiers().flags & PARAMETER) == 0 && tree.type == null) {
1279                     if (tree.init == null) {
1280                         //cannot use 'var' without initializer
1281                         log.error(tree, Errors.CantInferLocalVarType(tree.name, Fragments.LocalMissingInit));
1282                         tree.type = syms.errType;
1283                     } else {
1284                         Fragment msg = canInferLocalVarType(tree);
1285                         if (msg != null) {
1286                             //cannot use 'var' with initializer which require an explicit target
1287                             //(e.g. lambda, method reference, array initializer).
1288                             log.error(tree, Errors.CantInferLocalVarType(tree.name, msg));
1289                             tree.type = syms.errType;
1290                         }
1291                     }
1292                 }
1293                 try {
1294                     annotate.blockAnnotations();
1295                     memberEnter.memberEnter(tree, env);
1296                     typeAnnotations.organizeTypeAnnotationsSignaturesForLocalVarType(env, tree);
1297                 } finally {
1298                     annotate.unblockAnnotations();
1299                 }
1300             }
1301         } else {
1302             doQueueScanTreeAndTypeAnnotateForVarInit(tree, env);
1303         }
1304 
1305         VarSymbol v = tree.sym;
1306         Lint lint = env.info.lint.augment(v);
1307         Lint prevLint = chk.setLint(lint);
1308 
1309         // Check that the variable's declared type is well-formed.
1310         boolean isImplicitLambdaParameter = env.tree.hasTag(LAMBDA) &&
1311                 ((JCLambda)env.tree).paramKind == JCLambda.ParameterKind.IMPLICIT &&
1312                 (tree.sym.flags() & PARAMETER) != 0;
1313         chk.validate(tree.vartype, env, !isImplicitLambdaParameter && !tree.isImplicitlyTyped());
1314 
1315         try {
1316             v.getConstValue(); // ensure compile-time constant initializer is evaluated
1317             chk.checkDeprecatedAnnotation(tree.pos(), v);
1318 
1319             if (tree.init != null) {
1320                 if ((v.flags_field & FINAL) == 0 ||
1321                     !memberEnter.needsLazyConstValue(tree.init)) {
1322                     // Not a compile-time constant
1323                     // Attribute initializer in a new environment
1324                     // with the declared variable as owner.
1325                     // Check that initializer conforms to variable's declared type.
1326                     Env<AttrContext> initEnv = memberEnter.initEnv(tree, env);
1327                     initEnv.info.lint = lint;
1328                     // In order to catch self-references, we set the variable's
1329                     // declaration position to maximal possible value, effectively
1330                     // marking the variable as undefined.
1331                     initEnv.info.enclVar = v;
1332                     EarlyConstructionContext previousEarlyConstruction = initEnv.info.earlyContext;
1333                     try {
1334                         if (v.isStrictInstance() && allowValueClasses) {
1335                             // instance strict field init occur in early construction context
1336                             initEnv.info.earlyContext = EarlyConstructionContext.of((ClassSymbol)v.owner, false);
1337                         }
1338                         attribExpr(tree.init, initEnv, v.type);
1339                         if (tree.isImplicitlyTyped()) {
1340                             //fixup local variable type
1341                             v.type = chk.checkLocalVarType(tree, tree.init.type, tree.name);
1342                         }
1343                     } finally {
1344                         initEnv.info.earlyContext = previousEarlyConstruction;
1345                     }
1346                 }
1347                 if (tree.isImplicitlyTyped()) {
1348                     setupImplicitlyTypedVariable(tree, v.type);
1349                 }
1350             }
1351             result = tree.type = v.type;
1352             if (env.enclClass.sym.isRecord() && tree.sym.owner.kind == TYP && !v.isStatic()) {
1353                 if (isNonArgsMethodInObject(v.name)) {
1354                     log.error(tree, Errors.IllegalRecordComponentName(v));
1355                 }
1356             }
1357             chk.checkRequiresIdentity(tree, env.info.lint);
1358         }
1359         finally {
1360             chk.setLint(prevLint);
1361         }
1362     }
1363 
1364     private void doQueueScanTreeAndTypeAnnotateForVarInit(JCVariableDecl tree, Env<AttrContext> env) {
1365         if (tree.init != null &&
1366             (tree.sym.flags_field & Flags.FIELD_INIT_TYPE_ANNOTATIONS_QUEUED) == 0 &&
1367             env.info.scope.owner.kind != MTH && env.info.scope.owner.kind != VAR) {
1368             tree.sym.flags_field |= Flags.FIELD_INIT_TYPE_ANNOTATIONS_QUEUED;
1369             // Field initializer expression need to be entered.
1370             annotate.queueScanTreeAndTypeAnnotate(tree.init, env, tree.sym);
1371             annotate.flush();
1372         }
1373     }
1374 
1375     private boolean isNonArgsMethodInObject(Name name) {
1376         for (Symbol s : syms.objectType.tsym.members().getSymbolsByName(name, s -> s.kind == MTH)) {
1377             if (s.type.getParameterTypes().isEmpty()) {
1378                 return true;
1379             }
1380         }
1381         return false;
1382     }
1383 
1384     Fragment canInferLocalVarType(JCVariableDecl tree) {
1385         LocalInitScanner lis = new LocalInitScanner();
1386         lis.scan(tree.init);
1387         return lis.badInferenceMsg;
1388     }
1389 
1390     static class LocalInitScanner extends TreeScanner {
1391         Fragment badInferenceMsg = null;
1392         boolean needsTarget = true;
1393 
1394         @Override
1395         public void visitNewArray(JCNewArray tree) {
1396             if (tree.elemtype == null && needsTarget) {
1397                 badInferenceMsg = Fragments.LocalArrayMissingTarget;
1398             }
1399         }
1400 
1401         @Override
1402         public void visitLambda(JCLambda tree) {
1403             if (needsTarget) {
1404                 badInferenceMsg = Fragments.LocalLambdaMissingTarget;
1405             }
1406         }
1407 
1408         @Override
1409         public void visitTypeCast(JCTypeCast tree) {
1410             boolean prevNeedsTarget = needsTarget;
1411             try {
1412                 needsTarget = false;
1413                 super.visitTypeCast(tree);
1414             } finally {
1415                 needsTarget = prevNeedsTarget;
1416             }
1417         }
1418 
1419         @Override
1420         public void visitReference(JCMemberReference tree) {
1421             if (needsTarget) {
1422                 badInferenceMsg = Fragments.LocalMrefMissingTarget;
1423             }
1424         }
1425 
1426         @Override
1427         public void visitNewClass(JCNewClass tree) {
1428             boolean prevNeedsTarget = needsTarget;
1429             try {
1430                 needsTarget = false;
1431                 super.visitNewClass(tree);
1432             } finally {
1433                 needsTarget = prevNeedsTarget;
1434             }
1435         }
1436 
1437         @Override
1438         public void visitApply(JCMethodInvocation tree) {
1439             boolean prevNeedsTarget = needsTarget;
1440             try {
1441                 needsTarget = false;
1442                 super.visitApply(tree);
1443             } finally {
1444                 needsTarget = prevNeedsTarget;
1445             }
1446         }
1447     }
1448 
1449     public void visitSkip(JCSkip tree) {
1450         result = null;
1451     }
1452 
1453     public void visitBlock(JCBlock tree) {
1454         if (env.info.scope.owner.kind == TYP || env.info.scope.owner.kind == ERR) {
1455             // Block is a static or instance initializer;
1456             // let the owner of the environment be a freshly
1457             // created BLOCK-method.
1458             Symbol fakeOwner =
1459                 new MethodSymbol(tree.flags | BLOCK |
1460                     env.info.scope.owner.flags() & STRICTFP, names.empty, initBlockType,
1461                     env.info.scope.owner);
1462             final Env<AttrContext> localEnv =
1463                 env.dup(tree, env.info.dup(env.info.scope.dupUnshared(fakeOwner)));
1464 
1465             if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
1466             // Attribute all type annotations in the block
1467             annotate.queueScanTreeAndTypeAnnotate(tree, localEnv, localEnv.info.scope.owner);
1468             annotate.flush();
1469             attribStats(tree.stats, localEnv);
1470 
1471             {
1472                 // Store init and clinit type annotations with the ClassSymbol
1473                 // to allow output in Gen.normalizeDefs.
1474                 ClassSymbol cs = (ClassSymbol)env.info.scope.owner;
1475                 List<Attribute.TypeCompound> tas = localEnv.info.scope.owner.getRawTypeAttributes();
1476                 if ((tree.flags & STATIC) != 0) {
1477                     cs.appendClassInitTypeAttributes(tas);
1478                 } else {
1479                     cs.appendInitTypeAttributes(tas);
1480                 }
1481             }
1482         } else {
1483             // Create a new local environment with a local scope.
1484             Env<AttrContext> localEnv =
1485                 env.dup(tree, env.info.dup(env.info.scope.dup()));
1486             try {
1487                 attribStats(tree.stats, localEnv);
1488             } finally {
1489                 localEnv.info.scope.leave();
1490             }
1491         }
1492         result = null;
1493     }
1494 
1495     public void visitDoLoop(JCDoWhileLoop tree) {
1496         attribStat(tree.body, env.dup(tree));
1497         attribExpr(tree.cond, env, syms.booleanType);
1498         handleLoopConditionBindings(matchBindings, tree, tree.body);
1499         result = null;
1500     }
1501 
1502     public void visitWhileLoop(JCWhileLoop tree) {
1503         attribExpr(tree.cond, env, syms.booleanType);
1504         MatchBindings condBindings = matchBindings;
1505         // include condition's bindings when true in the body:
1506         Env<AttrContext> whileEnv = bindingEnv(env, condBindings.bindingsWhenTrue);
1507         try {
1508             attribStat(tree.body, whileEnv.dup(tree));
1509         } finally {
1510             whileEnv.info.scope.leave();
1511         }
1512         handleLoopConditionBindings(condBindings, tree, tree.body);
1513         result = null;
1514     }
1515 
1516     public void visitForLoop(JCForLoop tree) {
1517         Env<AttrContext> loopEnv =
1518             env.dup(env.tree, env.info.dup(env.info.scope.dup()));
1519         MatchBindings condBindings = MatchBindingsComputer.EMPTY;
1520         try {
1521             attribStats(tree.init, loopEnv);
1522             if (tree.cond != null) {
1523                 attribExpr(tree.cond, loopEnv, syms.booleanType);
1524                 // include condition's bindings when true in the body and step:
1525                 condBindings = matchBindings;
1526             }
1527             Env<AttrContext> bodyEnv = bindingEnv(loopEnv, condBindings.bindingsWhenTrue);
1528             try {
1529                 bodyEnv.tree = tree; // before, we were not in loop!
1530                 attribStats(tree.step, bodyEnv);
1531                 attribStat(tree.body, bodyEnv);
1532             } finally {
1533                 bodyEnv.info.scope.leave();
1534             }
1535             result = null;
1536         }
1537         finally {
1538             loopEnv.info.scope.leave();
1539         }
1540         handleLoopConditionBindings(condBindings, tree, tree.body);
1541     }
1542 
1543     /**
1544      * Include condition's bindings when false after the loop, if cannot get out of the loop
1545      */
1546     private void handleLoopConditionBindings(MatchBindings condBindings,
1547                                              JCStatement loop,
1548                                              JCStatement loopBody) {
1549         if (condBindings.bindingsWhenFalse.nonEmpty() &&
1550             !breaksTo(env, loop, loopBody)) {
1551             addBindings2Scope(loop, condBindings.bindingsWhenFalse);
1552         }
1553     }
1554 
1555     private boolean breaksTo(Env<AttrContext> env, JCTree loop, JCTree body) {
1556         preFlow(body);
1557         return flow.breaksToTree(env, loop, body, make);
1558     }
1559 
1560     /**
1561      * Add given bindings to the current scope, unless there's a break to
1562      * an immediately enclosing labeled statement.
1563      */
1564     private void addBindings2Scope(JCStatement introducingStatement,
1565                                    List<BindingSymbol> bindings) {
1566         if (bindings.isEmpty()) {
1567             return ;
1568         }
1569 
1570         var searchEnv = env;
1571         while (searchEnv.tree instanceof JCLabeledStatement labeled &&
1572                labeled.body == introducingStatement) {
1573             if (breaksTo(env, labeled, labeled.body)) {
1574                 //breaking to an immediately enclosing labeled statement
1575                 return ;
1576             }
1577             searchEnv = searchEnv.next;
1578             introducingStatement = labeled;
1579         }
1580 
1581         //include condition's body when false after the while, if cannot get out of the loop
1582         bindings.forEach(env.info.scope::enter);
1583         bindings.forEach(BindingSymbol::preserveBinding);
1584     }
1585 
1586     public void visitForeachLoop(JCEnhancedForLoop tree) {
1587         Env<AttrContext> loopEnv =
1588             env.dup(env.tree, env.info.dup(env.info.scope.dup()));
1589         try {
1590             //the Formal Parameter of a for-each loop is not in the scope when
1591             //attributing the for-each expression; we mimic this by attributing
1592             //the for-each expression first (against original scope).
1593             Type exprType = types.cvarUpperBound(attribExpr(tree.expr, loopEnv));
1594             chk.checkNonVoid(tree.pos(), exprType);
1595             Type elemtype = types.elemtype(exprType); // perhaps expr is an array?
1596             if (elemtype == null) {
1597                 // or perhaps expr implements Iterable<T>?
1598                 Type base = types.asSuper(exprType, syms.iterableType.tsym);
1599                 if (base == null) {
1600                     log.error(tree.expr.pos(),
1601                               Errors.ForeachNotApplicableToType(exprType,
1602                                                                 Fragments.TypeReqArrayOrIterable));
1603                     elemtype = types.createErrorType(exprType);
1604                 } else {
1605                     List<Type> iterableParams = base.allparams();
1606                     elemtype = iterableParams.isEmpty()
1607                         ? syms.objectType
1608                         : types.wildUpperBound(iterableParams.head);
1609 
1610                     // Check the return type of the method iterator().
1611                     // This is the bare minimum we need to verify to make sure code generation doesn't crash.
1612                     Symbol iterSymbol = rs.resolveInternalMethod(tree.pos(),
1613                             loopEnv, types.skipTypeVars(exprType, false), names.iterator, List.nil(), List.nil());
1614                     if (types.asSuper(iterSymbol.type.getReturnType(), syms.iteratorType.tsym) == null) {
1615                         log.error(tree.pos(),
1616                                 Errors.ForeachNotApplicableToType(exprType, Fragments.TypeReqArrayOrIterable));
1617                     }
1618                 }
1619             }
1620             if (tree.var.isImplicitlyTyped()) {
1621                 Type inferredType = chk.checkLocalVarType(tree.var, elemtype, tree.var.name);
1622                 tree.var.type = inferredType;
1623                 setupImplicitlyTypedVariable(tree.var, inferredType);
1624             }
1625             attribStat(tree.var, loopEnv);
1626             chk.checkType(tree.expr.pos(), elemtype, tree.var.sym.type);
1627             loopEnv.tree = tree; // before, we were not in loop!
1628             attribStat(tree.body, loopEnv);
1629             result = null;
1630         }
1631         finally {
1632             loopEnv.info.scope.leave();
1633         }
1634     }
1635 
1636     public void visitLabelled(JCLabeledStatement tree) {
1637         // Check that label is not used in an enclosing statement
1638         Env<AttrContext> env1 = env;
1639         while (env1 != null && !env1.tree.hasTag(CLASSDEF)) {
1640             if (env1.tree.hasTag(LABELLED) &&
1641                 ((JCLabeledStatement) env1.tree).label == tree.label) {
1642                 log.error(tree.pos(),
1643                           Errors.LabelAlreadyInUse(tree.label));
1644                 break;
1645             }
1646             env1 = env1.next;
1647         }
1648 
1649         attribStat(tree.body, env.dup(tree));
1650         result = null;
1651     }
1652 
1653     public void visitSwitch(JCSwitch tree) {
1654         handleSwitch(tree, tree.selector, tree.cases, (c, caseEnv) -> {
1655             attribStats(c.stats, caseEnv);
1656         });
1657         result = null;
1658     }
1659 
1660     public void visitSwitchExpression(JCSwitchExpression tree) {
1661         boolean wrongContext = false;
1662 
1663         tree.polyKind = (pt().hasTag(NONE) && pt() != Type.recoveryType && pt() != Infer.anyPoly) ?
1664                 PolyKind.STANDALONE : PolyKind.POLY;
1665 
1666         if (tree.polyKind == PolyKind.POLY && resultInfo.pt.hasTag(VOID)) {
1667             //this means we are returning a poly conditional from void-compatible lambda expression
1668             resultInfo.checkContext.report(tree, diags.fragment(Fragments.SwitchExpressionTargetCantBeVoid));
1669             resultInfo = recoveryInfo;
1670             wrongContext = true;
1671         }
1672 
1673         ResultInfo condInfo = tree.polyKind == PolyKind.STANDALONE ?
1674                 unknownExprInfo :
1675                 resultInfo.dup(switchExpressionContext(resultInfo.checkContext));
1676 
1677         ListBuffer<DiagnosticPosition> caseTypePositions = new ListBuffer<>();
1678         ListBuffer<Type> caseTypes = new ListBuffer<>();
1679 
1680         handleSwitch(tree, tree.selector, tree.cases, (c, caseEnv) -> {
1681             caseEnv.info.yieldResult = condInfo;
1682             attribStats(c.stats, caseEnv);
1683             new TreeScanner() {
1684                 @Override
1685                 public void visitYield(JCYield brk) {
1686                     if (brk.target == tree) {
1687                         caseTypePositions.append(brk.value != null ? brk.value.pos() : brk.pos());
1688                         caseTypes.append(brk.value != null ? brk.value.type : syms.errType);
1689                     }
1690                     super.visitYield(brk);
1691                 }
1692 
1693                 @Override public void visitClassDef(JCClassDecl tree) {}
1694                 @Override public void visitLambda(JCLambda tree) {}
1695             }.scan(c.stats);
1696         });
1697 
1698         if (tree.cases.isEmpty()) {
1699             log.error(tree.pos(),
1700                       Errors.SwitchExpressionEmpty);
1701         } else if (caseTypes.isEmpty()) {
1702             log.error(tree.pos(),
1703                       Errors.SwitchExpressionNoResultExpressions);
1704         }
1705 
1706         Type owntype = (tree.polyKind == PolyKind.STANDALONE) ? condType(caseTypePositions.toList(), caseTypes.toList()) : pt();
1707 
1708         result = tree.type = wrongContext? types.createErrorType(pt()) : check(tree, owntype, KindSelector.VAL, resultInfo);
1709     }
1710     //where:
1711         CheckContext switchExpressionContext(CheckContext checkContext) {
1712             return new Check.NestedCheckContext(checkContext) {
1713                 //this will use enclosing check context to check compatibility of
1714                 //subexpression against target type; if we are in a method check context,
1715                 //depending on whether boxing is allowed, we could have incompatibilities
1716                 @Override
1717                 public void report(DiagnosticPosition pos, JCDiagnostic details) {
1718                     enclosingContext.report(pos, diags.fragment(Fragments.IncompatibleTypeInSwitchExpression(details)));
1719                 }
1720             };
1721         }
1722 
1723     private void handleSwitch(JCTree switchTree,
1724                               JCExpression selector,
1725                               List<JCCase> cases,
1726                               BiConsumer<JCCase, Env<AttrContext>> attribCase) {
1727         Type seltype = attribExpr(selector, env);
1728         Type seltypeUnboxed = types.unboxedTypeOrType(seltype);
1729 
1730         Env<AttrContext> switchEnv =
1731             env.dup(switchTree, env.info.dup(env.info.scope.dup()));
1732 
1733         try {
1734             boolean enumSwitch = (seltype.tsym.flags() & Flags.ENUM) != 0;
1735             boolean stringSwitch = types.isSameType(seltype, syms.stringType);
1736             boolean booleanSwitch = types.isSameType(seltypeUnboxed, syms.booleanType);
1737             boolean errorEnumSwitch = TreeInfo.isErrorEnumSwitch(selector, cases);
1738             boolean intSwitch = types.isAssignable(seltype, syms.intType);
1739             boolean patternSwitch;
1740             if (seltype.isPrimitive() && !intSwitch) {
1741                 preview.checkSourceLevel(selector.pos(), Feature.PRIMITIVE_PATTERNS);
1742                 patternSwitch = true;
1743             }
1744             if (!enumSwitch && !stringSwitch && !errorEnumSwitch &&
1745                 !intSwitch) {
1746                 preview.checkSourceLevel(selector.pos(), Feature.PATTERN_SWITCH);
1747                 patternSwitch = true;
1748             } else {
1749                 patternSwitch = cases.stream()
1750                                      .flatMap(c -> c.labels.stream())
1751                                      .anyMatch(l -> l.hasTag(PATTERNCASELABEL) ||
1752                                                     TreeInfo.isNullCaseLabel(l));
1753             }
1754 
1755             // Attribute all cases and
1756             // check that there are no duplicate case labels or default clauses.
1757             Set<Object> constants = new HashSet<>(); // The set of case constants.
1758             boolean hasDefault = false;           // Is there a default label?
1759             boolean hasUnconditionalPattern = false; // Is there a unconditional pattern?
1760             boolean lastPatternErroneous = false; // Has the last pattern erroneous type?
1761             boolean hasNullPattern = false;       // Is there a null pattern?
1762             CaseTree.CaseKind caseKind = null;
1763             boolean wasError = false;
1764             JCCaseLabel unconditionalCaseLabel = null;
1765             for (List<JCCase> l = cases; l.nonEmpty(); l = l.tail) {
1766                 JCCase c = l.head;
1767                 if (caseKind == null) {
1768                     caseKind = c.caseKind;
1769                 } else if (caseKind != c.caseKind && !wasError) {
1770                     log.error(c.pos(),
1771                               Errors.SwitchMixingCaseTypes);
1772                     wasError = true;
1773                 }
1774                 MatchBindings currentBindings = null;
1775                 MatchBindings guardBindings = null;
1776                 for (List<JCCaseLabel> labels = c.labels; labels.nonEmpty(); labels = labels.tail) {
1777                     JCCaseLabel label = labels.head;
1778                     if (label instanceof JCConstantCaseLabel constLabel) {
1779                         JCExpression expr = constLabel.expr;
1780                         if (TreeInfo.isNull(expr)) {
1781                             preview.checkSourceLevel(expr.pos(), Feature.CASE_NULL);
1782                             if (hasNullPattern) {
1783                                 log.error(label.pos(), Errors.DuplicateCaseLabel);
1784                             }
1785                             hasNullPattern = true;
1786                             attribExpr(expr, switchEnv, seltype);
1787                             matchBindings = new MatchBindings(matchBindings.bindingsWhenTrue, matchBindings.bindingsWhenFalse, true);
1788                         } else if (enumSwitch) {
1789                             Symbol sym = enumConstant(expr, seltype);
1790                             if (sym == null) {
1791                                 if (allowPatternSwitch) {
1792                                     attribTree(expr, switchEnv, caseLabelResultInfo(seltype));
1793                                     Symbol enumSym = TreeInfo.symbol(expr);
1794                                     if (enumSym == null || !enumSym.isEnum() || enumSym.kind != VAR) {
1795                                         log.error(expr.pos(), Errors.EnumLabelMustBeEnumConstant);
1796                                     } else if (!constants.add(enumSym)) {
1797                                         log.error(label.pos(), Errors.DuplicateCaseLabel);
1798                                     }
1799                                 } else {
1800                                     log.error(expr.pos(), Errors.EnumLabelMustBeUnqualifiedEnum);
1801                                 }
1802                             } else if (!constants.add(sym)) {
1803                                 log.error(label.pos(), Errors.DuplicateCaseLabel);
1804                             }
1805                         } else if (errorEnumSwitch) {
1806                             //error recovery: the selector is erroneous, and all the case labels
1807                             //are identifiers. This could be an enum switch - don't report resolve
1808                             //error for the case label:
1809                             var prevResolveHelper = rs.basicLogResolveHelper;
1810                             try {
1811                                 rs.basicLogResolveHelper = rs.silentLogResolveHelper;
1812                                 attribExpr(expr, switchEnv, seltype);
1813                             } finally {
1814                                 rs.basicLogResolveHelper = prevResolveHelper;
1815                             }
1816                         } else {
1817                             Type pattype = attribTree(expr, switchEnv, caseLabelResultInfo(seltype));
1818                             if (!pattype.hasTag(ERROR)) {
1819                                 if (pattype.constValue() == null) {
1820                                     Symbol s = TreeInfo.symbol(expr);
1821                                     if (s != null && s.kind == TYP) {
1822                                         log.error(expr.pos(),
1823                                                   Errors.PatternExpected);
1824                                     } else if (s == null || !s.isEnum()) {
1825                                         log.error(expr.pos(),
1826                                                   (stringSwitch ? Errors.StringConstReq
1827                                                                 : intSwitch ? Errors.ConstExprReq
1828                                                                             : Errors.PatternOrEnumReq));
1829                                     } else if (!constants.add(s)) {
1830                                         log.error(label.pos(), Errors.DuplicateCaseLabel);
1831                                     }
1832                                 }
1833                                 else {
1834                                     boolean isLongFloatDoubleOrBooleanConstant =
1835                                             pattype.getTag().isInSuperClassesOf(LONG) || pattype.getTag().equals(BOOLEAN);
1836                                     if (isLongFloatDoubleOrBooleanConstant) {
1837                                         preview.checkSourceLevel(label.pos(), Feature.PRIMITIVE_PATTERNS);
1838                                     }
1839                                     if (!stringSwitch && !intSwitch && !(isLongFloatDoubleOrBooleanConstant && types.isSameType(seltypeUnboxed, pattype))) {
1840                                         log.error(label.pos(), Errors.ConstantLabelNotCompatible(pattype, seltype));
1841                                     } else if (!constants.add(pattype.constValue())) {
1842                                         log.error(c.pos(), Errors.DuplicateCaseLabel);
1843                                     }
1844                                 }
1845                             }
1846                         }
1847                     } else if (label instanceof JCDefaultCaseLabel def) {
1848                         if (hasDefault) {
1849                             log.error(label.pos(), Errors.DuplicateDefaultLabel);
1850                         } else if (hasUnconditionalPattern) {
1851                             log.error(label.pos(), Errors.UnconditionalPatternAndDefault);
1852                         }  else if (booleanSwitch && constants.containsAll(Set.of(0, 1))) {
1853                             log.error(label.pos(), Errors.DefaultAndBothBooleanValues);
1854                         }
1855                         hasDefault = true;
1856                         matchBindings = MatchBindingsComputer.EMPTY;
1857                     } else if (label instanceof JCPatternCaseLabel patternlabel) {
1858                         //pattern
1859                         JCPattern pat = patternlabel.pat;
1860                         attribExpr(pat, switchEnv, seltype);
1861                         Type primaryType = TreeInfo.primaryPatternType(pat);
1862 
1863                         if (primaryType.isPrimitive()) {
1864                             preview.checkSourceLevel(pat.pos(), Feature.PRIMITIVE_PATTERNS);
1865                         } else if (!primaryType.hasTag(TYPEVAR)) {
1866                             primaryType = chk.checkClassOrArrayType(pat.pos(), primaryType);
1867                         }
1868                         checkCastablePattern(pat.pos(), seltype, primaryType);
1869                         Type patternType = types.erasure(primaryType);
1870                         JCExpression guard = c.guard;
1871                         if (guardBindings == null && guard != null) {
1872                             MatchBindings afterPattern = matchBindings;
1873                             Env<AttrContext> bodyEnv = bindingEnv(switchEnv, matchBindings.bindingsWhenTrue);
1874                             try {
1875                                 attribExpr(guard, bodyEnv, syms.booleanType);
1876                             } finally {
1877                                 bodyEnv.info.scope.leave();
1878                             }
1879 
1880                             guardBindings = matchBindings;
1881                             matchBindings = afterPattern;
1882 
1883                             if (TreeInfo.isBooleanWithValue(guard, 0)) {
1884                                 log.error(guard.pos(), Errors.GuardHasConstantExpressionFalse);
1885                             }
1886                         }
1887                         boolean unguarded = TreeInfo.unguardedCase(c) && !pat.hasTag(RECORDPATTERN);
1888                         boolean unconditional =
1889                                 unguarded &&
1890                                 !patternType.isErroneous() &&
1891                                 types.isUnconditionallyExactTypeBased(seltype, patternType);
1892                         if (unconditional) {
1893                             if (hasUnconditionalPattern) {
1894                                 log.error(pat.pos(), Errors.DuplicateUnconditionalPattern);
1895                             } else if (hasDefault) {
1896                                 log.error(pat.pos(), Errors.UnconditionalPatternAndDefault);
1897                             } else if (booleanSwitch && constants.containsAll(Set.of(0, 1))) {
1898                                 log.error(pat.pos(), Errors.UnconditionalPatternAndBothBooleanValues);
1899                             }
1900                             hasUnconditionalPattern = true;
1901                             unconditionalCaseLabel = label;
1902                         }
1903                         lastPatternErroneous = patternType.isErroneous();
1904                     } else {
1905                         Assert.error();
1906                     }
1907                     currentBindings = matchBindingsComputer.switchCase(label, currentBindings, matchBindings);
1908                 }
1909 
1910                 if (guardBindings != null) {
1911                     currentBindings = matchBindingsComputer.caseGuard(c, currentBindings, guardBindings);
1912                 }
1913 
1914                 Env<AttrContext> caseEnv =
1915                         bindingEnv(switchEnv, c, currentBindings.bindingsWhenTrue);
1916                 try {
1917                     attribCase.accept(c, caseEnv);
1918                 } finally {
1919                     caseEnv.info.scope.leave();
1920                 }
1921                 addVars(c.stats, switchEnv.info.scope);
1922 
1923                 preFlow(c);
1924                 c.completesNormally = flow.aliveAfter(caseEnv, c, make);
1925             }
1926             if (patternSwitch) {
1927                 chk.checkSwitchCaseStructure(cases);
1928                 chk.checkSwitchCaseLabelDominated(unconditionalCaseLabel, cases);
1929             }
1930             if (switchTree.hasTag(SWITCH)) {
1931                 ((JCSwitch) switchTree).hasUnconditionalPattern =
1932                         hasDefault || hasUnconditionalPattern || lastPatternErroneous;
1933                 ((JCSwitch) switchTree).patternSwitch = patternSwitch;
1934             } else if (switchTree.hasTag(SWITCH_EXPRESSION)) {
1935                 ((JCSwitchExpression) switchTree).hasUnconditionalPattern =
1936                         hasDefault || hasUnconditionalPattern || lastPatternErroneous;
1937                 ((JCSwitchExpression) switchTree).patternSwitch = patternSwitch;
1938             } else {
1939                 Assert.error(switchTree.getTag().name());
1940             }
1941         } finally {
1942             switchEnv.info.scope.leave();
1943         }
1944     }
1945     // where
1946         private ResultInfo caseLabelResultInfo(Type seltype) {
1947             return new ResultInfo(KindSelector.VAL_TYP,
1948                                   !seltype.hasTag(ERROR) ? seltype
1949                                                          : Type.noType);
1950         }
1951         /** Add any variables defined in stats to the switch scope. */
1952         private static void addVars(List<JCStatement> stats, WriteableScope switchScope) {
1953             for (;stats.nonEmpty(); stats = stats.tail) {
1954                 JCTree stat = stats.head;
1955                 if (stat.hasTag(VARDEF))
1956                     switchScope.enter(((JCVariableDecl) stat).sym);
1957             }
1958         }
1959     // where
1960     /** Return the selected enumeration constant symbol, or null. */
1961     private Symbol enumConstant(JCTree tree, Type enumType) {
1962         if (tree.hasTag(IDENT)) {
1963             JCIdent ident = (JCIdent)tree;
1964             Name name = ident.name;
1965             for (Symbol sym : enumType.tsym.members().getSymbolsByName(name)) {
1966                 if (sym.kind == VAR) {
1967                     Symbol s = ident.sym = sym;
1968                     ((VarSymbol)s).getConstValue(); // ensure initializer is evaluated
1969                     ident.type = s.type;
1970                     return ((s.flags_field & Flags.ENUM) == 0)
1971                         ? null : s;
1972                 }
1973             }
1974         }
1975         return null;
1976     }
1977 
1978     public void visitSynchronized(JCSynchronized tree) {
1979         boolean identityType = chk.checkIdentityRefType(tree.pos(), attribExpr(tree.lock, env));
1980         if (identityType && tree.lock.type != null && tree.lock.type.isValueBased()) {
1981             log.warning(tree.pos(), LintWarnings.AttemptToSynchronizeOnInstanceOfValueBasedClass);
1982         }
1983         attribStat(tree.body, env);
1984         result = null;
1985     }
1986 
1987     public void visitTry(JCTry tree) {
1988         // Create a new local environment with a local
1989         Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
1990         try {
1991             boolean isTryWithResource = tree.resources.nonEmpty();
1992             // Create a nested environment for attributing the try block if needed
1993             Env<AttrContext> tryEnv = isTryWithResource ?
1994                 env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) :
1995                 localEnv;
1996             try {
1997                 // Attribute resource declarations
1998                 for (JCTree resource : tree.resources) {
1999                     CheckContext twrContext = new Check.NestedCheckContext(chk.subtypeHandler) {
2000                         @Override
2001                         public void report(DiagnosticPosition pos, JCDiagnostic details) {
2002                             chk.basicHandler.report(pos, diags.fragment(Fragments.TryNotApplicableToType(details)));
2003                         }
2004                     };
2005                     ResultInfo twrResult =
2006                         new ResultInfo(KindSelector.VAR,
2007                                        syms.autoCloseableType,
2008                                        twrContext);
2009                     if (resource.hasTag(VARDEF)) {
2010                         attribStat(resource, tryEnv);
2011                         twrResult.check(resource, resource.type);
2012 
2013                         //check that resource type cannot throw InterruptedException
2014                         checkAutoCloseable(localEnv, resource, true);
2015 
2016                         VarSymbol var = ((JCVariableDecl) resource).sym;
2017 
2018                         var.flags_field |= Flags.FINAL;
2019                         var.setData(ElementKind.RESOURCE_VARIABLE);
2020                     } else {
2021                         attribTree(resource, tryEnv, twrResult);
2022                     }
2023                 }
2024                 // Attribute body
2025                 attribStat(tree.body, tryEnv);
2026             } finally {
2027                 if (isTryWithResource)
2028                     tryEnv.info.scope.leave();
2029             }
2030 
2031             // Attribute catch clauses
2032             for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
2033                 JCCatch c = l.head;
2034                 Env<AttrContext> catchEnv =
2035                     localEnv.dup(c, localEnv.info.dup(localEnv.info.scope.dup()));
2036                 try {
2037                     Type ctype = attribStat(c.param, catchEnv);
2038                     if (TreeInfo.isMultiCatch(c)) {
2039                         //multi-catch parameter is implicitly marked as final
2040                         c.param.sym.flags_field |= FINAL | UNION;
2041                     }
2042                     if (c.param.sym.kind == VAR) {
2043                         c.param.sym.setData(ElementKind.EXCEPTION_PARAMETER);
2044                     }
2045                     chk.checkType(c.param.vartype.pos(),
2046                                   chk.checkClassType(c.param.vartype.pos(), ctype),
2047                                   syms.throwableType,
2048                                   chk.subtypeHandler);
2049                     attribStat(c.body, catchEnv);
2050                 } finally {
2051                     catchEnv.info.scope.leave();
2052                 }
2053             }
2054 
2055             // Attribute finalizer
2056             if (tree.finalizer != null) attribStat(tree.finalizer, localEnv);
2057             result = null;
2058         }
2059         finally {
2060             localEnv.info.scope.leave();
2061         }
2062     }
2063 
2064     void checkAutoCloseable(Env<AttrContext> env, JCTree tree, boolean useSite) {
2065         DiagnosticPosition pos = tree.pos();
2066         Type resource = tree.type;
2067         if (!resource.isErroneous() &&
2068             types.asSuper(resource, syms.autoCloseableType.tsym) != null &&
2069             !types.isSameType(resource, syms.autoCloseableType)) { // Don't emit warning for AutoCloseable itself
2070             Symbol close = syms.noSymbol;
2071             Log.DiagnosticHandler discardHandler = log.new DiscardDiagnosticHandler();
2072             try {
2073                 close = rs.resolveQualifiedMethod(pos,
2074                         env,
2075                         types.skipTypeVars(resource, false),
2076                         names.close,
2077                         List.nil(),
2078                         List.nil());
2079             }
2080             finally {
2081                 log.popDiagnosticHandler(discardHandler);
2082             }
2083             if (close.kind == MTH &&
2084                     (useSite || close.owner != syms.autoCloseableType.tsym) &&
2085                     ((MethodSymbol)close).binaryOverrides(syms.autoCloseableClose, resource.tsym, types) &&
2086                     chk.isHandled(syms.interruptedExceptionType, types.memberType(resource, close).getThrownTypes())) {
2087                 if (!useSite && close.owner == resource.tsym) {
2088                     log.warning(TreeInfo.diagnosticPositionFor(close, tree),
2089                         LintWarnings.TryResourceCanThrowInterruptedExc(resource));
2090                 } else {
2091                     log.warning(pos, LintWarnings.TryResourceThrowsInterruptedExc(resource));
2092                 }
2093             }
2094         }
2095     }
2096 
2097     public void visitConditional(JCConditional tree) {
2098         Type condtype = attribExpr(tree.cond, env, syms.booleanType);
2099         MatchBindings condBindings = matchBindings;
2100 
2101         tree.polyKind = (pt().hasTag(NONE) && pt() != Type.recoveryType && pt() != Infer.anyPoly ||
2102                 isBooleanOrNumeric(env, tree)) ?
2103                 PolyKind.STANDALONE : PolyKind.POLY;
2104 
2105         if (tree.polyKind == PolyKind.POLY && resultInfo.pt.hasTag(VOID)) {
2106             //this means we are returning a poly conditional from void-compatible lambda expression
2107             resultInfo.checkContext.report(tree, diags.fragment(Fragments.ConditionalTargetCantBeVoid));
2108             result = tree.type = types.createErrorType(resultInfo.pt);
2109             return;
2110         }
2111 
2112         ResultInfo condInfo = tree.polyKind == PolyKind.STANDALONE ?
2113                 unknownExprInfo :
2114                 resultInfo.dup(conditionalContext(resultInfo.checkContext));
2115 
2116 
2117         // x ? y : z
2118         // include x's bindings when true in y
2119         // include x's bindings when false in z
2120 
2121         Type truetype;
2122         Env<AttrContext> trueEnv = bindingEnv(env, condBindings.bindingsWhenTrue);
2123         try {
2124             truetype = attribTree(tree.truepart, trueEnv, condInfo);
2125         } finally {
2126             trueEnv.info.scope.leave();
2127         }
2128 
2129         MatchBindings trueBindings = matchBindings;
2130 
2131         Type falsetype;
2132         Env<AttrContext> falseEnv = bindingEnv(env, condBindings.bindingsWhenFalse);
2133         try {
2134             falsetype = attribTree(tree.falsepart, falseEnv, condInfo);
2135         } finally {
2136             falseEnv.info.scope.leave();
2137         }
2138 
2139         MatchBindings falseBindings = matchBindings;
2140 
2141         Type owntype = (tree.polyKind == PolyKind.STANDALONE) ?
2142                 condType(List.of(tree.truepart.pos(), tree.falsepart.pos()),
2143                          List.of(truetype, falsetype)) : pt();
2144         if (condtype.constValue() != null &&
2145                 truetype.constValue() != null &&
2146                 falsetype.constValue() != null &&
2147                 !owntype.hasTag(NONE)) {
2148             //constant folding
2149             owntype = cfolder.coerce(condtype.isTrue() ? truetype : falsetype, owntype);
2150         }
2151         result = check(tree, owntype, KindSelector.VAL, resultInfo);
2152         matchBindings = matchBindingsComputer.conditional(tree, condBindings, trueBindings, falseBindings);
2153     }
2154     //where
2155         private boolean isBooleanOrNumeric(Env<AttrContext> env, JCExpression tree) {
2156             switch (tree.getTag()) {
2157                 case LITERAL: return ((JCLiteral)tree).typetag.isSubRangeOf(DOUBLE) ||
2158                               ((JCLiteral)tree).typetag == BOOLEAN ||
2159                               ((JCLiteral)tree).typetag == BOT;
2160                 case LAMBDA: case REFERENCE: return false;
2161                 case PARENS: return isBooleanOrNumeric(env, ((JCParens)tree).expr);
2162                 case CONDEXPR:
2163                     JCConditional condTree = (JCConditional)tree;
2164                     return isBooleanOrNumeric(env, condTree.truepart) &&
2165                             isBooleanOrNumeric(env, condTree.falsepart);
2166                 case APPLY:
2167                     JCMethodInvocation speculativeMethodTree =
2168                             (JCMethodInvocation)deferredAttr.attribSpeculative(
2169                                     tree, env, unknownExprInfo,
2170                                     argumentAttr.withLocalCacheContext());
2171                     Symbol msym = TreeInfo.symbol(speculativeMethodTree.meth);
2172                     Type receiverType = speculativeMethodTree.meth.hasTag(IDENT) ?
2173                             env.enclClass.type :
2174                             ((JCFieldAccess)speculativeMethodTree.meth).selected.type;
2175                     Type owntype = types.memberType(receiverType, msym).getReturnType();
2176                     return primitiveOrBoxed(owntype);
2177                 case NEWCLASS:
2178                     JCExpression className =
2179                             removeClassParams.translate(((JCNewClass)tree).clazz);
2180                     JCExpression speculativeNewClassTree =
2181                             (JCExpression)deferredAttr.attribSpeculative(
2182                                     className, env, unknownTypeInfo,
2183                                     argumentAttr.withLocalCacheContext());
2184                     return primitiveOrBoxed(speculativeNewClassTree.type);
2185                 default:
2186                     Type speculativeType = deferredAttr.attribSpeculative(tree, env, unknownExprInfo,
2187                             argumentAttr.withLocalCacheContext()).type;
2188                     return primitiveOrBoxed(speculativeType);
2189             }
2190         }
2191         //where
2192             boolean primitiveOrBoxed(Type t) {
2193                 return (!t.hasTag(TYPEVAR) && !t.isErroneous() && types.unboxedTypeOrType(t).isPrimitive());
2194             }
2195 
2196             TreeTranslator removeClassParams = new TreeTranslator() {
2197                 @Override
2198                 public void visitTypeApply(JCTypeApply tree) {
2199                     result = translate(tree.clazz);
2200                 }
2201             };
2202 
2203         CheckContext conditionalContext(CheckContext checkContext) {
2204             return new Check.NestedCheckContext(checkContext) {
2205                 //this will use enclosing check context to check compatibility of
2206                 //subexpression against target type; if we are in a method check context,
2207                 //depending on whether boxing is allowed, we could have incompatibilities
2208                 @Override
2209                 public void report(DiagnosticPosition pos, JCDiagnostic details) {
2210                     enclosingContext.report(pos, diags.fragment(Fragments.IncompatibleTypeInConditional(details)));
2211                 }
2212             };
2213         }
2214 
2215         /** Compute the type of a conditional expression, after
2216          *  checking that it exists.  See JLS 15.25. Does not take into
2217          *  account the special case where condition and both arms
2218          *  are constants.
2219          *
2220          *  @param pos      The source position to be used for error
2221          *                  diagnostics.
2222          *  @param thentype The type of the expression's then-part.
2223          *  @param elsetype The type of the expression's else-part.
2224          */
2225         Type condType(List<DiagnosticPosition> positions, List<Type> condTypes) {
2226             if (condTypes.isEmpty()) {
2227                 return syms.objectType; //TODO: how to handle?
2228             }
2229             Type first = condTypes.head;
2230             // If same type, that is the result
2231             if (condTypes.tail.stream().allMatch(t -> types.isSameType(first, t)))
2232                 return first.baseType();
2233 
2234             List<Type> unboxedTypes = condTypes.stream()
2235                                                .map(t -> t.isPrimitive() ? t : types.unboxedType(t))
2236                                                .collect(List.collector());
2237 
2238             // Otherwise, if both arms can be converted to a numeric
2239             // type, return the least numeric type that fits both arms
2240             // (i.e. return larger of the two, or return int if one
2241             // arm is short, the other is char).
2242             if (unboxedTypes.stream().allMatch(t -> t.isPrimitive())) {
2243                 // If one arm has an integer subrange type (i.e., byte,
2244                 // short, or char), and the other is an integer constant
2245                 // that fits into the subrange, return the subrange type.
2246                 for (Type type : unboxedTypes) {
2247                     if (!type.getTag().isStrictSubRangeOf(INT)) {
2248                         continue;
2249                     }
2250                     if (unboxedTypes.stream().filter(t -> t != type).allMatch(t -> t.hasTag(INT) && types.isAssignable(t, type)))
2251                         return type.baseType();
2252                 }
2253 
2254                 for (TypeTag tag : primitiveTags) {
2255                     Type candidate = syms.typeOfTag[tag.ordinal()];
2256                     if (unboxedTypes.stream().allMatch(t -> types.isSubtype(t, candidate))) {
2257                         return candidate;
2258                     }
2259                 }
2260             }
2261 
2262             // Those were all the cases that could result in a primitive
2263             condTypes = condTypes.stream()
2264                                  .map(t -> t.isPrimitive() ? types.boxedClass(t).type : t)
2265                                  .collect(List.collector());
2266 
2267             for (Type type : condTypes) {
2268                 if (condTypes.stream().filter(t -> t != type).allMatch(t -> types.isSubtype(t, type)))
2269                     return type.baseType();
2270             }
2271 
2272             Iterator<DiagnosticPosition> posIt = positions.iterator();
2273 
2274             condTypes = condTypes.stream()
2275                                  .map(t -> chk.checkNonVoid(posIt.next(), t))
2276                                  .collect(List.collector());
2277 
2278             // both are known to be reference types.  The result is
2279             // lub(thentype,elsetype). This cannot fail, as it will
2280             // always be possible to infer "Object" if nothing better.
2281             return types.lub(condTypes.stream()
2282                         .map(t -> t.baseType())
2283                         .filter(t -> !t.hasTag(BOT))
2284                         .collect(List.collector()));
2285         }
2286 
2287     static final TypeTag[] primitiveTags = new TypeTag[]{
2288         BYTE,
2289         CHAR,
2290         SHORT,
2291         INT,
2292         LONG,
2293         FLOAT,
2294         DOUBLE,
2295         BOOLEAN,
2296     };
2297 
2298     Env<AttrContext> bindingEnv(Env<AttrContext> env, List<BindingSymbol> bindings) {
2299         return bindingEnv(env, env.tree, bindings);
2300     }
2301 
2302     Env<AttrContext> bindingEnv(Env<AttrContext> env, JCTree newTree, List<BindingSymbol> bindings) {
2303         Env<AttrContext> env1 = env.dup(newTree, env.info.dup(env.info.scope.dup()));
2304         bindings.forEach(env1.info.scope::enter);
2305         return env1;
2306     }
2307 
2308     public void visitIf(JCIf tree) {
2309         attribExpr(tree.cond, env, syms.booleanType);
2310 
2311         // if (x) { y } [ else z ]
2312         // include x's bindings when true in y
2313         // include x's bindings when false in z
2314 
2315         MatchBindings condBindings = matchBindings;
2316         Env<AttrContext> thenEnv = bindingEnv(env, condBindings.bindingsWhenTrue);
2317 
2318         try {
2319             attribStat(tree.thenpart, thenEnv);
2320         } finally {
2321             thenEnv.info.scope.leave();
2322         }
2323 
2324         preFlow(tree.thenpart);
2325         boolean aliveAfterThen = flow.aliveAfter(env, tree.thenpart, make);
2326         boolean aliveAfterElse;
2327 
2328         if (tree.elsepart != null) {
2329             Env<AttrContext> elseEnv = bindingEnv(env, condBindings.bindingsWhenFalse);
2330             try {
2331                 attribStat(tree.elsepart, elseEnv);
2332             } finally {
2333                 elseEnv.info.scope.leave();
2334             }
2335             preFlow(tree.elsepart);
2336             aliveAfterElse = flow.aliveAfter(env, tree.elsepart, make);
2337         } else {
2338             aliveAfterElse = true;
2339         }
2340 
2341         chk.checkEmptyIf(tree);
2342 
2343         List<BindingSymbol> afterIfBindings = List.nil();
2344 
2345         if (aliveAfterThen && !aliveAfterElse) {
2346             afterIfBindings = condBindings.bindingsWhenTrue;
2347         } else if (aliveAfterElse && !aliveAfterThen) {
2348             afterIfBindings = condBindings.bindingsWhenFalse;
2349         }
2350 
2351         addBindings2Scope(tree, afterIfBindings);
2352 
2353         result = null;
2354     }
2355 
2356         void preFlow(JCTree tree) {
2357             attrRecover.doRecovery();
2358             new PostAttrAnalyzer() {
2359                 @Override
2360                 public void scan(JCTree tree) {
2361                     if (tree == null ||
2362                             (tree.type != null &&
2363                             tree.type == Type.stuckType)) {
2364                         //don't touch stuck expressions!
2365                         return;
2366                     }
2367                     super.scan(tree);
2368                 }
2369 
2370                 @Override
2371                 public void visitClassDef(JCClassDecl that) {
2372                     if (that.sym != null) {
2373                         // Method preFlow shouldn't visit class definitions
2374                         // that have not been entered and attributed.
2375                         // See JDK-8254557 and JDK-8203277 for more details.
2376                         super.visitClassDef(that);
2377                     }
2378                 }
2379 
2380                 @Override
2381                 public void visitLambda(JCLambda that) {
2382                     if (that.type != null) {
2383                         // Method preFlow shouldn't visit lambda expressions
2384                         // that have not been entered and attributed.
2385                         // See JDK-8254557 and JDK-8203277 for more details.
2386                         super.visitLambda(that);
2387                     }
2388                 }
2389             }.scan(tree);
2390         }
2391 
2392     public void visitExec(JCExpressionStatement tree) {
2393         //a fresh environment is required for 292 inference to work properly ---
2394         //see Infer.instantiatePolymorphicSignatureInstance()
2395         Env<AttrContext> localEnv = env.dup(tree);
2396         attribExpr(tree.expr, localEnv);
2397         result = null;
2398     }
2399 
2400     public void visitBreak(JCBreak tree) {
2401         tree.target = findJumpTarget(tree.pos(), tree.getTag(), tree.label, env);
2402         result = null;
2403     }
2404 
2405     public void visitYield(JCYield tree) {
2406         if (env.info.yieldResult != null) {
2407             attribTree(tree.value, env, env.info.yieldResult);
2408             tree.target = findJumpTarget(tree.pos(), tree.getTag(), names.empty, env);
2409         } else {
2410             log.error(tree.pos(), tree.value.hasTag(PARENS)
2411                     ? Errors.NoSwitchExpressionQualify
2412                     : Errors.NoSwitchExpression);
2413             attribTree(tree.value, env, unknownExprInfo);
2414         }
2415         result = null;
2416     }
2417 
2418     public void visitContinue(JCContinue tree) {
2419         tree.target = findJumpTarget(tree.pos(), tree.getTag(), tree.label, env);
2420         result = null;
2421     }
2422     //where
2423         /** Return the target of a break, continue or yield statement,
2424          *  if it exists, report an error if not.
2425          *  Note: The target of a labelled break or continue is the
2426          *  (non-labelled) statement tree referred to by the label,
2427          *  not the tree representing the labelled statement itself.
2428          *
2429          *  @param pos     The position to be used for error diagnostics
2430          *  @param tag     The tag of the jump statement. This is either
2431          *                 Tree.BREAK or Tree.CONTINUE.
2432          *  @param label   The label of the jump statement, or null if no
2433          *                 label is given.
2434          *  @param env     The environment current at the jump statement.
2435          */
2436         private JCTree findJumpTarget(DiagnosticPosition pos,
2437                                                    JCTree.Tag tag,
2438                                                    Name label,
2439                                                    Env<AttrContext> env) {
2440             Pair<JCTree, Error> jumpTarget = findJumpTargetNoError(tag, label, env);
2441 
2442             if (jumpTarget.snd != null) {
2443                 log.error(pos, jumpTarget.snd);
2444             }
2445 
2446             return jumpTarget.fst;
2447         }
2448         /** Return the target of a break or continue statement, if it exists,
2449          *  report an error if not.
2450          *  Note: The target of a labelled break or continue is the
2451          *  (non-labelled) statement tree referred to by the label,
2452          *  not the tree representing the labelled statement itself.
2453          *
2454          *  @param tag     The tag of the jump statement. This is either
2455          *                 Tree.BREAK or Tree.CONTINUE.
2456          *  @param label   The label of the jump statement, or null if no
2457          *                 label is given.
2458          *  @param env     The environment current at the jump statement.
2459          */
2460         private Pair<JCTree, JCDiagnostic.Error> findJumpTargetNoError(JCTree.Tag tag,
2461                                                                        Name label,
2462                                                                        Env<AttrContext> env) {
2463             // Search environments outwards from the point of jump.
2464             Env<AttrContext> env1 = env;
2465             JCDiagnostic.Error pendingError = null;
2466             LOOP:
2467             while (env1 != null) {
2468                 switch (env1.tree.getTag()) {
2469                     case LABELLED:
2470                         JCLabeledStatement labelled = (JCLabeledStatement)env1.tree;
2471                         if (label == labelled.label) {
2472                             // If jump is a continue, check that target is a loop.
2473                             if (tag == CONTINUE) {
2474                                 if (!labelled.body.hasTag(DOLOOP) &&
2475                                         !labelled.body.hasTag(WHILELOOP) &&
2476                                         !labelled.body.hasTag(FORLOOP) &&
2477                                         !labelled.body.hasTag(FOREACHLOOP)) {
2478                                     pendingError = Errors.NotLoopLabel(label);
2479                                 }
2480                                 // Found labelled statement target, now go inwards
2481                                 // to next non-labelled tree.
2482                                 return Pair.of(TreeInfo.referencedStatement(labelled), pendingError);
2483                             } else {
2484                                 return Pair.of(labelled, pendingError);
2485                             }
2486                         }
2487                         break;
2488                     case DOLOOP:
2489                     case WHILELOOP:
2490                     case FORLOOP:
2491                     case FOREACHLOOP:
2492                         if (label == null) return Pair.of(env1.tree, pendingError);
2493                         break;
2494                     case SWITCH:
2495                         if (label == null && tag == BREAK) return Pair.of(env1.tree, null);
2496                         break;
2497                     case SWITCH_EXPRESSION:
2498                         if (tag == YIELD) {
2499                             return Pair.of(env1.tree, null);
2500                         } else if (tag == BREAK) {
2501                             pendingError = Errors.BreakOutsideSwitchExpression;
2502                         } else {
2503                             pendingError = Errors.ContinueOutsideSwitchExpression;
2504                         }
2505                         break;
2506                     case LAMBDA:
2507                     case METHODDEF:
2508                     case CLASSDEF:
2509                         break LOOP;
2510                     default:
2511                 }
2512                 env1 = env1.next;
2513             }
2514             if (label != null)
2515                 return Pair.of(null, Errors.UndefLabel(label));
2516             else if (pendingError != null)
2517                 return Pair.of(null, pendingError);
2518             else if (tag == CONTINUE)
2519                 return Pair.of(null, Errors.ContOutsideLoop);
2520             else
2521                 return Pair.of(null, Errors.BreakOutsideSwitchLoop);
2522         }
2523 
2524     public void visitReturn(JCReturn tree) {
2525         // Check that there is an enclosing method which is
2526         // nested within than the enclosing class.
2527         if (env.info.returnResult == null) {
2528             log.error(tree.pos(), Errors.RetOutsideMeth);
2529         } else if (env.info.yieldResult != null) {
2530             log.error(tree.pos(), Errors.ReturnOutsideSwitchExpression);
2531             if (tree.expr != null) {
2532                 attribExpr(tree.expr, env, env.info.yieldResult.pt);
2533             }
2534         } else if (!env.info.isLambda &&
2535                 env.enclMethod != null &&
2536                 TreeInfo.isCompactConstructor(env.enclMethod)) {
2537             log.error(env.enclMethod,
2538                     Errors.InvalidCanonicalConstructorInRecord(Fragments.Compact, env.enclMethod.sym.name, Fragments.CanonicalCantHaveReturnStatement));
2539         } else {
2540             // Attribute return expression, if it exists, and check that
2541             // it conforms to result type of enclosing method.
2542             if (tree.expr != null) {
2543                 if (env.info.returnResult.pt.hasTag(VOID)) {
2544                     env.info.returnResult.checkContext.report(tree.expr.pos(),
2545                               diags.fragment(Fragments.UnexpectedRetVal));
2546                 }
2547                 attribTree(tree.expr, env, env.info.returnResult);
2548             } else if (!env.info.returnResult.pt.hasTag(VOID) &&
2549                     !env.info.returnResult.pt.hasTag(NONE)) {
2550                 env.info.returnResult.checkContext.report(tree.pos(),
2551                               diags.fragment(Fragments.MissingRetVal(env.info.returnResult.pt)));
2552             }
2553         }
2554         result = null;
2555     }
2556 
2557     public void visitThrow(JCThrow tree) {
2558         Type owntype = attribExpr(tree.expr, env, Type.noType);
2559         chk.checkType(tree, owntype, syms.throwableType);
2560         result = null;
2561     }
2562 
2563     public void visitAssert(JCAssert tree) {
2564         attribExpr(tree.cond, env, syms.booleanType);
2565         if (tree.detail != null) {
2566             chk.checkNonVoid(tree.detail.pos(), attribExpr(tree.detail, env));
2567         }
2568         result = null;
2569     }
2570 
2571      /** Visitor method for method invocations.
2572      *  NOTE: The method part of an application will have in its type field
2573      *        the return type of the method, not the method's type itself!
2574      */
2575     public void visitApply(JCMethodInvocation tree) {
2576         // The local environment of a method application is
2577         // a new environment nested in the current one.
2578         Env<AttrContext> localEnv = env.dup(tree, env.info.dup());
2579 
2580         // The types of the actual method arguments.
2581         List<Type> argtypes;
2582 
2583         // The types of the actual method type arguments.
2584         List<Type> typeargtypes = null;
2585 
2586         Name methName = TreeInfo.name(tree.meth);
2587 
2588         boolean isConstructorCall =
2589             methName == names._this || methName == names._super;
2590 
2591         ListBuffer<Type> argtypesBuf = new ListBuffer<>();
2592         if (isConstructorCall) {
2593 
2594             // Attribute arguments, yielding list of argument types.
2595             KindSelector kind = attribArgs(KindSelector.MTH, tree.args, localEnv, argtypesBuf);
2596             argtypes = argtypesBuf.toList();
2597             typeargtypes = attribTypes(tree.typeargs, localEnv);
2598 
2599             // End of constructor prologue. Done with this()/super() parameters.
2600             env.info.earlyContext = EarlyConstructionContext.NONE;
2601 
2602             // Variable `site' points to the class in which the called
2603             // constructor is defined.
2604             Type site = env.enclClass.sym.type;
2605             if (methName == names._super) {
2606                 if (site == syms.objectType) {
2607                     log.error(tree.meth.pos(), Errors.NoSuperclass(site));
2608                     site = types.createErrorType(syms.objectType);
2609                 } else {
2610                     site = types.supertype(site);
2611                 }
2612             }
2613 
2614             if (site.hasTag(CLASS)) {
2615                 Type encl = site.getEnclosingType();
2616                 while (encl != null && encl.hasTag(TYPEVAR))
2617                     encl = encl.getUpperBound();
2618                 if (encl.hasTag(CLASS)) {
2619                     // we are calling a nested class
2620 
2621                     if (tree.meth.hasTag(SELECT)) {
2622                         JCTree qualifier = ((JCFieldAccess) tree.meth).selected;
2623 
2624                         // We are seeing a prefixed call, of the form
2625                         //     <expr>.super(...).
2626                         // Check that the prefix expression conforms
2627                         // to the outer instance type of the class.
2628                         chk.checkRefType(qualifier.pos(),
2629                                 attribTree(qualifier, localEnv,
2630                                            new ResultInfo(KindSelector.VAL,
2631                                                           encl,
2632                                                           chk.subtypeHandler)));
2633                     }
2634                 } else if (tree.meth.hasTag(SELECT)) {
2635                     log.error(tree.meth.pos(),
2636                               Errors.IllegalQualNotIcls(site.tsym));
2637                     attribExpr(((JCFieldAccess) tree.meth).selected, localEnv, site);
2638                 }
2639 
2640                 if (tree.meth.hasTag(IDENT)) {
2641                     // non-qualified super(...) call; check whether explicit constructor
2642                     // invocation is well-formed. If the super class is an inner class,
2643                     // make sure that an appropriate implicit qualifier exists. If the super
2644                     // class is a local class, make sure that the current class is defined
2645                     // in the same context as the local class.
2646                     checkNewInnerClass(tree.meth.pos(), localEnv, site, true);
2647                 }
2648 
2649                 // if we're calling a java.lang.Enum constructor,
2650                 // prefix the implicit String and int parameters
2651                 if (site.tsym == syms.enumSym)
2652                     argtypes = argtypes.prepend(syms.intType).prepend(syms.stringType);
2653 
2654                 // Resolve the called constructor under the assumption
2655                 // that we are referring to a superclass instance of the
2656                 // current instance (JLS ???).
2657                 boolean selectSuperPrev = localEnv.info.selectSuper;
2658                 localEnv.info.selectSuper = true;
2659                 localEnv.info.pendingResolutionPhase = null;
2660                 Symbol sym = rs.resolveConstructor(
2661                     tree.meth.pos(), localEnv, site, argtypes, typeargtypes);
2662                 localEnv.info.selectSuper = selectSuperPrev;
2663 
2664                 // Set method symbol to resolved constructor...
2665                 TreeInfo.setSymbol(tree.meth, sym);
2666 
2667                 // ...and check that it is legal in the current context.
2668                 // (this will also set the tree's type)
2669                 Type mpt = newMethodTemplate(resultInfo.pt, argtypes, typeargtypes);
2670                 checkId(tree.meth, site, sym, localEnv,
2671                         new ResultInfo(kind, mpt));
2672             } else if (site.hasTag(ERROR) && tree.meth.hasTag(SELECT)) {
2673                 attribExpr(((JCFieldAccess) tree.meth).selected, localEnv, site);
2674             }
2675             // Otherwise, `site' is an error type and we do nothing
2676             result = tree.type = syms.voidType;
2677         } else {
2678             // Otherwise, we are seeing a regular method call.
2679             // Attribute the arguments, yielding list of argument types, ...
2680             KindSelector kind = attribArgs(KindSelector.VAL, tree.args, localEnv, argtypesBuf);
2681             argtypes = argtypesBuf.toList();
2682             typeargtypes = attribAnyTypes(tree.typeargs, localEnv);
2683 
2684             // ... and attribute the method using as a prototype a methodtype
2685             // whose formal argument types is exactly the list of actual
2686             // arguments (this will also set the method symbol).
2687             Type mpt = newMethodTemplate(resultInfo.pt, argtypes, typeargtypes);
2688             localEnv.info.pendingResolutionPhase = null;
2689             Type mtype = attribTree(tree.meth, localEnv, new ResultInfo(kind, mpt, resultInfo.checkContext));
2690 
2691             // Compute the result type.
2692             Type restype = mtype.getReturnType();
2693             if (restype.hasTag(WILDCARD))
2694                 throw new AssertionError(mtype);
2695 
2696             Type qualifier = (tree.meth.hasTag(SELECT))
2697                     ? ((JCFieldAccess) tree.meth).selected.type
2698                     : env.enclClass.sym.type;
2699             Symbol msym = TreeInfo.symbol(tree.meth);
2700             restype = adjustMethodReturnType(msym, qualifier, methName, argtypes, restype);
2701 
2702             chk.checkRefTypes(tree.typeargs, typeargtypes);
2703 
2704             // Check that value of resulting type is admissible in the
2705             // current context.  Also, capture the return type
2706             Type capturedRes = resultInfo.checkContext.inferenceContext().cachedCapture(tree, restype, true);
2707             result = check(tree, capturedRes, KindSelector.VAL, resultInfo);
2708         }
2709         chk.checkRequiresIdentity(tree, env.info.lint);
2710         chk.validate(tree.typeargs, localEnv);
2711     }
2712     //where
2713         Type adjustMethodReturnType(Symbol msym, Type qualifierType, Name methodName, List<Type> argtypes, Type restype) {
2714             if (msym != null &&
2715                     (msym.owner == syms.objectType.tsym || msym.owner.isInterface()) &&
2716                     methodName == names.getClass &&
2717                     argtypes.isEmpty()) {
2718                 // as a special case, x.getClass() has type Class<? extends |X|>
2719                 return new ClassType(restype.getEnclosingType(),
2720                         List.of(new WildcardType(types.erasure(qualifierType.baseType()),
2721                                 BoundKind.EXTENDS,
2722                                 syms.boundClass)),
2723                         restype.tsym,
2724                         restype.getMetadata());
2725             } else if (msym != null &&
2726                     msym.owner == syms.arrayClass &&
2727                     methodName == names.clone &&
2728                     types.isArray(qualifierType)) {
2729                 // as a special case, array.clone() has a result that is
2730                 // the same as static type of the array being cloned
2731                 return qualifierType;
2732             } else {
2733                 return restype;
2734             }
2735         }
2736 
2737         /** Obtain a method type with given argument types.
2738          */
2739         Type newMethodTemplate(Type restype, List<Type> argtypes, List<Type> typeargtypes) {
2740             MethodType mt = new MethodType(argtypes, restype, List.nil(), syms.methodClass);
2741             return (typeargtypes == null) ? mt : (Type)new ForAll(typeargtypes, mt);
2742         }
2743 
2744     public void visitNewClass(final JCNewClass tree) {
2745         Type owntype = types.createErrorType(tree.type);
2746 
2747         // The local environment of a class creation is
2748         // a new environment nested in the current one.
2749         Env<AttrContext> localEnv = env.dup(tree, env.info.dup());
2750 
2751         // The anonymous inner class definition of the new expression,
2752         // if one is defined by it.
2753         JCClassDecl cdef = tree.def;
2754 
2755         // If enclosing class is given, attribute it, and
2756         // complete class name to be fully qualified
2757         JCExpression clazz = tree.clazz; // Class field following new
2758         JCExpression clazzid;            // Identifier in class field
2759         JCAnnotatedType annoclazzid;     // Annotated type enclosing clazzid
2760         annoclazzid = null;
2761 
2762         if (clazz.hasTag(TYPEAPPLY)) {
2763             clazzid = ((JCTypeApply) clazz).clazz;
2764             if (clazzid.hasTag(ANNOTATED_TYPE)) {
2765                 annoclazzid = (JCAnnotatedType) clazzid;
2766                 clazzid = annoclazzid.underlyingType;
2767             }
2768         } else {
2769             if (clazz.hasTag(ANNOTATED_TYPE)) {
2770                 annoclazzid = (JCAnnotatedType) clazz;
2771                 clazzid = annoclazzid.underlyingType;
2772             } else {
2773                 clazzid = clazz;
2774             }
2775         }
2776 
2777         JCExpression clazzid1 = clazzid; // The same in fully qualified form
2778 
2779         if (tree.encl != null) {
2780             // We are seeing a qualified new, of the form
2781             //    <expr>.new C <...> (...) ...
2782             // In this case, we let clazz stand for the name of the
2783             // allocated class C prefixed with the type of the qualifier
2784             // expression, so that we can
2785             // resolve it with standard techniques later. I.e., if
2786             // <expr> has type T, then <expr>.new C <...> (...)
2787             // yields a clazz T.C.
2788             Type encltype = chk.checkRefType(tree.encl.pos(),
2789                                              attribExpr(tree.encl, env));
2790             // TODO 308: in <expr>.new C, do we also want to add the type annotations
2791             // from expr to the combined type, or not? Yes, do this.
2792             clazzid1 = make.at(clazz.pos).Select(make.Type(encltype),
2793                                                  ((JCIdent) clazzid).name);
2794 
2795             clazzid1.endpos = clazzid.getEndPosition();
2796             if (clazz.hasTag(ANNOTATED_TYPE)) {
2797                 JCAnnotatedType annoType = (JCAnnotatedType) clazz;
2798                 List<JCAnnotation> annos = annoType.annotations;
2799 
2800                 if (annoType.underlyingType.hasTag(TYPEAPPLY)) {
2801                     clazzid1 = make.at(tree.pos).
2802                         TypeApply(clazzid1,
2803                                   ((JCTypeApply) clazz).arguments);
2804                 }
2805 
2806                 clazzid1 = make.at(tree.pos).
2807                     AnnotatedType(annos, clazzid1);
2808             } else if (clazz.hasTag(TYPEAPPLY)) {
2809                 clazzid1 = make.at(tree.pos).
2810                     TypeApply(clazzid1,
2811                               ((JCTypeApply) clazz).arguments);
2812             }
2813 
2814             clazz = clazzid1;
2815         }
2816 
2817         // Attribute clazz expression and store
2818         // symbol + type back into the attributed tree.
2819         Type clazztype = TreeInfo.isEnumInit(env.tree) ?
2820             attribIdentAsEnumType(env, (JCIdent)clazz) :
2821             attribType(clazz, env);
2822 
2823         clazztype = chk.checkDiamond(tree, clazztype);
2824         chk.validate(clazz, localEnv);
2825         if (tree.encl != null) {
2826             // We have to work in this case to store
2827             // symbol + type back into the attributed tree.
2828             tree.clazz.type = clazztype;
2829             TreeInfo.setSymbol(clazzid, TreeInfo.symbol(clazzid1));
2830             clazzid.type = ((JCIdent) clazzid).sym.type;
2831             if (annoclazzid != null) {
2832                 annoclazzid.type = clazzid.type;
2833             }
2834             if (!clazztype.isErroneous()) {
2835                 if (cdef != null && clazztype.tsym.isInterface()) {
2836                     log.error(tree.encl.pos(), Errors.AnonClassImplIntfNoQualForNew);
2837                 } else if (clazztype.tsym.isStatic()) {
2838                     log.error(tree.encl.pos(), Errors.QualifiedNewOfStaticClass(clazztype.tsym));
2839                 }
2840             }
2841         } else {
2842             // Check for the existence of an apropos outer instance
2843             checkNewInnerClass(tree.pos(), env, clazztype, false);
2844         }
2845 
2846         checkBreakTree(tree.clazz, localEnv);
2847 
2848         // Attribute constructor arguments.
2849         ListBuffer<Type> argtypesBuf = new ListBuffer<>();
2850         final KindSelector pkind =
2851             attribArgs(KindSelector.VAL, tree.args, localEnv, argtypesBuf);
2852         List<Type> argtypes = argtypesBuf.toList();
2853         List<Type> typeargtypes = attribTypes(tree.typeargs, localEnv);
2854 
2855         if (clazztype.hasTag(CLASS) || clazztype.hasTag(ERROR)) {
2856             // Enums may not be instantiated except implicitly
2857             if ((clazztype.tsym.flags_field & Flags.ENUM) != 0 &&
2858                 (!env.tree.hasTag(VARDEF) ||
2859                  (((JCVariableDecl) env.tree).mods.flags & Flags.ENUM) == 0 ||
2860                  ((JCVariableDecl) env.tree).init != tree))
2861                 log.error(tree.pos(), Errors.EnumCantBeInstantiated);
2862 
2863             boolean isSpeculativeDiamondInferenceRound = TreeInfo.isDiamond(tree) &&
2864                     resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE;
2865             boolean skipNonDiamondPath = false;
2866             // Check that class is not abstract
2867             if (cdef == null && !tree.classDeclRemoved() && !isSpeculativeDiamondInferenceRound && // class body may be nulled out in speculative tree copy
2868                 (clazztype.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) {
2869                 log.error(tree.pos(),
2870                           Errors.AbstractCantBeInstantiated(clazztype.tsym));
2871                 skipNonDiamondPath = true;
2872             } else if (cdef != null && clazztype.tsym.isInterface()) {
2873                 // Check that no constructor arguments are given to
2874                 // anonymous classes implementing an interface
2875                 if (!argtypes.isEmpty())
2876                     log.error(tree.args.head.pos(), Errors.AnonClassImplIntfNoArgs);
2877 
2878                 if (!typeargtypes.isEmpty())
2879                     log.error(tree.typeargs.head.pos(), Errors.AnonClassImplIntfNoTypeargs);
2880 
2881                 // Error recovery: pretend no arguments were supplied.
2882                 argtypes = List.nil();
2883                 typeargtypes = List.nil();
2884                 skipNonDiamondPath = true;
2885             }
2886             if (TreeInfo.isDiamond(tree)) {
2887                 ClassType site = new ClassType(clazztype.getEnclosingType(),
2888                             clazztype.tsym.type.getTypeArguments(),
2889                                                clazztype.tsym,
2890                                                clazztype.getMetadata());
2891 
2892                 Env<AttrContext> diamondEnv = localEnv.dup(tree);
2893                 diamondEnv.info.selectSuper = cdef != null || tree.classDeclRemoved();
2894                 diamondEnv.info.pendingResolutionPhase = null;
2895 
2896                 //if the type of the instance creation expression is a class type
2897                 //apply method resolution inference (JLS 15.12.2.7). The return type
2898                 //of the resolved constructor will be a partially instantiated type
2899                 Symbol constructor = rs.resolveDiamond(tree.pos(),
2900                             diamondEnv,
2901                             site,
2902                             argtypes,
2903                             typeargtypes);
2904                 tree.constructor = constructor.baseSymbol();
2905 
2906                 final TypeSymbol csym = clazztype.tsym;
2907                 ResultInfo diamondResult = new ResultInfo(pkind, newMethodTemplate(resultInfo.pt, argtypes, typeargtypes),
2908                         diamondContext(tree, csym, resultInfo.checkContext), CheckMode.NO_TREE_UPDATE);
2909                 Type constructorType = tree.constructorType = types.createErrorType(clazztype);
2910                 constructorType = checkId(tree, site,
2911                         constructor,
2912                         diamondEnv,
2913                         diamondResult);
2914 
2915                 tree.clazz.type = types.createErrorType(clazztype);
2916                 if (!constructorType.isErroneous()) {
2917                     tree.clazz.type = clazz.type = constructorType.getReturnType();
2918                     tree.constructorType = types.createMethodTypeWithReturn(constructorType, syms.voidType);
2919                 }
2920                 clazztype = chk.checkClassType(tree.clazz, tree.clazz.type, true);
2921             }
2922 
2923             // Resolve the called constructor under the assumption
2924             // that we are referring to a superclass instance of the
2925             // current instance (JLS ???).
2926             else if (!skipNonDiamondPath) {
2927                 //the following code alters some of the fields in the current
2928                 //AttrContext - hence, the current context must be dup'ed in
2929                 //order to avoid downstream failures
2930                 Env<AttrContext> rsEnv = localEnv.dup(tree);
2931                 rsEnv.info.selectSuper = cdef != null;
2932                 rsEnv.info.pendingResolutionPhase = null;
2933                 tree.constructor = rs.resolveConstructor(
2934                     tree.pos(), rsEnv, clazztype, argtypes, typeargtypes);
2935                 if (cdef == null) { //do not check twice!
2936                     tree.constructorType = checkId(tree,
2937                             clazztype,
2938                             tree.constructor,
2939                             rsEnv,
2940                             new ResultInfo(pkind, newMethodTemplate(syms.voidType, argtypes, typeargtypes), CheckMode.NO_TREE_UPDATE));
2941                     if (rsEnv.info.lastResolveVarargs())
2942                         Assert.check(tree.constructorType.isErroneous() || tree.varargsElement != null);
2943                 }
2944             }
2945 
2946             chk.checkRequiresIdentity(tree, env.info.lint);
2947 
2948             if (cdef != null) {
2949                 visitAnonymousClassDefinition(tree, clazz, clazztype, cdef, localEnv, argtypes, typeargtypes, pkind);
2950                 return;
2951             }
2952 
2953             if (tree.constructor != null && tree.constructor.kind == MTH)
2954                 owntype = clazztype;
2955         }
2956         result = check(tree, owntype, KindSelector.VAL, resultInfo);
2957         InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext();
2958         if (tree.constructorType != null && inferenceContext.free(tree.constructorType)) {
2959             //we need to wait for inference to finish and then replace inference vars in the constructor type
2960             inferenceContext.addFreeTypeListener(List.of(tree.constructorType),
2961                     instantiatedContext -> {
2962                         tree.constructorType = instantiatedContext.asInstType(tree.constructorType);
2963                     });
2964         }
2965         chk.validate(tree.typeargs, localEnv);
2966     }
2967 
2968         // where
2969         private void visitAnonymousClassDefinition(JCNewClass tree, JCExpression clazz, Type clazztype,
2970                                                    JCClassDecl cdef, Env<AttrContext> localEnv,
2971                                                    List<Type> argtypes, List<Type> typeargtypes,
2972                                                    KindSelector pkind) {
2973             // We are seeing an anonymous class instance creation.
2974             // In this case, the class instance creation
2975             // expression
2976             //
2977             //    E.new <typeargs1>C<typargs2>(args) { ... }
2978             //
2979             // is represented internally as
2980             //
2981             //    E . new <typeargs1>C<typargs2>(args) ( class <empty-name> { ... } )  .
2982             //
2983             // This expression is then *transformed* as follows:
2984             //
2985             // (1) add an extends or implements clause
2986             // (2) add a constructor.
2987             //
2988             // For instance, if C is a class, and ET is the type of E,
2989             // the expression
2990             //
2991             //    E.new <typeargs1>C<typargs2>(args) { ... }
2992             //
2993             // is translated to (where X is a fresh name and typarams is the
2994             // parameter list of the super constructor):
2995             //
2996             //   new <typeargs1>X(<*nullchk*>E, args) where
2997             //     X extends C<typargs2> {
2998             //       <typarams> X(ET e, args) {
2999             //         e.<typeargs1>super(args)
3000             //       }
3001             //       ...
3002             //     }
3003             InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext();
3004             Type enclType = clazztype.getEnclosingType();
3005             if (enclType != null &&
3006                     enclType.hasTag(CLASS) &&
3007                     !chk.checkDenotable((ClassType)enclType)) {
3008                 log.error(tree.encl, Errors.EnclosingClassTypeNonDenotable(enclType));
3009             }
3010             final boolean isDiamond = TreeInfo.isDiamond(tree);
3011             if (isDiamond
3012                     && ((tree.constructorType != null && inferenceContext.free(tree.constructorType))
3013                     || (tree.clazz.type != null && inferenceContext.free(tree.clazz.type)))) {
3014                 final ResultInfo resultInfoForClassDefinition = this.resultInfo;
3015                 Env<AttrContext> dupLocalEnv = copyEnv(localEnv);
3016                 inferenceContext.addFreeTypeListener(List.of(tree.constructorType, tree.clazz.type),
3017                         instantiatedContext -> {
3018                             tree.constructorType = instantiatedContext.asInstType(tree.constructorType);
3019                             tree.clazz.type = clazz.type = instantiatedContext.asInstType(clazz.type);
3020                             ResultInfo prevResult = this.resultInfo;
3021                             try {
3022                                 this.resultInfo = resultInfoForClassDefinition;
3023                                 visitAnonymousClassDefinition(tree, clazz, clazz.type, cdef,
3024                                         dupLocalEnv, argtypes, typeargtypes, pkind);
3025                             } finally {
3026                                 this.resultInfo = prevResult;
3027                             }
3028                         });
3029             } else {
3030                 if (isDiamond && clazztype.hasTag(CLASS)) {
3031                     List<Type> invalidDiamondArgs = chk.checkDiamondDenotable((ClassType)clazztype);
3032                     if (!clazztype.isErroneous() && invalidDiamondArgs.nonEmpty()) {
3033                         // One or more types inferred in the previous steps is non-denotable.
3034                         Fragment fragment = Diamond(clazztype.tsym);
3035                         log.error(tree.clazz.pos(),
3036                                 Errors.CantApplyDiamond1(
3037                                         fragment,
3038                                         invalidDiamondArgs.size() > 1 ?
3039                                                 DiamondInvalidArgs(invalidDiamondArgs, fragment) :
3040                                                 DiamondInvalidArg(invalidDiamondArgs, fragment)));
3041                     }
3042                     // For <>(){}, inferred types must also be accessible.
3043                     for (Type t : clazztype.getTypeArguments()) {
3044                         rs.checkAccessibleType(env, t);
3045                     }
3046                 }
3047 
3048                 // If we already errored, be careful to avoid a further avalanche. ErrorType answers
3049                 // false for isInterface call even when the original type is an interface.
3050                 boolean implementing = clazztype.tsym.isInterface() ||
3051                         clazztype.isErroneous() && !clazztype.getOriginalType().hasTag(NONE) &&
3052                         clazztype.getOriginalType().tsym.isInterface();
3053 
3054                 if (implementing) {
3055                     cdef.implementing = List.of(clazz);
3056                 } else {
3057                     cdef.extending = clazz;
3058                 }
3059 
3060                 if (resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK &&
3061                     rs.isSerializable(clazztype)) {
3062                     localEnv.info.isSerializable = true;
3063                 }
3064 
3065                 attribStat(cdef, localEnv);
3066 
3067                 List<Type> finalargtypes;
3068                 // If an outer instance is given,
3069                 // prefix it to the constructor arguments
3070                 // and delete it from the new expression
3071                 if (tree.encl != null && !clazztype.tsym.isInterface()) {
3072                     finalargtypes = argtypes.prepend(tree.encl.type);
3073                 } else {
3074                     finalargtypes = argtypes;
3075                 }
3076 
3077                 // Reassign clazztype and recompute constructor. As this necessarily involves
3078                 // another attribution pass for deferred types in the case of <>, replicate
3079                 // them. Original arguments have right decorations already.
3080                 if (isDiamond && pkind.contains(KindSelector.POLY)) {
3081                     finalargtypes = finalargtypes.map(deferredAttr.deferredCopier);
3082                 }
3083 
3084                 clazztype = clazztype.hasTag(ERROR) ? types.createErrorType(cdef.sym.type)
3085                                                     : cdef.sym.type;
3086                 Symbol sym = tree.constructor = rs.resolveConstructor(
3087                         tree.pos(), localEnv, clazztype, finalargtypes, typeargtypes);
3088                 Assert.check(!sym.kind.isResolutionError());
3089                 tree.constructor = sym;
3090                 tree.constructorType = checkId(tree,
3091                         clazztype,
3092                         tree.constructor,
3093                         localEnv,
3094                         new ResultInfo(pkind, newMethodTemplate(syms.voidType, finalargtypes, typeargtypes), CheckMode.NO_TREE_UPDATE));
3095             }
3096             Type owntype = (tree.constructor != null && tree.constructor.kind == MTH) ?
3097                                 clazztype : types.createErrorType(tree.type);
3098             result = check(tree, owntype, KindSelector.VAL, resultInfo.dup(CheckMode.NO_INFERENCE_HOOK));
3099             chk.validate(tree.typeargs, localEnv);
3100         }
3101 
3102         CheckContext diamondContext(JCNewClass clazz, TypeSymbol tsym, CheckContext checkContext) {
3103             return new Check.NestedCheckContext(checkContext) {
3104                 @Override
3105                 public void report(DiagnosticPosition _unused, JCDiagnostic details) {
3106                     enclosingContext.report(clazz.clazz,
3107                             diags.fragment(Fragments.CantApplyDiamond1(Fragments.Diamond(tsym), details)));
3108                 }
3109             };
3110         }
3111 
3112         void checkNewInnerClass(DiagnosticPosition pos, Env<AttrContext> env, Type type, boolean isSuper) {
3113             boolean isLocal = type.tsym.owner.kind == VAR || type.tsym.owner.kind == MTH;
3114             if ((type.tsym.flags() & (INTERFACE | ENUM | RECORD)) != 0 ||
3115                     (!isLocal && !type.tsym.isInner()) ||
3116                     (isSuper && env.enclClass.sym.isAnonymous())) {
3117                 // nothing to check
3118                 return;
3119             }
3120             Symbol res = isLocal ?
3121                     rs.findLocalClassOwner(env, type.tsym) :
3122                     rs.findSelfContaining(pos, env, type.getEnclosingType().tsym, isSuper);
3123             if (res.exists()) {
3124                 rs.accessBase(res, pos, env.enclClass.sym.type, names._this, true);
3125             } else {
3126                 log.error(pos, Errors.EnclClassRequired(type.tsym));
3127             }
3128         }
3129 
3130     /** Make an attributed null check tree.
3131      */
3132     public JCExpression makeNullCheck(JCExpression arg) {
3133         // optimization: new Outer() can never be null; skip null check
3134         if (arg.getTag() == NEWCLASS)
3135             return arg;
3136         // optimization: X.this is never null; skip null check
3137         Name name = TreeInfo.name(arg);
3138         if (name == names._this || name == names._super) return arg;
3139 
3140         JCTree.Tag optag = NULLCHK;
3141         JCUnary tree = make.at(arg.pos).Unary(optag, arg);
3142         tree.operator = operators.resolveUnary(arg, optag, arg.type);
3143         tree.type = arg.type;
3144         return tree;
3145     }
3146 
3147     public void visitNewArray(JCNewArray tree) {
3148         Type owntype = types.createErrorType(tree.type);
3149         Env<AttrContext> localEnv = env.dup(tree);
3150         Type elemtype;
3151         if (tree.elemtype != null) {
3152             elemtype = attribType(tree.elemtype, localEnv);
3153             chk.validate(tree.elemtype, localEnv);
3154             owntype = elemtype;
3155             for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) {
3156                 attribExpr(l.head, localEnv, syms.intType);
3157                 owntype = new ArrayType(owntype, syms.arrayClass);
3158             }
3159         } else {
3160             // we are seeing an untyped aggregate { ... }
3161             // this is allowed only if the prototype is an array
3162             if (pt().hasTag(ARRAY)) {
3163                 elemtype = types.elemtype(pt());
3164             } else {
3165                 if (!pt().hasTag(ERROR) &&
3166                         (env.info.enclVar == null || !env.info.enclVar.type.isErroneous())) {
3167                     log.error(tree.pos(),
3168                               Errors.IllegalInitializerForType(pt()));
3169                 }
3170                 elemtype = types.createErrorType(pt());
3171             }
3172         }
3173         if (tree.elems != null) {
3174             attribExprs(tree.elems, localEnv, elemtype);
3175             owntype = new ArrayType(elemtype, syms.arrayClass);
3176         }
3177         if (!types.isReifiable(elemtype))
3178             log.error(tree.pos(), Errors.GenericArrayCreation);
3179         result = check(tree, owntype, KindSelector.VAL, resultInfo);
3180     }
3181 
3182     /*
3183      * A lambda expression can only be attributed when a target-type is available.
3184      * In addition, if the target-type is that of a functional interface whose
3185      * descriptor contains inference variables in argument position the lambda expression
3186      * is 'stuck' (see DeferredAttr).
3187      */
3188     @Override
3189     public void visitLambda(final JCLambda that) {
3190         boolean wrongContext = false;
3191         if (pt().isErroneous() || (pt().hasTag(NONE) && pt() != Type.recoveryType)) {
3192             if (pt().hasTag(NONE) && (env.info.enclVar == null || !env.info.enclVar.type.isErroneous())) {
3193                 //lambda only allowed in assignment or method invocation/cast context
3194                 log.error(that.pos(), Errors.UnexpectedLambda);
3195             }
3196             resultInfo = recoveryInfo;
3197             wrongContext = true;
3198         }
3199         //create an environment for attribution of the lambda expression
3200         final Env<AttrContext> localEnv = lambdaEnv(that, env);
3201         boolean needsRecovery =
3202                 resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK;
3203         try {
3204             if (needsRecovery && rs.isSerializable(pt())) {
3205                 localEnv.info.isSerializable = true;
3206                 localEnv.info.isSerializableLambda = true;
3207             }
3208             List<Type> explicitParamTypes = null;
3209             if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) {
3210                 //attribute lambda parameters
3211                 attribStats(that.params, localEnv);
3212                 explicitParamTypes = TreeInfo.types(that.params);
3213             }
3214 
3215             TargetInfo targetInfo = getTargetInfo(that, resultInfo, explicitParamTypes);
3216             Type currentTarget = targetInfo.target;
3217             Type lambdaType = targetInfo.descriptor;
3218 
3219             if (currentTarget.isErroneous()) {
3220                 result = that.type = currentTarget;
3221                 return;
3222             }
3223 
3224             setFunctionalInfo(localEnv, that, pt(), lambdaType, currentTarget, resultInfo.checkContext);
3225 
3226             if (lambdaType.hasTag(FORALL)) {
3227                 //lambda expression target desc cannot be a generic method
3228                 Fragment msg = Fragments.InvalidGenericLambdaTarget(lambdaType,
3229                                                                     kindName(currentTarget.tsym),
3230                                                                     currentTarget.tsym);
3231                 resultInfo.checkContext.report(that, diags.fragment(msg));
3232                 result = that.type = types.createErrorType(pt());
3233                 return;
3234             }
3235 
3236             if (that.paramKind == JCLambda.ParameterKind.IMPLICIT) {
3237                 //add param type info in the AST
3238                 List<Type> actuals = lambdaType.getParameterTypes();
3239                 List<JCVariableDecl> params = that.params;
3240 
3241                 boolean arityMismatch = false;
3242 
3243                 while (params.nonEmpty()) {
3244                     if (actuals.isEmpty()) {
3245                         //not enough actuals to perform lambda parameter inference
3246                         arityMismatch = true;
3247                     }
3248                     //reset previously set info
3249                     Type argType = arityMismatch ?
3250                             syms.errType :
3251                             actuals.head;
3252                     if (params.head.type == null &&
3253                         params.head.isImplicitlyTyped()) { //error recovery
3254                         params.head.type = argType;
3255                         setupImplicitlyTypedVariable(params.head, argType);
3256                     }
3257                     params.head.sym = null;
3258                     actuals = actuals.isEmpty() ?
3259                             actuals :
3260                             actuals.tail;
3261                     params = params.tail;
3262                 }
3263 
3264                 //attribute lambda parameters
3265                 attribStats(that.params, localEnv);
3266 
3267                 if (arityMismatch) {
3268                     resultInfo.checkContext.report(that, diags.fragment(Fragments.WrongNumberArgsInLambda(currentTarget.tsym)));
3269                         result = that.type = types.createErrorType(currentTarget);
3270                         return;
3271                 }
3272             }
3273 
3274             //from this point on, no recovery is needed; if we are in assignment context
3275             //we will be able to attribute the whole lambda body, regardless of errors;
3276             //if we are in a 'check' method context, and the lambda is not compatible
3277             //with the target-type, it will be recovered anyway in Attr.checkId
3278             needsRecovery = false;
3279 
3280             ResultInfo bodyResultInfo = localEnv.info.returnResult =
3281                     lambdaBodyResult(that, lambdaType, resultInfo);
3282 
3283             if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) {
3284                 attribTree(that.getBody(), localEnv, bodyResultInfo);
3285             } else {
3286                 JCBlock body = (JCBlock)that.body;
3287 
3288                 checkBreakTree(body, localEnv);
3289                 attribStats(body.stats, localEnv);
3290             }
3291 
3292             result = check(that, currentTarget, KindSelector.VAL, resultInfo);
3293 
3294             boolean isSpeculativeRound =
3295                     resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE;
3296 
3297             preFlow(that);
3298             flow.analyzeLambda(env, that, make, isSpeculativeRound);
3299 
3300             that.type = currentTarget; //avoids recovery at this stage
3301             checkLambdaCompatible(that, lambdaType, currentTarget.tsym, resultInfo.checkContext);
3302 
3303             if (!isSpeculativeRound) {
3304                 //add thrown types as bounds to the thrown types free variables if needed:
3305                 if (resultInfo.checkContext.inferenceContext().free(lambdaType.getThrownTypes())) {
3306                     List<Type> inferredThrownTypes = flow.analyzeLambdaThrownTypes(env, that, make);
3307                     if(!checkExConstraints(inferredThrownTypes, lambdaType.getThrownTypes(), resultInfo.checkContext.inferenceContext())) {
3308                         log.error(that, Errors.IncompatibleThrownTypesInMref(lambdaType.getThrownTypes()));
3309                     }
3310                 }
3311 
3312                 checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), lambdaType, currentTarget);
3313             }
3314             result = wrongContext ? that.type = types.createErrorType(pt())
3315                                   : check(that, currentTarget, KindSelector.VAL, resultInfo);
3316         } catch (Types.FunctionDescriptorLookupError ex) {
3317             JCDiagnostic cause = ex.getDiagnostic();
3318             resultInfo.checkContext.report(that, cause);
3319             result = that.type = types.createErrorType(pt());
3320             return;
3321         } catch (CompletionFailure cf) {
3322             chk.completionError(that.pos(), cf);
3323         } catch (Throwable t) {
3324             //when an unexpected exception happens, avoid attempts to attribute the same tree again
3325             //as that would likely cause the same exception again.
3326             needsRecovery = false;
3327             throw t;
3328         } finally {
3329             localEnv.info.scope.leave();
3330             if (needsRecovery) {
3331                 Type prevResult = result;
3332                 try {
3333                     attribTree(that, env, recoveryInfo);
3334                 } finally {
3335                     if (result == Type.recoveryType) {
3336                         result = prevResult;
3337                     }
3338                 }
3339             }
3340         }
3341     }
3342     //where
3343         class TargetInfo {
3344             Type target;
3345             Type descriptor;
3346 
3347             public TargetInfo(Type target, Type descriptor) {
3348                 this.target = target;
3349                 this.descriptor = descriptor;
3350             }
3351         }
3352 
3353         TargetInfo getTargetInfo(JCPolyExpression that, ResultInfo resultInfo, List<Type> explicitParamTypes) {
3354             Type lambdaType;
3355             Type currentTarget = resultInfo.pt;
3356             if (resultInfo.pt != Type.recoveryType) {
3357                 /* We need to adjust the target. If the target is an
3358                  * intersection type, for example: SAM & I1 & I2 ...
3359                  * the target will be updated to SAM
3360                  */
3361                 currentTarget = targetChecker.visit(currentTarget, that);
3362                 if (!currentTarget.isIntersection()) {
3363                     if (explicitParamTypes != null) {
3364                         currentTarget = infer.instantiateFunctionalInterface(that,
3365                                 currentTarget, explicitParamTypes, resultInfo.checkContext);
3366                     }
3367                     currentTarget = types.removeWildcards(currentTarget);
3368                     lambdaType = types.findDescriptorType(currentTarget);
3369                 } else {
3370                     IntersectionClassType ict = (IntersectionClassType)currentTarget;
3371                     ListBuffer<Type> components = new ListBuffer<>();
3372                     for (Type bound : ict.getExplicitComponents()) {
3373                         if (explicitParamTypes != null) {
3374                             try {
3375                                 bound = infer.instantiateFunctionalInterface(that,
3376                                         bound, explicitParamTypes, resultInfo.checkContext);
3377                             } catch (FunctionDescriptorLookupError t) {
3378                                 // do nothing
3379                             }
3380                         }
3381                         if (bound.tsym != syms.objectType.tsym && (!bound.isInterface() || (bound.tsym.flags() & ANNOTATION) != 0)) {
3382                             // bound must be j.l.Object or an interface, but not an annotation
3383                             reportIntersectionError(that, "not.an.intf.component", bound);
3384                         }
3385                         bound = types.removeWildcards(bound);
3386                         components.add(bound);
3387                     }
3388                     currentTarget = types.makeIntersectionType(components.toList());
3389                     currentTarget.tsym.flags_field |= INTERFACE;
3390                     lambdaType = types.findDescriptorType(currentTarget);
3391                 }
3392 
3393             } else {
3394                 currentTarget = Type.recoveryType;
3395                 lambdaType = fallbackDescriptorType(that);
3396             }
3397             if (that.hasTag(LAMBDA) && lambdaType.hasTag(FORALL)) {
3398                 //lambda expression target desc cannot be a generic method
3399                 Fragment msg = Fragments.InvalidGenericLambdaTarget(lambdaType,
3400                                                                     kindName(currentTarget.tsym),
3401                                                                     currentTarget.tsym);
3402                 resultInfo.checkContext.report(that, diags.fragment(msg));
3403                 currentTarget = types.createErrorType(pt());
3404             }
3405             return new TargetInfo(currentTarget, lambdaType);
3406         }
3407 
3408         private void reportIntersectionError(DiagnosticPosition pos, String key, Object... args) {
3409              resultInfo.checkContext.report(pos,
3410                  diags.fragment(Fragments.BadIntersectionTargetForFunctionalExpr(diags.fragment(key, args))));
3411         }
3412 
3413         void preFlow(JCLambda tree) {
3414             attrRecover.doRecovery();
3415             new PostAttrAnalyzer() {
3416                 @Override
3417                 public void scan(JCTree tree) {
3418                     if (tree == null ||
3419                             (tree.type != null &&
3420                             tree.type == Type.stuckType)) {
3421                         //don't touch stuck expressions!
3422                         return;
3423                     }
3424                     super.scan(tree);
3425                 }
3426 
3427                 @Override
3428                 public void visitClassDef(JCClassDecl that) {
3429                     // or class declaration trees!
3430                 }
3431 
3432                 public void visitLambda(JCLambda that) {
3433                     // or lambda expressions!
3434                 }
3435             }.scan(tree.body);
3436         }
3437 
3438         Types.MapVisitor<DiagnosticPosition> targetChecker = new Types.MapVisitor<DiagnosticPosition>() {
3439 
3440             @Override
3441             public Type visitClassType(ClassType t, DiagnosticPosition pos) {
3442                 return t.isIntersection() ?
3443                         visitIntersectionClassType((IntersectionClassType)t, pos) : t;
3444             }
3445 
3446             public Type visitIntersectionClassType(IntersectionClassType ict, DiagnosticPosition pos) {
3447                 types.findDescriptorSymbol(makeNotionalInterface(ict, pos));
3448                 return ict;
3449             }
3450 
3451             private TypeSymbol makeNotionalInterface(IntersectionClassType ict, DiagnosticPosition pos) {
3452                 ListBuffer<Type> targs = new ListBuffer<>();
3453                 ListBuffer<Type> supertypes = new ListBuffer<>();
3454                 for (Type i : ict.interfaces_field) {
3455                     if (i.isParameterized()) {
3456                         targs.appendList(i.tsym.type.allparams());
3457                     }
3458                     supertypes.append(i.tsym.type);
3459                 }
3460                 IntersectionClassType notionalIntf = types.makeIntersectionType(supertypes.toList());
3461                 notionalIntf.allparams_field = targs.toList();
3462                 notionalIntf.tsym.flags_field |= INTERFACE;
3463                 return notionalIntf.tsym;
3464             }
3465         };
3466 
3467         private Type fallbackDescriptorType(JCExpression tree) {
3468             switch (tree.getTag()) {
3469                 case LAMBDA:
3470                     JCLambda lambda = (JCLambda)tree;
3471                     List<Type> argtypes = List.nil();
3472                     for (JCVariableDecl param : lambda.params) {
3473                         argtypes = !param.isImplicitlyTyped() && param.vartype.type != null ?
3474                                 argtypes.append(param.vartype.type) :
3475                                 argtypes.append(syms.errType);
3476                     }
3477                     return new MethodType(argtypes, Type.recoveryType,
3478                             List.of(syms.throwableType), syms.methodClass);
3479                 case REFERENCE:
3480                     return new MethodType(List.nil(), Type.recoveryType,
3481                             List.of(syms.throwableType), syms.methodClass);
3482                 default:
3483                     Assert.error("Cannot get here!");
3484             }
3485             return null;
3486         }
3487 
3488         private void checkAccessibleTypes(final DiagnosticPosition pos, final Env<AttrContext> env,
3489                 final InferenceContext inferenceContext, final Type... ts) {
3490             checkAccessibleTypes(pos, env, inferenceContext, List.from(ts));
3491         }
3492 
3493         private void checkAccessibleTypes(final DiagnosticPosition pos, final Env<AttrContext> env,
3494                 final InferenceContext inferenceContext, final List<Type> ts) {
3495             if (inferenceContext.free(ts)) {
3496                 inferenceContext.addFreeTypeListener(ts,
3497                         solvedContext -> checkAccessibleTypes(pos, env, solvedContext, solvedContext.asInstTypes(ts)));
3498             } else {
3499                 for (Type t : ts) {
3500                     rs.checkAccessibleType(env, t);
3501                 }
3502             }
3503         }
3504 
3505         /**
3506          * Lambda/method reference have a special check context that ensures
3507          * that i.e. a lambda return type is compatible with the expected
3508          * type according to both the inherited context and the assignment
3509          * context.
3510          */
3511         class FunctionalReturnContext extends Check.NestedCheckContext {
3512 
3513             FunctionalReturnContext(CheckContext enclosingContext) {
3514                 super(enclosingContext);
3515             }
3516 
3517             @Override
3518             public boolean compatible(Type found, Type req, Warner warn) {
3519                 //return type must be compatible in both current context and assignment context
3520                 return chk.basicHandler.compatible(inferenceContext().asUndetVar(found), inferenceContext().asUndetVar(req), warn);
3521             }
3522 
3523             @Override
3524             public void report(DiagnosticPosition pos, JCDiagnostic details) {
3525                 enclosingContext.report(pos, diags.fragment(Fragments.IncompatibleRetTypeInLambda(details)));
3526             }
3527         }
3528 
3529         class ExpressionLambdaReturnContext extends FunctionalReturnContext {
3530 
3531             JCExpression expr;
3532             boolean expStmtExpected;
3533 
3534             ExpressionLambdaReturnContext(JCExpression expr, CheckContext enclosingContext) {
3535                 super(enclosingContext);
3536                 this.expr = expr;
3537             }
3538 
3539             @Override
3540             public void report(DiagnosticPosition pos, JCDiagnostic details) {
3541                 if (expStmtExpected) {
3542                     enclosingContext.report(pos, diags.fragment(Fragments.StatExprExpected));
3543                 } else {
3544                     super.report(pos, details);
3545                 }
3546             }
3547 
3548             @Override
3549             public boolean compatible(Type found, Type req, Warner warn) {
3550                 //a void return is compatible with an expression statement lambda
3551                 if (req.hasTag(VOID)) {
3552                     expStmtExpected = true;
3553                     return TreeInfo.isExpressionStatement(expr);
3554                 } else {
3555                     return super.compatible(found, req, warn);
3556                 }
3557             }
3558         }
3559 
3560         ResultInfo lambdaBodyResult(JCLambda that, Type descriptor, ResultInfo resultInfo) {
3561             FunctionalReturnContext funcContext = that.getBodyKind() == JCLambda.BodyKind.EXPRESSION ?
3562                     new ExpressionLambdaReturnContext((JCExpression)that.getBody(), resultInfo.checkContext) :
3563                     new FunctionalReturnContext(resultInfo.checkContext);
3564 
3565             return descriptor.getReturnType() == Type.recoveryType ?
3566                     recoveryInfo :
3567                     new ResultInfo(KindSelector.VAL,
3568                             descriptor.getReturnType(), funcContext);
3569         }
3570 
3571         /**
3572         * Lambda compatibility. Check that given return types, thrown types, parameter types
3573         * are compatible with the expected functional interface descriptor. This means that:
3574         * (i) parameter types must be identical to those of the target descriptor; (ii) return
3575         * types must be compatible with the return type of the expected descriptor.
3576         */
3577         void checkLambdaCompatible(JCLambda tree, Type descriptor, TypeSymbol target, CheckContext checkContext) {
3578             Type returnType = checkContext.inferenceContext().asUndetVar(descriptor.getReturnType());
3579 
3580             //return values have already been checked - but if lambda has no return
3581             //values, we must ensure that void/value compatibility is correct;
3582             //this amounts at checking that, if a lambda body can complete normally,
3583             //the descriptor's return type must be void
3584             if (tree.getBodyKind() == JCLambda.BodyKind.STATEMENT && tree.canCompleteNormally &&
3585                     !returnType.hasTag(VOID) && returnType != Type.recoveryType) {
3586                 Fragment msg =
3587                         Fragments.IncompatibleRetTypeInLambda(Fragments.MissingRetVal(returnType));
3588                 checkContext.report(tree,
3589                                     diags.fragment(msg));
3590             }
3591 
3592             List<Type> argTypes = checkContext.inferenceContext().asUndetVars(descriptor.getParameterTypes());
3593             if (!types.isSameTypes(argTypes, TreeInfo.types(tree.params))) {
3594                 checkContext.report(tree, diags.fragment(argTypes.size() != tree.params.size()
3595                         ? Fragments.WrongNumberArgsInLambda(target)
3596                         : Fragments.IncompatibleArgTypesInLambda(argTypes, TreeInfo.types(tree.params))));
3597             }
3598         }
3599 
3600         /* This method returns an environment to be used to attribute a lambda
3601          * expression.
3602          *
3603          * The owner of this environment is a method symbol. If the current owner
3604          * is not a method (e.g. if the lambda occurs in a field initializer), then
3605          * a synthetic method symbol owner is created.
3606          */
3607         public Env<AttrContext> lambdaEnv(JCLambda that, Env<AttrContext> env) {
3608             Env<AttrContext> lambdaEnv;
3609             Symbol owner = env.info.scope.owner;
3610             if (owner.kind == VAR && owner.owner.kind == TYP) {
3611                 // If the lambda is nested in a field initializer, we need to create a fake init method.
3612                 // Uniqueness of this symbol is not important (as e.g. annotations will be added on the
3613                 // init symbol's owner).
3614                 ClassSymbol enclClass = owner.enclClass();
3615                 Name initName = owner.isStatic() ? names.clinit : names.init;
3616                 MethodSymbol initSym = new MethodSymbol(BLOCK | (owner.isStatic() ? STATIC : 0) | SYNTHETIC | PRIVATE,
3617                         initName, initBlockType, enclClass);
3618                 initSym.params = List.nil();
3619                 lambdaEnv = env.dup(that, env.info.dup(env.info.scope.dupUnshared(initSym)));
3620             } else {
3621                 lambdaEnv = env.dup(that, env.info.dup(env.info.scope.dup()));
3622             }
3623             lambdaEnv.info.yieldResult = null;
3624             lambdaEnv.info.isLambda = true;
3625             lambdaEnv.info.earlyContext = lambdaEnv.info.earlyContext.nested(false);
3626             return lambdaEnv;
3627         }
3628 
3629     @Override
3630     public void visitReference(final JCMemberReference that) {
3631         if (pt().isErroneous() || (pt().hasTag(NONE) && pt() != Type.recoveryType)) {
3632             if (pt().hasTag(NONE) && (env.info.enclVar == null || !env.info.enclVar.type.isErroneous())) {
3633                 //method reference only allowed in assignment or method invocation/cast context
3634                 log.error(that.pos(), Errors.UnexpectedMref);
3635             }
3636             result = that.type = types.createErrorType(pt());
3637             return;
3638         }
3639         final Env<AttrContext> localEnv = env.dup(that);
3640         try {
3641             //attribute member reference qualifier - if this is a constructor
3642             //reference, the expected kind must be a type
3643             Type exprType = attribTree(that.expr, env, memberReferenceQualifierResult(that));
3644 
3645             if (that.getMode() == JCMemberReference.ReferenceMode.NEW) {
3646                 exprType = chk.checkConstructorRefType(that.expr, exprType);
3647                 if (!exprType.isErroneous() &&
3648                     exprType.isRaw() &&
3649                     that.typeargs != null) {
3650                     log.error(that.expr.pos(),
3651                               Errors.InvalidMref(Kinds.kindName(that.getMode()),
3652                                                  Fragments.MrefInferAndExplicitParams));
3653                     exprType = types.createErrorType(exprType);
3654                 }
3655             }
3656 
3657             if (exprType.isErroneous()) {
3658                 //if the qualifier expression contains problems,
3659                 //give up attribution of method reference
3660                 result = that.type = exprType;
3661                 return;
3662             }
3663 
3664             if (TreeInfo.isStaticSelector(that.expr, names)) {
3665                 //if the qualifier is a type, validate it; raw warning check is
3666                 //omitted as we don't know at this stage as to whether this is a
3667                 //raw selector (because of inference)
3668                 chk.validate(that.expr, env, false);
3669             } else {
3670                 Symbol lhsSym = TreeInfo.symbol(that.expr);
3671                 localEnv.info.selectSuper = lhsSym != null && lhsSym.name == names._super;
3672             }
3673             //attrib type-arguments
3674             List<Type> typeargtypes = List.nil();
3675             if (that.typeargs != null) {
3676                 typeargtypes = attribTypes(that.typeargs, localEnv);
3677             }
3678 
3679             boolean isTargetSerializable =
3680                     resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK &&
3681                     rs.isSerializable(pt());
3682             TargetInfo targetInfo = getTargetInfo(that, resultInfo, null);
3683             Type currentTarget = targetInfo.target;
3684             Type desc = targetInfo.descriptor;
3685 
3686             setFunctionalInfo(localEnv, that, pt(), desc, currentTarget, resultInfo.checkContext);
3687             List<Type> argtypes = desc.getParameterTypes();
3688             Resolve.MethodCheck referenceCheck = rs.resolveMethodCheck;
3689 
3690             if (resultInfo.checkContext.inferenceContext().free(argtypes)) {
3691                 referenceCheck = rs.new MethodReferenceCheck(resultInfo.checkContext.inferenceContext());
3692             }
3693 
3694             Pair<Symbol, Resolve.ReferenceLookupHelper> refResult = null;
3695             List<Type> saved_undet = resultInfo.checkContext.inferenceContext().save();
3696             try {
3697                 refResult = rs.resolveMemberReference(localEnv, that, that.expr.type,
3698                         that.name, argtypes, typeargtypes, targetInfo.descriptor, referenceCheck,
3699                         resultInfo.checkContext.inferenceContext(), rs.basicReferenceChooser);
3700             } finally {
3701                 resultInfo.checkContext.inferenceContext().rollback(saved_undet);
3702             }
3703 
3704             Symbol refSym = refResult.fst;
3705             Resolve.ReferenceLookupHelper lookupHelper = refResult.snd;
3706 
3707             /** this switch will need to go away and be replaced by the new RESOLUTION_TARGET testing
3708              *  JDK-8075541
3709              */
3710             if (refSym.kind != MTH) {
3711                 boolean targetError;
3712                 switch (refSym.kind) {
3713                     case ABSENT_MTH:
3714                         targetError = false;
3715                         break;
3716                     case WRONG_MTH:
3717                     case WRONG_MTHS:
3718                     case AMBIGUOUS:
3719                     case HIDDEN:
3720                     case STATICERR:
3721                         targetError = true;
3722                         break;
3723                     default:
3724                         Assert.error("unexpected result kind " + refSym.kind);
3725                         targetError = false;
3726                 }
3727 
3728                 JCDiagnostic detailsDiag = ((Resolve.ResolveError)refSym.baseSymbol())
3729                         .getDiagnostic(JCDiagnostic.DiagnosticType.FRAGMENT,
3730                                 that, exprType.tsym, exprType, that.name, argtypes, typeargtypes);
3731 
3732                 JCDiagnostic diag = diags.create(log.currentSource(), that,
3733                         targetError ?
3734                             Fragments.InvalidMref(Kinds.kindName(that.getMode()), detailsDiag) :
3735                             Errors.InvalidMref(Kinds.kindName(that.getMode()), detailsDiag));
3736 
3737                 if (targetError && currentTarget == Type.recoveryType) {
3738                     //a target error doesn't make sense during recovery stage
3739                     //as we don't know what actual parameter types are
3740                     result = that.type = currentTarget;
3741                     return;
3742                 } else {
3743                     if (targetError) {
3744                         resultInfo.checkContext.report(that, diag);
3745                     } else {
3746                         log.report(diag);
3747                     }
3748                     result = that.type = types.createErrorType(currentTarget);
3749                     return;
3750                 }
3751             }
3752 
3753             that.sym = refSym.isConstructor() ? refSym.baseSymbol() : refSym;
3754             that.kind = lookupHelper.referenceKind(that.sym);
3755             that.ownerAccessible = rs.isAccessible(localEnv, that.sym.enclClass());
3756 
3757             if (desc.getReturnType() == Type.recoveryType) {
3758                 // stop here
3759                 result = that.type = currentTarget;
3760                 return;
3761             }
3762 
3763             if (!env.info.attributionMode.isSpeculative && that.getMode() == JCMemberReference.ReferenceMode.NEW) {
3764                 checkNewInnerClass(that.pos(), env, exprType, false);
3765             }
3766 
3767             if (resultInfo.checkContext.deferredAttrContext().mode == AttrMode.CHECK) {
3768 
3769                 if (that.getMode() == ReferenceMode.INVOKE &&
3770                         TreeInfo.isStaticSelector(that.expr, names) &&
3771                         that.kind.isUnbound() &&
3772                         lookupHelper.site.isRaw()) {
3773                     chk.checkRaw(that.expr, localEnv);
3774                 }
3775 
3776                 if (that.sym.isStatic() && TreeInfo.isStaticSelector(that.expr, names) &&
3777                         exprType.getTypeArguments().nonEmpty()) {
3778                     //static ref with class type-args
3779                     log.error(that.expr.pos(),
3780                               Errors.InvalidMref(Kinds.kindName(that.getMode()),
3781                                                  Fragments.StaticMrefWithTargs));
3782                     result = that.type = types.createErrorType(currentTarget);
3783                     return;
3784                 }
3785 
3786                 if (!refSym.isStatic() && that.kind == JCMemberReference.ReferenceKind.SUPER) {
3787                     // Check that super-qualified symbols are not abstract (JLS)
3788                     rs.checkNonAbstract(that.pos(), that.sym);
3789                 }
3790 
3791                 if (isTargetSerializable) {
3792                     chk.checkAccessFromSerializableElement(that, true);
3793                 }
3794             }
3795 
3796             ResultInfo checkInfo =
3797                     resultInfo.dup(newMethodTemplate(
3798                         desc.getReturnType().hasTag(VOID) ? Type.noType : desc.getReturnType(),
3799                         that.kind.isUnbound() ? argtypes.tail : argtypes, typeargtypes),
3800                         new FunctionalReturnContext(resultInfo.checkContext), CheckMode.NO_TREE_UPDATE);
3801 
3802             Type refType = checkId(that, lookupHelper.site, refSym, localEnv, checkInfo);
3803 
3804             if (that.kind.isUnbound() &&
3805                     resultInfo.checkContext.inferenceContext().free(argtypes.head)) {
3806                 //re-generate inference constraints for unbound receiver
3807                 if (!types.isSubtype(resultInfo.checkContext.inferenceContext().asUndetVar(argtypes.head), exprType)) {
3808                     //cannot happen as this has already been checked - we just need
3809                     //to regenerate the inference constraints, as that has been lost
3810                     //as a result of the call to inferenceContext.save()
3811                     Assert.error("Can't get here");
3812                 }
3813             }
3814 
3815             if (!refType.isErroneous()) {
3816                 refType = types.createMethodTypeWithReturn(refType,
3817                         adjustMethodReturnType(refSym, lookupHelper.site, that.name, checkInfo.pt.getParameterTypes(), refType.getReturnType()));
3818             }
3819 
3820             //go ahead with standard method reference compatibility check - note that param check
3821             //is a no-op (as this has been taken care during method applicability)
3822             boolean isSpeculativeRound =
3823                     resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE;
3824 
3825             that.type = currentTarget; //avoids recovery at this stage
3826             checkReferenceCompatible(that, desc, refType, resultInfo.checkContext, isSpeculativeRound);
3827             if (!isSpeculativeRound) {
3828                 checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), desc, currentTarget);
3829             }
3830             chk.checkRequiresIdentity(that, localEnv.info.lint);
3831             result = check(that, currentTarget, KindSelector.VAL, resultInfo);
3832         } catch (Types.FunctionDescriptorLookupError ex) {
3833             JCDiagnostic cause = ex.getDiagnostic();
3834             resultInfo.checkContext.report(that, cause);
3835             result = that.type = types.createErrorType(pt());
3836             return;
3837         }
3838     }
3839     //where
3840         ResultInfo memberReferenceQualifierResult(JCMemberReference tree) {
3841             //if this is a constructor reference, the expected kind must be a type
3842             return new ResultInfo(tree.getMode() == ReferenceMode.INVOKE ?
3843                                   KindSelector.VAL_TYP : KindSelector.TYP,
3844                                   Type.noType);
3845         }
3846 
3847 
3848     @SuppressWarnings("fallthrough")
3849     void checkReferenceCompatible(JCMemberReference tree, Type descriptor, Type refType, CheckContext checkContext, boolean speculativeAttr) {
3850         InferenceContext inferenceContext = checkContext.inferenceContext();
3851         Type returnType = inferenceContext.asUndetVar(descriptor.getReturnType());
3852 
3853         Type resType;
3854         switch (tree.getMode()) {
3855             case NEW:
3856                 if (!tree.expr.type.isRaw()) {
3857                     resType = tree.expr.type;
3858                     break;
3859                 }
3860             default:
3861                 resType = refType.getReturnType();
3862         }
3863 
3864         Type incompatibleReturnType = resType;
3865 
3866         if (returnType.hasTag(VOID)) {
3867             incompatibleReturnType = null;
3868         }
3869 
3870         if (!returnType.hasTag(VOID) && !resType.hasTag(VOID)) {
3871             Type capturedResType = captureMRefReturnType ? types.capture(resType) : resType;
3872             if (resType.isErroneous() ||
3873                     new FunctionalReturnContext(checkContext).compatible(capturedResType, returnType,
3874                             checkContext.checkWarner(tree, capturedResType, returnType))) {
3875                 incompatibleReturnType = null;
3876             }
3877         }
3878 
3879         if (incompatibleReturnType != null) {
3880             Fragment msg =
3881                     Fragments.IncompatibleRetTypeInMref(Fragments.InconvertibleTypes(resType, descriptor.getReturnType()));
3882             checkContext.report(tree, diags.fragment(msg));
3883         } else {
3884             if (inferenceContext.free(refType)) {
3885                 // we need to wait for inference to finish and then replace inference vars in the referent type
3886                 inferenceContext.addFreeTypeListener(List.of(refType),
3887                         instantiatedContext -> {
3888                             tree.referentType = instantiatedContext.asInstType(refType);
3889                         });
3890             } else {
3891                 tree.referentType = refType;
3892             }
3893         }
3894 
3895         if (!speculativeAttr) {
3896             if (!checkExConstraints(refType.getThrownTypes(), descriptor.getThrownTypes(), inferenceContext)) {
3897                 log.error(tree, Errors.IncompatibleThrownTypesInMref(refType.getThrownTypes()));
3898             }
3899         }
3900     }
3901 
3902     boolean checkExConstraints(
3903             List<Type> thrownByFuncExpr,
3904             List<Type> thrownAtFuncType,
3905             InferenceContext inferenceContext) {
3906         /** 18.2.5: Otherwise, let E1, ..., En be the types in the function type's throws clause that
3907          *  are not proper types
3908          */
3909         List<Type> nonProperList = thrownAtFuncType.stream()
3910                 .filter(e -> inferenceContext.free(e)).collect(List.collector());
3911         List<Type> properList = thrownAtFuncType.diff(nonProperList);
3912 
3913         /** Let X1,...,Xm be the checked exception types that the lambda body can throw or
3914          *  in the throws clause of the invocation type of the method reference's compile-time
3915          *  declaration
3916          */
3917         List<Type> checkedList = thrownByFuncExpr.stream()
3918                 .filter(e -> chk.isChecked(e)).collect(List.collector());
3919 
3920         /** If n = 0 (the function type's throws clause consists only of proper types), then
3921          *  if there exists some i (1 <= i <= m) such that Xi is not a subtype of any proper type
3922          *  in the throws clause, the constraint reduces to false; otherwise, the constraint
3923          *  reduces to true
3924          */
3925         ListBuffer<Type> uncaughtByProperTypes = new ListBuffer<>();
3926         for (Type checked : checkedList) {
3927             boolean isSubtype = false;
3928             for (Type proper : properList) {
3929                 if (types.isSubtype(checked, proper)) {
3930                     isSubtype = true;
3931                     break;
3932                 }
3933             }
3934             if (!isSubtype) {
3935                 uncaughtByProperTypes.add(checked);
3936             }
3937         }
3938 
3939         if (nonProperList.isEmpty() && !uncaughtByProperTypes.isEmpty()) {
3940             return false;
3941         }
3942 
3943         /** If n > 0, the constraint reduces to a set of subtyping constraints:
3944          *  for all i (1 <= i <= m), if Xi is not a subtype of any proper type in the
3945          *  throws clause, then the constraints include, for all j (1 <= j <= n), <Xi <: Ej>
3946          */
3947         List<Type> nonProperAsUndet = inferenceContext.asUndetVars(nonProperList);
3948         uncaughtByProperTypes.forEach(checkedEx -> {
3949             nonProperAsUndet.forEach(nonProper -> {
3950                 types.isSubtype(checkedEx, nonProper);
3951             });
3952         });
3953 
3954         /** In addition, for all j (1 <= j <= n), the constraint reduces to the bound throws Ej
3955          */
3956         nonProperAsUndet.stream()
3957                 .filter(t -> t.hasTag(UNDETVAR))
3958                 .forEach(t -> ((UndetVar)t).setThrow());
3959         return true;
3960     }
3961 
3962     /**
3963      * Set functional type info on the underlying AST. Note: as the target descriptor
3964      * might contain inference variables, we might need to register an hook in the
3965      * current inference context.
3966      */
3967     private void setFunctionalInfo(final Env<AttrContext> env, final JCFunctionalExpression fExpr,
3968             final Type pt, final Type descriptorType, final Type primaryTarget, final CheckContext checkContext) {
3969         if (checkContext.inferenceContext().free(descriptorType)) {
3970             checkContext.inferenceContext().addFreeTypeListener(List.of(pt, descriptorType),
3971                     inferenceContext -> setFunctionalInfo(env, fExpr, pt, inferenceContext.asInstType(descriptorType),
3972                     inferenceContext.asInstType(primaryTarget), checkContext));
3973         } else {
3974             fExpr.owner = env.info.scope.owner;
3975             if (pt.hasTag(CLASS)) {
3976                 fExpr.target = primaryTarget;
3977             }
3978             if (checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK &&
3979                     pt != Type.recoveryType) {
3980                 //check that functional interface class is well-formed
3981                 try {
3982                     /* Types.makeFunctionalInterfaceClass() may throw an exception
3983                      * when it's executed post-inference. See the listener code
3984                      * above.
3985                      */
3986                     ClassSymbol csym = types.makeFunctionalInterfaceClass(env,
3987                             names.empty, fExpr.target, ABSTRACT);
3988                     if (csym != null) {
3989                         chk.checkImplementations(env.tree, csym, csym);
3990                         try {
3991                             //perform an additional functional interface check on the synthetic class,
3992                             //as there may be spurious errors for raw targets - because of existing issues
3993                             //with membership and inheritance (see JDK-8074570).
3994                             csym.flags_field |= INTERFACE;
3995                             types.findDescriptorType(csym.type);
3996                         } catch (FunctionDescriptorLookupError err) {
3997                             resultInfo.checkContext.report(fExpr,
3998                                     diags.fragment(Fragments.NoSuitableFunctionalIntfInst(fExpr.target)));
3999                         }
4000                     }
4001                 } catch (Types.FunctionDescriptorLookupError ex) {
4002                     JCDiagnostic cause = ex.getDiagnostic();
4003                     resultInfo.checkContext.report(env.tree, cause);
4004                 }
4005             }
4006         }
4007     }
4008 
4009     public void visitParens(JCParens tree) {
4010         Type owntype = attribTree(tree.expr, env, resultInfo);
4011         result = check(tree, owntype, pkind(), resultInfo);
4012         Symbol sym = TreeInfo.symbol(tree);
4013         if (sym != null && sym.kind.matches(KindSelector.TYP_PCK) && sym.kind != Kind.ERR)
4014             log.error(tree.pos(), Errors.IllegalParenthesizedExpression);
4015     }
4016 
4017     public void visitAssign(JCAssign tree) {
4018         Type owntype = attribTree(tree.lhs, env.dup(tree), varAssignmentInfo);
4019         Type capturedType = capture(owntype);
4020         attribExpr(tree.rhs, env, owntype);
4021         result = check(tree, capturedType, KindSelector.VAL, resultInfo);
4022     }
4023 
4024     public void visitAssignop(JCAssignOp tree) {
4025         // Attribute arguments.
4026         Type owntype = attribTree(tree.lhs, env, varAssignmentOpInfo);
4027         Type operand = attribExpr(tree.rhs, env);
4028         // Find operator.
4029         Symbol operator = tree.operator = operators.resolveBinary(tree, tree.getTag().noAssignOp(), owntype, operand);
4030         if (operator != operators.noOpSymbol &&
4031                 !owntype.isErroneous() &&
4032                 !operand.isErroneous()) {
4033             chk.checkDivZero(tree.rhs.pos(), operator, operand);
4034             chk.checkCastable(tree.rhs.pos(),
4035                               operator.type.getReturnType(),
4036                               owntype);
4037             switch (tree.getTag()) {
4038             case SL_ASG, SR_ASG, USR_ASG -> { }     // we only use (at most) the lower 6 bits, so any integral type is OK
4039             default -> chk.checkLossOfPrecision(tree.rhs.pos(), operand, owntype);
4040             }
4041             chk.checkOutOfRangeShift(tree.rhs.pos(), operator, operand);
4042         }
4043         result = check(tree, owntype, KindSelector.VAL, resultInfo);
4044     }
4045 
4046     public void visitUnary(JCUnary tree) {
4047         // Attribute arguments.
4048         Type argtype = (tree.getTag().isIncOrDecUnaryOp())
4049             ? attribTree(tree.arg, env, varAssignmentOpInfo)
4050             : chk.checkNonVoid(tree.arg.pos(), attribExpr(tree.arg, env));
4051 
4052         // Find operator.
4053         OperatorSymbol operator = tree.operator = operators.resolveUnary(tree, tree.getTag(), argtype);
4054         Type owntype = types.createErrorType(tree.type);
4055         if (operator != operators.noOpSymbol &&
4056                 !argtype.isErroneous()) {
4057             owntype = (tree.getTag().isIncOrDecUnaryOp())
4058                 ? tree.arg.type
4059                 : operator.type.getReturnType();
4060             int opc = operator.opcode;
4061 
4062             // If the argument is constant, fold it.
4063             if (argtype.constValue() != null) {
4064                 Type ctype = cfolder.fold1(opc, argtype);
4065                 if (ctype != null) {
4066                     owntype = cfolder.coerce(ctype, owntype);
4067                 }
4068             }
4069         }
4070         result = check(tree, owntype, KindSelector.VAL, resultInfo);
4071         matchBindings = matchBindingsComputer.unary(tree, matchBindings);
4072     }
4073 
4074     public void visitBinary(JCBinary tree) {
4075         // Attribute arguments.
4076         Type left = chk.checkNonVoid(tree.lhs.pos(), attribExpr(tree.lhs, env));
4077         // x && y
4078         // include x's bindings when true in y
4079 
4080         // x || y
4081         // include x's bindings when false in y
4082 
4083         MatchBindings lhsBindings = matchBindings;
4084         List<BindingSymbol> propagatedBindings;
4085         switch (tree.getTag()) {
4086             case AND:
4087                 propagatedBindings = lhsBindings.bindingsWhenTrue;
4088                 break;
4089             case OR:
4090                 propagatedBindings = lhsBindings.bindingsWhenFalse;
4091                 break;
4092             default:
4093                 propagatedBindings = List.nil();
4094                 break;
4095         }
4096         Env<AttrContext> rhsEnv = bindingEnv(env, propagatedBindings);
4097         Type right;
4098         try {
4099             right = chk.checkNonVoid(tree.rhs.pos(), attribExpr(tree.rhs, rhsEnv));
4100         } finally {
4101             rhsEnv.info.scope.leave();
4102         }
4103 
4104         matchBindings = matchBindingsComputer.binary(tree, lhsBindings, matchBindings);
4105 
4106         // Find operator.
4107         OperatorSymbol operator = tree.operator = operators.resolveBinary(tree, tree.getTag(), left, right);
4108         Type owntype = types.createErrorType(tree.type);
4109         if (operator != operators.noOpSymbol &&
4110                 !left.isErroneous() &&
4111                 !right.isErroneous()) {
4112             owntype = operator.type.getReturnType();
4113             int opc = operator.opcode;
4114             // If both arguments are constants, fold them.
4115             if (left.constValue() != null && right.constValue() != null) {
4116                 Type ctype = cfolder.fold2(opc, left, right);
4117                 if (ctype != null) {
4118                     owntype = cfolder.coerce(ctype, owntype);
4119                 }
4120             }
4121 
4122             // Check that argument types of a reference ==, != are
4123             // castable to each other, (JLS 15.21).  Note: unboxing
4124             // comparisons will not have an acmp* opc at this point.
4125             if ((opc == ByteCodes.if_acmpeq || opc == ByteCodes.if_acmpne)) {
4126                 if (!types.isCastable(left, right, new Warner(tree.pos()))) {
4127                     log.error(tree.pos(), Errors.IncomparableTypes(left, right));
4128                 }
4129             }
4130 
4131             chk.checkDivZero(tree.rhs.pos(), operator, right);
4132             chk.checkOutOfRangeShift(tree.rhs.pos(), operator, right);
4133         }
4134         result = check(tree, owntype, KindSelector.VAL, resultInfo);
4135     }
4136 
4137     public void visitTypeCast(final JCTypeCast tree) {
4138         Type clazztype = attribType(tree.clazz, env);
4139         chk.validate(tree.clazz, env, false);
4140         chk.checkRequiresIdentity(tree, env.info.lint);
4141         //a fresh environment is required for 292 inference to work properly ---
4142         //see Infer.instantiatePolymorphicSignatureInstance()
4143         Env<AttrContext> localEnv = env.dup(tree);
4144         //should we propagate the target type?
4145         final ResultInfo castInfo;
4146         JCExpression expr = TreeInfo.skipParens(tree.expr);
4147         boolean isPoly = (expr.hasTag(LAMBDA) || expr.hasTag(REFERENCE));
4148         if (isPoly) {
4149             //expression is a poly - we need to propagate target type info
4150             castInfo = new ResultInfo(KindSelector.VAL, clazztype,
4151                                       new Check.NestedCheckContext(resultInfo.checkContext) {
4152                 @Override
4153                 public boolean compatible(Type found, Type req, Warner warn) {
4154                     return types.isCastable(found, req, warn);
4155                 }
4156             });
4157         } else {
4158             //standalone cast - target-type info is not propagated
4159             castInfo = unknownExprInfo;
4160         }
4161         Type exprtype = attribTree(tree.expr, localEnv, castInfo);
4162         Type owntype = isPoly ? clazztype : chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
4163         if (exprtype.constValue() != null)
4164             owntype = cfolder.coerce(exprtype, owntype);
4165         result = check(tree, capture(owntype), KindSelector.VAL, resultInfo);
4166         if (!isPoly)
4167             chk.checkRedundantCast(localEnv, tree);
4168     }
4169 
4170     public void visitTypeTest(JCInstanceOf tree) {
4171         Type exprtype = attribExpr(tree.expr, env);
4172         if (exprtype.isPrimitive()) {
4173             preview.checkSourceLevel(tree.expr.pos(), Feature.PRIMITIVE_PATTERNS);
4174         } else {
4175             exprtype = chk.checkNullOrRefType(
4176                     tree.expr.pos(), exprtype);
4177         }
4178         Type clazztype;
4179         JCTree typeTree;
4180         if (tree.pattern.getTag() == BINDINGPATTERN ||
4181             tree.pattern.getTag() == RECORDPATTERN) {
4182             attribExpr(tree.pattern, env, exprtype);
4183             clazztype = tree.pattern.type;
4184             if (types.isSubtype(exprtype, clazztype) &&
4185                 !exprtype.isErroneous() && !clazztype.isErroneous() &&
4186                 tree.pattern.getTag() != RECORDPATTERN) {
4187                 if (!allowUnconditionalPatternsInstanceOf) {
4188                     log.error(tree.pos(), Feature.UNCONDITIONAL_PATTERN_IN_INSTANCEOF.error(this.sourceName));
4189                 }
4190             }
4191             typeTree = TreeInfo.primaryPatternTypeTree((JCPattern) tree.pattern);
4192         } else {
4193             clazztype = attribType(tree.pattern, env);
4194             typeTree = tree.pattern;
4195             chk.validate(typeTree, env, false);
4196         }
4197         if (clazztype.isPrimitive()) {
4198             preview.checkSourceLevel(tree.pattern.pos(), Feature.PRIMITIVE_PATTERNS);
4199         } else {
4200             if (!clazztype.hasTag(TYPEVAR)) {
4201                 clazztype = chk.checkClassOrArrayType(typeTree.pos(), clazztype);
4202             }
4203             if (!clazztype.isErroneous() && !types.isReifiable(clazztype)) {
4204                 boolean valid = false;
4205                 if (allowReifiableTypesInInstanceof) {
4206                     valid = checkCastablePattern(tree.expr.pos(), exprtype, clazztype);
4207                 } else {
4208                     log.error(tree.pos(), Feature.REIFIABLE_TYPES_INSTANCEOF.error(this.sourceName));
4209                     allowReifiableTypesInInstanceof = true;
4210                 }
4211                 if (!valid) {
4212                     clazztype = types.createErrorType(clazztype);
4213                 }
4214             }
4215         }
4216         chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
4217         result = check(tree, syms.booleanType, KindSelector.VAL, resultInfo);
4218     }
4219 
4220     private boolean checkCastablePattern(DiagnosticPosition pos,
4221                                          Type exprType,
4222                                          Type pattType) {
4223         Warner warner = new Warner();
4224         // if any type is erroneous, the problem is reported elsewhere
4225         if (exprType.isErroneous() || pattType.isErroneous()) {
4226             return false;
4227         }
4228         if (!types.isCastable(exprType, pattType, warner)) {
4229             chk.basicHandler.report(pos,
4230                     diags.fragment(Fragments.InconvertibleTypes(exprType, pattType)));
4231             return false;
4232         } else if ((exprType.isPrimitive() || pattType.isPrimitive()) &&
4233                 (!exprType.isPrimitive() || !pattType.isPrimitive() || !types.isSameType(exprType, pattType))) {
4234             preview.checkSourceLevel(pos, Feature.PRIMITIVE_PATTERNS);
4235             return true;
4236         } else if (warner.hasLint(LintCategory.UNCHECKED)) {
4237             log.error(pos,
4238                     Errors.InstanceofReifiableNotSafe(exprType, pattType));
4239             return false;
4240         } else {
4241             return true;
4242         }
4243     }
4244 
4245     @Override
4246     public void visitAnyPattern(JCAnyPattern tree) {
4247         result = tree.type = resultInfo.pt;
4248     }
4249 
4250     public void visitBindingPattern(JCBindingPattern tree) {
4251         Type type;
4252         if (!tree.var.isImplicitlyTyped()) {
4253             type = attribType(tree.var.vartype, env);
4254         } else {
4255             type = resultInfo.pt;
4256         }
4257         BindingSymbol v = new BindingSymbol(tree.var.mods.flags | tree.var.declKind.additionalSymbolFlags,
4258                                             tree.var.name, type, env.info.scope.owner);
4259         v.pos = tree.pos;
4260         tree.var.sym = v;
4261         if (chk.checkUnique(tree.var.pos(), v, env.info.scope)) {
4262             chk.checkTransparentVar(tree.var.pos(), v, env.info.scope);
4263         }
4264         if (tree.var.isImplicitlyTyped()) {
4265             setupImplicitlyTypedVariable(tree.var, type == Type.noType ? syms.errType
4266                                                       : type);
4267         }
4268         chk.validate(tree.var.vartype, env, true);
4269         annotate.annotateLater(tree.var.mods.annotations, env, v);
4270         if (!tree.var.isImplicitlyTyped()) {
4271             annotate.queueScanTreeAndTypeAnnotate(tree.var.vartype, env, v);
4272         }
4273         annotate.flush();
4274         typeAnnotations.organizeTypeAnnotationsSignaturesForLocalVarType(env, tree.var);
4275         result = tree.type = tree.var.type = v.type;
4276         if (v.isUnnamedVariable()) {
4277             matchBindings = MatchBindingsComputer.EMPTY;
4278         } else {
4279             matchBindings = new MatchBindings(List.of(v), List.nil());
4280         }
4281         chk.checkRequiresIdentity(tree, env.info.lint);
4282     }
4283 
4284     @Override
4285     public void visitRecordPattern(JCRecordPattern tree) {
4286         Type site;
4287 
4288         if (tree.deconstructor.hasTag(VARTYPE)) {
4289             log.error(tree.pos(), Errors.DeconstructionPatternVarNotAllowed);
4290             tree.record = syms.errSymbol;
4291             site = tree.type = types.createErrorType(tree.record.type);
4292         } else {
4293             Type type = attribType(tree.deconstructor, env);
4294             if (type.isRaw() && type.tsym.getTypeParameters().nonEmpty()) {
4295                 Type inferred = infer.instantiatePatternType(resultInfo.pt, type.tsym);
4296                 if (inferred == null) {
4297                     log.error(tree.pos(), Errors.PatternTypeCannotInfer);
4298                 } else {
4299                     type = inferred;
4300                 }
4301             }
4302             tree.type = tree.deconstructor.type = type;
4303             site = types.capture(tree.type);
4304             chk.validate(tree.deconstructor, env, true);
4305         }
4306 
4307         List<Type> expectedRecordTypes;
4308         if (site.tsym instanceof ClassSymbol clazz && clazz.isRecord()) {
4309             ClassSymbol record = (ClassSymbol) site.tsym;
4310             expectedRecordTypes = record.getRecordComponents()
4311                                         .stream()
4312                                         .map(rc -> types.memberType(site, rc))
4313                                         .map(t -> types.upward(t, types.captures(t)).baseType())
4314                                         .collect(List.collector());
4315             tree.record = record;
4316         } else {
4317             log.error(tree.pos(), Errors.DeconstructionPatternOnlyRecords(site.tsym));
4318             expectedRecordTypes = Stream.generate(() -> types.createErrorType(tree.type))
4319                                 .limit(tree.nested.size())
4320                                 .collect(List.collector());
4321             tree.record = syms.errSymbol;
4322         }
4323         ListBuffer<BindingSymbol> outBindings = new ListBuffer<>();
4324         List<Type> recordTypes = expectedRecordTypes;
4325         List<JCPattern> nestedPatterns = tree.nested;
4326         Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
4327         try {
4328             while (recordTypes.nonEmpty() && nestedPatterns.nonEmpty()) {
4329                 attribExpr(nestedPatterns.head, localEnv, recordTypes.head);
4330                 checkCastablePattern(nestedPatterns.head.pos(), recordTypes.head, nestedPatterns.head.type);
4331                 outBindings.addAll(matchBindings.bindingsWhenTrue);
4332                 matchBindings.bindingsWhenTrue.forEach(localEnv.info.scope::enter);
4333                 nestedPatterns = nestedPatterns.tail;
4334                 recordTypes = recordTypes.tail;
4335             }
4336             if (recordTypes.nonEmpty() || nestedPatterns.nonEmpty()) {
4337                 while (nestedPatterns.nonEmpty()) {
4338                     attribExpr(nestedPatterns.head, localEnv, Type.noType);
4339                     nestedPatterns = nestedPatterns.tail;
4340                 }
4341                 List<Type> nestedTypes =
4342                         tree.nested.stream().map(p -> p.type).collect(List.collector());
4343                 log.error(tree.pos(),
4344                           Errors.IncorrectNumberOfNestedPatterns(expectedRecordTypes,
4345                                                                  nestedTypes));
4346             }
4347         } finally {
4348             localEnv.info.scope.leave();
4349         }
4350         result = tree.type;
4351         matchBindings = new MatchBindings(outBindings.toList(), List.nil());
4352     }
4353 
4354     public void visitIndexed(JCArrayAccess tree) {
4355         Type owntype = types.createErrorType(tree.type);
4356         Type atype = attribExpr(tree.indexed, env);
4357         attribExpr(tree.index, env, syms.intType);
4358         if (types.isArray(atype))
4359             owntype = types.elemtype(atype);
4360         else if (!atype.hasTag(ERROR))
4361             log.error(tree.pos(), Errors.ArrayReqButFound(atype));
4362         if (!pkind().contains(KindSelector.VAL))
4363             owntype = capture(owntype);
4364         result = check(tree, owntype, KindSelector.VAR, resultInfo);
4365     }
4366 
4367     public void visitIdent(JCIdent tree) {
4368         Symbol sym;
4369 
4370         // Find symbol
4371         if (pt().hasTag(METHOD) || pt().hasTag(FORALL)) {
4372             // If we are looking for a method, the prototype `pt' will be a
4373             // method type with the type of the call's arguments as parameters.
4374             env.info.pendingResolutionPhase = null;
4375             sym = rs.resolveMethod(tree.pos(), env, tree.name, pt().getParameterTypes(), pt().getTypeArguments());
4376         } else if (tree.sym != null && tree.sym.kind != VAR) {
4377             sym = tree.sym;
4378         } else {
4379             sym = rs.resolveIdent(tree.pos(), env, tree.name, pkind());
4380         }
4381         tree.sym = sym;
4382 
4383         // Also find the environment current for the class where
4384         // sym is defined (`symEnv').
4385         Env<AttrContext> symEnv = env;
4386         if (env.enclClass.sym.owner.kind != PCK && // we are in an inner class
4387             sym.kind.matches(KindSelector.VAL_MTH) &&
4388             sym.owner.kind == TYP &&
4389             tree.name != names._this && tree.name != names._super) {
4390 
4391             // Find environment in which identifier is defined.
4392             while (symEnv.outer != null &&
4393                    !sym.isMemberOf(symEnv.enclClass.sym, types)) {
4394                 symEnv = symEnv.outer;
4395             }
4396         }
4397 
4398         // If symbol is a variable, ...
4399         if (sym.kind == VAR) {
4400             VarSymbol v = (VarSymbol)sym;
4401 
4402             // ..., evaluate its initializer, if it has one, and check for
4403             // illegal forward reference.
4404             checkInit(tree, env, v, false);
4405 
4406             // If we are expecting a variable (as opposed to a value), check
4407             // that the variable is assignable in the current environment.
4408             if (KindSelector.ASG.subset(pkind()))
4409                 checkAssignable(tree.pos(), v, null, env);
4410         }
4411 
4412         Env<AttrContext> env1 = env;
4413         if (sym.kind != ERR && sym.kind != TYP &&
4414             sym.owner != null && sym.owner != env1.enclClass.sym) {
4415             // If the found symbol is inaccessible, then it is
4416             // accessed through an enclosing instance.  Locate this
4417             // enclosing instance:
4418             while (env1.outer != null && !rs.isAccessible(env, env1.enclClass.sym.type, sym))
4419                 env1 = env1.outer;
4420         }
4421 
4422         if (env.info.isSerializable) {
4423             chk.checkAccessFromSerializableElement(tree, env.info.isSerializableLambda);
4424         }
4425 
4426         result = checkId(tree, env1.enclClass.sym.type, sym, env, resultInfo);
4427     }
4428 
4429     public void visitSelect(JCFieldAccess tree) {
4430         // Determine the expected kind of the qualifier expression.
4431         KindSelector skind = KindSelector.NIL;
4432         if (tree.name == names._this || tree.name == names._super ||
4433                 tree.name == names._class)
4434         {
4435             skind = KindSelector.TYP;
4436         } else {
4437             if (pkind().contains(KindSelector.PCK))
4438                 skind = KindSelector.of(skind, KindSelector.PCK);
4439             if (pkind().contains(KindSelector.TYP))
4440                 skind = KindSelector.of(skind, KindSelector.TYP, KindSelector.PCK);
4441             if (pkind().contains(KindSelector.VAL_MTH))
4442                 skind = KindSelector.of(skind, KindSelector.VAL, KindSelector.TYP);
4443         }
4444 
4445         // Attribute the qualifier expression, and determine its symbol (if any).
4446         Type site;
4447         EarlyConstructionContext earlyConstructionPrev = env.info.earlyContext;
4448         JCTree earlyFieldQualifier = earlyFieldQualifier(tree);
4449         try {
4450             if (earlyFieldQualifier != null) {
4451                 // if we're seeing a likely field access, and qualifier is this/super,
4452                 // pretend we're not in early construction context. This allows Resolve
4453                 // to skip premature checks against this/super
4454                 env.info.earlyContext = EarlyConstructionContext.NONE;
4455             }
4456             site = attribTree(tree.selected, env, new ResultInfo(skind, Type.noType));
4457         } finally {
4458             env.info.earlyContext = earlyConstructionPrev;
4459         }
4460         Assert.check(site == tree.selected.type);
4461         if (!pkind().contains(KindSelector.TYP_PCK))
4462             site = capture(site); // Capture field access
4463 
4464         // don't allow T.class T[].class, etc
4465         if (skind == KindSelector.TYP) {
4466             Type elt = site;
4467             while (elt.hasTag(ARRAY))
4468                 elt = ((ArrayType)elt).elemtype;
4469             if (elt.hasTag(TYPEVAR)) {
4470                 log.error(tree.pos(), Errors.TypeVarCantBeDeref);
4471                 result = tree.type = types.createErrorType(tree.name, site.tsym, site);
4472                 tree.sym = tree.type.tsym;
4473                 return ;
4474             }
4475         }
4476 
4477         // If qualifier symbol is a type or `super', assert `selectSuper'
4478         // for the selection. This is relevant for determining whether
4479         // protected symbols are accessible.
4480         Symbol sitesym = TreeInfo.symbol(tree.selected);
4481         boolean selectSuperPrev = env.info.selectSuper;
4482         env.info.selectSuper =
4483             sitesym != null &&
4484             sitesym.name == names._super;
4485 
4486         // Determine the symbol represented by the selection.
4487         env.info.pendingResolutionPhase = null;
4488         Symbol sym;
4489         sym = selectSym(tree, sitesym, site, env, resultInfo, earlyFieldQualifier);
4490         if (sym.kind == VAR && sym.name != names._super && env.info.defaultSuperCallSite != null) {
4491             log.error(tree.selected.pos(), Errors.NotEnclClass(site.tsym));
4492             sym = syms.errSymbol;
4493         }
4494         if (sym.exists() && !isType(sym) &&
4495                 tree.name != names._this && tree.name != names._super &&
4496                 pkind().contains(KindSelector.TYP_PCK)) {
4497             site = capture(site);
4498             sym = selectSym(tree, sitesym, site, env, resultInfo, earlyFieldQualifier);
4499         }
4500         boolean varArgs = env.info.lastResolveVarargs();
4501         tree.sym = sym;
4502 
4503         if (site.hasTag(TYPEVAR) && !isType(sym) && sym.kind != ERR) {
4504             site = types.skipTypeVars(site, true);
4505         }
4506 
4507         // If that symbol is a variable, ...
4508         if (sym.kind == VAR) {
4509             VarSymbol v = (VarSymbol)sym;
4510 
4511             // ..., evaluate its initializer, if it has one, and check for
4512             // illegal forward reference.
4513             checkInit(tree, env, v, true);
4514 
4515             // If we are expecting a variable (as opposed to a value), check
4516             // that the variable is assignable in the current environment.
4517             if (KindSelector.ASG.subset(pkind()))
4518                 checkAssignable(tree.pos(), v, tree.selected, env);
4519         }
4520 
4521         if (sitesym != null &&
4522                 sitesym.kind == VAR &&
4523                 ((VarSymbol)sitesym).isResourceVariable() &&
4524                 sym.kind == MTH &&
4525                 sym.name.equals(names.close) &&
4526                 sym.overrides(syms.autoCloseableClose, sitesym.type.tsym, types, true)) {
4527             log.warning(tree, LintWarnings.TryExplicitCloseCall);
4528         }
4529 
4530         // Disallow selecting a type from an expression
4531         if (isType(sym) && (sitesym == null || !sitesym.kind.matches(KindSelector.TYP_PCK))) {
4532             tree.type = check(tree.selected, pt(),
4533                               sitesym == null ?
4534                                       KindSelector.VAL : sitesym.kind.toSelector(),
4535                               new ResultInfo(KindSelector.TYP_PCK, pt()));
4536         }
4537 
4538         if (isType(sitesym)) {
4539             if (sym.name != names._this && sym.name != names._super) {
4540                 // Check if type-qualified fields or methods are static (JLS)
4541                 if ((sym.flags() & STATIC) == 0 &&
4542                     sym.name != names._super &&
4543                     (sym.kind == VAR || sym.kind == MTH)) {
4544                     rs.accessBase(rs.new StaticError(sym),
4545                               tree.pos(), site, sym.name, true);
4546                 }
4547             }
4548         } else if (sym.kind != ERR &&
4549                    (sym.flags() & STATIC) != 0 &&
4550                    sym.name != names._class) {
4551             // If the qualified item is not a type and the selected item is static, report
4552             // a warning. Make allowance for the class of an array type e.g. Object[].class)
4553             if (!sym.owner.isAnonymous()) {
4554                 log.warning(tree, LintWarnings.StaticNotQualifiedByType(sym.kind.kindName(), sym.owner));
4555             } else {
4556                 log.warning(tree, LintWarnings.StaticNotQualifiedByType2(sym.kind.kindName()));
4557             }
4558         }
4559 
4560         // If we are selecting an instance member via a `super', ...
4561         if (env.info.selectSuper && (sym.flags() & STATIC) == 0) {
4562 
4563             // Check that super-qualified symbols are not abstract (JLS)
4564             rs.checkNonAbstract(tree.pos(), sym);
4565 
4566             if (site.isRaw()) {
4567                 // Determine argument types for site.
4568                 Type site1 = types.asSuper(env.enclClass.sym.type, site.tsym);
4569                 if (site1 != null) site = site1;
4570             }
4571         }
4572 
4573         if (env.info.isSerializable) {
4574             chk.checkAccessFromSerializableElement(tree, env.info.isSerializableLambda);
4575         }
4576 
4577         env.info.selectSuper = selectSuperPrev;
4578         result = checkId(tree, site, sym, env, resultInfo);
4579     }
4580 
4581     private JCTree earlyFieldQualifier(JCFieldAccess tree) {
4582         boolean methodSelect = resultInfo.pt.hasTag(METHOD) || resultInfo.pt.hasTag(FORALL);
4583         if (!methodSelect &&
4584                 (TreeInfo.isThisOrSelectorDotThis(tree.selected) ||
4585                 TreeInfo.isSuperOrSelectorDotSuper(tree.selected))) {
4586             return tree.selected;
4587         }
4588         return null;
4589     }
4590 
4591     //where
4592         /** Determine symbol referenced by a Select expression,
4593          *
4594          *  @param tree   The select tree.
4595          *  @param site   The type of the selected expression,
4596          *  @param env    The current environment.
4597          *  @param resultInfo The current result.
4598          */
4599         private Symbol selectSym(JCFieldAccess tree,
4600                                  Symbol location,
4601                                  Type site,
4602                                  Env<AttrContext> env,
4603                                  ResultInfo resultInfo,
4604                                  JCTree earlyFieldQualifier) {
4605             DiagnosticPosition pos = tree.pos();
4606             Name name = tree.name;
4607             switch (site.getTag()) {
4608             case PACKAGE:
4609                 return rs.accessBase(
4610                     rs.findIdentInPackage(pos, env, site.tsym, name, resultInfo.pkind),
4611                     pos, location, site, name, true);
4612             case ARRAY:
4613             case CLASS:
4614                 if (resultInfo.pt.hasTag(METHOD) || resultInfo.pt.hasTag(FORALL)) {
4615                     return rs.resolveQualifiedMethod(
4616                         pos, env, location, site, name, resultInfo.pt.getParameterTypes(), resultInfo.pt.getTypeArguments());
4617                 } else if (name == names._this || name == names._super) {
4618                     Symbol sym = rs.resolveSelf(pos, env, site.tsym, tree);
4619                     return rs.accessBase(sym, pos, env.enclClass.sym.type, name, true);
4620                 } else if (name == names._class) {
4621                     // In this case, we have already made sure in
4622                     // visitSelect that qualifier expression is a type.
4623                     return syms.getClassField(site, types);
4624                 } else {
4625                     // We are seeing a plain identifier as selector.
4626                     Symbol sym = rs.findIdentInType(pos, env, site, name, resultInfo.pkind, earlyFieldQualifier);
4627                         sym = rs.accessBase(sym, pos, location, site, name, true);
4628                     return sym;
4629                 }
4630             case WILDCARD:
4631                 throw new AssertionError(tree);
4632             case TYPEVAR:
4633                 // Normally, site.getUpperBound() shouldn't be null.
4634                 // It should only happen during memberEnter/attribBase
4635                 // when determining the supertype which *must* be
4636                 // done before attributing the type variables.  In
4637                 // other words, we are seeing this illegal program:
4638                 // class B<T> extends A<T.foo> {}
4639                 Symbol sym = (site.getUpperBound() != null)
4640                     ? selectSym(tree, location, capture(site.getUpperBound()), env, resultInfo, earlyFieldQualifier)
4641                     : null;
4642                 if (sym == null) {
4643                     log.error(pos, Errors.TypeVarCantBeDeref);
4644                     return syms.errSymbol;
4645                 } else {
4646                     // JLS 4.9 specifies the members are derived by inheritance.
4647                     // We skip inducing a whole class by filtering members that
4648                     // can never be inherited:
4649                     Symbol sym2;
4650                     if (sym.isPrivate()) {
4651                         // Private members
4652                         sym2 = rs.new AccessError(env, site, sym);
4653                     } else if (sym.owner.isInterface() && sym.kind == MTH && (sym.flags() & STATIC) != 0) {
4654                         // Interface static methods
4655                         sym2 = rs.new SymbolNotFoundError(ABSENT_MTH);
4656                     } else {
4657                         sym2 = sym;
4658                     }
4659                     rs.accessBase(sym2, pos, location, site, name, true);
4660                     return sym;
4661                 }
4662             case ERROR:
4663                 // preserve identifier names through errors
4664                 return types.createErrorType(name, site.tsym, site).tsym;
4665             default:
4666                 // The qualifier expression is of a primitive type -- only
4667                 // .class is allowed for these.
4668                 if (name == names._class) {
4669                     // In this case, we have already made sure in Select that
4670                     // qualifier expression is a type.
4671                     return syms.getClassField(site, types);
4672                 } else {
4673                     log.error(pos, Errors.CantDeref(site));
4674                     return types.createErrorType(name, syms.errSymbol, site).tsym;
4675                 }
4676             }
4677         }
4678 
4679         /** Determine type of identifier or select expression and check that
4680          *  (1) the referenced symbol is not deprecated
4681          *  (2) the symbol's type is safe (@see checkSafe)
4682          *  (3) if symbol is a variable, check that its type and kind are
4683          *      compatible with the prototype and protokind.
4684          *  (4) if symbol is an instance field of a raw type,
4685          *      which is being assigned to, issue an unchecked warning if its
4686          *      type changes under erasure.
4687          *  (5) if symbol is an instance method of a raw type, issue an
4688          *      unchecked warning if its argument types change under erasure.
4689          *  If checks succeed:
4690          *    If symbol is a constant, return its constant type
4691          *    else if symbol is a method, return its result type
4692          *    otherwise return its type.
4693          *  Otherwise return errType.
4694          *
4695          *  @param tree       The syntax tree representing the identifier
4696          *  @param site       If this is a select, the type of the selected
4697          *                    expression, otherwise the type of the current class.
4698          *  @param sym        The symbol representing the identifier.
4699          *  @param env        The current environment.
4700          *  @param resultInfo    The expected result
4701          */
4702         Type checkId(JCTree tree,
4703                      Type site,
4704                      Symbol sym,
4705                      Env<AttrContext> env,
4706                      ResultInfo resultInfo) {
4707             return (resultInfo.pt.hasTag(FORALL) || resultInfo.pt.hasTag(METHOD)) ?
4708                     checkMethodIdInternal(tree, site, sym, env, resultInfo) :
4709                     checkIdInternal(tree, site, sym, resultInfo.pt, env, resultInfo);
4710         }
4711 
4712         Type checkMethodIdInternal(JCTree tree,
4713                      Type site,
4714                      Symbol sym,
4715                      Env<AttrContext> env,
4716                      ResultInfo resultInfo) {
4717             if (resultInfo.pkind.contains(KindSelector.POLY)) {
4718                 return attrRecover.recoverMethodInvocation(tree, site, sym, env, resultInfo);
4719             } else {
4720                 return checkIdInternal(tree, site, sym, resultInfo.pt, env, resultInfo);
4721             }
4722         }
4723 
4724         Type checkIdInternal(JCTree tree,
4725                      Type site,
4726                      Symbol sym,
4727                      Type pt,
4728                      Env<AttrContext> env,
4729                      ResultInfo resultInfo) {
4730             Type owntype; // The computed type of this identifier occurrence.
4731             switch (sym.kind) {
4732             case TYP:
4733                 // For types, the computed type equals the symbol's type,
4734                 // except for two situations:
4735                 owntype = sym.type;
4736                 if (owntype.hasTag(CLASS)) {
4737                     chk.checkForBadAuxiliaryClassAccess(tree.pos(), env, (ClassSymbol)sym);
4738                     Type ownOuter = owntype.getEnclosingType();
4739 
4740                     // (a) If the symbol's type is parameterized, erase it
4741                     // because no type parameters were given.
4742                     // We recover generic outer type later in visitTypeApply.
4743                     if (owntype.tsym.type.getTypeArguments().nonEmpty()) {
4744                         owntype = types.erasure(owntype);
4745                     }
4746 
4747                     // (b) If the symbol's type is an inner class, then
4748                     // we have to interpret its outer type as a superclass
4749                     // of the site type. Example:
4750                     //
4751                     // class Tree<A> { class Visitor { ... } }
4752                     // class PointTree extends Tree<Point> { ... }
4753                     // ...PointTree.Visitor...
4754                     //
4755                     // Then the type of the last expression above is
4756                     // Tree<Point>.Visitor.
4757                     else if ((ownOuter.hasTag(CLASS) || ownOuter.hasTag(TYPEVAR)) && site != ownOuter) {
4758                         Type normOuter = types.asEnclosingSuper(site, ownOuter.tsym);
4759                         if (normOuter == null) // perhaps from an import
4760                             normOuter = types.erasure(ownOuter);
4761                         if (normOuter != ownOuter)
4762                             owntype = new ClassType(
4763                                 normOuter, List.nil(), owntype.tsym,
4764                                 owntype.getMetadata());
4765                     }
4766                 }
4767                 break;
4768             case VAR:
4769                 VarSymbol v = (VarSymbol)sym;
4770 
4771                 if (env.info.enclVar != null
4772                         && v.type.hasTag(NONE)) {
4773                     //self reference to implicitly typed variable declaration
4774                     log.error(TreeInfo.positionFor(v, env.enclClass), Errors.CantInferLocalVarType(v.name, Fragments.LocalSelfRef));
4775                     return tree.type = v.type = types.createErrorType(v.type);
4776                 }
4777 
4778                 // Test (4): if symbol is an instance field of a raw type,
4779                 // which is being assigned to, issue an unchecked warning if
4780                 // its type changes under erasure.
4781                 if (KindSelector.ASG.subset(pkind()) &&
4782                     v.owner.kind == TYP &&
4783                     (v.flags() & STATIC) == 0 &&
4784                     (site.hasTag(CLASS) || site.hasTag(TYPEVAR))) {
4785                     Type s = types.asOuterSuper(site, v.owner);
4786                     if (s != null &&
4787                         s.isRaw() &&
4788                         !types.isSameType(v.type, v.erasure(types))) {
4789                         chk.warnUnchecked(tree.pos(), LintWarnings.UncheckedAssignToVar(v, s));
4790                     }
4791                 }
4792                 // The computed type of a variable is the type of the
4793                 // variable symbol, taken as a member of the site type.
4794                 owntype = (sym.owner.kind == TYP &&
4795                            sym.name != names._this && sym.name != names._super)
4796                     ? types.memberType(site, sym)
4797                     : sym.type;
4798 
4799                 // If the variable is a constant, record constant value in
4800                 // computed type.
4801                 if (v.getConstValue() != null && isStaticReference(tree))
4802                     owntype = owntype.constType(v.getConstValue());
4803 
4804                 if (resultInfo.pkind == KindSelector.VAL) {
4805                     owntype = capture(owntype); // capture "names as expressions"
4806                 }
4807                 break;
4808             case MTH: {
4809                 owntype = checkMethod(site, sym,
4810                         new ResultInfo(resultInfo.pkind, resultInfo.pt.getReturnType(), resultInfo.checkContext, resultInfo.checkMode),
4811                         env, TreeInfo.args(env.tree), resultInfo.pt.getParameterTypes(),
4812                         resultInfo.pt.getTypeArguments());
4813                 chk.checkRestricted(tree.pos(), sym);
4814                 break;
4815             }
4816             case PCK: case ERR:
4817                 owntype = sym.type;
4818                 break;
4819             default:
4820                 throw new AssertionError("unexpected kind: " + sym.kind +
4821                                          " in tree " + tree);
4822             }
4823 
4824             // Emit a `deprecation' warning if symbol is deprecated.
4825             // (for constructors (but not for constructor references), the error
4826             // was given when the constructor was resolved)
4827 
4828             if (sym.name != names.init || tree.hasTag(REFERENCE)) {
4829                 chk.checkDeprecated(tree.pos(), env.info.scope.owner, sym);
4830                 chk.checkSunAPI(tree.pos(), sym);
4831                 chk.checkProfile(tree.pos(), sym);
4832                 chk.checkPreview(tree.pos(), env.info.scope.owner, site, sym);
4833             }
4834 
4835             if (pt.isErroneous()) {
4836                 owntype = types.createErrorType(owntype);
4837             }
4838 
4839             // If symbol is a variable, check that its type and
4840             // kind are compatible with the prototype and protokind.
4841             return check(tree, owntype, sym.kind.toSelector(), resultInfo);
4842         }
4843 
4844         /** Check that variable is initialized and evaluate the variable's
4845          *  initializer, if not yet done. Also check that variable is not
4846          *  referenced before it is defined.
4847          *  @param tree    The tree making up the variable reference.
4848          *  @param env     The current environment.
4849          *  @param v       The variable's symbol.
4850          */
4851         private void checkInit(JCTree tree,
4852                                Env<AttrContext> env,
4853                                VarSymbol v,
4854                                boolean onlyWarning) {
4855             // A forward reference is diagnosed if the declaration position
4856             // of the variable is greater than the current tree position
4857             // and the tree and variable definition occur in the same class
4858             // definition.  Note that writes don't count as references.
4859             // This check applies only to class and instance
4860             // variables.  Local variables follow different scope rules,
4861             // and are subject to definite assignment checking.
4862             Env<AttrContext> initEnv = enclosingInitEnv(env);
4863             if (initEnv != null &&
4864                 (initEnv.info.enclVar == v || v.pos > tree.pos) &&
4865                 v.owner.kind == TYP &&
4866                 v.owner == env.info.scope.owner.enclClass() &&
4867                 ((v.flags() & STATIC) != 0) == Resolve.isStatic(env) &&
4868                 (!env.tree.hasTag(ASSIGN) ||
4869                  TreeInfo.skipParens(((JCAssign) env.tree).lhs) != tree)) {
4870                 if (!onlyWarning || isStaticEnumField(v)) {
4871                     Error errkey = (initEnv.info.enclVar == v) ?
4872                                 Errors.IllegalSelfRef : Errors.IllegalForwardRef;
4873                     log.error(tree.pos(), errkey);
4874                 } else if (useBeforeDeclarationWarning) {
4875                     Warning warnkey = (initEnv.info.enclVar == v) ?
4876                                 Warnings.SelfRef(v) : Warnings.ForwardRef(v);
4877                     log.warning(tree.pos(), warnkey);
4878                 }
4879             }
4880 
4881             v.getConstValue(); // ensure initializer is evaluated
4882 
4883             checkEnumInitializer(tree, env, v);
4884         }
4885 
4886         /**
4887          * Returns the enclosing init environment associated with this env (if any). An init env
4888          * can be either a field declaration env or a static/instance initializer env.
4889          */
4890         Env<AttrContext> enclosingInitEnv(Env<AttrContext> env) {
4891             while (true) {
4892                 switch (env.tree.getTag()) {
4893                     case VARDEF:
4894                         JCVariableDecl vdecl = (JCVariableDecl)env.tree;
4895                         if (vdecl.sym.owner.kind == TYP) {
4896                             //field
4897                             return env;
4898                         }
4899                         break;
4900                     case BLOCK:
4901                         if (env.next.tree.hasTag(CLASSDEF)) {
4902                             //instance/static initializer
4903                             return env;
4904                         }
4905                         break;
4906                     case METHODDEF:
4907                     case CLASSDEF:
4908                     case TOPLEVEL:
4909                         return null;
4910                 }
4911                 Assert.checkNonNull(env.next);
4912                 env = env.next;
4913             }
4914         }
4915 
4916         /**
4917          * Check for illegal references to static members of enum.  In
4918          * an enum type, constructors and initializers may not
4919          * reference its static members unless they are constant.
4920          *
4921          * @param tree    The tree making up the variable reference.
4922          * @param env     The current environment.
4923          * @param v       The variable's symbol.
4924          * @jls 8.9 Enum Types
4925          */
4926         private void checkEnumInitializer(JCTree tree, Env<AttrContext> env, VarSymbol v) {
4927             // JLS:
4928             //
4929             // "It is a compile-time error to reference a static field
4930             // of an enum type that is not a compile-time constant
4931             // (15.28) from constructors, instance initializer blocks,
4932             // or instance variable initializer expressions of that
4933             // type. It is a compile-time error for the constructors,
4934             // instance initializer blocks, or instance variable
4935             // initializer expressions of an enum constant e to refer
4936             // to itself or to an enum constant of the same type that
4937             // is declared to the right of e."
4938             if (isStaticEnumField(v)) {
4939                 ClassSymbol enclClass = env.info.scope.owner.enclClass();
4940 
4941                 if (enclClass == null || enclClass.owner == null)
4942                     return;
4943 
4944                 // See if the enclosing class is the enum (or a
4945                 // subclass thereof) declaring v.  If not, this
4946                 // reference is OK.
4947                 if (v.owner != enclClass && !types.isSubtype(enclClass.type, v.owner.type))
4948                     return;
4949 
4950                 // If the reference isn't from an initializer, then
4951                 // the reference is OK.
4952                 if (!Resolve.isInitializer(env))
4953                     return;
4954 
4955                 log.error(tree.pos(), Errors.IllegalEnumStaticRef);
4956             }
4957         }
4958 
4959         /** Is the given symbol a static, non-constant field of an Enum?
4960          *  Note: enum literals should not be regarded as such
4961          */
4962         private boolean isStaticEnumField(VarSymbol v) {
4963             return Flags.isEnum(v.owner) &&
4964                    Flags.isStatic(v) &&
4965                    !Flags.isConstant(v) &&
4966                    v.name != names._class;
4967         }
4968 
4969     /**
4970      * Check that method arguments conform to its instantiation.
4971      **/
4972     public Type checkMethod(Type site,
4973                             final Symbol sym,
4974                             ResultInfo resultInfo,
4975                             Env<AttrContext> env,
4976                             final List<JCExpression> argtrees,
4977                             List<Type> argtypes,
4978                             List<Type> typeargtypes) {
4979         // Test (5): if symbol is an instance method of a raw type, issue
4980         // an unchecked warning if its argument types change under erasure.
4981         if ((sym.flags() & STATIC) == 0 &&
4982             (site.hasTag(CLASS) || site.hasTag(TYPEVAR))) {
4983             Type s = types.asOuterSuper(site, sym.owner);
4984             if (s != null && s.isRaw() &&
4985                 !types.isSameTypes(sym.type.getParameterTypes(),
4986                                    sym.erasure(types).getParameterTypes())) {
4987                 chk.warnUnchecked(env.tree.pos(), LintWarnings.UncheckedCallMbrOfRawType(sym, s));
4988             }
4989         }
4990 
4991         if (env.info.defaultSuperCallSite != null) {
4992             for (Type sup : types.interfaces(env.enclClass.type).prepend(types.supertype((env.enclClass.type)))) {
4993                 if (!sup.tsym.isSubClass(sym.enclClass(), types) ||
4994                         types.isSameType(sup, env.info.defaultSuperCallSite)) continue;
4995                 List<MethodSymbol> icand_sup =
4996                         types.interfaceCandidates(sup, (MethodSymbol)sym);
4997                 if (icand_sup.nonEmpty() &&
4998                         icand_sup.head != sym &&
4999                         icand_sup.head.overrides(sym, icand_sup.head.enclClass(), types, true)) {
5000                     log.error(env.tree.pos(),
5001                               Errors.IllegalDefaultSuperCall(env.info.defaultSuperCallSite, Fragments.OverriddenDefault(sym, sup)));
5002                     break;
5003                 }
5004             }
5005             env.info.defaultSuperCallSite = null;
5006         }
5007 
5008         if (sym.isStatic() && site.isInterface() && env.tree.hasTag(APPLY)) {
5009             JCMethodInvocation app = (JCMethodInvocation)env.tree;
5010             if (app.meth.hasTag(SELECT) &&
5011                     !TreeInfo.isStaticSelector(((JCFieldAccess)app.meth).selected, names)) {
5012                 log.error(env.tree.pos(), Errors.IllegalStaticIntfMethCall(site));
5013             }
5014         }
5015 
5016         // Compute the identifier's instantiated type.
5017         // For methods, we need to compute the instance type by
5018         // Resolve.instantiate from the symbol's type as well as
5019         // any type arguments and value arguments.
5020         Warner noteWarner = new Warner();
5021         try {
5022             Type owntype = rs.checkMethod(
5023                     env,
5024                     site,
5025                     sym,
5026                     resultInfo,
5027                     argtypes,
5028                     typeargtypes,
5029                     noteWarner);
5030 
5031             DeferredAttr.DeferredTypeMap<Void> checkDeferredMap =
5032                 deferredAttr.new DeferredTypeMap<>(DeferredAttr.AttrMode.CHECK, sym, env.info.pendingResolutionPhase);
5033 
5034             argtypes = argtypes.map(checkDeferredMap);
5035 
5036             if (noteWarner.hasNonSilentLint(LintCategory.UNCHECKED)) {
5037                 chk.warnUnchecked(env.tree.pos(), LintWarnings.UncheckedMethInvocationApplied(kindName(sym),
5038                         sym.name,
5039                         rs.methodArguments(sym.type.getParameterTypes()),
5040                         rs.methodArguments(argtypes.map(checkDeferredMap)),
5041                         kindName(sym.location()),
5042                         sym.location()));
5043                 if (resultInfo.pt != Infer.anyPoly ||
5044                         !owntype.hasTag(METHOD) ||
5045                         !owntype.isPartial()) {
5046                     //if this is not a partially inferred method type, erase return type. Otherwise,
5047                     //erasure is carried out in PartiallyInferredMethodType.check().
5048                     owntype = new MethodType(owntype.getParameterTypes(),
5049                             types.erasure(owntype.getReturnType()),
5050                             types.erasure(owntype.getThrownTypes()),
5051                             syms.methodClass);
5052                 }
5053             }
5054 
5055             PolyKind pkind = (sym.type.hasTag(FORALL) &&
5056                  sym.type.getReturnType().containsAny(((ForAll)sym.type).tvars)) ?
5057                  PolyKind.POLY : PolyKind.STANDALONE;
5058             TreeInfo.setPolyKind(env.tree, pkind);
5059 
5060             return (resultInfo.pt == Infer.anyPoly) ?
5061                     owntype :
5062                     chk.checkMethod(owntype, sym, env, argtrees, argtypes, env.info.lastResolveVarargs(),
5063                             resultInfo.checkContext.inferenceContext());
5064         } catch (Infer.InferenceException ex) {
5065             //invalid target type - propagate exception outwards or report error
5066             //depending on the current check context
5067             resultInfo.checkContext.report(env.tree.pos(), ex.getDiagnostic());
5068             return types.createErrorType(site);
5069         } catch (Resolve.InapplicableMethodException ex) {
5070             final JCDiagnostic diag = ex.getDiagnostic();
5071             Resolve.InapplicableSymbolError errSym = rs.new InapplicableSymbolError(null) {
5072                 @Override
5073                 protected Pair<Symbol, JCDiagnostic> errCandidate() {
5074                     return new Pair<>(sym, diag);
5075                 }
5076             };
5077             List<Type> argtypes2 = argtypes.map(
5078                     rs.new ResolveDeferredRecoveryMap(AttrMode.CHECK, sym, env.info.pendingResolutionPhase));
5079             JCDiagnostic errDiag = errSym.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
5080                     env.tree, sym, site, sym.name, argtypes2, typeargtypes);
5081             log.report(errDiag);
5082             return types.createErrorType(site);
5083         }
5084     }
5085 
5086     public void visitLiteral(JCLiteral tree) {
5087         result = check(tree, litType(tree.typetag).constType(tree.value),
5088                 KindSelector.VAL, resultInfo);
5089     }
5090     //where
5091     /** Return the type of a literal with given type tag.
5092      */
5093     Type litType(TypeTag tag) {
5094         return (tag == CLASS) ? syms.stringType : syms.typeOfTag[tag.ordinal()];
5095     }
5096 
5097     public void visitTypeIdent(JCPrimitiveTypeTree tree) {
5098         result = check(tree, syms.typeOfTag[tree.typetag.ordinal()], KindSelector.TYP, resultInfo);
5099     }
5100 
5101     public void visitTypeArray(JCArrayTypeTree tree) {
5102         Type etype = attribType(tree.elemtype, env);
5103         Type type = new ArrayType(etype, syms.arrayClass);
5104         result = check(tree, type, KindSelector.TYP, resultInfo);
5105     }
5106 
5107     /** Visitor method for parameterized types.
5108      *  Bound checking is left until later, since types are attributed
5109      *  before supertype structure is completely known
5110      */
5111     public void visitTypeApply(JCTypeApply tree) {
5112         Type owntype = types.createErrorType(tree.type);
5113 
5114         // Attribute functor part of application and make sure it's a class.
5115         Type clazztype = chk.checkClassType(tree.clazz.pos(), attribType(tree.clazz, env));
5116 
5117         // Attribute type parameters
5118         List<Type> actuals = attribTypes(tree.arguments, env);
5119 
5120         if (clazztype.hasTag(CLASS)) {
5121             List<Type> formals = clazztype.tsym.type.getTypeArguments();
5122             if (actuals.isEmpty()) //diamond
5123                 actuals = formals;
5124 
5125             if (actuals.length() == formals.length()) {
5126                 List<Type> a = actuals;
5127                 List<Type> f = formals;
5128                 while (a.nonEmpty()) {
5129                     a.head = a.head.withTypeVar(f.head);
5130                     a = a.tail;
5131                     f = f.tail;
5132                 }
5133                 // Compute the proper generic outer
5134                 Type clazzOuter = clazztype.getEnclosingType();
5135                 if (clazzOuter.hasTag(CLASS)) {
5136                     Type site;
5137                     JCExpression clazz = TreeInfo.typeIn(tree.clazz);
5138                     if (clazz.hasTag(IDENT)) {
5139                         site = env.enclClass.sym.type;
5140                     } else if (clazz.hasTag(SELECT)) {
5141                         site = ((JCFieldAccess) clazz).selected.type;
5142                     } else throw new AssertionError(""+tree);
5143                     if (clazzOuter.hasTag(CLASS) && site != clazzOuter) {
5144                         if (site.hasTag(CLASS) || site.hasTag(TYPEVAR))
5145                             site = types.asEnclosingSuper(site, clazzOuter.tsym);
5146                         if (site == null)
5147                             site = types.erasure(clazzOuter);
5148                         clazzOuter = site;
5149                     }
5150                 }
5151                 owntype = new ClassType(clazzOuter, actuals, clazztype.tsym,
5152                                         clazztype.getMetadata());
5153             } else {
5154                 if (formals.length() != 0) {
5155                     log.error(tree.pos(),
5156                               Errors.WrongNumberTypeArgs(Integer.toString(formals.length())));
5157                 } else {
5158                     log.error(tree.pos(), Errors.TypeDoesntTakeParams(clazztype.tsym));
5159                 }
5160                 owntype = types.createErrorType(tree.type);
5161             }
5162         } else if (clazztype.hasTag(ERROR)) {
5163             ErrorType parameterizedErroneous =
5164                     new ErrorType(clazztype.getOriginalType(),
5165                                   clazztype.tsym,
5166                                   clazztype.getMetadata());
5167 
5168             parameterizedErroneous.typarams_field = actuals;
5169             owntype = parameterizedErroneous;
5170         }
5171         result = check(tree, owntype, KindSelector.TYP, resultInfo);
5172     }
5173 
5174     public void visitTypeUnion(JCTypeUnion tree) {
5175         ListBuffer<Type> multicatchTypes = new ListBuffer<>();
5176         ListBuffer<Type> all_multicatchTypes = null; // lazy, only if needed
5177         for (JCExpression typeTree : tree.alternatives) {
5178             Type ctype = attribType(typeTree, env);
5179             ctype = chk.checkType(typeTree.pos(),
5180                           chk.checkClassType(typeTree.pos(), ctype),
5181                           syms.throwableType,
5182                           chk.subtypeHandler);
5183             if (!ctype.isErroneous()) {
5184                 //check that alternatives of a union type are pairwise
5185                 //unrelated w.r.t. subtyping
5186                 if (chk.intersects(ctype,  multicatchTypes.toList())) {
5187                     for (Type t : multicatchTypes) {
5188                         boolean sub = types.isSubtype(ctype, t);
5189                         boolean sup = types.isSubtype(t, ctype);
5190                         if (sub || sup) {
5191                             //assume 'a' <: 'b'
5192                             Type a = sub ? ctype : t;
5193                             Type b = sub ? t : ctype;
5194                             log.error(typeTree.pos(), Errors.MulticatchTypesMustBeDisjoint(a, b));
5195                         }
5196                     }
5197                 }
5198                 multicatchTypes.append(ctype);
5199                 if (all_multicatchTypes != null)
5200                     all_multicatchTypes.append(ctype);
5201             } else {
5202                 if (all_multicatchTypes == null) {
5203                     all_multicatchTypes = new ListBuffer<>();
5204                     all_multicatchTypes.appendList(multicatchTypes);
5205                 }
5206                 all_multicatchTypes.append(ctype);
5207             }
5208         }
5209         Type t = check(tree, types.lub(multicatchTypes.toList()),
5210                 KindSelector.TYP, resultInfo.dup(CheckMode.NO_TREE_UPDATE));
5211         if (t.hasTag(CLASS)) {
5212             List<Type> alternatives =
5213                 ((all_multicatchTypes == null) ? multicatchTypes : all_multicatchTypes).toList();
5214             t = new UnionClassType((ClassType) t, alternatives);
5215         }
5216         tree.type = result = t;
5217     }
5218 
5219     public void visitTypeIntersection(JCTypeIntersection tree) {
5220         attribTypes(tree.bounds, env);
5221         tree.type = result = checkIntersection(tree, tree.bounds);
5222     }
5223 
5224     public void visitTypeParameter(JCTypeParameter tree) {
5225         TypeVar typeVar = (TypeVar) tree.type;
5226 
5227         if (tree.annotations != null && tree.annotations.nonEmpty()) {
5228             annotate.annotateTypeParameterSecondStage(tree, tree.annotations);
5229         }
5230 
5231         if (!typeVar.getUpperBound().isErroneous()) {
5232             //fixup type-parameter bound computed in 'attribTypeVariables'
5233             typeVar.setUpperBound(checkIntersection(tree, tree.bounds));
5234         }
5235     }
5236 
5237     Type checkIntersection(JCTree tree, List<JCExpression> bounds) {
5238         Set<Symbol> boundSet = new HashSet<>();
5239         if (bounds.nonEmpty()) {
5240             // accept class or interface or typevar as first bound.
5241             bounds.head.type = checkBase(bounds.head.type, bounds.head, env, false, false, false);
5242             boundSet.add(types.erasure(bounds.head.type).tsym);
5243             if (bounds.head.type.isErroneous()) {
5244                 return bounds.head.type;
5245             }
5246             else if (bounds.head.type.hasTag(TYPEVAR)) {
5247                 // if first bound was a typevar, do not accept further bounds.
5248                 if (bounds.tail.nonEmpty()) {
5249                     log.error(bounds.tail.head.pos(),
5250                               Errors.TypeVarMayNotBeFollowedByOtherBounds);
5251                     return bounds.head.type;
5252                 }
5253             } else {
5254                 // if first bound was a class or interface, accept only interfaces
5255                 // as further bounds.
5256                 for (JCExpression bound : bounds.tail) {
5257                     bound.type = checkBase(bound.type, bound, env, false, true, false);
5258                     if (bound.type.isErroneous()) {
5259                         bounds = List.of(bound);
5260                     }
5261                     else if (bound.type.hasTag(CLASS)) {
5262                         chk.checkNotRepeated(bound.pos(), types.erasure(bound.type), boundSet);
5263                     }
5264                 }
5265             }
5266         }
5267 
5268         if (bounds.length() == 0) {
5269             return syms.objectType;
5270         } else if (bounds.length() == 1) {
5271             return bounds.head.type;
5272         } else {
5273             Type owntype = types.makeIntersectionType(TreeInfo.types(bounds));
5274             // ... the variable's bound is a class type flagged COMPOUND
5275             // (see comment for TypeVar.bound).
5276             // In this case, generate a class tree that represents the
5277             // bound class, ...
5278             JCExpression extending;
5279             List<JCExpression> implementing;
5280             if (!bounds.head.type.isInterface()) {
5281                 extending = bounds.head;
5282                 implementing = bounds.tail;
5283             } else {
5284                 extending = null;
5285                 implementing = bounds;
5286             }
5287             JCClassDecl cd = make.at(tree).ClassDef(
5288                 make.Modifiers(PUBLIC | ABSTRACT),
5289                 names.empty, List.nil(),
5290                 extending, implementing, List.nil());
5291 
5292             ClassSymbol c = (ClassSymbol)owntype.tsym;
5293             Assert.check((c.flags() & COMPOUND) != 0);
5294             cd.sym = c;
5295             c.sourcefile = env.toplevel.sourcefile;
5296 
5297             // ... and attribute the bound class
5298             c.flags_field |= UNATTRIBUTED;
5299             Env<AttrContext> cenv = enter.classEnv(cd, env);
5300             typeEnvs.put(c, cenv);
5301             attribClass(c);
5302             return owntype;
5303         }
5304     }
5305 
5306     public void visitWildcard(JCWildcard tree) {
5307         //- System.err.println("visitWildcard("+tree+");");//DEBUG
5308         Type type = (tree.kind.kind == BoundKind.UNBOUND)
5309             ? syms.objectType
5310             : attribType(tree.inner, env);
5311         result = check(tree, new WildcardType(chk.checkRefType(tree.pos(), type),
5312                                               tree.kind.kind,
5313                                               syms.boundClass),
5314                 KindSelector.TYP, resultInfo);
5315     }
5316 
5317     public void visitAnnotation(JCAnnotation tree) {
5318         Assert.error("should be handled in annotate");
5319     }
5320 
5321     @Override
5322     public void visitModifiers(JCModifiers tree) {
5323         //error recovery only:
5324         Assert.check(resultInfo.pkind == KindSelector.ERR);
5325 
5326         attribAnnotationTypes(tree.annotations, env);
5327     }
5328 
5329     public void visitAnnotatedType(JCAnnotatedType tree) {
5330         attribAnnotationTypes(tree.annotations, env);
5331         Type underlyingType = attribTree(tree.underlyingType, env, resultInfo);
5332         if (underlyingType.getTag() == PACKAGE || underlyingType.getTag() == VOID) {
5333             result = tree.type = underlyingType;
5334         } else {
5335             Type annotatedType = underlyingType.preannotatedType();
5336 
5337             annotate.annotateTypeSecondStage(tree, tree.annotations, annotatedType);
5338             result = tree.type = annotatedType;
5339         }
5340     }
5341 
5342     public void visitErroneous(JCErroneous tree) {
5343         if (tree.errs != null) {
5344             WriteableScope newScope = env.info.scope;
5345 
5346             if (env.tree instanceof JCClassDecl) {
5347                 Symbol fakeOwner =
5348                     new MethodSymbol(BLOCK, names.empty, null,
5349                         env.info.scope.owner);
5350                 newScope = newScope.dupUnshared(fakeOwner);
5351             }
5352 
5353             Env<AttrContext> errEnv =
5354                     env.dup(env.tree,
5355                             env.info.dup(newScope));
5356             errEnv.info.returnResult = unknownExprInfo;
5357             for (JCTree err : tree.errs)
5358                 attribTree(err, errEnv, new ResultInfo(KindSelector.ERR, pt()));
5359         }
5360         result = tree.type = syms.errType;
5361     }
5362 
5363     /** Default visitor method for all other trees.
5364      */
5365     public void visitTree(JCTree tree) {
5366         throw new AssertionError();
5367     }
5368 
5369     /**
5370      * Attribute an env for either a top level tree or class or module declaration.
5371      */
5372     public void attrib(Env<AttrContext> env) {
5373         switch (env.tree.getTag()) {
5374             case MODULEDEF:
5375                 attribModule(env.tree.pos(), ((JCModuleDecl)env.tree).sym);
5376                 break;
5377             case PACKAGEDEF:
5378                 attribPackage(env.tree.pos(), ((JCPackageDecl) env.tree).packge);
5379                 break;
5380             default:
5381                 attribClass(env.tree.pos(), env.enclClass.sym);
5382         }
5383 
5384         annotate.flush();
5385 
5386         // Now that this tree is attributed, we can calculate the Lint configuration everywhere within it
5387         lintMapper.calculateLints(env.toplevel.sourcefile, env.tree);
5388     }
5389 
5390     public void attribPackage(DiagnosticPosition pos, PackageSymbol p) {
5391         try {
5392             annotate.flush();
5393             attribPackage(p);
5394         } catch (CompletionFailure ex) {
5395             chk.completionError(pos, ex);
5396         }
5397     }
5398 
5399     void attribPackage(PackageSymbol p) {
5400         attribWithLint(p,
5401                        env -> chk.checkDeprecatedAnnotation(((JCPackageDecl) env.tree).pid.pos(), p));
5402     }
5403 
5404     public void attribModule(DiagnosticPosition pos, ModuleSymbol m) {
5405         try {
5406             annotate.flush();
5407             attribModule(m);
5408         } catch (CompletionFailure ex) {
5409             chk.completionError(pos, ex);
5410         }
5411     }
5412 
5413     void attribModule(ModuleSymbol m) {
5414         attribWithLint(m, env -> attribStat(env.tree, env));
5415     }
5416 
5417     private void attribWithLint(TypeSymbol sym, Consumer<Env<AttrContext>> attrib) {
5418         Env<AttrContext> env = typeEnvs.get(sym);
5419 
5420         Env<AttrContext> lintEnv = env;
5421         while (lintEnv.info.lint == null)
5422             lintEnv = lintEnv.next;
5423 
5424         Lint lint = lintEnv.info.lint.augment(sym);
5425 
5426         Lint prevLint = chk.setLint(lint);
5427         JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
5428 
5429         try {
5430             attrib.accept(env);
5431         } finally {
5432             log.useSource(prev);
5433             chk.setLint(prevLint);
5434         }
5435     }
5436 
5437     /** Main method: attribute class definition associated with given class symbol.
5438      *  reporting completion failures at the given position.
5439      *  @param pos The source position at which completion errors are to be
5440      *             reported.
5441      *  @param c   The class symbol whose definition will be attributed.
5442      */
5443     public void attribClass(DiagnosticPosition pos, ClassSymbol c) {
5444         try {
5445             annotate.flush();
5446             attribClass(c);
5447         } catch (CompletionFailure ex) {
5448             chk.completionError(pos, ex);
5449         }
5450     }
5451 
5452     /** Attribute class definition associated with given class symbol.
5453      *  @param c   The class symbol whose definition will be attributed.
5454      */
5455     void attribClass(ClassSymbol c) throws CompletionFailure {
5456         if (c.type.hasTag(ERROR)) return;
5457 
5458         // Check for cycles in the inheritance graph, which can arise from
5459         // ill-formed class files.
5460         chk.checkNonCyclic(null, c.type);
5461 
5462         Type st = types.supertype(c.type);
5463         if ((c.flags_field & Flags.COMPOUND) == 0 &&
5464             (c.flags_field & Flags.SUPER_OWNER_ATTRIBUTED) == 0 &&
5465             breakTree == null) {
5466             // First, attribute superclass.
5467             if (st.hasTag(CLASS))
5468                 attribClass((ClassSymbol)st.tsym);
5469 
5470             // Next attribute owner, if it is a class.
5471             if (c.owner.kind == TYP && c.owner.type.hasTag(CLASS))
5472                 attribClass((ClassSymbol)c.owner);
5473 
5474             c.flags_field |= Flags.SUPER_OWNER_ATTRIBUTED;
5475         }
5476 
5477         // The previous operations might have attributed the current class
5478         // if there was a cycle. So we test first whether the class is still
5479         // UNATTRIBUTED.
5480         if ((c.flags_field & UNATTRIBUTED) != 0) {
5481             c.flags_field &= ~UNATTRIBUTED;
5482 
5483             // Get environment current at the point of class definition.
5484             Env<AttrContext> env = typeEnvs.get(c);
5485 
5486             // The info.lint field in the envs stored in typeEnvs is deliberately uninitialized,
5487             // because the annotations were not available at the time the env was created. Therefore,
5488             // we look up the environment chain for the first enclosing environment for which the
5489             // lint value is set. Typically, this is the parent env, but might be further if there
5490             // are any envs created as a result of TypeParameter nodes.
5491             Env<AttrContext> lintEnv = env;
5492             while (lintEnv.info.lint == null)
5493                 lintEnv = lintEnv.next;
5494 
5495             // Having found the enclosing lint value, we can initialize the lint value for this class
5496             env.info.lint = lintEnv.info.lint.augment(c);
5497 
5498             Lint prevLint = chk.setLint(env.info.lint);
5499             JavaFileObject prev = log.useSource(c.sourcefile);
5500             ResultInfo prevReturnRes = env.info.returnResult;
5501 
5502             try {
5503                 if (c.isSealed() &&
5504                         !c.isEnum() &&
5505                         !c.isPermittedExplicit &&
5506                         c.getPermittedSubclasses().isEmpty()) {
5507                     log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.SealedClassMustHaveSubclasses);
5508                 }
5509 
5510                 if (c.isSealed()) {
5511                     Set<Symbol> permittedTypes = new HashSet<>();
5512                     boolean sealedInUnnamed = c.packge().modle == syms.unnamedModule || c.packge().modle == syms.noModule;
5513                     for (Type subType : c.getPermittedSubclasses()) {
5514                         if (subType.isErroneous()) {
5515                             // the type already caused errors, don't produce more potentially misleading errors
5516                             continue;
5517                         }
5518                         boolean isTypeVar = false;
5519                         if (subType.getTag() == TYPEVAR) {
5520                             isTypeVar = true; //error recovery
5521                             log.error(TreeInfo.diagnosticPositionFor(subType.tsym, env.tree),
5522                                     Errors.InvalidPermitsClause(Fragments.IsATypeVariable(subType)));
5523                         }
5524                         if (subType.tsym.isAnonymous() && !c.isEnum()) {
5525                             log.error(TreeInfo.diagnosticPositionFor(subType.tsym, env.tree),  Errors.LocalClassesCantExtendSealed(Fragments.Anonymous));
5526                         }
5527                         if (permittedTypes.contains(subType.tsym)) {
5528                             DiagnosticPosition pos =
5529                                     env.enclClass.permitting.stream()
5530                                             .filter(permittedExpr -> TreeInfo.diagnosticPositionFor(subType.tsym, permittedExpr, true) != null)
5531                                             .limit(2).collect(List.collector()).get(1);
5532                             log.error(pos, Errors.InvalidPermitsClause(Fragments.IsDuplicated(subType)));
5533                         } else {
5534                             permittedTypes.add(subType.tsym);
5535                         }
5536                         if (sealedInUnnamed) {
5537                             if (subType.tsym.packge() != c.packge()) {
5538                                 log.error(TreeInfo.diagnosticPositionFor(subType.tsym, env.tree),
5539                                         Errors.ClassInUnnamedModuleCantExtendSealedInDiffPackage(c)
5540                                 );
5541                             }
5542                         } else if (subType.tsym.packge().modle != c.packge().modle) {
5543                             log.error(TreeInfo.diagnosticPositionFor(subType.tsym, env.tree),
5544                                     Errors.ClassInModuleCantExtendSealedInDiffModule(c, c.packge().modle)
5545                             );
5546                         }
5547                         if (subType.tsym == c.type.tsym || types.isSuperType(subType, c.type)) {
5548                             log.error(TreeInfo.diagnosticPositionFor(subType.tsym, ((JCClassDecl)env.tree).permitting),
5549                                     Errors.InvalidPermitsClause(
5550                                             subType.tsym == c.type.tsym ?
5551                                                     Fragments.MustNotBeSameClass :
5552                                                     Fragments.MustNotBeSupertype(subType)
5553                                     )
5554                             );
5555                         } else if (!isTypeVar) {
5556                             boolean thisIsASuper = types.directSupertypes(subType)
5557                                                         .stream()
5558                                                         .anyMatch(d -> d.tsym == c);
5559                             if (!thisIsASuper) {
5560                                 if(c.isInterface()) {
5561                                     log.error(TreeInfo.diagnosticPositionFor(subType.tsym, env.tree),
5562                                             Errors.InvalidPermitsClause(Fragments.DoesntImplementSealed(kindName(subType.tsym), subType)));
5563                                 } else {
5564                                     log.error(TreeInfo.diagnosticPositionFor(subType.tsym, env.tree),
5565                                             Errors.InvalidPermitsClause(Fragments.DoesntExtendSealed(subType)));
5566                                 }
5567                             }
5568                         }
5569                     }
5570                 }
5571 
5572                 List<ClassSymbol> sealedSupers = types.directSupertypes(c.type)
5573                                                       .stream()
5574                                                       .filter(s -> s.tsym.isSealed())
5575                                                       .map(s -> (ClassSymbol) s.tsym)
5576                                                       .collect(List.collector());
5577 
5578                 if (sealedSupers.isEmpty()) {
5579                     if ((c.flags_field & Flags.NON_SEALED) != 0) {
5580                         boolean hasErrorSuper = false;
5581 
5582                         hasErrorSuper |= types.directSupertypes(c.type)
5583                                               .stream()
5584                                               .anyMatch(s -> s.tsym.kind == Kind.ERR);
5585 
5586                         ClassType ct = (ClassType) c.type;
5587 
5588                         hasErrorSuper |= !ct.isCompound() && ct.interfaces_field != ct.all_interfaces_field;
5589 
5590                         if (!hasErrorSuper) {
5591                             log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.NonSealedWithNoSealedSupertype(c));
5592                         }
5593                     }
5594                 } else {
5595                     if (c.isDirectlyOrIndirectlyLocal() && !c.isEnum()) {
5596                         log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.LocalClassesCantExtendSealed(c.isAnonymous() ? Fragments.Anonymous : Fragments.Local));
5597                     }
5598 
5599                     if (!c.type.isCompound()) {
5600                         for (ClassSymbol supertypeSym : sealedSupers) {
5601                             if (!supertypeSym.isPermittedSubclass(c.type.tsym)) {
5602                                 log.error(TreeInfo.diagnosticPositionFor(c.type.tsym, env.tree), Errors.CantInheritFromSealed(supertypeSym));
5603                             }
5604                         }
5605                         if (!c.isNonSealed() && !c.isFinal() && !c.isSealed()) {
5606                             log.error(TreeInfo.diagnosticPositionFor(c, env.tree),
5607                                     c.isInterface() ?
5608                                             Errors.NonSealedOrSealedExpected :
5609                                             Errors.NonSealedSealedOrFinalExpected);
5610                         }
5611                     }
5612                 }
5613 
5614                 env.info.returnResult = null;
5615                 // java.lang.Enum may not be subclassed by a non-enum
5616                 if (st.tsym == syms.enumSym &&
5617                     ((c.flags_field & (Flags.ENUM|Flags.COMPOUND)) == 0))
5618                     log.error(env.tree.pos(), Errors.EnumNoSubclassing);
5619 
5620                 // Enums may not be extended by source-level classes
5621                 if (st.tsym != null &&
5622                     ((st.tsym.flags_field & Flags.ENUM) != 0) &&
5623                     ((c.flags_field & (Flags.ENUM | Flags.COMPOUND)) == 0)) {
5624                     log.error(env.tree.pos(), Errors.EnumTypesNotExtensible);
5625                 }
5626 
5627                 if (rs.isSerializable(c.type)) {
5628                     env.info.isSerializable = true;
5629                 }
5630 
5631                 attribClassBody(env, c);
5632 
5633                 chk.checkDeprecatedAnnotation(env.tree.pos(), c);
5634                 chk.checkClassOverrideEqualsAndHashIfNeeded(env.tree.pos(), c);
5635                 chk.checkFunctionalInterface((JCClassDecl) env.tree, c);
5636                 chk.checkLeaksNotAccessible(env, (JCClassDecl) env.tree);
5637 
5638                 if (c.isImplicit()) {
5639                     chk.checkHasMain(env.tree.pos(), c);
5640                 }
5641             } finally {
5642                 env.info.returnResult = prevReturnRes;
5643                 log.useSource(prev);
5644                 chk.setLint(prevLint);
5645             }
5646 
5647         }
5648     }
5649 
5650     public void visitImport(JCImport tree) {
5651         // nothing to do
5652     }
5653 
5654     public void visitModuleDef(JCModuleDecl tree) {
5655         tree.sym.completeUsesProvides();
5656         ModuleSymbol msym = tree.sym;
5657         Lint lint = env.outer.info.lint = env.outer.info.lint.augment(msym);
5658         Lint prevLint = chk.setLint(lint);
5659         try {
5660             chk.checkModuleName(tree);
5661             chk.checkDeprecatedAnnotation(tree, msym);
5662         } finally {
5663             chk.setLint(prevLint);
5664         }
5665     }
5666 
5667     /** Finish the attribution of a class. */
5668     private void attribClassBody(Env<AttrContext> env, ClassSymbol c) {
5669         JCClassDecl tree = (JCClassDecl)env.tree;
5670         Assert.check(c == tree.sym);
5671 
5672         // Validate type parameters, supertype and interfaces.
5673         attribStats(tree.typarams, env);
5674         if (!c.isAnonymous()) {
5675             //already checked if anonymous
5676             chk.validate(tree.typarams, env);
5677             chk.validate(tree.extending, env);
5678             chk.validate(tree.implementing, env);
5679         }
5680 
5681         chk.checkRequiresIdentity(tree, env.info.lint);
5682 
5683         c.markAbstractIfNeeded(types);
5684 
5685         // If this is a non-abstract class, check that it has no abstract
5686         // methods or unimplemented methods of an implemented interface.
5687         if ((c.flags() & (ABSTRACT | INTERFACE)) == 0) {
5688             chk.checkAllDefined(tree.pos(), c);
5689         }
5690 
5691         if ((c.flags() & ANNOTATION) != 0) {
5692             if (tree.implementing.nonEmpty())
5693                 log.error(tree.implementing.head.pos(),
5694                           Errors.CantExtendIntfAnnotation);
5695             if (tree.typarams.nonEmpty()) {
5696                 log.error(tree.typarams.head.pos(),
5697                           Errors.IntfAnnotationCantHaveTypeParams(c));
5698             }
5699 
5700             // If this annotation type has a @Repeatable, validate
5701             Attribute.Compound repeatable = c.getAnnotationTypeMetadata().getRepeatable();
5702             // If this annotation type has a @Repeatable, validate
5703             if (repeatable != null) {
5704                 // get diagnostic position for error reporting
5705                 DiagnosticPosition cbPos = getDiagnosticPosition(tree, repeatable.type);
5706                 Assert.checkNonNull(cbPos);
5707 
5708                 chk.validateRepeatable(c, repeatable, cbPos);
5709             }
5710         } else {
5711             try {
5712                 // Check that all extended classes and interfaces
5713                 // are compatible (i.e. no two define methods with same arguments
5714                 // yet different return types).  (JLS 8.4.8.3)
5715                 chk.checkCompatibleSupertypes(tree.pos(), c.type);
5716                 chk.checkDefaultMethodClashes(tree.pos(), c.type);
5717                 chk.checkPotentiallyAmbiguousOverloads(tree, c.type);
5718             } catch (CompletionFailure cf) {
5719                 chk.completionError(tree.pos(), cf);
5720             }
5721         }
5722 
5723         // Check that class does not import the same parameterized interface
5724         // with two different argument lists.
5725         chk.checkClassBounds(tree.pos(), c.type);
5726 
5727         tree.type = c.type;
5728 
5729         for (List<JCTypeParameter> l = tree.typarams;
5730              l.nonEmpty(); l = l.tail) {
5731              Assert.checkNonNull(env.info.scope.findFirst(l.head.name));
5732         }
5733 
5734         // Check that a generic class doesn't extend Throwable
5735         if (!c.type.allparams().isEmpty() && types.isSubtype(c.type, syms.throwableType))
5736             log.error(tree.extending.pos(), Errors.GenericThrowable);
5737 
5738         // Check that all methods which implement some
5739         // method conform to the method they implement.
5740         chk.checkImplementations(tree);
5741 
5742         //check that a resource implementing AutoCloseable cannot throw InterruptedException
5743         checkAutoCloseable(env, tree, false);
5744 
5745         for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
5746             // Attribute declaration
5747             attribStat(l.head, env);
5748             // Check that declarations in inner classes are not static (JLS 8.1.2)
5749             // Make an exception for static constants.
5750             if (!allowRecords &&
5751                     c.owner.kind != PCK &&
5752                     ((c.flags() & STATIC) == 0 || c.name == names.empty) &&
5753                     (TreeInfo.flags(l.head) & (STATIC | INTERFACE)) != 0) {
5754                 VarSymbol sym = null;
5755                 if (l.head.hasTag(VARDEF)) sym = ((JCVariableDecl) l.head).sym;
5756                 if (sym == null ||
5757                         sym.kind != VAR ||
5758                         sym.getConstValue() == null)
5759                     log.error(l.head.pos(), Errors.IclsCantHaveStaticDecl(c));
5760             }
5761         }
5762 
5763         // Check for proper placement of super()/this() calls.
5764         chk.checkSuperInitCalls(tree);
5765 
5766         // Check for cycles among non-initial constructors.
5767         chk.checkCyclicConstructors(tree);
5768 
5769         // Check for cycles among annotation elements.
5770         chk.checkNonCyclicElements(tree);
5771 
5772         // Check for proper use of serialVersionUID and other
5773         // serialization-related fields and methods
5774         if (env.info.lint.isEnabled(LintCategory.SERIAL)
5775                 && rs.isSerializable(c.type)
5776                 && !c.isAnonymous()) {
5777             chk.checkSerialStructure(env, tree, c);
5778         }
5779         // Correctly organize the positions of the type annotations
5780         typeAnnotations.organizeTypeAnnotationsBodies(tree);
5781 
5782         // Check type annotations applicability rules
5783         validateTypeAnnotations(tree, false);
5784     }
5785         // where
5786         /** get a diagnostic position for an attribute of Type t, or null if attribute missing */
5787         private DiagnosticPosition getDiagnosticPosition(JCClassDecl tree, Type t) {
5788             for(List<JCAnnotation> al = tree.mods.annotations; !al.isEmpty(); al = al.tail) {
5789                 if (types.isSameType(al.head.annotationType.type, t))
5790                     return al.head.pos();
5791             }
5792 
5793             return null;
5794         }
5795 
5796     private Type capture(Type type) {
5797         return types.capture(type);
5798     }
5799 
5800     private void setupImplicitlyTypedVariable(JCVariableDecl tree, Type type) {
5801         Assert.check(tree.isImplicitlyTyped());
5802 
5803         type.complete();
5804 
5805         if (tree.vartype == null) {
5806             return ;
5807         }
5808 
5809         Assert.check(tree.vartype.hasTag(VARTYPE));
5810 
5811         JCVarType vartype = (JCVarType) tree.vartype;
5812 
5813         vartype.type = type;
5814     }
5815 
5816     public void validateTypeAnnotations(JCTree tree, boolean sigOnly) {
5817         tree.accept(new TypeAnnotationsValidator(sigOnly));
5818     }
5819     //where
5820     private final class TypeAnnotationsValidator extends TreeScanner {
5821 
5822         private final boolean sigOnly;
5823         public TypeAnnotationsValidator(boolean sigOnly) {
5824             this.sigOnly = sigOnly;
5825         }
5826 
5827         public void visitAnnotation(JCAnnotation tree) {
5828             chk.validateTypeAnnotation(tree, null, false);
5829             super.visitAnnotation(tree);
5830         }
5831         public void visitAnnotatedType(JCAnnotatedType tree) {
5832             if (!tree.underlyingType.type.isErroneous()) {
5833                 super.visitAnnotatedType(tree);
5834             }
5835         }
5836         public void visitTypeParameter(JCTypeParameter tree) {
5837             chk.validateTypeAnnotations(tree.annotations, tree.type.tsym, true);
5838             scan(tree.bounds);
5839             // Don't call super.
5840             // This is needed because above we call validateTypeAnnotation with
5841             // false, which would forbid annotations on type parameters.
5842             // super.visitTypeParameter(tree);
5843         }
5844         public void visitMethodDef(JCMethodDecl tree) {
5845             if (tree.recvparam != null &&
5846                     !tree.recvparam.vartype.type.isErroneous()) {
5847                 checkForDeclarationAnnotations(tree.recvparam.mods.annotations, tree.recvparam.sym);
5848             }
5849             if (tree.restype != null && tree.restype.type != null) {
5850                 validateAnnotatedType(tree.restype, tree.restype.type);
5851             }
5852             if (sigOnly) {
5853                 scan(tree.mods);
5854                 scan(tree.restype);
5855                 scan(tree.typarams);
5856                 scan(tree.recvparam);
5857                 scan(tree.params);
5858                 scan(tree.thrown);
5859             } else {
5860                 scan(tree.defaultValue);
5861                 scan(tree.body);
5862             }
5863         }
5864         public void visitVarDef(final JCVariableDecl tree) {
5865             //System.err.println("validateTypeAnnotations.visitVarDef " + tree);
5866             if (tree.sym != null && tree.sym.type != null && !tree.isImplicitlyTyped())
5867                 validateAnnotatedType(tree.vartype, tree.sym.type);
5868             scan(tree.mods);
5869             scan(tree.vartype);
5870             if (!sigOnly) {
5871                 scan(tree.init);
5872             }
5873         }
5874         public void visitTypeCast(JCTypeCast tree) {
5875             if (tree.clazz != null && tree.clazz.type != null)
5876                 validateAnnotatedType(tree.clazz, tree.clazz.type);
5877             super.visitTypeCast(tree);
5878         }
5879         public void visitTypeTest(JCInstanceOf tree) {
5880             if (tree.pattern != null && !(tree.pattern instanceof JCPattern) && tree.pattern.type != null)
5881                 validateAnnotatedType(tree.pattern, tree.pattern.type);
5882             super.visitTypeTest(tree);
5883         }
5884         public void visitNewClass(JCNewClass tree) {
5885             if (tree.clazz != null && tree.clazz.type != null) {
5886                 if (tree.clazz.hasTag(ANNOTATED_TYPE)) {
5887                     checkForDeclarationAnnotations(((JCAnnotatedType) tree.clazz).annotations,
5888                             tree.clazz.type.tsym);
5889                 }
5890                 if (tree.def != null) {
5891                     checkForDeclarationAnnotations(tree.def.mods.annotations, tree.clazz.type.tsym);
5892                 }
5893 
5894                 validateAnnotatedType(tree.clazz, tree.clazz.type);
5895             }
5896             super.visitNewClass(tree);
5897         }
5898         public void visitNewArray(JCNewArray tree) {
5899             if (tree.elemtype != null && tree.elemtype.type != null) {
5900                 if (tree.elemtype.hasTag(ANNOTATED_TYPE)) {
5901                     checkForDeclarationAnnotations(((JCAnnotatedType) tree.elemtype).annotations,
5902                             tree.elemtype.type.tsym);
5903                 }
5904                 validateAnnotatedType(tree.elemtype, tree.elemtype.type);
5905             }
5906             super.visitNewArray(tree);
5907         }
5908         public void visitClassDef(JCClassDecl tree) {
5909             //System.err.println("validateTypeAnnotations.visitClassDef " + tree);
5910             if (sigOnly) {
5911                 scan(tree.mods);
5912                 scan(tree.typarams);
5913                 scan(tree.extending);
5914                 scan(tree.implementing);
5915             }
5916             for (JCTree member : tree.defs) {
5917                 if (member.hasTag(Tag.CLASSDEF)) {
5918                     continue;
5919                 }
5920                 scan(member);
5921             }
5922         }
5923         public void visitBlock(JCBlock tree) {
5924             if (!sigOnly) {
5925                 scan(tree.stats);
5926             }
5927         }
5928 
5929         /* I would want to model this after
5930          * com.sun.tools.javac.comp.Check.Validator.visitSelectInternal(JCFieldAccess)
5931          * and override visitSelect and visitTypeApply.
5932          * However, we only set the annotated type in the top-level type
5933          * of the symbol.
5934          * Therefore, we need to override each individual location where a type
5935          * can occur.
5936          */
5937         private void validateAnnotatedType(final JCTree errtree, final Type type) {
5938             //System.err.println("Attr.validateAnnotatedType: " + errtree + " type: " + type);
5939 
5940             if (type.isPrimitiveOrVoid()) {
5941                 return;
5942             }
5943 
5944             JCTree enclTr = errtree;
5945             Type enclTy = type;
5946 
5947             boolean repeat = true;
5948             while (repeat) {
5949                 if (enclTr.hasTag(TYPEAPPLY)) {
5950                     List<Type> tyargs = enclTy.getTypeArguments();
5951                     List<JCExpression> trargs = ((JCTypeApply)enclTr).getTypeArguments();
5952                     if (trargs.length() > 0) {
5953                         // Nothing to do for diamonds
5954                         if (tyargs.length() == trargs.length()) {
5955                             for (int i = 0; i < tyargs.length(); ++i) {
5956                                 validateAnnotatedType(trargs.get(i), tyargs.get(i));
5957                             }
5958                         }
5959                         // If the lengths don't match, it's either a diamond
5960                         // or some nested type that redundantly provides
5961                         // type arguments in the tree.
5962                     }
5963 
5964                     // Look at the clazz part of a generic type
5965                     enclTr = ((JCTree.JCTypeApply)enclTr).clazz;
5966                 }
5967 
5968                 if (enclTr.hasTag(SELECT)) {
5969                     enclTr = ((JCTree.JCFieldAccess)enclTr).getExpression();
5970                     if (enclTy != null &&
5971                             !enclTy.hasTag(NONE)) {
5972                         enclTy = enclTy.getEnclosingType();
5973                     }
5974                 } else if (enclTr.hasTag(ANNOTATED_TYPE)) {
5975                     JCAnnotatedType at = (JCTree.JCAnnotatedType) enclTr;
5976                     if (enclTy == null || enclTy.hasTag(NONE)) {
5977                         ListBuffer<Attribute.TypeCompound> onlyTypeAnnotationsBuf = new ListBuffer<>();
5978                         for (JCAnnotation an : at.getAnnotations()) {
5979                             if (chk.isTypeAnnotation(an, false)) {
5980                                 onlyTypeAnnotationsBuf.add((Attribute.TypeCompound) an.attribute);
5981                             }
5982                         }
5983                         List<Attribute.TypeCompound> onlyTypeAnnotations = onlyTypeAnnotationsBuf.toList();
5984                         if (!onlyTypeAnnotations.isEmpty()) {
5985                             Fragment annotationFragment = onlyTypeAnnotations.size() == 1 ?
5986                                     Fragments.TypeAnnotation1(onlyTypeAnnotations.head) :
5987                                     Fragments.TypeAnnotation(onlyTypeAnnotations);
5988                             JCDiagnostic.AnnotatedType annotatedType = new JCDiagnostic.AnnotatedType(
5989                                     type.stripMetadata().annotatedType(onlyTypeAnnotations));
5990                             log.error(at.underlyingType.pos(), Errors.TypeAnnotationInadmissible(annotationFragment,
5991                                     type.tsym.owner, annotatedType));
5992                         }
5993                         repeat = false;
5994                     }
5995                     enclTr = at.underlyingType;
5996                     // enclTy doesn't need to be changed
5997                 } else if (enclTr.hasTag(IDENT)) {
5998                     repeat = false;
5999                 } else if (enclTr.hasTag(JCTree.Tag.WILDCARD)) {
6000                     JCWildcard wc = (JCWildcard) enclTr;
6001                     if (wc.getKind() == JCTree.Kind.EXTENDS_WILDCARD ||
6002                             wc.getKind() == JCTree.Kind.SUPER_WILDCARD) {
6003                         validateAnnotatedType(wc.getBound(), wc.getBound().type);
6004                     } else {
6005                         // Nothing to do for UNBOUND
6006                     }
6007                     repeat = false;
6008                 } else if (enclTr.hasTag(TYPEARRAY)) {
6009                     JCArrayTypeTree art = (JCArrayTypeTree) enclTr;
6010                     validateAnnotatedType(art.getType(), art.elemtype.type);
6011                     repeat = false;
6012                 } else if (enclTr.hasTag(TYPEUNION)) {
6013                     JCTypeUnion ut = (JCTypeUnion) enclTr;
6014                     for (JCTree t : ut.getTypeAlternatives()) {
6015                         validateAnnotatedType(t, t.type);
6016                     }
6017                     repeat = false;
6018                 } else if (enclTr.hasTag(TYPEINTERSECTION)) {
6019                     JCTypeIntersection it = (JCTypeIntersection) enclTr;
6020                     for (JCTree t : it.getBounds()) {
6021                         validateAnnotatedType(t, t.type);
6022                     }
6023                     repeat = false;
6024                 } else if (enclTr.getKind() == JCTree.Kind.PRIMITIVE_TYPE ||
6025                            enclTr.getKind() == JCTree.Kind.ERRONEOUS) {
6026                     repeat = false;
6027                 } else {
6028                     Assert.error("Unexpected tree: " + enclTr + " with kind: " + enclTr.getKind() +
6029                             " within: "+ errtree + " with kind: " + errtree.getKind());
6030                 }
6031             }
6032         }
6033 
6034         private void checkForDeclarationAnnotations(List<? extends JCAnnotation> annotations,
6035                 Symbol sym) {
6036             // Ensure that no declaration annotations are present.
6037             // Note that a tree type might be an AnnotatedType with
6038             // empty annotations, if only declaration annotations were given.
6039             // This method will raise an error for such a type.
6040             for (JCAnnotation ai : annotations) {
6041                 if (!ai.type.isErroneous() &&
6042                         typeAnnotations.annotationTargetType(ai, ai.attribute, sym) == TypeAnnotations.AnnotationType.DECLARATION) {
6043                     log.error(ai.pos(), Errors.AnnotationTypeNotApplicableToType(ai.type));
6044                 }
6045             }
6046         }
6047     }
6048 
6049     // <editor-fold desc="post-attribution visitor">
6050 
6051     /**
6052      * Handle missing types/symbols in an AST. This routine is useful when
6053      * the compiler has encountered some errors (which might have ended up
6054      * terminating attribution abruptly); if the compiler is used in fail-over
6055      * mode (e.g. by an IDE) and the AST contains semantic errors, this routine
6056      * prevents NPE to be propagated during subsequent compilation steps.
6057      */
6058     public void postAttr(JCTree tree) {
6059         new PostAttrAnalyzer().scan(tree);
6060     }
6061 
6062     class PostAttrAnalyzer extends TreeScanner {
6063 
6064         private void initTypeIfNeeded(JCTree that) {
6065             if (that.type == null) {
6066                 if (that.hasTag(METHODDEF)) {
6067                     that.type = dummyMethodType((JCMethodDecl)that);
6068                 } else {
6069                     that.type = syms.unknownType;
6070                 }
6071             }
6072         }
6073 
6074         /* Construct a dummy method type. If we have a method declaration,
6075          * and the declared return type is void, then use that return type
6076          * instead of UNKNOWN to avoid spurious error messages in lambda
6077          * bodies (see:JDK-8041704).
6078          */
6079         private Type dummyMethodType(JCMethodDecl md) {
6080             Type restype = syms.unknownType;
6081             if (md != null && md.restype != null && md.restype.hasTag(TYPEIDENT)) {
6082                 JCPrimitiveTypeTree prim = (JCPrimitiveTypeTree)md.restype;
6083                 if (prim.typetag == VOID)
6084                     restype = syms.voidType;
6085             }
6086             return new MethodType(List.nil(), restype,
6087                                   List.nil(), syms.methodClass);
6088         }
6089         private Type dummyMethodType() {
6090             return dummyMethodType(null);
6091         }
6092 
6093         @Override
6094         public void scan(JCTree tree) {
6095             if (tree == null) return;
6096             if (tree instanceof JCExpression) {
6097                 initTypeIfNeeded(tree);
6098             }
6099             super.scan(tree);
6100         }
6101 
6102         @Override
6103         public void visitIdent(JCIdent that) {
6104             if (that.sym == null) {
6105                 that.sym = syms.unknownSymbol;
6106             }
6107         }
6108 
6109         @Override
6110         public void visitSelect(JCFieldAccess that) {
6111             if (that.sym == null) {
6112                 that.sym = syms.unknownSymbol;
6113             }
6114             super.visitSelect(that);
6115         }
6116 
6117         @Override
6118         public void visitClassDef(JCClassDecl that) {
6119             initTypeIfNeeded(that);
6120             if (that.sym == null) {
6121                 that.sym = new ClassSymbol(0, that.name, that.type, syms.noSymbol);
6122             }
6123             super.visitClassDef(that);
6124         }
6125 
6126         @Override
6127         public void visitMethodDef(JCMethodDecl that) {
6128             initTypeIfNeeded(that);
6129             if (that.sym == null) {
6130                 that.sym = new MethodSymbol(0, that.name, that.type, syms.noSymbol);
6131             }
6132             super.visitMethodDef(that);
6133         }
6134 
6135         @Override
6136         public void visitVarDef(JCVariableDecl that) {
6137             initTypeIfNeeded(that);
6138             if (that.sym == null) {
6139                 that.sym = new VarSymbol(0, that.name, that.type, syms.noSymbol);
6140                 that.sym.adr = 0;
6141             }
6142             super.visitVarDef(that);
6143         }
6144 
6145         @Override
6146         public void visitBindingPattern(JCBindingPattern that) {
6147             initTypeIfNeeded(that);
6148             initTypeIfNeeded(that.var);
6149             if (that.var.sym == null) {
6150                 that.var.sym = new BindingSymbol(0, that.var.name, that.var.type, syms.noSymbol);
6151                 that.var.sym.adr = 0;
6152             }
6153             super.visitBindingPattern(that);
6154         }
6155 
6156         @Override
6157         public void visitRecordPattern(JCRecordPattern that) {
6158             initTypeIfNeeded(that);
6159             if (that.record == null) {
6160                 that.record = new ClassSymbol(0, TreeInfo.name(that.deconstructor),
6161                                               that.type, syms.noSymbol);
6162             }
6163             if (that.fullComponentTypes == null) {
6164                 that.fullComponentTypes = List.nil();
6165             }
6166             super.visitRecordPattern(that);
6167         }
6168 
6169         @Override
6170         public void visitNewClass(JCNewClass that) {
6171             if (that.constructor == null) {
6172                 that.constructor = new MethodSymbol(0, names.init,
6173                         dummyMethodType(), syms.noSymbol);
6174             }
6175             if (that.constructorType == null) {
6176                 that.constructorType = syms.unknownType;
6177             }
6178             super.visitNewClass(that);
6179         }
6180 
6181         @Override
6182         public void visitAssignop(JCAssignOp that) {
6183             if (that.operator == null) {
6184                 that.operator = new OperatorSymbol(names.empty, dummyMethodType(),
6185                         -1, syms.noSymbol);
6186             }
6187             super.visitAssignop(that);
6188         }
6189 
6190         @Override
6191         public void visitBinary(JCBinary that) {
6192             if (that.operator == null) {
6193                 that.operator = new OperatorSymbol(names.empty, dummyMethodType(),
6194                         -1, syms.noSymbol);
6195             }
6196             super.visitBinary(that);
6197         }
6198 
6199         @Override
6200         public void visitUnary(JCUnary that) {
6201             if (that.operator == null) {
6202                 that.operator = new OperatorSymbol(names.empty, dummyMethodType(),
6203                         -1, syms.noSymbol);
6204             }
6205             super.visitUnary(that);
6206         }
6207 
6208         @Override
6209         public void visitReference(JCMemberReference that) {
6210             super.visitReference(that);
6211             if (that.sym == null) {
6212                 that.sym = new MethodSymbol(0, names.empty, dummyMethodType(),
6213                         syms.noSymbol);
6214             }
6215         }
6216 
6217         @Override
6218         public void visitVarType(JCVarType that) {
6219             initTypeIfNeeded(that);
6220         }
6221     }
6222     // </editor-fold>
6223 
6224     public void setPackageSymbols(JCExpression pid, Symbol pkg) {
6225         new TreeScanner() {
6226             Symbol packge = pkg;
6227             @Override
6228             public void visitIdent(JCIdent that) {
6229                 that.sym = packge;
6230             }
6231 
6232             @Override
6233             public void visitSelect(JCFieldAccess that) {
6234                 that.sym = packge;
6235                 packge = packge.owner;
6236                 super.visitSelect(that);
6237             }
6238         }.scan(pid);
6239     }
6240 
6241 }