1 /*
   2  * Copyright (c) 1999, 2024, 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 com.sun.tools.javac.api.Formattable.LocalizedString;
  29 import com.sun.tools.javac.code.*;
  30 import com.sun.tools.javac.code.Scope.WriteableScope;
  31 import com.sun.tools.javac.code.Source.Feature;
  32 import com.sun.tools.javac.code.Symbol.*;
  33 import com.sun.tools.javac.code.Type.*;
  34 import com.sun.tools.javac.comp.Attr.ResultInfo;
  35 import com.sun.tools.javac.comp.Check.CheckContext;
  36 import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
  37 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
  38 import com.sun.tools.javac.comp.DeferredAttr.DeferredType;
  39 import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
  40 import com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.Template;
  41 import com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind;
  42 import com.sun.tools.javac.jvm.*;
  43 import com.sun.tools.javac.main.Option;
  44 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  45 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  46 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
  47 import com.sun.tools.javac.tree.*;
  48 import com.sun.tools.javac.tree.JCTree.*;
  49 import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
  50 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
  51 import com.sun.tools.javac.util.*;
  52 import com.sun.tools.javac.util.DefinedBy.Api;
  53 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
  54 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  55 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
  56 
  57 import java.util.Arrays;
  58 import java.util.Collection;
  59 import java.util.EnumSet;
  60 import java.util.HashSet;
  61 import java.util.Iterator;
  62 import java.util.LinkedHashMap;
  63 import java.util.Map;
  64 import java.util.Set;
  65 import java.util.function.BiFunction;
  66 import java.util.function.BiPredicate;
  67 import java.util.function.Function;
  68 import java.util.function.Predicate;
  69 import java.util.function.UnaryOperator;
  70 import java.util.stream.Stream;
  71 import java.util.stream.StreamSupport;
  72 
  73 import javax.lang.model.element.ElementVisitor;
  74 
  75 import static com.sun.tools.javac.code.Flags.*;
  76 import static com.sun.tools.javac.code.Flags.BLOCK;
  77 import static com.sun.tools.javac.code.Flags.STATIC;
  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.comp.Resolve.MethodResolutionPhase.*;
  82 import static com.sun.tools.javac.main.Option.DOE;
  83 import static com.sun.tools.javac.tree.JCTree.Tag.*;
  84 import static com.sun.tools.javac.util.Iterators.createCompoundIterator;
  85 
  86 /** Helper class for name resolution, used mostly by the attribution phase.
  87  *
  88  *  <p><b>This is NOT part of any supported API.
  89  *  If you write code that depends on this, you do so at your own risk.
  90  *  This code and its internal interfaces are subject to change or
  91  *  deletion without notice.</b>
  92  */
  93 public class Resolve {
  94     protected static final Context.Key<Resolve> resolveKey = new Context.Key<>();
  95 
  96     Names names;
  97     Log log;
  98     Symtab syms;
  99     Attr attr;
 100     AttrRecover attrRecover;
 101     DeferredAttr deferredAttr;
 102     Check chk;
 103     Infer infer;
 104     Preview preview;
 105     ClassFinder finder;
 106     ModuleFinder moduleFinder;
 107     Types types;
 108     JCDiagnostic.Factory diags;
 109     public final boolean allowModules;
 110     public final boolean allowRecords;
 111     private final boolean compactMethodDiags;
 112     private final boolean allowLocalVariableTypeInference;
 113     private final boolean allowYieldStatement;
 114     final EnumSet<VerboseResolutionMode> verboseResolutionMode;
 115     final boolean dumpMethodReferenceSearchResults;
 116     final boolean dumpStacktraceOnError;
 117 
 118     WriteableScope polymorphicSignatureScope;
 119 
 120     @SuppressWarnings("this-escape")
 121     protected Resolve(Context context) {
 122         context.put(resolveKey, this);
 123         syms = Symtab.instance(context);
 124 
 125         varNotFound = new SymbolNotFoundError(ABSENT_VAR);
 126         methodNotFound = new SymbolNotFoundError(ABSENT_MTH);
 127         typeNotFound = new SymbolNotFoundError(ABSENT_TYP);
 128         referenceNotFound = ReferenceLookupResult.error(methodNotFound);
 129 
 130         names = Names.instance(context);
 131         log = Log.instance(context);
 132         attr = Attr.instance(context);
 133         attrRecover = AttrRecover.instance(context);
 134         deferredAttr = DeferredAttr.instance(context);
 135         chk = Check.instance(context);
 136         infer = Infer.instance(context);
 137         finder = ClassFinder.instance(context);
 138         moduleFinder = ModuleFinder.instance(context);
 139         types = Types.instance(context);
 140         diags = JCDiagnostic.Factory.instance(context);
 141         preview = Preview.instance(context);
 142         Source source = Source.instance(context);
 143         Options options = Options.instance(context);
 144         compactMethodDiags = options.isSet(Option.XDIAGS, "compact") ||
 145                 options.isUnset(Option.XDIAGS) && options.isUnset("rawDiagnostics");
 146         verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
 147         Target target = Target.instance(context);
 148         allowLocalVariableTypeInference = Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source);
 149         allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source);
 150         polymorphicSignatureScope = WriteableScope.create(syms.noSymbol);
 151         allowModules = Feature.MODULES.allowedInSource(source);
 152         allowRecords = Feature.RECORDS.allowedInSource(source);
 153         dumpMethodReferenceSearchResults = options.isSet("debug.dumpMethodReferenceSearchResults");
 154         dumpStacktraceOnError = options.isSet("dev") || options.isSet(DOE);
 155     }
 156 
 157     /** error symbols, which are returned when resolution fails
 158      */
 159     private final SymbolNotFoundError varNotFound;
 160     private final SymbolNotFoundError methodNotFound;
 161     private final SymbolNotFoundError typeNotFound;
 162 
 163     /** empty reference lookup result */
 164     private final ReferenceLookupResult referenceNotFound;
 165 
 166     public static Resolve instance(Context context) {
 167         Resolve instance = context.get(resolveKey);
 168         if (instance == null)
 169             instance = new Resolve(context);
 170         return instance;
 171     }
 172 
 173     private static Symbol bestOf(Symbol s1,
 174                                  Symbol s2) {
 175         return s1.kind.betterThan(s2.kind) ? s1 : s2;
 176     }
 177 
 178     // <editor-fold defaultstate="collapsed" desc="Verbose resolution diagnostics support">
 179     enum VerboseResolutionMode {
 180         SUCCESS("success"),
 181         FAILURE("failure"),
 182         APPLICABLE("applicable"),
 183         INAPPLICABLE("inapplicable"),
 184         DEFERRED_INST("deferred-inference"),
 185         PREDEF("predef"),
 186         OBJECT_INIT("object-init"),
 187         INTERNAL("internal");
 188 
 189         final String opt;
 190 
 191         private VerboseResolutionMode(String opt) {
 192             this.opt = opt;
 193         }
 194 
 195         static EnumSet<VerboseResolutionMode> getVerboseResolutionMode(Options opts) {
 196             String s = opts.get("debug.verboseResolution");
 197             EnumSet<VerboseResolutionMode> res = EnumSet.noneOf(VerboseResolutionMode.class);
 198             if (s == null) return res;
 199             if (s.contains("all")) {
 200                 res = EnumSet.allOf(VerboseResolutionMode.class);
 201             }
 202             Collection<String> args = Arrays.asList(s.split(","));
 203             for (VerboseResolutionMode mode : values()) {
 204                 if (args.contains(mode.opt)) {
 205                     res.add(mode);
 206                 } else if (args.contains("-" + mode.opt)) {
 207                     res.remove(mode);
 208                 }
 209             }
 210             return res;
 211         }
 212     }
 213 
 214     void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site,
 215             List<Type> argtypes, List<Type> typeargtypes, Symbol bestSoFar) {
 216         boolean success = !bestSoFar.kind.isResolutionError();
 217 
 218         if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) {
 219             return;
 220         } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) {
 221             return;
 222         }
 223 
 224         if (bestSoFar.name == names.init &&
 225                 bestSoFar.owner == syms.objectType.tsym &&
 226                 !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) {
 227             return; //skip diags for Object constructor resolution
 228         } else if (site == syms.predefClass.type &&
 229                 !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) {
 230             return; //skip spurious diags for predef symbols (i.e. operators)
 231         } else if (currentResolutionContext.internalResolution &&
 232                 !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) {
 233             return;
 234         }
 235 
 236         int pos = 0;
 237         int mostSpecificPos = -1;
 238         ListBuffer<JCDiagnostic> subDiags = new ListBuffer<>();
 239         for (Candidate c : currentResolutionContext.candidates) {
 240             if (currentResolutionContext.step != c.step ||
 241                     (c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE)) ||
 242                     (!c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))) {
 243                 continue;
 244             } else {
 245                 subDiags.append(c.isApplicable() ?
 246                         getVerboseApplicableCandidateDiag(pos, c.sym, c.mtype) :
 247                         getVerboseInapplicableCandidateDiag(pos, c.sym, c.details));
 248                 if (c.sym == bestSoFar)
 249                     mostSpecificPos = pos;
 250                 pos++;
 251             }
 252         }
 253         String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1";
 254         List<Type> argtypes2 = argtypes.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, bestSoFar, currentResolutionContext.step));
 255         JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name,
 256                 site.tsym, mostSpecificPos, currentResolutionContext.step,
 257                 methodArguments(argtypes2),
 258                 methodArguments(typeargtypes));
 259         JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList());
 260         log.report(d);
 261     }
 262 
 263     JCDiagnostic getVerboseApplicableCandidateDiag(int pos, Symbol sym, Type inst) {
 264         JCDiagnostic subDiag = null;
 265         if (sym.type.hasTag(FORALL)) {
 266             subDiag = diags.fragment(Fragments.PartialInstSig(inst));
 267         }
 268 
 269         String key = subDiag == null ?
 270                 "applicable.method.found" :
 271                 "applicable.method.found.1";
 272 
 273         return diags.fragment(key, pos, sym, subDiag);
 274     }
 275 
 276     JCDiagnostic getVerboseInapplicableCandidateDiag(int pos, Symbol sym, JCDiagnostic subDiag) {
 277         return diags.fragment(Fragments.NotApplicableMethodFound(pos, sym, subDiag));
 278     }
 279     // </editor-fold>
 280 
 281 /* ************************************************************************
 282  * Identifier resolution
 283  *************************************************************************/
 284 
 285     /** An environment is "static" if its static level is greater than
 286      *  the one of its outer environment
 287      */
 288     protected static boolean isStatic(Env<AttrContext> env) {
 289         return env.outer != null && env.info.staticLevel > env.outer.info.staticLevel;
 290     }
 291 
 292     /** An environment is an "initializer" if it is a constructor or
 293      *  an instance initializer.
 294      */
 295     static boolean isInitializer(Env<AttrContext> env) {
 296         Symbol owner = env.info.scope.owner;
 297         return owner.isConstructor() ||
 298             owner.owner.kind == TYP &&
 299             (owner.kind == VAR ||
 300              owner.kind == MTH && (owner.flags() & BLOCK) != 0) &&
 301             (owner.flags() & STATIC) == 0;
 302     }
 303 
 304     /** Is class accessible in given environment?
 305      *  @param env    The current environment.
 306      *  @param c      The class whose accessibility is checked.
 307      */
 308     public boolean isAccessible(Env<AttrContext> env, TypeSymbol c) {
 309         return isAccessible(env, c, false);
 310     }
 311 
 312     public boolean isAccessible(Env<AttrContext> env, TypeSymbol c, boolean checkInner) {
 313 
 314         /* 15.9.5.1: Note that it is possible for the signature of the anonymous constructor
 315            to refer to an inaccessible type
 316         */
 317         if (env.enclMethod != null && (env.enclMethod.mods.flags & ANONCONSTR) != 0)
 318             return true;
 319 
 320         if (env.info.visitingServiceImplementation &&
 321             env.toplevel.modle == c.packge().modle) {
 322             return true;
 323         }
 324 
 325         boolean isAccessible = false;
 326         switch ((short)(c.flags() & AccessFlags)) {
 327             case PRIVATE:
 328                 isAccessible =
 329                     env.enclClass.sym.outermostClass() ==
 330                     c.owner.outermostClass();
 331                 break;
 332             case 0:
 333                 isAccessible =
 334                     env.toplevel.packge == c.owner // fast special case
 335                     ||
 336                     env.toplevel.packge == c.packge();
 337                 break;
 338             default: // error recovery
 339                 isAccessible = true;
 340                 break;
 341             case PUBLIC:
 342                 if (allowModules) {
 343                     ModuleSymbol currModule = env.toplevel.modle;
 344                     currModule.complete();
 345                     PackageSymbol p = c.packge();
 346                     isAccessible =
 347                         currModule == p.modle ||
 348                         currModule.visiblePackages.get(p.fullname) == p ||
 349                         p == syms.rootPackage ||
 350                         (p.modle == syms.unnamedModule && currModule.readModules.contains(p.modle));
 351                 } else {
 352                     isAccessible = true;
 353                 }
 354                 break;
 355             case PROTECTED:
 356                 isAccessible =
 357                     env.toplevel.packge == c.owner // fast special case
 358                     ||
 359                     env.toplevel.packge == c.packge()
 360                     ||
 361                     isInnerSubClass(env.enclClass.sym, c.owner)
 362                     ||
 363                     env.info.allowProtectedAccess;
 364                 break;
 365         }
 366         return (checkInner == false || c.type.getEnclosingType() == Type.noType) ?
 367             isAccessible :
 368             isAccessible && isAccessible(env, c.type.getEnclosingType(), checkInner);
 369     }
 370     //where
 371         /** Is given class a subclass of given base class, or an inner class
 372          *  of a subclass?
 373          *  Return null if no such class exists.
 374          *  @param c     The class which is the subclass or is contained in it.
 375          *  @param base  The base class
 376          */
 377         private boolean isInnerSubClass(ClassSymbol c, Symbol base) {
 378             while (c != null && !c.isSubClass(base, types)) {
 379                 c = c.owner.enclClass();
 380             }
 381             return c != null;
 382         }
 383 
 384     boolean isAccessible(Env<AttrContext> env, Type t) {
 385         return isAccessible(env, t, false);
 386     }
 387 
 388     boolean isAccessible(Env<AttrContext> env, Type t, boolean checkInner) {
 389         if (t.hasTag(ARRAY)) {
 390             return isAccessible(env, types.cvarUpperBound(types.elemtype(t)));
 391         } else if (t.isUnion()) {
 392             return StreamSupport.stream(((UnionClassType) t).getAlternativeTypes().spliterator(), false)
 393                     .allMatch(alternative -> isAccessible(env, alternative.tsym, checkInner));
 394         } else {
 395             return isAccessible(env, t.tsym, checkInner);
 396         }
 397     }
 398 
 399     /** Is symbol accessible as a member of given type in given environment?
 400      *  @param env    The current environment.
 401      *  @param site   The type of which the tested symbol is regarded
 402      *                as a member.
 403      *  @param sym    The symbol.
 404      */
 405     public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym) {
 406         return isAccessible(env, site, sym, false);
 407     }
 408     public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym, boolean checkInner) {
 409         if (sym.name == names.init && sym.owner != site.tsym) return false;
 410 
 411         /* 15.9.5.1: Note that it is possible for the signature of the anonymous constructor
 412            to refer to an inaccessible type
 413         */
 414         if (env.enclMethod != null && (env.enclMethod.mods.flags & ANONCONSTR) != 0)
 415             return true;
 416 
 417         if (env.info.visitingServiceImplementation &&
 418             env.toplevel.modle == sym.packge().modle) {
 419             return true;
 420         }
 421 
 422         ClassSymbol enclosingCsym = env.enclClass.sym;
 423         try {
 424             switch ((short)(sym.flags() & AccessFlags)) {
 425                 case PRIVATE:
 426                     return
 427                             (env.enclClass.sym == sym.owner // fast special case
 428                                     ||
 429                                     env.enclClass.sym.outermostClass() ==
 430                                             sym.owner.outermostClass())
 431                                     &&
 432                                     sym.isInheritedIn(site.tsym, types);
 433                 case 0:
 434                     return
 435                             (env.toplevel.packge == sym.owner.owner // fast special case
 436                                     ||
 437                                     env.toplevel.packge == sym.packge())
 438                                     &&
 439                                     isAccessible(env, site, checkInner)
 440                                     &&
 441                                     sym.isInheritedIn(site.tsym, types)
 442                                     &&
 443                                     notOverriddenIn(site, sym);
 444                 case PROTECTED:
 445                     return
 446                             (env.toplevel.packge == sym.owner.owner // fast special case
 447                                     ||
 448                                     env.toplevel.packge == sym.packge()
 449                                     ||
 450                                     isProtectedAccessible(sym, env.enclClass.sym, site)
 451                                     ||
 452                                     // OK to select instance method or field from 'super' or type name
 453                                     // (but type names should be disallowed elsewhere!)
 454                                     env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP)
 455                                     &&
 456                                     isAccessible(env, site, checkInner)
 457                                     &&
 458                                     notOverriddenIn(site, sym);
 459                 default: // this case includes erroneous combinations as well
 460                     return isAccessible(env, site, checkInner) && notOverriddenIn(site, sym);
 461             }
 462         } finally {
 463             env.enclClass.sym = enclosingCsym;
 464         }
 465     }
 466     //where
 467     /* `sym' is accessible only if not overridden by
 468      * another symbol which is a member of `site'
 469      * (because, if it is overridden, `sym' is not strictly
 470      * speaking a member of `site'). A polymorphic signature method
 471      * cannot be overridden (e.g. MH.invokeExact(Object[])).
 472      */
 473     private boolean notOverriddenIn(Type site, Symbol sym) {
 474         if (sym.kind != MTH || sym.isConstructor() || sym.isStatic())
 475             return true;
 476         else {
 477             Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true);
 478             return (s2 == null || s2 == sym || sym.owner == s2.owner || (sym.owner.isInterface() && s2.owner == syms.objectType.tsym) ||
 479                     !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym)));
 480         }
 481     }
 482     //where
 483         /** Is given protected symbol accessible if it is selected from given site
 484          *  and the selection takes place in given class?
 485          *  @param sym     The symbol with protected access
 486          *  @param c       The class where the access takes place
 487          *  @param site    The type of the qualifier
 488          */
 489         private
 490         boolean isProtectedAccessible(Symbol sym, ClassSymbol c, Type site) {
 491             Type newSite = site.hasTag(TYPEVAR) ? site.getUpperBound() : site;
 492             while (c != null &&
 493                    !(c.isSubClass(sym.owner, types) &&
 494                      (c.flags() & INTERFACE) == 0 &&
 495                      // In JLS 2e 6.6.2.1, the subclass restriction applies
 496                      // only to instance fields and methods -- types are excluded
 497                      // regardless of whether they are declared 'static' or not.
 498                      ((sym.flags() & STATIC) != 0 || sym.kind == TYP || newSite.tsym.isSubClass(c, types))))
 499                 c = c.owner.enclClass();
 500             return c != null;
 501         }
 502 
 503     /**
 504      * Performs a recursive scan of a type looking for accessibility problems
 505      * from current attribution environment
 506      */
 507     void checkAccessibleType(Env<AttrContext> env, Type t) {
 508         accessibilityChecker.visit(t, env);
 509     }
 510 
 511     /**
 512      * Accessibility type-visitor
 513      */
 514     Types.SimpleVisitor<Void, Env<AttrContext>> accessibilityChecker =
 515             new Types.SimpleVisitor<Void, Env<AttrContext>>() {
 516 
 517         void visit(List<Type> ts, Env<AttrContext> env) {
 518             for (Type t : ts) {
 519                 visit(t, env);
 520             }
 521         }
 522 
 523         public Void visitType(Type t, Env<AttrContext> env) {
 524             return null;
 525         }
 526 
 527         @Override
 528         public Void visitArrayType(ArrayType t, Env<AttrContext> env) {
 529             visit(t.elemtype, env);
 530             return null;
 531         }
 532 
 533         @Override
 534         public Void visitClassType(ClassType t, Env<AttrContext> env) {
 535             visit(t.getTypeArguments(), env);
 536             if (!isAccessible(env, t, true)) {
 537                 accessBase(new AccessError(env, null, t.tsym), env.tree.pos(), env.enclClass.sym, t, t.tsym.name, true);
 538             }
 539             return null;
 540         }
 541 
 542         @Override
 543         public Void visitWildcardType(WildcardType t, Env<AttrContext> env) {
 544             visit(t.type, env);
 545             return null;
 546         }
 547 
 548         @Override
 549         public Void visitMethodType(MethodType t, Env<AttrContext> env) {
 550             visit(t.getParameterTypes(), env);
 551             visit(t.getReturnType(), env);
 552             visit(t.getThrownTypes(), env);
 553             return null;
 554         }
 555     };
 556 
 557     /** Try to instantiate the type of a method so that it fits
 558      *  given type arguments and argument types. If successful, return
 559      *  the method's instantiated type, else return null.
 560      *  The instantiation will take into account an additional leading
 561      *  formal parameter if the method is an instance method seen as a member
 562      *  of an under determined site. In this case, we treat site as an additional
 563      *  parameter and the parameters of the class containing the method as
 564      *  additional type variables that get instantiated.
 565      *
 566      *  @param env         The current environment
 567      *  @param site        The type of which the method is a member.
 568      *  @param m           The method symbol.
 569      *  @param argtypes    The invocation's given value arguments.
 570      *  @param typeargtypes    The invocation's given type arguments.
 571      *  @param allowBoxing Allow boxing conversions of arguments.
 572      *  @param useVarargs Box trailing arguments into an array for varargs.
 573      */
 574     Type rawInstantiate(Env<AttrContext> env,
 575                         Type site,
 576                         Symbol m,
 577                         ResultInfo resultInfo,
 578                         List<Type> argtypes,
 579                         List<Type> typeargtypes,
 580                         boolean allowBoxing,
 581                         boolean useVarargs,
 582                         Warner warn) throws Infer.InferenceException {
 583         Type mt = types.memberType(site, m);
 584         // tvars is the list of formal type variables for which type arguments
 585         // need to inferred.
 586         List<Type> tvars = List.nil();
 587         if (typeargtypes == null) typeargtypes = List.nil();
 588         if (!mt.hasTag(FORALL) && typeargtypes.nonEmpty()) {
 589             // This is not a polymorphic method, but typeargs are supplied
 590             // which is fine, see JLS 15.12.2.1
 591         } else if (mt.hasTag(FORALL) && typeargtypes.nonEmpty()) {
 592             ForAll pmt = (ForAll) mt;
 593             if (typeargtypes.length() != pmt.tvars.length())
 594                  // not enough args
 595                 throw new InapplicableMethodException(diags.fragment(Fragments.WrongNumberTypeArgs(Integer.toString(pmt.tvars.length()))), dumpStacktraceOnError);
 596             // Check type arguments are within bounds
 597             List<Type> formals = pmt.tvars;
 598             List<Type> actuals = typeargtypes;
 599             while (formals.nonEmpty() && actuals.nonEmpty()) {
 600                 List<Type> bounds = types.subst(types.getBounds((TypeVar)formals.head),
 601                                                 pmt.tvars, typeargtypes);
 602                 for (; bounds.nonEmpty(); bounds = bounds.tail) {
 603                     if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn)) {
 604                         throw new InapplicableMethodException(diags.fragment(Fragments.ExplicitParamDoNotConformToBounds(actuals.head, bounds)), dumpStacktraceOnError);
 605                     }
 606                 }
 607                 formals = formals.tail;
 608                 actuals = actuals.tail;
 609             }
 610             mt = types.subst(pmt.qtype, pmt.tvars, typeargtypes);
 611         } else if (mt.hasTag(FORALL)) {
 612             ForAll pmt = (ForAll) mt;
 613             List<Type> tvars1 = types.newInstances(pmt.tvars);
 614             tvars = tvars.appendList(tvars1);
 615             mt = types.subst(pmt.qtype, pmt.tvars, tvars1);
 616         }
 617 
 618         // find out whether we need to go the slow route via infer
 619         boolean instNeeded = tvars.tail != null; /*inlined: tvars.nonEmpty()*/
 620         for (List<Type> l = argtypes;
 621              l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded;
 622              l = l.tail) {
 623             if (l.head.hasTag(FORALL)) instNeeded = true;
 624         }
 625 
 626         if (instNeeded) {
 627             return infer.instantiateMethod(env,
 628                                     tvars,
 629                                     (MethodType)mt,
 630                                     resultInfo,
 631                                     (MethodSymbol)m,
 632                                     argtypes,
 633                                     allowBoxing,
 634                                     useVarargs,
 635                                     currentResolutionContext,
 636                                     warn);
 637         }
 638 
 639         DeferredAttr.DeferredAttrContext dc = currentResolutionContext.deferredAttrContext(m, infer.emptyContext, resultInfo, warn);
 640         currentResolutionContext.methodCheck.argumentsAcceptable(env, dc,
 641                                 argtypes, mt.getParameterTypes(), warn);
 642         dc.complete();
 643         return mt;
 644     }
 645 
 646     Type checkMethod(Env<AttrContext> env,
 647                      Type site,
 648                      Symbol m,
 649                      ResultInfo resultInfo,
 650                      List<Type> argtypes,
 651                      List<Type> typeargtypes,
 652                      Warner warn) {
 653         MethodResolutionContext prevContext = currentResolutionContext;
 654         try {
 655             currentResolutionContext = new MethodResolutionContext();
 656             currentResolutionContext.attrMode = (resultInfo.pt == Infer.anyPoly) ?
 657                     AttrMode.SPECULATIVE : DeferredAttr.AttrMode.CHECK;
 658             if (env.tree.hasTag(JCTree.Tag.REFERENCE)) {
 659                 //method/constructor references need special check class
 660                 //to handle inference variables in 'argtypes' (might happen
 661                 //during an unsticking round)
 662                 currentResolutionContext.methodCheck =
 663                         new MethodReferenceCheck(resultInfo.checkContext.inferenceContext());
 664             }
 665             MethodResolutionPhase step = currentResolutionContext.step = env.info.pendingResolutionPhase;
 666             return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes,
 667                     step.isBoxingRequired(), step.isVarargsRequired(), warn);
 668         }
 669         finally {
 670             currentResolutionContext = prevContext;
 671         }
 672     }
 673 
 674     /** Same but returns null instead throwing a NoInstanceException
 675      */
 676     Type instantiate(Env<AttrContext> env,
 677                      Type site,
 678                      Symbol m,
 679                      ResultInfo resultInfo,
 680                      List<Type> argtypes,
 681                      List<Type> typeargtypes,
 682                      boolean allowBoxing,
 683                      boolean useVarargs,
 684                      Warner warn) {
 685         try {
 686             return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes,
 687                                   allowBoxing, useVarargs, warn);
 688         } catch (InapplicableMethodException ex) {
 689             return null;
 690         }
 691     }
 692 
 693     /**
 694      * This interface defines an entry point that should be used to perform a
 695      * method check. A method check usually consist in determining as to whether
 696      * a set of types (actuals) is compatible with another set of types (formals).
 697      * Since the notion of compatibility can vary depending on the circumstances,
 698      * this interfaces allows to easily add new pluggable method check routines.
 699      */
 700     interface MethodCheck {
 701         /**
 702          * Main method check routine. A method check usually consist in determining
 703          * as to whether a set of types (actuals) is compatible with another set of
 704          * types (formals). If an incompatibility is found, an unchecked exception
 705          * is assumed to be thrown.
 706          */
 707         void argumentsAcceptable(Env<AttrContext> env,
 708                                 DeferredAttrContext deferredAttrContext,
 709                                 List<Type> argtypes,
 710                                 List<Type> formals,
 711                                 Warner warn);
 712 
 713         /**
 714          * Retrieve the method check object that will be used during a
 715          * most specific check.
 716          */
 717         MethodCheck mostSpecificCheck(List<Type> actuals);
 718     }
 719 
 720     /**
 721      * Helper enum defining all method check diagnostics (used by resolveMethodCheck).
 722      */
 723     enum MethodCheckDiag {
 724         /**
 725          * Actuals and formals differs in length.
 726          */
 727         ARITY_MISMATCH("arg.length.mismatch", "infer.arg.length.mismatch"),
 728         /**
 729          * An actual is incompatible with a formal.
 730          */
 731         ARG_MISMATCH("no.conforming.assignment.exists", "infer.no.conforming.assignment.exists"),
 732         /**
 733          * An actual is incompatible with the varargs element type.
 734          */
 735         VARARG_MISMATCH("varargs.argument.mismatch", "infer.varargs.argument.mismatch"),
 736         /**
 737          * The varargs element type is inaccessible.
 738          */
 739         INACCESSIBLE_VARARGS("inaccessible.varargs.type", "inaccessible.varargs.type");
 740 
 741         final String basicKey;
 742         final String inferKey;
 743 
 744         MethodCheckDiag(String basicKey, String inferKey) {
 745             this.basicKey = basicKey;
 746             this.inferKey = inferKey;
 747         }
 748 
 749         String regex() {
 750             return String.format("([a-z]*\\.)*(%s|%s)", basicKey, inferKey);
 751         }
 752     }
 753 
 754     /**
 755      * Dummy method check object. All methods are deemed applicable, regardless
 756      * of their formal parameter types.
 757      */
 758     MethodCheck nilMethodCheck = new MethodCheck() {
 759         public void argumentsAcceptable(Env<AttrContext> env, DeferredAttrContext deferredAttrContext, List<Type> argtypes, List<Type> formals, Warner warn) {
 760             //do nothing - method always applicable regardless of actuals
 761         }
 762 
 763         public MethodCheck mostSpecificCheck(List<Type> actuals) {
 764             return this;
 765         }
 766     };
 767 
 768     /**
 769      * Base class for 'real' method checks. The class defines the logic for
 770      * iterating through formals and actuals and provides and entry point
 771      * that can be used by subclasses in order to define the actual check logic.
 772      */
 773     abstract class AbstractMethodCheck implements MethodCheck {
 774         @Override
 775         public void argumentsAcceptable(final Env<AttrContext> env,
 776                                     DeferredAttrContext deferredAttrContext,
 777                                     List<Type> argtypes,
 778                                     List<Type> formals,
 779                                     Warner warn) {
 780             //should we expand formals?
 781             boolean useVarargs = deferredAttrContext.phase.isVarargsRequired();
 782             JCTree callTree = treeForDiagnostics(env);
 783             List<JCExpression> trees = TreeInfo.args(callTree);
 784 
 785             //inference context used during this method check
 786             InferenceContext inferenceContext = deferredAttrContext.inferenceContext;
 787 
 788             Type varargsFormal = useVarargs ? formals.last() : null;
 789 
 790             if (varargsFormal == null &&
 791                     argtypes.size() != formals.size()) {
 792                 reportMC(callTree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
 793             }
 794 
 795             while (argtypes.nonEmpty() && formals.head != varargsFormal) {
 796                 DiagnosticPosition pos = trees != null ? trees.head : null;
 797                 checkArg(pos, false, argtypes.head, formals.head, deferredAttrContext, warn);
 798                 argtypes = argtypes.tail;
 799                 formals = formals.tail;
 800                 trees = trees != null ? trees.tail : trees;
 801             }
 802 
 803             if (formals.head != varargsFormal) {
 804                 reportMC(callTree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
 805             }
 806 
 807             if (useVarargs) {
 808                 //note: if applicability check is triggered by most specific test,
 809                 //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
 810                 final Type elt = types.elemtype(varargsFormal);
 811                 while (argtypes.nonEmpty()) {
 812                     DiagnosticPosition pos = trees != null ? trees.head : null;
 813                     checkArg(pos, true, argtypes.head, elt, deferredAttrContext, warn);
 814                     argtypes = argtypes.tail;
 815                     trees = trees != null ? trees.tail : trees;
 816                 }
 817             }
 818         }
 819 
 820             // where
 821             private JCTree treeForDiagnostics(Env<AttrContext> env) {
 822                 return env.info.preferredTreeForDiagnostics != null ? env.info.preferredTreeForDiagnostics : env.tree;
 823             }
 824 
 825         /**
 826          * Does the actual argument conforms to the corresponding formal?
 827          */
 828         abstract void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn);
 829 
 830         protected void reportMC(DiagnosticPosition pos, MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) {
 831             boolean inferDiag = inferenceContext != infer.emptyContext;
 832             if (inferDiag && (!diag.inferKey.equals(diag.basicKey))) {
 833                 Object[] args2 = new Object[args.length + 1];
 834                 System.arraycopy(args, 0, args2, 1, args.length);
 835                 args2[0] = inferenceContext.inferenceVars();
 836                 args = args2;
 837             }
 838             String key = inferDiag ? diag.inferKey : diag.basicKey;
 839             throw inferDiag ?
 840                 infer.error(diags.create(DiagnosticType.FRAGMENT, log.currentSource(), pos, key, args)) :
 841                 getMethodCheckFailure().setMessage(diags.create(DiagnosticType.FRAGMENT, log.currentSource(), pos, key, args));
 842         }
 843 
 844         /**
 845          * To eliminate the overhead associated with allocating an exception object in such an
 846          * hot execution path, we use flyweight pattern - and share the same exception instance
 847          * across multiple method check failures.
 848          */
 849         class SharedInapplicableMethodException extends InapplicableMethodException {
 850             private static final long serialVersionUID = 0;
 851 
 852             SharedInapplicableMethodException() {
 853                 super(null, Resolve.this.dumpStacktraceOnError);
 854             }
 855 
 856             SharedInapplicableMethodException setMessage(JCDiagnostic details) {
 857                 this.diagnostic = details;
 858                 return this;
 859             }
 860         }
 861 
 862         private SharedInapplicableMethodException methodCheckFailure;
 863 
 864         public MethodCheck mostSpecificCheck(List<Type> actuals) {
 865             return nilMethodCheck;
 866         }
 867 
 868         private SharedInapplicableMethodException getMethodCheckFailure() {
 869             return methodCheckFailure == null ? methodCheckFailure = new SharedInapplicableMethodException() : methodCheckFailure;
 870         }
 871     }
 872 
 873     /**
 874      * Arity-based method check. A method is applicable if the number of actuals
 875      * supplied conforms to the method signature.
 876      */
 877     MethodCheck arityMethodCheck = new AbstractMethodCheck() {
 878         @Override
 879         void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
 880             //do nothing - actual always compatible to formals
 881         }
 882 
 883         @Override
 884         public String toString() {
 885             return "arityMethodCheck";
 886         }
 887     };
 888 
 889     /**
 890      * Main method applicability routine. Given a list of actual types A,
 891      * a list of formal types F, determines whether the types in A are
 892      * compatible (by method invocation conversion) with the types in F.
 893      *
 894      * Since this routine is shared between overload resolution and method
 895      * type-inference, a (possibly empty) inference context is used to convert
 896      * formal types to the corresponding 'undet' form ahead of a compatibility
 897      * check so that constraints can be propagated and collected.
 898      *
 899      * Moreover, if one or more types in A is a deferred type, this routine uses
 900      * DeferredAttr in order to perform deferred attribution. If one or more actual
 901      * deferred types are stuck, they are placed in a queue and revisited later
 902      * after the remainder of the arguments have been seen. If this is not sufficient
 903      * to 'unstuck' the argument, a cyclic inference error is called out.
 904      *
 905      * A method check handler (see above) is used in order to report errors.
 906      */
 907     MethodCheck resolveMethodCheck = new AbstractMethodCheck() {
 908 
 909         @Override
 910         void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
 911             ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn);
 912             mresult.check(pos, actual);
 913         }
 914 
 915         @Override
 916         public void argumentsAcceptable(final Env<AttrContext> env,
 917                                     DeferredAttrContext deferredAttrContext,
 918                                     List<Type> argtypes,
 919                                     List<Type> formals,
 920                                     Warner warn) {
 921             super.argumentsAcceptable(env, deferredAttrContext, argtypes, formals, warn);
 922             // should we check varargs element type accessibility?
 923             if (deferredAttrContext.phase.isVarargsRequired()) {
 924                 if (deferredAttrContext.mode == AttrMode.CHECK) {
 925                     varargsAccessible(env, types.elemtype(formals.last()), deferredAttrContext.inferenceContext);
 926                 }
 927             }
 928         }
 929 
 930         /**
 931          * Test that the runtime array element type corresponding to 't' is accessible.  't' should be the
 932          * varargs element type of either the method invocation type signature (after inference completes)
 933          * or the method declaration signature (before inference completes).
 934          */
 935         private void varargsAccessible(final Env<AttrContext> env, final Type t, final InferenceContext inferenceContext) {
 936             if (inferenceContext.free(t)) {
 937                 inferenceContext.addFreeTypeListener(List.of(t),
 938                         solvedContext -> varargsAccessible(env, solvedContext.asInstType(t), solvedContext));
 939             } else {
 940                 if (!isAccessible(env, types.erasure(t))) {
 941                     Symbol location = env.enclClass.sym;
 942                     reportMC(env.tree, MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location);
 943                 }
 944             }
 945         }
 946 
 947         private ResultInfo methodCheckResult(final boolean varargsCheck, Type to,
 948                 final DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner) {
 949             CheckContext checkContext = new MethodCheckContext(!deferredAttrContext.phase.isBoxingRequired(), deferredAttrContext, rsWarner) {
 950                 MethodCheckDiag methodDiag = varargsCheck ?
 951                                  MethodCheckDiag.VARARG_MISMATCH : MethodCheckDiag.ARG_MISMATCH;
 952 
 953                 @Override
 954                 public void report(DiagnosticPosition pos, JCDiagnostic details) {
 955                     reportMC(pos, methodDiag, deferredAttrContext.inferenceContext, details);
 956                 }
 957             };
 958             return new MethodResultInfo(to, checkContext);
 959         }
 960 
 961         @Override
 962         public MethodCheck mostSpecificCheck(List<Type> actuals) {
 963             return new MostSpecificCheck(actuals);
 964         }
 965 
 966         @Override
 967         public String toString() {
 968             return "resolveMethodCheck";
 969         }
 970     };
 971 
 972     /**
 973      * This class handles method reference applicability checks; since during
 974      * these checks it's sometime possible to have inference variables on
 975      * the actual argument types list, the method applicability check must be
 976      * extended so that inference variables are 'opened' as needed.
 977      */
 978     class MethodReferenceCheck extends AbstractMethodCheck {
 979 
 980         InferenceContext pendingInferenceContext;
 981 
 982         MethodReferenceCheck(InferenceContext pendingInferenceContext) {
 983             this.pendingInferenceContext = pendingInferenceContext;
 984         }
 985 
 986         @Override
 987         void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
 988             ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn);
 989             mresult.check(pos, actual);
 990         }
 991 
 992         private ResultInfo methodCheckResult(final boolean varargsCheck, Type to,
 993                 final DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner) {
 994             CheckContext checkContext = new MethodCheckContext(!deferredAttrContext.phase.isBoxingRequired(), deferredAttrContext, rsWarner) {
 995                 MethodCheckDiag methodDiag = varargsCheck ?
 996                                  MethodCheckDiag.VARARG_MISMATCH : MethodCheckDiag.ARG_MISMATCH;
 997 
 998                 @Override
 999                 public boolean compatible(Type found, Type req, Warner warn) {
1000                     found = pendingInferenceContext.asUndetVar(found);
1001                     if (found.hasTag(UNDETVAR) && req.isPrimitive()) {
1002                         req = types.boxedClass(req).type;
1003                     }
1004                     return super.compatible(found, req, warn);
1005                 }
1006 
1007                 @Override
1008                 public void report(DiagnosticPosition pos, JCDiagnostic details) {
1009                     reportMC(pos, methodDiag, deferredAttrContext.inferenceContext, details);
1010                 }
1011             };
1012             return new MethodResultInfo(to, checkContext);
1013         }
1014 
1015         @Override
1016         public MethodCheck mostSpecificCheck(List<Type> actuals) {
1017             return new MostSpecificCheck(actuals);
1018         }
1019 
1020         @Override
1021         public String toString() {
1022             return "MethodReferenceCheck";
1023         }
1024     }
1025 
1026     /**
1027      * Check context to be used during method applicability checks. A method check
1028      * context might contain inference variables.
1029      */
1030     abstract class MethodCheckContext implements CheckContext {
1031 
1032         boolean strict;
1033         DeferredAttrContext deferredAttrContext;
1034         Warner rsWarner;
1035 
1036         public MethodCheckContext(boolean strict, DeferredAttrContext deferredAttrContext, Warner rsWarner) {
1037            this.strict = strict;
1038            this.deferredAttrContext = deferredAttrContext;
1039            this.rsWarner = rsWarner;
1040         }
1041 
1042         public boolean compatible(Type found, Type req, Warner warn) {
1043             InferenceContext inferenceContext = deferredAttrContext.inferenceContext;
1044             return strict ?
1045                     types.isSubtypeUnchecked(inferenceContext.asUndetVar(found), inferenceContext.asUndetVar(req), warn) :
1046                     types.isConvertible(inferenceContext.asUndetVar(found), inferenceContext.asUndetVar(req), warn);
1047         }
1048 
1049         public void report(DiagnosticPosition pos, JCDiagnostic details) {
1050             throw new InapplicableMethodException(details, Resolve.this.dumpStacktraceOnError);
1051         }
1052 
1053         public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
1054             return rsWarner;
1055         }
1056 
1057         public InferenceContext inferenceContext() {
1058             return deferredAttrContext.inferenceContext;
1059         }
1060 
1061         public DeferredAttrContext deferredAttrContext() {
1062             return deferredAttrContext;
1063         }
1064 
1065         @Override
1066         public String toString() {
1067             return "MethodCheckContext";
1068         }
1069     }
1070 
1071     /**
1072      * ResultInfo class to be used during method applicability checks. Check
1073      * for deferred types goes through special path.
1074      */
1075     class MethodResultInfo extends ResultInfo {
1076 
1077         public MethodResultInfo(Type pt, CheckContext checkContext) {
1078             attr.super(KindSelector.VAL, pt, checkContext);
1079         }
1080 
1081         @Override
1082         protected Type check(DiagnosticPosition pos, Type found) {
1083             if (found.hasTag(DEFERRED)) {
1084                 DeferredType dt = (DeferredType)found;
1085                 return dt.check(this);
1086             } else {
1087                 Type uResult = U(found);
1088                 Type capturedType = pos == null || pos.getTree() == null ?
1089                         types.capture(uResult) :
1090                         checkContext.inferenceContext()
1091                             .cachedCapture(pos.getTree(), uResult, true);
1092                 return super.check(pos, chk.checkNonVoid(pos, capturedType));
1093             }
1094         }
1095 
1096         /**
1097          * javac has a long-standing 'simplification' (see 6391995):
1098          * given an actual argument type, the method check is performed
1099          * on its upper bound. This leads to inconsistencies when an
1100          * argument type is checked against itself. For example, given
1101          * a type-variable T, it is not true that {@code U(T) <: T},
1102          * so we need to guard against that.
1103          */
1104         private Type U(Type found) {
1105             return found == pt ?
1106                     found : types.cvarUpperBound(found);
1107         }
1108 
1109         @Override
1110         protected MethodResultInfo dup(Type newPt) {
1111             return new MethodResultInfo(newPt, checkContext);
1112         }
1113 
1114         @Override
1115         protected ResultInfo dup(CheckContext newContext) {
1116             return new MethodResultInfo(pt, newContext);
1117         }
1118 
1119         @Override
1120         protected ResultInfo dup(Type newPt, CheckContext newContext) {
1121             return new MethodResultInfo(newPt, newContext);
1122         }
1123     }
1124 
1125     /**
1126      * Most specific method applicability routine. Given a list of actual types A,
1127      * a list of formal types F1, and a list of formal types F2, the routine determines
1128      * as to whether the types in F1 can be considered more specific than those in F2 w.r.t.
1129      * argument types A.
1130      */
1131     class MostSpecificCheck implements MethodCheck {
1132 
1133         List<Type> actuals;
1134 
1135         MostSpecificCheck(List<Type> actuals) {
1136             this.actuals = actuals;
1137         }
1138 
1139         @Override
1140         public void argumentsAcceptable(final Env<AttrContext> env,
1141                                     DeferredAttrContext deferredAttrContext,
1142                                     List<Type> formals1,
1143                                     List<Type> formals2,
1144                                     Warner warn) {
1145             formals2 = adjustArgs(formals2, deferredAttrContext.msym, formals1.length(), deferredAttrContext.phase.isVarargsRequired());
1146             while (formals2.nonEmpty()) {
1147                 ResultInfo mresult = methodCheckResult(formals2.head, deferredAttrContext, warn, actuals.head);
1148                 mresult.check(null, formals1.head);
1149                 formals1 = formals1.tail;
1150                 formals2 = formals2.tail;
1151                 actuals = actuals.isEmpty() ? actuals : actuals.tail;
1152             }
1153         }
1154 
1155        /**
1156         * Create a method check context to be used during the most specific applicability check
1157         */
1158         ResultInfo methodCheckResult(Type to, DeferredAttr.DeferredAttrContext deferredAttrContext,
1159                Warner rsWarner, Type actual) {
1160             return attr.new ResultInfo(KindSelector.VAL, to,
1161                    new MostSpecificCheckContext(deferredAttrContext, rsWarner, actual));
1162         }
1163 
1164         /**
1165          * Subclass of method check context class that implements most specific
1166          * method conversion. If the actual type under analysis is a deferred type
1167          * a full blown structural analysis is carried out.
1168          */
1169         class MostSpecificCheckContext extends MethodCheckContext {
1170 
1171             Type actual;
1172 
1173             public MostSpecificCheckContext(DeferredAttrContext deferredAttrContext, Warner rsWarner, Type actual) {
1174                 super(true, deferredAttrContext, rsWarner);
1175                 this.actual = actual;
1176             }
1177 
1178             public boolean compatible(Type found, Type req, Warner warn) {
1179                 if (unrelatedFunctionalInterfaces(found, req) &&
1180                     (actual != null && actual.getTag() == DEFERRED)) {
1181                     DeferredType dt = (DeferredType) actual;
1182                     JCTree speculativeTree = dt.speculativeTree(deferredAttrContext);
1183                     if (speculativeTree != deferredAttr.stuckTree) {
1184                         return functionalInterfaceMostSpecific(found, req, speculativeTree);
1185                     }
1186                 }
1187                 return compatibleBySubtyping(found, req);
1188             }
1189 
1190             private boolean compatibleBySubtyping(Type found, Type req) {
1191                 if (!strict && found.isPrimitive() != req.isPrimitive()) {
1192                     found = found.isPrimitive() ? types.boxedClass(found).type : types.unboxedType(found);
1193                 }
1194                 return types.isSubtypeNoCapture(found, deferredAttrContext.inferenceContext.asUndetVar(req));
1195             }
1196 
1197             /** Whether {@code t} and {@code s} are unrelated functional interface types. */
1198             private boolean unrelatedFunctionalInterfaces(Type t, Type s) {
1199                 return types.isFunctionalInterface(t.tsym) &&
1200                        types.isFunctionalInterface(s.tsym) &&
1201                        unrelatedInterfaces(t, s);
1202             }
1203 
1204             /** Whether {@code t} and {@code s} are unrelated interface types; recurs on intersections. **/
1205             private boolean unrelatedInterfaces(Type t, Type s) {
1206                 if (t.isCompound()) {
1207                     for (Type ti : types.interfaces(t)) {
1208                         if (!unrelatedInterfaces(ti, s)) {
1209                             return false;
1210                         }
1211                     }
1212                     return true;
1213                 } else if (s.isCompound()) {
1214                     for (Type si : types.interfaces(s)) {
1215                         if (!unrelatedInterfaces(t, si)) {
1216                             return false;
1217                         }
1218                     }
1219                     return true;
1220                 } else {
1221                     return types.asSuper(t, s.tsym) == null && types.asSuper(s, t.tsym) == null;
1222                 }
1223             }
1224 
1225             /** Parameters {@code t} and {@code s} are unrelated functional interface types. */
1226             private boolean functionalInterfaceMostSpecific(Type t, Type s, JCTree tree) {
1227                 Type tDesc;
1228                 Type tDescNoCapture;
1229                 Type sDesc;
1230                 try {
1231                     tDesc = types.findDescriptorType(types.capture(t));
1232                     tDescNoCapture = types.findDescriptorType(t);
1233                     sDesc = types.findDescriptorType(s);
1234                 } catch (Types.FunctionDescriptorLookupError ex) {
1235                     // don't report, a more meaningful error should be reported upstream
1236                     return false;
1237                 }
1238                 final List<Type> tTypeParams = tDesc.getTypeArguments();
1239                 final List<Type> tTypeParamsNoCapture = tDescNoCapture.getTypeArguments();
1240                 final List<Type> sTypeParams = sDesc.getTypeArguments();
1241 
1242                 // compare type parameters
1243                 if (tDesc.hasTag(FORALL) && !types.hasSameBounds((ForAll) tDesc, (ForAll) tDescNoCapture)) {
1244                     return false;
1245                 }
1246                 // can't use Types.hasSameBounds on sDesc because bounds may have ivars
1247                 List<Type> tIter = tTypeParams;
1248                 List<Type> sIter = sTypeParams;
1249                 while (tIter.nonEmpty() && sIter.nonEmpty()) {
1250                     Type tBound = tIter.head.getUpperBound();
1251                     Type sBound = types.subst(sIter.head.getUpperBound(), sTypeParams, tTypeParams);
1252                     if (tBound.containsAny(tTypeParams) && inferenceContext().free(sBound)) {
1253                         return false;
1254                     }
1255                     if (!types.isSameType(tBound, inferenceContext().asUndetVar(sBound))) {
1256                         return false;
1257                     }
1258                     tIter = tIter.tail;
1259                     sIter = sIter.tail;
1260                 }
1261                 if (!tIter.isEmpty() || !sIter.isEmpty()) {
1262                     return false;
1263                 }
1264 
1265                 // compare parameters
1266                 List<Type> tParams = tDesc.getParameterTypes();
1267                 List<Type> tParamsNoCapture = tDescNoCapture.getParameterTypes();
1268                 List<Type> sParams = sDesc.getParameterTypes();
1269                 while (tParams.nonEmpty() && tParamsNoCapture.nonEmpty() && sParams.nonEmpty()) {
1270                     Type tParam = tParams.head;
1271                     Type tParamNoCapture = types.subst(tParamsNoCapture.head, tTypeParamsNoCapture, tTypeParams);
1272                     Type sParam = types.subst(sParams.head, sTypeParams, tTypeParams);
1273                     if (tParam.containsAny(tTypeParams) && inferenceContext().free(sParam)) {
1274                         return false;
1275                     }
1276                     if (!types.isSubtype(inferenceContext().asUndetVar(sParam), tParam)) {
1277                         return false;
1278                     }
1279                     if (!types.isSameType(tParamNoCapture, inferenceContext().asUndetVar(sParam))) {
1280                         return false;
1281                     }
1282                     tParams = tParams.tail;
1283                     tParamsNoCapture = tParamsNoCapture.tail;
1284                     sParams = sParams.tail;
1285                 }
1286                 if (!tParams.isEmpty() || !tParamsNoCapture.isEmpty() || !sParams.isEmpty()) {
1287                     return false;
1288                 }
1289 
1290                 // compare returns
1291                 Type tRet = tDesc.getReturnType();
1292                 Type sRet = types.subst(sDesc.getReturnType(), sTypeParams, tTypeParams);
1293                 if (tRet.containsAny(tTypeParams) && inferenceContext().free(sRet)) {
1294                     return false;
1295                 }
1296                 MostSpecificFunctionReturnChecker msc = new MostSpecificFunctionReturnChecker(tRet, sRet);
1297                 msc.scan(tree);
1298                 return msc.result;
1299             }
1300 
1301             /**
1302              * Tests whether one functional interface type can be considered more specific
1303              * than another unrelated functional interface type for the scanned expression.
1304              */
1305             class MostSpecificFunctionReturnChecker extends DeferredAttr.PolyScanner {
1306 
1307                 final Type tRet;
1308                 final Type sRet;
1309                 boolean result;
1310 
1311                 /** Parameters {@code t} and {@code s} are unrelated functional interface types. */
1312                 MostSpecificFunctionReturnChecker(Type tRet, Type sRet) {
1313                     this.tRet = tRet;
1314                     this.sRet = sRet;
1315                     result = true;
1316                 }
1317 
1318                 @Override
1319                 void skip(JCTree tree) {
1320                     result = false;
1321                 }
1322 
1323                 @Override
1324                 public void visitConditional(JCConditional tree) {
1325                     scan(asExpr(tree.truepart));
1326                     scan(asExpr(tree.falsepart));
1327                 }
1328 
1329                 @Override
1330                 public void visitReference(JCMemberReference tree) {
1331                     if (sRet.hasTag(VOID)) {
1332                         // do nothing
1333                     } else if (tRet.hasTag(VOID)) {
1334                         result = false;
1335                     } else if (tRet.isPrimitive() != sRet.isPrimitive()) {
1336                         boolean retValIsPrimitive =
1337                                 tree.refPolyKind == PolyKind.STANDALONE &&
1338                                 tree.sym.type.getReturnType().isPrimitive();
1339                         result &= (retValIsPrimitive == tRet.isPrimitive()) &&
1340                                   (retValIsPrimitive != sRet.isPrimitive());
1341                     } else {
1342                         result &= compatibleBySubtyping(tRet, sRet);
1343                     }
1344                 }
1345 
1346                 @Override
1347                 public void visitParens(JCParens tree) {
1348                     scan(asExpr(tree.expr));
1349                 }
1350 
1351                 @Override
1352                 public void visitLambda(JCLambda tree) {
1353                     if (sRet.hasTag(VOID)) {
1354                         // do nothing
1355                     } else if (tRet.hasTag(VOID)) {
1356                         result = false;
1357                     } else {
1358                         List<JCExpression> lambdaResults = lambdaResults(tree);
1359                         if (!lambdaResults.isEmpty() && unrelatedFunctionalInterfaces(tRet, sRet)) {
1360                             for (JCExpression expr : lambdaResults) {
1361                                 result &= functionalInterfaceMostSpecific(tRet, sRet, expr);
1362                             }
1363                         } else if (!lambdaResults.isEmpty() && tRet.isPrimitive() != sRet.isPrimitive()) {
1364                             for (JCExpression expr : lambdaResults) {
1365                                 boolean retValIsPrimitive = expr.isStandalone() && expr.type.isPrimitive();
1366                                 result &= (retValIsPrimitive == tRet.isPrimitive()) &&
1367                                         (retValIsPrimitive != sRet.isPrimitive());
1368                             }
1369                         } else {
1370                             result &= compatibleBySubtyping(tRet, sRet);
1371                         }
1372                     }
1373                 }
1374                 //where
1375 
1376                 private List<JCExpression> lambdaResults(JCLambda lambda) {
1377                     if (lambda.getBodyKind() == JCTree.JCLambda.BodyKind.EXPRESSION) {
1378                         return List.of(asExpr((JCExpression) lambda.body));
1379                     } else {
1380                         final ListBuffer<JCExpression> buffer = new ListBuffer<>();
1381                         DeferredAttr.LambdaReturnScanner lambdaScanner =
1382                                 new DeferredAttr.LambdaReturnScanner() {
1383                                     @Override
1384                                     public void visitReturn(JCReturn tree) {
1385                                         if (tree.expr != null) {
1386                                             buffer.append(asExpr(tree.expr));
1387                                         }
1388                                     }
1389                                 };
1390                         lambdaScanner.scan(lambda.body);
1391                         return buffer.toList();
1392                     }
1393                 }
1394 
1395                 private JCExpression asExpr(JCExpression expr) {
1396                     if (expr.type.hasTag(DEFERRED)) {
1397                         JCTree speculativeTree = ((DeferredType)expr.type).speculativeTree(deferredAttrContext);
1398                         if (speculativeTree != deferredAttr.stuckTree) {
1399                             expr = (JCExpression)speculativeTree;
1400                         }
1401                     }
1402                     return expr;
1403                 }
1404             }
1405 
1406         }
1407 
1408         public MethodCheck mostSpecificCheck(List<Type> actuals) {
1409             Assert.error("Cannot get here!");
1410             return null;
1411         }
1412     }
1413 
1414     public static class InapplicableMethodException extends CompilerInternalException {
1415         private static final long serialVersionUID = 0;
1416 
1417         transient JCDiagnostic diagnostic;
1418 
1419         InapplicableMethodException(JCDiagnostic diag, boolean dumpStackTraceOnError) {
1420             super(dumpStackTraceOnError);
1421             this.diagnostic = diag;
1422         }
1423 
1424         public JCDiagnostic getDiagnostic() {
1425             return diagnostic;
1426         }
1427     }
1428 
1429 /* ***************************************************************************
1430  *  Symbol lookup
1431  *  the following naming conventions for arguments are used
1432  *
1433  *       env      is the environment where the symbol was mentioned
1434  *       site     is the type of which the symbol is a member
1435  *       name     is the symbol's name
1436  *                if no arguments are given
1437  *       argtypes are the value arguments, if we search for a method
1438  *
1439  *  If no symbol was found, a ResolveError detailing the problem is returned.
1440  ****************************************************************************/
1441 
1442     /** Find field. Synthetic fields are always skipped.
1443      *  @param env     The current environment.
1444      *  @param site    The original type from where the selection takes place.
1445      *  @param name    The name of the field.
1446      *  @param c       The class to search for the field. This is always
1447      *                 a superclass or implemented interface of site's class.
1448      */
1449     Symbol findField(Env<AttrContext> env,
1450                      Type site,
1451                      Name name,
1452                      TypeSymbol c) {
1453         while (c.type.hasTag(TYPEVAR))
1454             c = c.type.getUpperBound().tsym;
1455         Symbol bestSoFar = varNotFound;
1456         Symbol sym;
1457         for (Symbol s : c.members().getSymbolsByName(name)) {
1458             if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) {
1459                 return isAccessible(env, site, s)
1460                     ? s : new AccessError(env, site, s);
1461             }
1462         }
1463         Type st = types.supertype(c.type);
1464         if (st != null && (st.hasTag(CLASS) || st.hasTag(TYPEVAR))) {
1465             sym = findField(env, site, name, st.tsym);
1466             bestSoFar = bestOf(bestSoFar, sym);
1467         }
1468         for (List<Type> l = types.interfaces(c.type);
1469              bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
1470              l = l.tail) {
1471             sym = findField(env, site, name, l.head.tsym);
1472             if (bestSoFar.exists() && sym.exists() &&
1473                 sym.owner != bestSoFar.owner)
1474                 bestSoFar = new AmbiguityError(bestSoFar, sym);
1475             else
1476                 bestSoFar = bestOf(bestSoFar, sym);
1477         }
1478         return bestSoFar;
1479     }
1480 
1481     /** Resolve a field identifier, throw a fatal error if not found.
1482      *  @param pos       The position to use for error reporting.
1483      *  @param env       The environment current at the method invocation.
1484      *  @param site      The type of the qualifying expression, in which
1485      *                   identifier is searched.
1486      *  @param name      The identifier's name.
1487      */
1488     public VarSymbol resolveInternalField(DiagnosticPosition pos, Env<AttrContext> env,
1489                                           Type site, Name name) {
1490         Symbol sym = findField(env, site, name, site.tsym);
1491         if (sym.kind == VAR) return (VarSymbol)sym;
1492         else throw new FatalError(
1493                  diags.fragment(Fragments.FatalErrCantLocateField(name)));
1494     }
1495 
1496     /** Find unqualified variable or field with given name.
1497      *  Synthetic fields always skipped.
1498      *  @param pos       The position to use for error reporting.
1499      *  @param env     The current environment.
1500      *  @param name    The name of the variable or field.
1501      */
1502     Symbol findVar(DiagnosticPosition pos, Env<AttrContext> env, Name name) {
1503         Symbol bestSoFar = varNotFound;
1504         Env<AttrContext> env1 = env;
1505         boolean staticOnly = false;
1506         while (env1.outer != null) {
1507             Symbol sym = null;
1508             for (Symbol s : env1.info.scope.getSymbolsByName(name)) {
1509                 if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) {
1510                     sym = s;
1511                     if (staticOnly) {
1512                         return new StaticError(sym);
1513                     }
1514                     break;
1515                 }
1516             }
1517             if (isStatic(env1)) staticOnly = true;
1518             if (sym == null) {
1519                 sym = findField(env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
1520             }
1521             if (sym.exists()) {
1522                 if (sym.kind == VAR &&
1523                         sym.owner.kind == TYP &&
1524                         (sym.flags() & STATIC) == 0) {
1525                     if (staticOnly)
1526                         return new StaticError(sym);
1527                     if (env1.info.ctorPrologue && !isAllowedEarlyReference(pos, env1, (VarSymbol)sym)) {
1528                         if (!env.tree.hasTag(ASSIGN) || !TreeInfo.isIdentOrThisDotIdent(((JCAssign)env.tree).lhs)) {
1529                             return new RefBeforeCtorCalledError(sym);
1530                         }
1531                     }
1532                 }
1533                 return sym;
1534             } else {
1535                 bestSoFar = bestOf(bestSoFar, sym);
1536             }
1537 
1538             if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
1539             env1 = env1.outer;
1540         }
1541 
1542         Symbol sym = findField(env, syms.predefClass.type, name, syms.predefClass);
1543         if (sym.exists())
1544             return sym;
1545         if (bestSoFar.exists())
1546             return bestSoFar;
1547 
1548         Symbol origin = null;
1549         for (Scope sc : new Scope[] { env.toplevel.namedImportScope, env.toplevel.starImportScope }) {
1550             for (Symbol currentSymbol : sc.getSymbolsByName(name)) {
1551                 if (currentSymbol.kind != VAR)
1552                     continue;
1553                 // invariant: sym.kind == Symbol.Kind.VAR
1554                 if (!bestSoFar.kind.isResolutionError() &&
1555                     currentSymbol.owner != bestSoFar.owner)
1556                     return new AmbiguityError(bestSoFar, currentSymbol);
1557                 else if (!bestSoFar.kind.betterThan(VAR)) {
1558                     origin = sc.getOrigin(currentSymbol).owner;
1559                     bestSoFar = isAccessible(env, origin.type, currentSymbol)
1560                         ? currentSymbol : new AccessError(env, origin.type, currentSymbol);
1561                 }
1562             }
1563             if (bestSoFar.exists()) break;
1564         }
1565         if (bestSoFar.kind == VAR && bestSoFar.owner.type != origin.type)
1566             return bestSoFar.clone(origin);
1567         else
1568             return bestSoFar;
1569     }
1570 
1571     Warner noteWarner = new Warner();
1572 
1573     /** Select the best method for a call site among two choices.
1574      *  @param env              The current environment.
1575      *  @param site             The original type from where the
1576      *                          selection takes place.
1577      *  @param argtypes         The invocation's value arguments,
1578      *  @param typeargtypes     The invocation's type arguments,
1579      *  @param sym              Proposed new best match.
1580      *  @param bestSoFar        Previously found best match.
1581      *  @param allowBoxing Allow boxing conversions of arguments.
1582      *  @param useVarargs Box trailing arguments into an array for varargs.
1583      */
1584     @SuppressWarnings("fallthrough")
1585     Symbol selectBest(Env<AttrContext> env,
1586                       Type site,
1587                       List<Type> argtypes,
1588                       List<Type> typeargtypes,
1589                       Symbol sym,
1590                       Symbol bestSoFar,
1591                       boolean allowBoxing,
1592                       boolean useVarargs) {
1593         if (sym.kind == ERR ||
1594                 (site.tsym != sym.owner && !sym.isInheritedIn(site.tsym, types)) ||
1595                 !notOverriddenIn(site, sym)) {
1596             return bestSoFar;
1597         } else if (useVarargs && (sym.flags() & VARARGS) == 0) {
1598             return bestSoFar.kind.isResolutionError() ?
1599                     new BadVarargsMethod((ResolveError)bestSoFar.baseSymbol()) :
1600                     bestSoFar;
1601         }
1602         Assert.check(!sym.kind.isResolutionError());
1603         try {
1604             types.noWarnings.clear();
1605             Type mt = rawInstantiate(env, site, sym, null, argtypes, typeargtypes,
1606                                allowBoxing, useVarargs, types.noWarnings);
1607             currentResolutionContext.addApplicableCandidate(sym, mt);
1608         } catch (InapplicableMethodException ex) {
1609             currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic());
1610             // Currently, an InapplicableMethodException occurs.
1611             // If bestSoFar.kind was ABSENT_MTH, return an InapplicableSymbolError(kind is WRONG_MTH).
1612             // If bestSoFar.kind was HIDDEN(AccessError)/WRONG_MTH/WRONG_MTHS, return an InapplicableSymbolsError(kind is WRONG_MTHS).
1613             // See JDK-8255968 for more information.
1614             switch (bestSoFar.kind) {
1615                 case ABSENT_MTH:
1616                     return new InapplicableSymbolError(currentResolutionContext);
1617                 case HIDDEN:
1618                     if (bestSoFar instanceof AccessError accessError) {
1619                         // Add the JCDiagnostic of previous AccessError to the currentResolutionContext
1620                         // and construct InapplicableSymbolsError.
1621                         // Intentionally fallthrough.
1622                         currentResolutionContext.addInapplicableCandidate(accessError.sym,
1623                                 accessError.getDiagnostic(JCDiagnostic.DiagnosticType.FRAGMENT, null, null, site, null, argtypes, typeargtypes));
1624                     } else {
1625                         return bestSoFar;
1626                     }
1627                 case WRONG_MTH:
1628                     bestSoFar = new InapplicableSymbolsError(currentResolutionContext);
1629                 default:
1630                     return bestSoFar;
1631             }
1632         }
1633         if (!isAccessible(env, site, sym)) {
1634             AccessError curAccessError = new AccessError(env, site, sym);
1635             JCDiagnostic curDiagnostic = curAccessError.getDiagnostic(JCDiagnostic.DiagnosticType.FRAGMENT, null, null, site, null, argtypes, typeargtypes);
1636             // Currently, an AccessError occurs.
1637             // If bestSoFar.kind was ABSENT_MTH, return an AccessError(kind is HIDDEN).
1638             // If bestSoFar.kind was HIDDEN(AccessError), WRONG_MTH, WRONG_MTHS, return an InapplicableSymbolsError(kind is WRONG_MTHS).
1639             // See JDK-8255968 for more information.
1640             if (bestSoFar.kind == ABSENT_MTH) {
1641                 bestSoFar = curAccessError;
1642             } else if (bestSoFar.kind == WRONG_MTH) {
1643                 // Add the JCDiagnostic of current AccessError to the currentResolutionContext
1644                 // and construct InapplicableSymbolsError.
1645                 currentResolutionContext.addInapplicableCandidate(sym, curDiagnostic);
1646                 bestSoFar = new InapplicableSymbolsError(currentResolutionContext);
1647             } else if (bestSoFar.kind == WRONG_MTHS) {
1648                 // Add the JCDiagnostic of current AccessError to the currentResolutionContext
1649                 currentResolutionContext.addInapplicableCandidate(sym, curDiagnostic);
1650             } else if (bestSoFar.kind == HIDDEN && bestSoFar instanceof AccessError accessError) {
1651                 // Add the JCDiagnostics of previous and current AccessError to the currentResolutionContext
1652                 // and construct InapplicableSymbolsError.
1653                 currentResolutionContext.addInapplicableCandidate(accessError.sym,
1654                         accessError.getDiagnostic(JCDiagnostic.DiagnosticType.FRAGMENT, null, null, site, null, argtypes, typeargtypes));
1655                 currentResolutionContext.addInapplicableCandidate(sym, curDiagnostic);
1656                 bestSoFar = new InapplicableSymbolsError(currentResolutionContext);
1657             }
1658             return bestSoFar;
1659         }
1660         return (bestSoFar.kind.isResolutionError() && bestSoFar.kind != AMBIGUOUS)
1661             ? sym
1662             : mostSpecific(argtypes, sym, bestSoFar, env, site, useVarargs);
1663     }
1664 
1665     /* Return the most specific of the two methods for a call,
1666      *  given that both are accessible and applicable.
1667      *  @param m1               A new candidate for most specific.
1668      *  @param m2               The previous most specific candidate.
1669      *  @param env              The current environment.
1670      *  @param site             The original type from where the selection
1671      *                          takes place.
1672      *  @param allowBoxing Allow boxing conversions of arguments.
1673      *  @param useVarargs Box trailing arguments into an array for varargs.
1674      */
1675     Symbol mostSpecific(List<Type> argtypes, Symbol m1,
1676                         Symbol m2,
1677                         Env<AttrContext> env,
1678                         final Type site,
1679                         boolean useVarargs) {
1680         switch (m2.kind) {
1681         case MTH:
1682             if (m1 == m2) return m1;
1683             boolean m1SignatureMoreSpecific =
1684                     signatureMoreSpecific(argtypes, env, site, m1, m2, useVarargs);
1685             boolean m2SignatureMoreSpecific =
1686                     signatureMoreSpecific(argtypes, env, site, m2, m1, useVarargs);
1687             if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) {
1688                 Type mt1 = types.memberType(site, m1);
1689                 Type mt2 = types.memberType(site, m2);
1690                 if (!types.overrideEquivalent(mt1, mt2))
1691                     return ambiguityError(m1, m2);
1692 
1693                 // same signature; select (a) the non-bridge method, or
1694                 // (b) the one that overrides the other, or (c) the concrete
1695                 // one, or (d) merge both abstract signatures
1696                 if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE))
1697                     return ((m1.flags() & BRIDGE) != 0) ? m2 : m1;
1698 
1699                 if (m1.baseSymbol() == m2.baseSymbol()) {
1700                     // this is the same imported symbol which has been cloned twice.
1701                     // Return the first one (either will do).
1702                     return m1;
1703                 }
1704 
1705                 // if one overrides or hides the other, use it
1706                 TypeSymbol m1Owner = (TypeSymbol)m1.owner;
1707                 TypeSymbol m2Owner = (TypeSymbol)m2.owner;
1708                 // the two owners can never be the same if the target methods are compiled from source,
1709                 // but we need to protect against cases where the methods are defined in some classfile
1710                 // and make sure we issue an ambiguity error accordingly (by skipping the logic below).
1711                 if (m1Owner != m2Owner) {
1712                     if (types.asSuper(m1Owner.type, m2Owner) != null &&
1713                         ((m1.owner.flags_field & INTERFACE) == 0 ||
1714                          (m2.owner.flags_field & INTERFACE) != 0) &&
1715                         m1.overrides(m2, m1Owner, types, false))
1716                         return m1;
1717                     if (types.asSuper(m2Owner.type, m1Owner) != null &&
1718                         ((m2.owner.flags_field & INTERFACE) == 0 ||
1719                          (m1.owner.flags_field & INTERFACE) != 0) &&
1720                         m2.overrides(m1, m2Owner, types, false))
1721                         return m2;
1722                 }
1723                 boolean m1Abstract = (m1.flags() & ABSTRACT) != 0;
1724                 boolean m2Abstract = (m2.flags() & ABSTRACT) != 0;
1725                 if (m1Abstract && !m2Abstract) return m2;
1726                 if (m2Abstract && !m1Abstract) return m1;
1727                 // both abstract or both concrete
1728                 return ambiguityError(m1, m2);
1729             }
1730             if (m1SignatureMoreSpecific) return m1;
1731             if (m2SignatureMoreSpecific) return m2;
1732             return ambiguityError(m1, m2);
1733         case AMBIGUOUS:
1734             //compare m1 to ambiguous methods in m2
1735             AmbiguityError e = (AmbiguityError)m2.baseSymbol();
1736             boolean m1MoreSpecificThanAnyAmbiguous = true;
1737             boolean allAmbiguousMoreSpecificThanM1 = true;
1738             for (Symbol s : e.ambiguousSyms) {
1739                 Symbol moreSpecific = mostSpecific(argtypes, m1, s, env, site, useVarargs);
1740                 m1MoreSpecificThanAnyAmbiguous &= moreSpecific == m1;
1741                 allAmbiguousMoreSpecificThanM1 &= moreSpecific == s;
1742             }
1743             if (m1MoreSpecificThanAnyAmbiguous)
1744                 return m1;
1745             //if m1 is more specific than some ambiguous methods, but other ambiguous methods are
1746             //more specific than m1, add it as a new ambiguous method:
1747             if (!allAmbiguousMoreSpecificThanM1)
1748                 e.addAmbiguousSymbol(m1);
1749             return e;
1750         default:
1751             throw new AssertionError();
1752         }
1753     }
1754     //where
1755     private boolean signatureMoreSpecific(List<Type> actuals, Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean useVarargs) {
1756         noteWarner.clear();
1757         int maxLength = Math.max(
1758                             Math.max(m1.type.getParameterTypes().length(), actuals.length()),
1759                             m2.type.getParameterTypes().length());
1760         MethodResolutionContext prevResolutionContext = currentResolutionContext;
1761         try {
1762             currentResolutionContext = new MethodResolutionContext();
1763             currentResolutionContext.step = prevResolutionContext.step;
1764             currentResolutionContext.methodCheck =
1765                     prevResolutionContext.methodCheck.mostSpecificCheck(actuals);
1766             Type mst = instantiate(env, site, m2, null,
1767                     adjustArgs(types.cvarLowerBounds(types.memberType(site, m1).getParameterTypes()), m1, maxLength, useVarargs), null,
1768                     false, useVarargs, noteWarner);
1769             return mst != null &&
1770                     !noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
1771         } finally {
1772             currentResolutionContext = prevResolutionContext;
1773         }
1774     }
1775 
1776     List<Type> adjustArgs(List<Type> args, Symbol msym, int length, boolean allowVarargs) {
1777         if ((msym.flags() & VARARGS) != 0 && allowVarargs) {
1778             Type varargsElem = types.elemtype(args.last());
1779             if (varargsElem == null) {
1780                 Assert.error("Bad varargs = " + args.last() + " " + msym);
1781             }
1782             List<Type> newArgs = args.reverse().tail.prepend(varargsElem).reverse();
1783             while (newArgs.length() < length) {
1784                 newArgs = newArgs.append(newArgs.last());
1785             }
1786             return newArgs;
1787         } else {
1788             return args;
1789         }
1790     }
1791     //where
1792     Symbol ambiguityError(Symbol m1, Symbol m2) {
1793         if (((m1.flags() | m2.flags()) & CLASH) != 0) {
1794             return (m1.flags() & CLASH) == 0 ? m1 : m2;
1795         } else {
1796             return new AmbiguityError(m1, m2);
1797         }
1798     }
1799 
1800     Symbol findMethodInScope(Env<AttrContext> env,
1801             Type site,
1802             Name name,
1803             List<Type> argtypes,
1804             List<Type> typeargtypes,
1805             Scope sc,
1806             Symbol bestSoFar,
1807             boolean allowBoxing,
1808             boolean useVarargs,
1809             boolean abstractok) {
1810         for (Symbol s : sc.getSymbolsByName(name, new LookupFilter(abstractok))) {
1811             bestSoFar = selectBest(env, site, argtypes, typeargtypes, s,
1812                     bestSoFar, allowBoxing, useVarargs);
1813         }
1814         return bestSoFar;
1815     }
1816     //where
1817         class LookupFilter implements Predicate<Symbol> {
1818 
1819             boolean abstractOk;
1820 
1821             LookupFilter(boolean abstractOk) {
1822                 this.abstractOk = abstractOk;
1823             }
1824 
1825             @Override
1826             public boolean test(Symbol s) {
1827                 long flags = s.flags();
1828                 return s.kind == MTH &&
1829                         (flags & SYNTHETIC) == 0 &&
1830                         (abstractOk ||
1831                         (flags & DEFAULT) != 0 ||
1832                         (flags & ABSTRACT) == 0);
1833             }
1834         }
1835 
1836     /** Find best qualified method matching given name, type and value
1837      *  arguments.
1838      *  @param env       The current environment.
1839      *  @param site      The original type from where the selection
1840      *                   takes place.
1841      *  @param name      The method's name.
1842      *  @param argtypes  The method's value arguments.
1843      *  @param typeargtypes The method's type arguments
1844      *  @param allowBoxing Allow boxing conversions of arguments.
1845      *  @param useVarargs Box trailing arguments into an array for varargs.
1846      */
1847     Symbol findMethod(Env<AttrContext> env,
1848                       Type site,
1849                       Name name,
1850                       List<Type> argtypes,
1851                       List<Type> typeargtypes,
1852                       boolean allowBoxing,
1853                       boolean useVarargs) {
1854         Symbol bestSoFar = methodNotFound;
1855         bestSoFar = findMethod(env,
1856                           site,
1857                           name,
1858                           argtypes,
1859                           typeargtypes,
1860                           site.tsym.type,
1861                           bestSoFar,
1862                           allowBoxing,
1863                           useVarargs);
1864         return bestSoFar;
1865     }
1866     // where
1867     private Symbol findMethod(Env<AttrContext> env,
1868                               Type site,
1869                               Name name,
1870                               List<Type> argtypes,
1871                               List<Type> typeargtypes,
1872                               Type intype,
1873                               Symbol bestSoFar,
1874                               boolean allowBoxing,
1875                               boolean useVarargs) {
1876         @SuppressWarnings({"unchecked","rawtypes"})
1877         List<Type>[] itypes = (List<Type>[])new List[] { List.<Type>nil(), List.<Type>nil() };
1878 
1879         InterfaceLookupPhase iphase = InterfaceLookupPhase.ABSTRACT_OK;
1880         boolean isInterface = site.tsym.isInterface();
1881         for (TypeSymbol s : isInterface ? List.of(intype.tsym) : superclasses(intype)) {
1882             bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
1883                     s.members(), bestSoFar, allowBoxing, useVarargs, true);
1884             if (name == names.init) return bestSoFar;
1885             iphase = (iphase == null) ? null : iphase.update(s, this);
1886             if (iphase != null) {
1887                 for (Type itype : types.interfaces(s.type)) {
1888                     itypes[iphase.ordinal()] = types.union(types.closure(itype), itypes[iphase.ordinal()]);
1889                 }
1890             }
1891         }
1892 
1893         Symbol concrete = bestSoFar.kind.isValid() &&
1894                 (bestSoFar.flags() & ABSTRACT) == 0 ?
1895                 bestSoFar : methodNotFound;
1896 
1897         for (InterfaceLookupPhase iphase2 : InterfaceLookupPhase.values()) {
1898             //keep searching for abstract methods
1899             for (Type itype : itypes[iphase2.ordinal()]) {
1900                 if (!itype.isInterface()) continue; //skip j.l.Object (included by Types.closure())
1901                 if (iphase2 == InterfaceLookupPhase.DEFAULT_OK &&
1902                         (itype.tsym.flags() & DEFAULT) == 0) continue;
1903                 bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
1904                         itype.tsym.members(), bestSoFar, allowBoxing, useVarargs, true);
1905                 if (concrete != bestSoFar &&
1906                     concrete.kind.isValid() &&
1907                     bestSoFar.kind.isValid() &&
1908                         types.isSubSignature(concrete.type, bestSoFar.type)) {
1909                     //this is an hack - as javac does not do full membership checks
1910                     //most specific ends up comparing abstract methods that might have
1911                     //been implemented by some concrete method in a subclass and,
1912                     //because of raw override, it is possible for an abstract method
1913                     //to be more specific than the concrete method - so we need
1914                     //to explicitly call that out (see CR 6178365)
1915                     bestSoFar = concrete;
1916                 }
1917             }
1918         }
1919         if (isInterface && bestSoFar.kind.isResolutionError()) {
1920             bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
1921                     syms.objectType.tsym.members(), bestSoFar, allowBoxing, useVarargs, true);
1922             if (bestSoFar.kind.isValid()) {
1923                 Symbol baseSymbol = bestSoFar;
1924                 bestSoFar = new MethodSymbol(bestSoFar.flags_field, bestSoFar.name, bestSoFar.type, intype.tsym) {
1925                     @Override
1926                     public Symbol baseSymbol() {
1927                         return baseSymbol;
1928                     }
1929                 };
1930             }
1931         }
1932         return bestSoFar;
1933     }
1934 
1935     enum InterfaceLookupPhase {
1936         ABSTRACT_OK() {
1937             @Override
1938             InterfaceLookupPhase update(Symbol s, Resolve rs) {
1939                 //We should not look for abstract methods if receiver is a concrete class
1940                 //(as concrete classes are expected to implement all abstracts coming
1941                 //from superinterfaces)
1942                 if ((s.flags() & (ABSTRACT | INTERFACE | ENUM)) != 0) {
1943                     return this;
1944                 } else {
1945                     return DEFAULT_OK;
1946                 }
1947             }
1948         },
1949         DEFAULT_OK() {
1950             @Override
1951             InterfaceLookupPhase update(Symbol s, Resolve rs) {
1952                 return this;
1953             }
1954         };
1955 
1956         abstract InterfaceLookupPhase update(Symbol s, Resolve rs);
1957     }
1958 
1959     /**
1960      * Return an Iterable object to scan the superclasses of a given type.
1961      * It's crucial that the scan is done lazily, as we don't want to accidentally
1962      * access more supertypes than strictly needed (as this could trigger completion
1963      * errors if some of the not-needed supertypes are missing/ill-formed).
1964      */
1965     Iterable<TypeSymbol> superclasses(final Type intype) {
1966         return () -> new Iterator<TypeSymbol>() {
1967 
1968             List<TypeSymbol> seen = List.nil();
1969             TypeSymbol currentSym = symbolFor(intype);
1970             TypeSymbol prevSym = null;
1971 
1972             public boolean hasNext() {
1973                 if (currentSym == syms.noSymbol) {
1974                     currentSym = symbolFor(types.supertype(prevSym.type));
1975                 }
1976                 return currentSym != null;
1977             }
1978 
1979             public TypeSymbol next() {
1980                 prevSym = currentSym;
1981                 currentSym = syms.noSymbol;
1982                 Assert.check(prevSym != null || prevSym != syms.noSymbol);
1983                 return prevSym;
1984             }
1985 
1986             public void remove() {
1987                 throw new UnsupportedOperationException();
1988             }
1989 
1990             TypeSymbol symbolFor(Type t) {
1991                 if (!t.hasTag(CLASS) &&
1992                         !t.hasTag(TYPEVAR)) {
1993                     return null;
1994                 }
1995                 t = types.skipTypeVars(t, false);
1996                 if (seen.contains(t.tsym)) {
1997                     //degenerate case in which we have a circular
1998                     //class hierarchy - because of ill-formed classfiles
1999                     return null;
2000                 }
2001                 seen = seen.prepend(t.tsym);
2002                 return t.tsym;
2003             }
2004         };
2005     }
2006 
2007     /** Find unqualified method matching given name, type and value arguments.
2008      *  @param env       The current environment.
2009      *  @param name      The method's name.
2010      *  @param argtypes  The method's value arguments.
2011      *  @param typeargtypes  The method's type arguments.
2012      *  @param allowBoxing Allow boxing conversions of arguments.
2013      *  @param useVarargs Box trailing arguments into an array for varargs.
2014      */
2015     Symbol findFun(Env<AttrContext> env, Name name,
2016                    List<Type> argtypes, List<Type> typeargtypes,
2017                    boolean allowBoxing, boolean useVarargs) {
2018         Symbol bestSoFar = methodNotFound;
2019         Env<AttrContext> env1 = env;
2020         boolean staticOnly = false;
2021         while (env1.outer != null) {
2022             if (isStatic(env1)) staticOnly = true;
2023             Assert.check(env1.info.preferredTreeForDiagnostics == null);
2024             env1.info.preferredTreeForDiagnostics = env.tree;
2025             try {
2026                 Symbol sym = findMethod(
2027                     env1, env1.enclClass.sym.type, name, argtypes, typeargtypes,
2028                     allowBoxing, useVarargs);
2029                 if (sym.exists()) {
2030                     if (sym.kind == MTH &&
2031                             sym.owner.kind == TYP &&
2032                             (sym.flags() & STATIC) == 0) {
2033                         if (staticOnly)
2034                             return new StaticError(sym);
2035                         if (env1.info.ctorPrologue && env1 == env)
2036                             return new RefBeforeCtorCalledError(sym);
2037                     }
2038                     return sym;
2039                 } else {
2040                     bestSoFar = bestOf(bestSoFar, sym);
2041                 }
2042             } finally {
2043                 env1.info.preferredTreeForDiagnostics = null;
2044             }
2045             if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
2046             env1 = env1.outer;
2047         }
2048 
2049         Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
2050                                 typeargtypes, allowBoxing, useVarargs);
2051         if (sym.exists())
2052             return sym;
2053 
2054         for (Symbol currentSym : env.toplevel.namedImportScope.getSymbolsByName(name)) {
2055             Symbol origin = env.toplevel.namedImportScope.getOrigin(currentSym).owner;
2056             if (currentSym.kind == MTH) {
2057                 if (currentSym.owner.type != origin.type)
2058                     currentSym = currentSym.clone(origin);
2059                 if (!isAccessible(env, origin.type, currentSym))
2060                     currentSym = new AccessError(env, origin.type, currentSym);
2061                 bestSoFar = selectBest(env, origin.type,
2062                                        argtypes, typeargtypes,
2063                                        currentSym, bestSoFar,
2064                                        allowBoxing, useVarargs);
2065             }
2066         }
2067         if (bestSoFar.exists())
2068             return bestSoFar;
2069 
2070         for (Symbol currentSym : env.toplevel.starImportScope.getSymbolsByName(name)) {
2071             Symbol origin = env.toplevel.starImportScope.getOrigin(currentSym).owner;
2072             if (currentSym.kind == MTH) {
2073                 if (currentSym.owner.type != origin.type)
2074                     currentSym = currentSym.clone(origin);
2075                 if (!isAccessible(env, origin.type, currentSym))
2076                     currentSym = new AccessError(env, origin.type, currentSym);
2077                 bestSoFar = selectBest(env, origin.type,
2078                                        argtypes, typeargtypes,
2079                                        currentSym, bestSoFar,
2080                                        allowBoxing, useVarargs);
2081             }
2082         }
2083         return bestSoFar;
2084     }
2085 
2086     /** Load toplevel or member class with given fully qualified name and
2087      *  verify that it is accessible.
2088      *  @param env       The current environment.
2089      *  @param name      The fully qualified name of the class to be loaded.
2090      */
2091     Symbol loadClass(Env<AttrContext> env, Name name, RecoveryLoadClass recoveryLoadClass) {
2092         try {
2093             ClassSymbol c = finder.loadClass(env.toplevel.modle, name);
2094             return isAccessible(env, c) ? c : new AccessError(env, null, c);
2095         } catch (ClassFinder.BadClassFile err) {
2096             return new BadClassFileError(err);
2097         } catch (CompletionFailure ex) {
2098             Symbol candidate = recoveryLoadClass.loadClass(env, name);
2099 
2100             if (candidate != null) {
2101                 return candidate;
2102             }
2103 
2104             return typeNotFound;
2105         }
2106     }
2107 
2108     public interface RecoveryLoadClass {
2109         Symbol loadClass(Env<AttrContext> env, Name name);
2110     }
2111 
2112     private final RecoveryLoadClass noRecovery = (env, name) -> null;
2113 
2114     private final RecoveryLoadClass doRecoveryLoadClass = new RecoveryLoadClass() {
2115         @Override public Symbol loadClass(Env<AttrContext> env, Name name) {
2116             List<Name> candidates = Convert.classCandidates(name);
2117             return lookupInvisibleSymbol(env, name,
2118                                          n -> () -> createCompoundIterator(candidates,
2119                                                                            c -> syms.getClassesForName(c)
2120                                                                                     .iterator()),
2121                                          (ms, n) -> {
2122                 for (Name candidate : candidates) {
2123                     try {
2124                         return finder.loadClass(ms, candidate);
2125                     } catch (CompletionFailure cf) {
2126                         //ignore
2127                     }
2128                 }
2129                 return null;
2130             }, sym -> sym.kind == Kind.TYP, typeNotFound);
2131         }
2132     };
2133 
2134     private final RecoveryLoadClass namedImportScopeRecovery = (env, name) -> {
2135         Scope importScope = env.toplevel.namedImportScope;
2136         Symbol existing = importScope.findFirst(Convert.shortName(name),
2137                                                 sym -> sym.kind == TYP && sym.flatName() == name);
2138 
2139         if (existing != null) {
2140             return new InvisibleSymbolError(env, true, existing);
2141         }
2142         return null;
2143     };
2144 
2145     private final RecoveryLoadClass starImportScopeRecovery = (env, name) -> {
2146         Scope importScope = env.toplevel.starImportScope;
2147         Symbol existing = importScope.findFirst(Convert.shortName(name),
2148                                                 sym -> sym.kind == TYP && sym.flatName() == name);
2149 
2150         if (existing != null) {
2151             try {
2152                 existing = finder.loadClass(existing.packge().modle, name);
2153 
2154                 return new InvisibleSymbolError(env, true, existing);
2155             } catch (CompletionFailure cf) {
2156                 //ignore
2157             }
2158         }
2159 
2160         return null;
2161     };
2162 
2163     Symbol lookupPackage(Env<AttrContext> env, Name name) {
2164         PackageSymbol pack = syms.lookupPackage(env.toplevel.modle, name);
2165 
2166         if (allowModules && isImportOnDemand(env, name)) {
2167             if (pack.members().isEmpty()) {
2168                 return lookupInvisibleSymbol(env, name, syms::getPackagesForName, syms::enterPackage, sym -> {
2169                     sym.complete();
2170                     return !sym.members().isEmpty();
2171                 }, pack);
2172             }
2173         }
2174 
2175         return pack;
2176     }
2177 
2178     private boolean isImportOnDemand(Env<AttrContext> env, Name name) {
2179         if (!env.tree.hasTag(IMPORT))
2180             return false;
2181 
2182         JCTree qualid = ((JCImport) env.tree).qualid;
2183 
2184         if (!qualid.hasTag(SELECT))
2185             return false;
2186 
2187         if (TreeInfo.name(qualid) != names.asterisk)
2188             return false;
2189 
2190         return TreeInfo.fullName(((JCFieldAccess) qualid).selected) == name;
2191     }
2192 
2193     private <S extends Symbol> Symbol lookupInvisibleSymbol(Env<AttrContext> env,
2194                                                             Name name,
2195                                                             Function<Name, Iterable<S>> get,
2196                                                             BiFunction<ModuleSymbol, Name, S> load,
2197                                                             Predicate<S> validate,
2198                                                             Symbol defaultResult) {
2199         //even if a class/package cannot be found in the current module and among packages in modules
2200         //it depends on that are exported for any or this module, the class/package may exist internally
2201         //in some of these modules, or may exist in a module on which this module does not depend.
2202         //Provide better diagnostic in such cases by looking for the class in any module:
2203         Iterable<? extends S> candidates = get.apply(name);
2204 
2205         for (S sym : candidates) {
2206             if (validate.test(sym))
2207                 return createInvisibleSymbolError(env, sym);
2208         }
2209 
2210         Set<ModuleSymbol> recoverableModules = new HashSet<>(syms.getAllModules());
2211 
2212         recoverableModules.add(syms.unnamedModule);
2213         recoverableModules.remove(env.toplevel.modle);
2214 
2215         for (ModuleSymbol ms : recoverableModules) {
2216             //avoid overly eager completing classes from source-based modules, as those
2217             //may not be completable with the current compiler settings:
2218             if (ms.sourceLocation == null) {
2219                 if (ms.classLocation == null) {
2220                     ms = moduleFinder.findModule(ms);
2221                 }
2222 
2223                 if (ms.kind != ERR) {
2224                     S sym = load.apply(ms, name);
2225 
2226                     if (sym != null && validate.test(sym)) {
2227                         return createInvisibleSymbolError(env, sym);
2228                     }
2229                 }
2230             }
2231         }
2232 
2233         return defaultResult;
2234     }
2235 
2236     private Symbol createInvisibleSymbolError(Env<AttrContext> env, Symbol sym) {
2237         if (symbolPackageVisible(env, sym)) {
2238             return new AccessError(env, null, sym);
2239         } else {
2240             return new InvisibleSymbolError(env, false, sym);
2241         }
2242     }
2243 
2244     private boolean symbolPackageVisible(Env<AttrContext> env, Symbol sym) {
2245         ModuleSymbol envMod = env.toplevel.modle;
2246         PackageSymbol symPack = sym.packge();
2247         return envMod == symPack.modle ||
2248                envMod.visiblePackages.containsKey(symPack.fullname);
2249     }
2250 
2251     /**
2252      * Find a type declared in a scope (not inherited).  Return null
2253      * if none is found.
2254      *  @param env       The current environment.
2255      *  @param site      The original type from where the selection takes
2256      *                   place.
2257      *  @param name      The type's name.
2258      *  @param c         The class to search for the member type. This is
2259      *                   always a superclass or implemented interface of
2260      *                   site's class.
2261      */
2262     Symbol findImmediateMemberType(Env<AttrContext> env,
2263                                    Type site,
2264                                    Name name,
2265                                    TypeSymbol c) {
2266         for (Symbol sym : c.members().getSymbolsByName(name)) {
2267             if (sym.kind == TYP) {
2268                 return isAccessible(env, site, sym)
2269                     ? sym
2270                     : new AccessError(env, site, sym);
2271             }
2272         }
2273         return typeNotFound;
2274     }
2275 
2276     /** Find a member type inherited from a superclass or interface.
2277      *  @param env       The current environment.
2278      *  @param site      The original type from where the selection takes
2279      *                   place.
2280      *  @param name      The type's name.
2281      *  @param c         The class to search for the member type. This is
2282      *                   always a superclass or implemented interface of
2283      *                   site's class.
2284      */
2285     Symbol findInheritedMemberType(Env<AttrContext> env,
2286                                    Type site,
2287                                    Name name,
2288                                    TypeSymbol c) {
2289         Symbol bestSoFar = typeNotFound;
2290         Symbol sym;
2291         Type st = types.supertype(c.type);
2292         if (st != null && st.hasTag(CLASS)) {
2293             sym = findMemberType(env, site, name, st.tsym);
2294             bestSoFar = bestOf(bestSoFar, sym);
2295         }
2296         for (List<Type> l = types.interfaces(c.type);
2297              bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
2298              l = l.tail) {
2299             sym = findMemberType(env, site, name, l.head.tsym);
2300             if (!bestSoFar.kind.isResolutionError() &&
2301                 !sym.kind.isResolutionError() &&
2302                 sym.owner != bestSoFar.owner)
2303                 bestSoFar = new AmbiguityError(bestSoFar, sym);
2304             else
2305                 bestSoFar = bestOf(bestSoFar, sym);
2306         }
2307         return bestSoFar;
2308     }
2309 
2310     /** Find qualified member type.
2311      *  @param env       The current environment.
2312      *  @param site      The original type from where the selection takes
2313      *                   place.
2314      *  @param name      The type's name.
2315      *  @param c         The class to search for the member type. This is
2316      *                   always a superclass or implemented interface of
2317      *                   site's class.
2318      */
2319     Symbol findMemberType(Env<AttrContext> env,
2320                           Type site,
2321                           Name name,
2322                           TypeSymbol c) {
2323         Symbol sym = findImmediateMemberType(env, site, name, c);
2324 
2325         if (sym != typeNotFound)
2326             return sym;
2327 
2328         return findInheritedMemberType(env, site, name, c);
2329 
2330     }
2331 
2332     /** Find a global type in given scope and load corresponding class.
2333      *  @param env       The current environment.
2334      *  @param scope     The scope in which to look for the type.
2335      *  @param name      The type's name.
2336      */
2337     Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name, RecoveryLoadClass recoveryLoadClass) {
2338         Symbol bestSoFar = typeNotFound;
2339         for (Symbol s : scope.getSymbolsByName(name)) {
2340             Symbol sym = loadClass(env, s.flatName(), recoveryLoadClass);
2341             if (bestSoFar.kind == TYP && sym.kind == TYP &&
2342                 bestSoFar != sym)
2343                 return new AmbiguityError(bestSoFar, sym);
2344             else
2345                 bestSoFar = bestOf(bestSoFar, sym);
2346         }
2347         return bestSoFar;
2348     }
2349 
2350     Symbol findTypeVar(Env<AttrContext> env, Name name, boolean staticOnly) {
2351         for (Symbol sym : env.info.scope.getSymbolsByName(name)) {
2352             if (sym.kind == TYP) {
2353                 if (sym.type.hasTag(TYPEVAR) &&
2354                         (staticOnly || (isStatic(env) && sym.owner.kind == TYP)))
2355                     // if staticOnly is set, it means that we have recursed through a static declaration,
2356                     // so type variable symbols should not be accessible. If staticOnly is unset, but
2357                     // we are in a static declaration (field or method), we should not allow type-variables
2358                     // defined in the enclosing class to "leak" into this context.
2359                     return new StaticError(sym);
2360                 return sym;
2361             }
2362         }
2363         return typeNotFound;
2364     }
2365 
2366     /** Find an unqualified type symbol.
2367      *  @param env       The current environment.
2368      *  @param name      The type's name.
2369      */
2370     Symbol findType(Env<AttrContext> env, Name name) {
2371         if (name == names.empty)
2372             return typeNotFound; // do not allow inadvertent "lookup" of anonymous types
2373         Symbol bestSoFar = typeNotFound;
2374         Symbol sym;
2375         boolean staticOnly = false;
2376         for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) {
2377             // First, look for a type variable and the first member type
2378             final Symbol tyvar = findTypeVar(env1, name, staticOnly);
2379             if (isStatic(env1)) staticOnly = true;
2380             sym = findImmediateMemberType(env1, env1.enclClass.sym.type,
2381                                           name, env1.enclClass.sym);
2382 
2383             // Return the type variable if we have it, and have no
2384             // immediate member, OR the type variable is for a method.
2385             if (tyvar != typeNotFound) {
2386                 if (env.baseClause || sym == typeNotFound ||
2387                     (tyvar.kind == TYP && tyvar.exists() &&
2388                      tyvar.owner.kind == MTH)) {
2389                     return tyvar;
2390                 }
2391             }
2392 
2393             // If the environment is a class def, finish up,
2394             // otherwise, do the entire findMemberType
2395             if (sym == typeNotFound)
2396                 sym = findInheritedMemberType(env1, env1.enclClass.sym.type,
2397                                               name, env1.enclClass.sym);
2398 
2399             if (staticOnly && sym.kind == TYP &&
2400                 sym.type.hasTag(CLASS) &&
2401                 sym.type.getEnclosingType().hasTag(CLASS) &&
2402                 env1.enclClass.sym.type.isParameterized() &&
2403                 sym.type.getEnclosingType().isParameterized())
2404                 return new StaticError(sym);
2405             else if (sym.exists()) return sym;
2406             else bestSoFar = bestOf(bestSoFar, sym);
2407 
2408             JCClassDecl encl = env1.baseClause ? (JCClassDecl)env1.tree : env1.enclClass;
2409             if ((encl.sym.flags() & STATIC) != 0)
2410                 staticOnly = true;
2411         }
2412 
2413         if (!env.tree.hasTag(IMPORT)) {
2414             sym = findGlobalType(env, env.toplevel.namedImportScope, name, namedImportScopeRecovery);
2415             if (sym.exists()) return sym;
2416             else bestSoFar = bestOf(bestSoFar, sym);
2417 
2418             sym = findGlobalType(env, env.toplevel.toplevelScope, name, noRecovery);
2419             if (sym.exists()) return sym;
2420             else bestSoFar = bestOf(bestSoFar, sym);
2421 
2422             sym = findGlobalType(env, env.toplevel.packge.members(), name, noRecovery);
2423             if (sym.exists()) return sym;
2424             else bestSoFar = bestOf(bestSoFar, sym);
2425 
2426             sym = findGlobalType(env, env.toplevel.starImportScope, name, starImportScopeRecovery);
2427             if (sym.exists()) return sym;
2428             else bestSoFar = bestOf(bestSoFar, sym);
2429         }
2430 
2431         return bestSoFar;
2432     }
2433 
2434     /** Find an unqualified identifier which matches a specified kind set.
2435      *  @param pos       position on which report warnings, if any;
2436      *                   null warnings should not be reported
2437      *  @param env       The current environment.
2438      *  @param name      The identifier's name.
2439      *  @param kind      Indicates the possible symbol kinds
2440      *                   (a subset of VAL, TYP, PCK).
2441      */
2442     Symbol findIdent(DiagnosticPosition pos, Env<AttrContext> env, Name name, KindSelector kind) {
2443         try {
2444             return checkNonExistentType(checkRestrictedType(pos, findIdentInternal(pos, env, name, kind), name));
2445         } catch (ClassFinder.BadClassFile err) {
2446             return new BadClassFileError(err);
2447         } catch (CompletionFailure cf) {
2448             chk.completionError(pos, cf);
2449             return typeNotFound;
2450         }
2451     }
2452 
2453     Symbol findIdentInternal(DiagnosticPosition pos, Env<AttrContext> env, Name name, KindSelector kind) {
2454         Symbol bestSoFar = typeNotFound;
2455         Symbol sym;
2456 
2457         if (kind.contains(KindSelector.VAL)) {
2458             sym = findVar(pos, env, name);
2459             if (sym.exists()) return sym;
2460             else bestSoFar = bestOf(bestSoFar, sym);
2461         }
2462 
2463         if (kind.contains(KindSelector.TYP)) {
2464             sym = findType(env, name);
2465             if (sym.exists()) return sym;
2466             else bestSoFar = bestOf(bestSoFar, sym);
2467         }
2468 
2469         if (kind.contains(KindSelector.PCK))
2470             return lookupPackage(env, name);
2471         else return bestSoFar;
2472     }
2473 
2474     /** Find an identifier in a package which matches a specified kind set.
2475      *  @param pos       position on which report warnings, if any;
2476      *                   null warnings should not be reported
2477      *  @param env       The current environment.
2478      *  @param name      The identifier's name.
2479      *  @param kind      Indicates the possible symbol kinds
2480      *                   (a nonempty subset of TYP, PCK).
2481      */
2482     Symbol findIdentInPackage(DiagnosticPosition pos,
2483                               Env<AttrContext> env, TypeSymbol pck,
2484                               Name name, KindSelector kind) {
2485         return checkNonExistentType(checkRestrictedType(pos, findIdentInPackageInternal(env, pck, name, kind), name));
2486     }
2487 
2488     Symbol findIdentInPackageInternal(Env<AttrContext> env, TypeSymbol pck,
2489                               Name name, KindSelector kind) {
2490         Name fullname = TypeSymbol.formFullName(name, pck);
2491         Symbol bestSoFar = typeNotFound;
2492         if (kind.contains(KindSelector.TYP)) {
2493             RecoveryLoadClass recoveryLoadClass =
2494                     allowModules && !kind.contains(KindSelector.PCK) &&
2495                     !pck.exists() && !env.info.attributionMode.isSpeculative ?
2496                         doRecoveryLoadClass : noRecovery;
2497             Symbol sym = loadClass(env, fullname, recoveryLoadClass);
2498             if (sym.exists()) {
2499                 // don't allow programs to use flatnames
2500                 if (name == sym.name) return sym;
2501             }
2502             else bestSoFar = bestOf(bestSoFar, sym);
2503         }
2504         if (kind.contains(KindSelector.PCK)) {
2505             return lookupPackage(env, fullname);
2506         }
2507         return bestSoFar;
2508     }
2509 
2510     /** Find an identifier among the members of a given type `site'.
2511      *  @param pos       position on which report warnings, if any;
2512      *                   null warnings should not be reported
2513      *  @param env       The current environment.
2514      *  @param site      The type containing the symbol to be found.
2515      *  @param name      The identifier's name.
2516      *  @param kind      Indicates the possible symbol kinds
2517      *                   (a subset of VAL, TYP).
2518      */
2519     Symbol findIdentInType(DiagnosticPosition pos,
2520                            Env<AttrContext> env, Type site,
2521                            Name name, KindSelector kind) {
2522         try {
2523             return checkNonExistentType(checkRestrictedType(pos, findIdentInTypeInternal(env, site, name, kind), name));
2524         } catch (ClassFinder.BadClassFile err) {
2525             return new BadClassFileError(err);
2526         } catch (CompletionFailure cf) {
2527             chk.completionError(pos, cf);
2528             return typeNotFound;
2529         }
2530     }
2531 
2532     private Symbol checkNonExistentType(Symbol symbol) {
2533         /*  Guard against returning a type is not on the class path of the current compilation,
2534          *  but *was* on the class path of a separate compilation that produced a class file
2535          *  that is on the class path of the current compilation. Such a type will fail completion
2536          *  but the completion failure may have been silently swallowed (e.g. missing annotation types)
2537          *  with an error stub symbol lingering in the symbol tables.
2538          */
2539         return symbol instanceof ClassSymbol c && c.type.isErroneous() && c.classfile == null ? typeNotFound : symbol;
2540     }
2541 
2542     Symbol findIdentInTypeInternal(Env<AttrContext> env, Type site,
2543                            Name name, KindSelector kind) {
2544         Symbol bestSoFar = typeNotFound;
2545         Symbol sym;
2546         if (kind.contains(KindSelector.VAL)) {
2547             sym = findField(env, site, name, site.tsym);
2548             if (sym.exists()) return sym;
2549             else bestSoFar = bestOf(bestSoFar, sym);
2550         }
2551 
2552         if (kind.contains(KindSelector.TYP)) {
2553             sym = findMemberType(env, site, name, site.tsym);
2554             if (sym.exists()) return sym;
2555             else bestSoFar = bestOf(bestSoFar, sym);
2556         }
2557         return bestSoFar;
2558     }
2559 
2560     private Symbol checkRestrictedType(DiagnosticPosition pos, Symbol bestSoFar, Name name) {
2561         if (bestSoFar.kind == TYP || bestSoFar.kind == ABSENT_TYP) {
2562             if (allowLocalVariableTypeInference && name.equals(names.var)) {
2563                 bestSoFar = new BadRestrictedTypeError(names.var);
2564             } else if (name.equals(names.yield)) {
2565                 if (allowYieldStatement) {
2566                     bestSoFar = new BadRestrictedTypeError(names.yield);
2567                 } else if (pos != null) {
2568                     log.warning(pos, Warnings.IllegalRefToRestrictedType(names.yield));
2569                 }
2570             }
2571         }
2572         return bestSoFar;
2573     }
2574 
2575 /* ***************************************************************************
2576  *  Access checking
2577  *  The following methods convert ResolveErrors to ErrorSymbols, issuing
2578  *  an error message in the process
2579  ****************************************************************************/
2580 
2581     /** If `sym' is a bad symbol: report error and return errSymbol
2582      *  else pass through unchanged,
2583      *  additional arguments duplicate what has been used in trying to find the
2584      *  symbol {@literal (--> flyweight pattern)}. This improves performance since we
2585      *  expect misses to happen frequently.
2586      *
2587      *  @param sym       The symbol that was found, or a ResolveError.
2588      *  @param pos       The position to use for error reporting.
2589      *  @param location  The symbol the served as a context for this lookup
2590      *  @param site      The original type from where the selection took place.
2591      *  @param name      The symbol's name.
2592      *  @param qualified Did we get here through a qualified expression resolution?
2593      *  @param argtypes  The invocation's value arguments,
2594      *                   if we looked for a method.
2595      *  @param typeargtypes  The invocation's type arguments,
2596      *                   if we looked for a method.
2597      *  @param logResolveHelper helper class used to log resolve errors
2598      */
2599     Symbol accessInternal(Symbol sym,
2600                   DiagnosticPosition pos,
2601                   Symbol location,
2602                   Type site,
2603                   Name name,
2604                   boolean qualified,
2605                   List<Type> argtypes,
2606                   List<Type> typeargtypes,
2607                   LogResolveHelper logResolveHelper) {
2608         if (sym.kind.isResolutionError()) {
2609             ResolveError errSym = (ResolveError)sym.baseSymbol();
2610             sym = errSym.access(name, qualified ? site.tsym : syms.noSymbol);
2611             argtypes = logResolveHelper.getArgumentTypes(errSym, sym, name, argtypes);
2612             if (logResolveHelper.resolveDiagnosticNeeded(site, argtypes, typeargtypes)) {
2613                 logResolveError(errSym, pos, location, site, name, argtypes, typeargtypes);
2614             }
2615         }
2616         return sym;
2617     }
2618 
2619     /**
2620      * Variant of the generalized access routine, to be used for generating method
2621      * resolution diagnostics
2622      */
2623     Symbol accessMethod(Symbol sym,
2624                   DiagnosticPosition pos,
2625                   Symbol location,
2626                   Type site,
2627                   Name name,
2628                   boolean qualified,
2629                   List<Type> argtypes,
2630                   List<Type> typeargtypes) {
2631         return accessInternal(sym, pos, location, site, name, qualified, argtypes, typeargtypes, methodLogResolveHelper);
2632     }
2633 
2634     /** Same as original accessMethod(), but without location.
2635      */
2636     Symbol accessMethod(Symbol sym,
2637                   DiagnosticPosition pos,
2638                   Type site,
2639                   Name name,
2640                   boolean qualified,
2641                   List<Type> argtypes,
2642                   List<Type> typeargtypes) {
2643         return accessMethod(sym, pos, site.tsym, site, name, qualified, argtypes, typeargtypes);
2644     }
2645 
2646     /**
2647      * Variant of the generalized access routine, to be used for generating variable,
2648      * type resolution diagnostics
2649      */
2650     Symbol accessBase(Symbol sym,
2651                   DiagnosticPosition pos,
2652                   Symbol location,
2653                   Type site,
2654                   Name name,
2655                   boolean qualified) {
2656         return accessInternal(sym, pos, location, site, name, qualified, List.nil(), null, basicLogResolveHelper);
2657     }
2658 
2659     /** Same as original accessBase(), but without location.
2660      */
2661     Symbol accessBase(Symbol sym,
2662                   DiagnosticPosition pos,
2663                   Type site,
2664                   Name name,
2665                   boolean qualified) {
2666         return accessBase(sym, pos, site.tsym, site, name, qualified);
2667     }
2668 
2669     interface LogResolveHelper {
2670         boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes);
2671         List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes);
2672     }
2673 
2674     LogResolveHelper basicLogResolveHelper = new LogResolveHelper() {
2675         public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) {
2676             return !site.isErroneous();
2677         }
2678         public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
2679             return argtypes;
2680         }
2681     };
2682 
2683     LogResolveHelper silentLogResolveHelper = new LogResolveHelper() {
2684         public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) {
2685             return false;
2686         }
2687         public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
2688             return argtypes;
2689         }
2690     };
2691 
2692     LogResolveHelper methodLogResolveHelper = new LogResolveHelper() {
2693         public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) {
2694             return !site.isErroneous() &&
2695                         !Type.isErroneous(argtypes) &&
2696                         (typeargtypes == null || !Type.isErroneous(typeargtypes));
2697         }
2698         public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
2699             return argtypes.map(new ResolveDeferredRecoveryMap(AttrMode.SPECULATIVE, accessedSym, currentResolutionContext.step));
2700         }
2701     };
2702 
2703     class ResolveDeferredRecoveryMap extends DeferredAttr.RecoveryDeferredTypeMap {
2704 
2705         public ResolveDeferredRecoveryMap(AttrMode mode, Symbol msym, MethodResolutionPhase step) {
2706             deferredAttr.super(mode, msym, step);
2707         }
2708 
2709         @Override
2710         protected Type typeOf(DeferredType dt, Type pt) {
2711             Type res = super.typeOf(dt, pt);
2712             if (!res.isErroneous()) {
2713                 switch (TreeInfo.skipParens(dt.tree).getTag()) {
2714                     case LAMBDA:
2715                     case REFERENCE:
2716                         return dt;
2717                     case CONDEXPR:
2718                         return res == Type.recoveryType ?
2719                                 dt : res;
2720                 }
2721             }
2722             return res;
2723         }
2724     }
2725 
2726     /** Check that sym is not an abstract method.
2727      */
2728     void checkNonAbstract(DiagnosticPosition pos, Symbol sym) {
2729         if ((sym.flags() & ABSTRACT) != 0 && (sym.flags() & DEFAULT) == 0)
2730             log.error(pos,
2731                       Errors.AbstractCantBeAccessedDirectly(kindName(sym),sym, sym.location()));
2732     }
2733 
2734 /* ***************************************************************************
2735  *  Name resolution
2736  *  Naming conventions are as for symbol lookup
2737  *  Unlike the find... methods these methods will report access errors
2738  ****************************************************************************/
2739 
2740     /** Resolve an unqualified (non-method) identifier.
2741      *  @param pos       The position to use for error reporting.
2742      *  @param env       The environment current at the identifier use.
2743      *  @param name      The identifier's name.
2744      *  @param kind      The set of admissible symbol kinds for the identifier.
2745      */
2746     Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env,
2747                         Name name, KindSelector kind) {
2748         return accessBase(
2749             findIdent(pos, env, name, kind),
2750             pos, env.enclClass.sym.type, name, false);
2751     }
2752 
2753     /** Resolve an unqualified method identifier.
2754      *  @param pos       The position to use for error reporting.
2755      *  @param env       The environment current at the method invocation.
2756      *  @param name      The identifier's name.
2757      *  @param argtypes  The types of the invocation's value arguments.
2758      *  @param typeargtypes  The types of the invocation's type arguments.
2759      */
2760     Symbol resolveMethod(DiagnosticPosition pos,
2761                          Env<AttrContext> env,
2762                          Name name,
2763                          List<Type> argtypes,
2764                          List<Type> typeargtypes) {
2765         return lookupMethod(env, pos, env.enclClass.sym, resolveMethodCheck,
2766                 new BasicLookupHelper(name, env.enclClass.sym.type, argtypes, typeargtypes) {
2767                     @Override
2768                     Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2769                         return findFun(env, name, argtypes, typeargtypes,
2770                                 phase.isBoxingRequired(),
2771                                 phase.isVarargsRequired());
2772                     }});
2773     }
2774 
2775     /** Resolve a qualified method identifier
2776      *  @param pos       The position to use for error reporting.
2777      *  @param env       The environment current at the method invocation.
2778      *  @param site      The type of the qualifying expression, in which
2779      *                   identifier is searched.
2780      *  @param name      The identifier's name.
2781      *  @param argtypes  The types of the invocation's value arguments.
2782      *  @param typeargtypes  The types of the invocation's type arguments.
2783      */
2784     Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
2785                                   Type site, Name name, List<Type> argtypes,
2786                                   List<Type> typeargtypes) {
2787         return resolveQualifiedMethod(pos, env, site.tsym, site, name, argtypes, typeargtypes);
2788     }
2789     Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
2790                                   Symbol location, Type site, Name name, List<Type> argtypes,
2791                                   List<Type> typeargtypes) {
2792         return resolveQualifiedMethod(new MethodResolutionContext(), pos, env, location, site, name, argtypes, typeargtypes);
2793     }
2794     private Symbol resolveQualifiedMethod(MethodResolutionContext resolveContext,
2795                                   DiagnosticPosition pos, Env<AttrContext> env,
2796                                   Symbol location, Type site, Name name, List<Type> argtypes,
2797                                   List<Type> typeargtypes) {
2798         return lookupMethod(env, pos, location, resolveContext, new BasicLookupHelper(name, site, argtypes, typeargtypes) {
2799             @Override
2800             Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2801                 return findMethod(env, site, name, argtypes, typeargtypes,
2802                         phase.isBoxingRequired(),
2803                         phase.isVarargsRequired());
2804             }
2805             @Override
2806             Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2807                 if (sym.kind.isResolutionError()) {
2808                     sym = super.access(env, pos, location, sym);
2809                 } else {
2810                     MethodSymbol msym = (MethodSymbol)sym;
2811                     if ((msym.flags() & SIGNATURE_POLYMORPHIC) != 0) {
2812                         env.info.pendingResolutionPhase = BASIC;
2813                         return findPolymorphicSignatureInstance(env, sym, argtypes);
2814                     }
2815                 }
2816                 return sym;
2817             }
2818         });
2819     }
2820 
2821     /** Find or create an implicit method of exactly the given type (after erasure).
2822      *  Searches in a side table, not the main scope of the site.
2823      *  This emulates the lookup process required by JSR 292 in JVM.
2824      *  @param env       Attribution environment
2825      *  @param spMethod  signature polymorphic method - i.e. MH.invokeExact
2826      *  @param argtypes  The required argument types
2827      */
2828     Symbol findPolymorphicSignatureInstance(Env<AttrContext> env,
2829                                             final Symbol spMethod,
2830                                             List<Type> argtypes) {
2831         Type mtype = infer.instantiatePolymorphicSignatureInstance(env,
2832                 (MethodSymbol)spMethod, currentResolutionContext, argtypes);
2833         return findPolymorphicSignatureInstance(spMethod, mtype);
2834     }
2835 
2836     Symbol findPolymorphicSignatureInstance(final Symbol spMethod,
2837                                             Type mtype) {
2838         for (Symbol sym : polymorphicSignatureScope.getSymbolsByName(spMethod.name)) {
2839             // Check that there is already a method symbol for the method
2840             // type and owner
2841             if (types.isSameType(mtype, sym.type) &&
2842                 spMethod.owner == sym.owner) {
2843                 return sym;
2844             }
2845         }
2846 
2847         Type spReturnType = spMethod.asType().getReturnType();
2848         if (types.isSameType(spReturnType, syms.objectType)) {
2849             // Polymorphic return, pass through mtype
2850         } else if (!types.isSameType(spReturnType, mtype.getReturnType())) {
2851             // Retain the sig poly method's return type, which differs from that of mtype
2852             // Will result in an incompatible return type error
2853             mtype = new MethodType(mtype.getParameterTypes(),
2854                     spReturnType,
2855                     mtype.getThrownTypes(),
2856                     syms.methodClass);
2857         }
2858 
2859         // Create the desired method
2860         // Retain static modifier is to support invocations to
2861         // MethodHandle.linkTo* methods
2862         long flags = ABSTRACT | HYPOTHETICAL |
2863                      spMethod.flags() & (Flags.AccessFlags | Flags.STATIC);
2864         Symbol msym = new MethodSymbol(flags, spMethod.name, mtype, spMethod.owner) {
2865             @Override
2866             public Symbol baseSymbol() {
2867                 return spMethod;
2868             }
2869         };
2870         if (!mtype.isErroneous()) { // Cache only if kosher.
2871             polymorphicSignatureScope.enter(msym);
2872         }
2873         return msym;
2874     }
2875 
2876     /** Resolve a qualified method identifier, throw a fatal error if not
2877      *  found.
2878      *  @param pos       The position to use for error reporting.
2879      *  @param env       The environment current at the method invocation.
2880      *  @param site      The type of the qualifying expression, in which
2881      *                   identifier is searched.
2882      *  @param name      The identifier's name.
2883      *  @param argtypes  The types of the invocation's value arguments.
2884      *  @param typeargtypes  The types of the invocation's type arguments.
2885      */
2886     public MethodSymbol resolveInternalMethod(DiagnosticPosition pos, Env<AttrContext> env,
2887                                         Type site, Name name,
2888                                         List<Type> argtypes,
2889                                         List<Type> typeargtypes) {
2890         MethodResolutionContext resolveContext = new MethodResolutionContext();
2891         resolveContext.internalResolution = true;
2892         Symbol sym = resolveQualifiedMethod(resolveContext, pos, env, site.tsym,
2893                 site, name, argtypes, typeargtypes);
2894         if (sym.kind == MTH) return (MethodSymbol)sym;
2895         else throw new FatalError(
2896                  diags.fragment(Fragments.FatalErrCantLocateMeth(name)));
2897     }
2898 
2899     /** Resolve constructor.
2900      *  @param pos       The position to use for error reporting.
2901      *  @param env       The environment current at the constructor invocation.
2902      *  @param site      The type of class for which a constructor is searched.
2903      *  @param argtypes  The types of the constructor invocation's value
2904      *                   arguments.
2905      *  @param typeargtypes  The types of the constructor invocation's type
2906      *                   arguments.
2907      */
2908     Symbol resolveConstructor(DiagnosticPosition pos,
2909                               Env<AttrContext> env,
2910                               Type site,
2911                               List<Type> argtypes,
2912                               List<Type> typeargtypes) {
2913         return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes);
2914     }
2915 
2916     private Symbol resolveConstructor(MethodResolutionContext resolveContext,
2917                               final DiagnosticPosition pos,
2918                               Env<AttrContext> env,
2919                               Type site,
2920                               List<Type> argtypes,
2921                               List<Type> typeargtypes) {
2922         return lookupMethod(env, pos, site.tsym, resolveContext, new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
2923             @Override
2924             Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2925                 return findConstructor(pos, env, site, argtypes, typeargtypes,
2926                         phase.isBoxingRequired(),
2927                         phase.isVarargsRequired());
2928             }
2929         });
2930     }
2931 
2932     /** Resolve a constructor, throw a fatal error if not found.
2933      *  @param pos       The position to use for error reporting.
2934      *  @param env       The environment current at the method invocation.
2935      *  @param site      The type to be constructed.
2936      *  @param argtypes  The types of the invocation's value arguments.
2937      *  @param typeargtypes  The types of the invocation's type arguments.
2938      */
2939     public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2940                                         Type site,
2941                                         List<Type> argtypes,
2942                                         List<Type> typeargtypes) {
2943         MethodResolutionContext resolveContext = new MethodResolutionContext();
2944         resolveContext.internalResolution = true;
2945         Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes);
2946         if (sym.kind == MTH) return (MethodSymbol)sym;
2947         else throw new FatalError(
2948                  diags.fragment(Fragments.FatalErrCantLocateCtor(site)));
2949     }
2950 
2951     Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2952                               Type site, List<Type> argtypes,
2953                               List<Type> typeargtypes,
2954                               boolean allowBoxing,
2955                               boolean useVarargs) {
2956         Symbol sym = findMethod(env, site,
2957                                     names.init, argtypes,
2958                                     typeargtypes, allowBoxing,
2959                                     useVarargs);
2960         chk.checkDeprecated(pos, env.info.scope.owner, sym);
2961         chk.checkPreview(pos, env.info.scope.owner, sym);
2962         return sym;
2963     }
2964 
2965     /** Resolve constructor using diamond inference.
2966      *  @param pos       The position to use for error reporting.
2967      *  @param env       The environment current at the constructor invocation.
2968      *  @param site      The type of class for which a constructor is searched.
2969      *                   The scope of this class has been touched in attribution.
2970      *  @param argtypes  The types of the constructor invocation's value
2971      *                   arguments.
2972      *  @param typeargtypes  The types of the constructor invocation's type
2973      *                   arguments.
2974      */
2975     Symbol resolveDiamond(DiagnosticPosition pos,
2976                               Env<AttrContext> env,
2977                               Type site,
2978                               List<Type> argtypes,
2979                               List<Type> typeargtypes) {
2980         return lookupMethod(env, pos, site.tsym, resolveMethodCheck,
2981                 new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
2982                     @Override
2983                     Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2984                         return findDiamond(pos, env, site, argtypes, typeargtypes,
2985                                 phase.isBoxingRequired(),
2986                                 phase.isVarargsRequired());
2987                     }
2988                     @Override
2989                     Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2990                         if (sym.kind.isResolutionError()) {
2991                             if (sym.kind != WRONG_MTH &&
2992                                 sym.kind != WRONG_MTHS) {
2993                                 sym = super.access(env, pos, location, sym);
2994                             } else {
2995                                 sym = new DiamondError(sym, currentResolutionContext);
2996                                 sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes);
2997                                 env.info.pendingResolutionPhase = currentResolutionContext.step;
2998                             }
2999                         }
3000                         return sym;
3001                     }});
3002     }
3003 
3004     /** Find the constructor using diamond inference and do some checks(deprecated and preview).
3005      *  @param pos          The position to use for error reporting.
3006      *  @param env          The environment current at the constructor invocation.
3007      *  @param site         The type of class for which a constructor is searched.
3008      *                      The scope of this class has been touched in attribution.
3009      *  @param argtypes     The types of the constructor invocation's value arguments.
3010      *  @param typeargtypes The types of the constructor invocation's type arguments.
3011      *  @param allowBoxing  Allow boxing conversions of arguments.
3012      *  @param useVarargs   Box trailing arguments into an array for varargs.
3013      */
3014     private Symbol findDiamond(DiagnosticPosition pos,
3015                                Env<AttrContext> env,
3016                                Type site,
3017                                List<Type> argtypes,
3018                                List<Type> typeargtypes,
3019                                boolean allowBoxing,
3020                                boolean useVarargs) {
3021         Symbol sym = findDiamond(env, site, argtypes, typeargtypes, allowBoxing, useVarargs);
3022         chk.checkDeprecated(pos, env.info.scope.owner, sym);
3023         chk.checkPreview(pos, env.info.scope.owner, sym);
3024         return sym;
3025     }
3026 
3027     /** This method scans all the constructor symbol in a given class scope -
3028      *  assuming that the original scope contains a constructor of the kind:
3029      *  {@code Foo(X x, Y y)}, where X,Y are class type-variables declared in Foo,
3030      *  a method check is executed against the modified constructor type:
3031      *  {@code <X,Y>Foo<X,Y>(X x, Y y)}. This is crucial in order to enable diamond
3032      *  inference. The inferred return type of the synthetic constructor IS
3033      *  the inferred type for the diamond operator.
3034      */
3035     private Symbol findDiamond(Env<AttrContext> env,
3036                               Type site,
3037                               List<Type> argtypes,
3038                               List<Type> typeargtypes,
3039                               boolean allowBoxing,
3040                               boolean useVarargs) {
3041         Symbol bestSoFar = methodNotFound;
3042         TypeSymbol tsym = site.tsym.isInterface() ? syms.objectType.tsym : site.tsym;
3043         for (final Symbol sym : tsym.members().getSymbolsByName(names.init)) {
3044             //- System.out.println(" e " + e.sym);
3045             if (sym.kind == MTH &&
3046                 (sym.flags_field & SYNTHETIC) == 0) {
3047                     List<Type> oldParams = sym.type.hasTag(FORALL) ?
3048                             ((ForAll)sym.type).tvars :
3049                             List.nil();
3050                     Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams),
3051                                                  types.createMethodTypeWithReturn(sym.type.asMethodType(), site));
3052                     MethodSymbol newConstr = new MethodSymbol(sym.flags(), names.init, constrType, site.tsym) {
3053                         @Override
3054                         public Symbol baseSymbol() {
3055                             return sym;
3056                         }
3057                     };
3058                     bestSoFar = selectBest(env, site, argtypes, typeargtypes,
3059                             newConstr,
3060                             bestSoFar,
3061                             allowBoxing,
3062                             useVarargs);
3063             }
3064         }
3065         return bestSoFar;
3066     }
3067 
3068     Symbol getMemberReference(DiagnosticPosition pos,
3069             Env<AttrContext> env,
3070             JCMemberReference referenceTree,
3071             Type site,
3072             Name name) {
3073 
3074         site = types.capture(site);
3075 
3076         ReferenceLookupHelper lookupHelper = makeReferenceLookupHelper(
3077                 referenceTree, site, name, List.nil(), null, VARARITY);
3078 
3079         Env<AttrContext> newEnv = env.dup(env.tree, env.info.dup());
3080         Symbol sym = lookupMethod(newEnv, env.tree.pos(), site.tsym,
3081                 nilMethodCheck, lookupHelper);
3082 
3083         env.info.pendingResolutionPhase = newEnv.info.pendingResolutionPhase;
3084 
3085         return sym;
3086     }
3087 
3088     ReferenceLookupHelper makeReferenceLookupHelper(JCMemberReference referenceTree,
3089                                   Type site,
3090                                   Name name,
3091                                   List<Type> argtypes,
3092                                   List<Type> typeargtypes,
3093                                   MethodResolutionPhase maxPhase) {
3094         if (!name.equals(names.init)) {
3095             //method reference
3096             return new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
3097         } else if (site.hasTag(ARRAY)) {
3098             //array constructor reference
3099             return new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
3100         } else {
3101             //class constructor reference
3102             return new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
3103         }
3104     }
3105 
3106     /**
3107      * Resolution of member references is typically done as a single
3108      * overload resolution step, where the argument types A are inferred from
3109      * the target functional descriptor.
3110      *
3111      * If the member reference is a method reference with a type qualifier,
3112      * a two-step lookup process is performed. The first step uses the
3113      * expected argument list A, while the second step discards the first
3114      * type from A (which is treated as a receiver type).
3115      *
3116      * There are two cases in which inference is performed: (i) if the member
3117      * reference is a constructor reference and the qualifier type is raw - in
3118      * which case diamond inference is used to infer a parameterization for the
3119      * type qualifier; (ii) if the member reference is an unbound reference
3120      * where the type qualifier is raw - in that case, during the unbound lookup
3121      * the receiver argument type is used to infer an instantiation for the raw
3122      * qualifier type.
3123      *
3124      * When a multi-step resolution process is exploited, the process of picking
3125      * the resulting symbol is delegated to an helper class {@link com.sun.tools.javac.comp.Resolve.ReferenceChooser}.
3126      *
3127      * This routine returns a pair (T,S), where S is the member reference symbol,
3128      * and T is the type of the class in which S is defined. This is necessary as
3129      * the type T might be dynamically inferred (i.e. if constructor reference
3130      * has a raw qualifier).
3131      */
3132     Pair<Symbol, ReferenceLookupHelper> resolveMemberReference(Env<AttrContext> env,
3133                                   JCMemberReference referenceTree,
3134                                   Type site,
3135                                   Name name,
3136                                   List<Type> argtypes,
3137                                   List<Type> typeargtypes,
3138                                   Type descriptor,
3139                                   MethodCheck methodCheck,
3140                                   InferenceContext inferenceContext,
3141                                   ReferenceChooser referenceChooser) {
3142 
3143         //step 1 - bound lookup
3144         ReferenceLookupHelper boundLookupHelper = makeReferenceLookupHelper(
3145                 referenceTree, site, name, argtypes, typeargtypes, VARARITY);
3146         Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
3147         MethodResolutionContext boundSearchResolveContext = new MethodResolutionContext();
3148         boundSearchResolveContext.methodCheck = methodCheck;
3149         Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(),
3150                 site.tsym, boundSearchResolveContext, boundLookupHelper);
3151         boolean isStaticSelector = TreeInfo.isStaticSelector(referenceTree.expr, names);
3152         ReferenceLookupResult boundRes = new ReferenceLookupResult(boundSym, boundSearchResolveContext, isStaticSelector);
3153         if (dumpMethodReferenceSearchResults) {
3154             dumpMethodReferenceSearchResults(referenceTree, boundSearchResolveContext, boundSym, true);
3155         }
3156 
3157         //step 2 - unbound lookup
3158         Symbol unboundSym = methodNotFound;
3159         Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup());
3160         ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext);
3161         ReferenceLookupResult unboundRes = referenceNotFound;
3162         if (unboundLookupHelper != null) {
3163             MethodResolutionContext unboundSearchResolveContext =
3164                     new MethodResolutionContext();
3165             unboundSearchResolveContext.methodCheck = methodCheck;
3166             unboundSym = lookupMethod(unboundEnv, env.tree.pos(),
3167                     site.tsym, unboundSearchResolveContext, unboundLookupHelper);
3168             unboundRes = new ReferenceLookupResult(unboundSym, unboundSearchResolveContext, isStaticSelector);
3169             if (dumpMethodReferenceSearchResults) {
3170                 dumpMethodReferenceSearchResults(referenceTree, unboundSearchResolveContext, unboundSym, false);
3171             }
3172         }
3173 
3174         //merge results
3175         Pair<Symbol, ReferenceLookupHelper> res;
3176         ReferenceLookupResult bestRes = referenceChooser.result(boundRes, unboundRes);
3177         res = new Pair<>(bestRes.sym,
3178                 bestRes == unboundRes ? unboundLookupHelper : boundLookupHelper);
3179         env.info.pendingResolutionPhase = bestRes == unboundRes ?
3180                 unboundEnv.info.pendingResolutionPhase :
3181                 boundEnv.info.pendingResolutionPhase;
3182 
3183         if (!res.fst.kind.isResolutionError()) {
3184             //handle sigpoly method references
3185             MethodSymbol msym = (MethodSymbol)res.fst;
3186             if ((msym.flags() & SIGNATURE_POLYMORPHIC) != 0) {
3187                 env.info.pendingResolutionPhase = BASIC;
3188                 res = new Pair<>(findPolymorphicSignatureInstance(msym, descriptor), res.snd);
3189             }
3190         }
3191 
3192         return res;
3193     }
3194 
3195     private void dumpMethodReferenceSearchResults(JCMemberReference referenceTree,
3196                                                   MethodResolutionContext resolutionContext,
3197                                                   Symbol bestSoFar,
3198                                                   boolean bound) {
3199         ListBuffer<JCDiagnostic> subDiags = new ListBuffer<>();
3200         int pos = 0;
3201         int mostSpecificPos = -1;
3202         for (Candidate c : resolutionContext.candidates) {
3203             if (resolutionContext.step != c.step || !c.isApplicable()) {
3204                 continue;
3205             } else {
3206                 JCDiagnostic subDiag = null;
3207                 if (c.sym.type.hasTag(FORALL)) {
3208                     subDiag = diags.fragment(Fragments.PartialInstSig(c.mtype));
3209                 }
3210 
3211                 String key = subDiag == null ?
3212                         "applicable.method.found.2" :
3213                         "applicable.method.found.3";
3214                 subDiags.append(diags.fragment(key, pos,
3215                         c.sym.isStatic() ? Fragments.Static : Fragments.NonStatic, c.sym, subDiag));
3216                 if (c.sym == bestSoFar)
3217                     mostSpecificPos = pos;
3218                 pos++;
3219             }
3220         }
3221         JCDiagnostic main = diags.note(
3222                 log.currentSource(),
3223                 referenceTree,
3224                 "method.ref.search.results.multi",
3225                 bound ? Fragments.Bound : Fragments.Unbound,
3226                 referenceTree.toString(), mostSpecificPos);
3227         JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList());
3228         log.report(d);
3229     }
3230 
3231     /**
3232      * This class is used to represent a method reference lookup result. It keeps track of two
3233      * things: (i) the symbol found during a method reference lookup and (ii) the static kind
3234      * of the lookup (see {@link com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind}).
3235      */
3236     static class ReferenceLookupResult {
3237 
3238         /**
3239          * Static kind associated with a method reference lookup. Erroneous lookups end up with
3240          * the UNDEFINED kind; successful lookups will end up with either STATIC, NON_STATIC,
3241          * depending on whether all applicable candidates are static or non-static methods,
3242          * respectively. If a successful lookup has both static and non-static applicable methods,
3243          * its kind is set to BOTH.
3244          */
3245         enum StaticKind {
3246             STATIC,
3247             NON_STATIC,
3248             BOTH,
3249             UNDEFINED;
3250 
3251             /**
3252              * Retrieve the static kind associated with a given (method) symbol.
3253              */
3254             static StaticKind from(Symbol s) {
3255                 return s.isStatic() ?
3256                         STATIC : NON_STATIC;
3257             }
3258 
3259             /**
3260              * Merge two static kinds together.
3261              */
3262             static StaticKind reduce(StaticKind sk1, StaticKind sk2) {
3263                 if (sk1 == UNDEFINED) {
3264                     return sk2;
3265                 } else if (sk2 == UNDEFINED) {
3266                     return sk1;
3267                 } else {
3268                     return sk1 == sk2 ? sk1 : BOTH;
3269                 }
3270             }
3271         }
3272 
3273         /** The static kind. */
3274         StaticKind staticKind;
3275 
3276         /** The lookup result. */
3277         Symbol sym;
3278 
3279         ReferenceLookupResult(Symbol sym, MethodResolutionContext resolutionContext, boolean isStaticSelector) {
3280             this(sym, staticKind(sym, resolutionContext, isStaticSelector));
3281         }
3282 
3283         private ReferenceLookupResult(Symbol sym, StaticKind staticKind) {
3284             this.staticKind = staticKind;
3285             this.sym = sym;
3286         }
3287 
3288         private static StaticKind staticKind(Symbol sym, MethodResolutionContext resolutionContext, boolean isStaticSelector) {
3289             if (sym.kind == MTH && !isStaticSelector) {
3290                 return StaticKind.from(sym);
3291             } else if (sym.kind == MTH || sym.kind == AMBIGUOUS) {
3292                 return resolutionContext.candidates.stream()
3293                         .filter(c -> c.isApplicable() && c.step == resolutionContext.step)
3294                         .map(c -> StaticKind.from(c.sym))
3295                         .reduce(StaticKind::reduce)
3296                         .orElse(StaticKind.UNDEFINED);
3297             } else {
3298                 return StaticKind.UNDEFINED;
3299             }
3300         }
3301 
3302         /**
3303          * Does this result corresponds to a successful lookup (i.e. one where a method has been found?)
3304          */
3305         boolean isSuccess() {
3306             return staticKind != StaticKind.UNDEFINED;
3307         }
3308 
3309         /**
3310          * Does this result have given static kind?
3311          */
3312         boolean hasKind(StaticKind sk) {
3313             return this.staticKind == sk;
3314         }
3315 
3316         /**
3317          * Error recovery helper: can this lookup result be ignored (for the purpose of returning
3318          * some 'better' result) ?
3319          */
3320         boolean canIgnore() {
3321             switch (sym.kind) {
3322                 case ABSENT_MTH:
3323                     return true;
3324                 case WRONG_MTH:
3325                     InapplicableSymbolError errSym =
3326                             (InapplicableSymbolError)sym.baseSymbol();
3327                     return new Template(MethodCheckDiag.ARITY_MISMATCH.regex())
3328                             .matches(errSym.errCandidate().snd);
3329                 case WRONG_MTHS:
3330                     InapplicableSymbolsError errSyms =
3331                             (InapplicableSymbolsError)sym.baseSymbol();
3332                     return errSyms.filterCandidates(errSyms.mapCandidates()).isEmpty();
3333                 default:
3334                     return false;
3335             }
3336         }
3337 
3338         static ReferenceLookupResult error(Symbol sym) {
3339             return new ReferenceLookupResult(sym, StaticKind.UNDEFINED);
3340         }
3341     }
3342 
3343     /**
3344      * This abstract class embodies the logic that converts one (bound lookup) or two (unbound lookup)
3345      * {@code ReferenceLookupResult} objects into a {@code Symbol}, which is then regarded as the
3346      * result of method reference resolution.
3347      */
3348     abstract class ReferenceChooser {
3349         /**
3350          * Generate a result from a pair of lookup result objects. This method delegates to the
3351          * appropriate result generation routine.
3352          */
3353         ReferenceLookupResult result(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
3354             return unboundRes != referenceNotFound ?
3355                     unboundResult(boundRes, unboundRes) :
3356                     boundResult(boundRes);
3357         }
3358 
3359         /**
3360          * Generate a symbol from a given bound lookup result.
3361          */
3362         abstract ReferenceLookupResult boundResult(ReferenceLookupResult boundRes);
3363 
3364         /**
3365          * Generate a symbol from a pair of bound/unbound lookup results.
3366          */
3367         abstract ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes);
3368     }
3369 
3370     /**
3371      * This chooser implements the selection strategy used during a full lookup; this logic
3372      * is described in JLS SE 8 (15.3.2).
3373      */
3374     ReferenceChooser basicReferenceChooser = new ReferenceChooser() {
3375 
3376         @Override
3377         ReferenceLookupResult boundResult(ReferenceLookupResult boundRes) {
3378             return !boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC) ?
3379                     boundRes : //the search produces a non-static method
3380                     ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.sym, false));
3381         }
3382 
3383         @Override
3384         ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
3385             if (boundRes.isSuccess() && boundRes.sym.isStatic() &&
3386                     (!unboundRes.isSuccess() || unboundRes.hasKind(StaticKind.STATIC))) {
3387                 //the first search produces a static method and no non-static method is applicable
3388                 //during the second search
3389                 return boundRes;
3390             } else if (unboundRes.isSuccess() && !unboundRes.sym.isStatic() &&
3391                     (!boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC))) {
3392                 //the second search produces a non-static method and no static method is applicable
3393                 //during the first search
3394                 return unboundRes;
3395             } else if (boundRes.isSuccess() && unboundRes.isSuccess()) {
3396                 //both searches produce some result; ambiguity (error recovery)
3397                 return ReferenceLookupResult.error(ambiguityError(boundRes.sym, unboundRes.sym));
3398             } else if (boundRes.isSuccess() || unboundRes.isSuccess()) {
3399                 //Both searches failed to produce a result with correct staticness (i.e. first search
3400                 //produces an non-static method). Alternatively, a given search produced a result
3401                 //with the right staticness, but the other search has applicable methods with wrong
3402                 //staticness (error recovery)
3403                 return ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.isSuccess() ?
3404                         boundRes.sym : unboundRes.sym, true));
3405             } else {
3406                 //both searches fail to produce a result - pick 'better' error using heuristics (error recovery)
3407                 return (boundRes.canIgnore() && !unboundRes.canIgnore()) ?
3408                         unboundRes : boundRes;
3409             }
3410         }
3411     };
3412 
3413     /**
3414      * This chooser implements the selection strategy used during an arity-based lookup; this logic
3415      * is described in JLS SE 8 (15.12.2.1).
3416      */
3417     ReferenceChooser structuralReferenceChooser = new ReferenceChooser() {
3418 
3419         @Override
3420         ReferenceLookupResult boundResult(ReferenceLookupResult boundRes) {
3421             return (!boundRes.isSuccess() || !boundRes.hasKind(StaticKind.STATIC)) ?
3422                     boundRes : //the search has at least one applicable non-static method
3423                     ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.sym, false));
3424         }
3425 
3426         @Override
3427         ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
3428             if (boundRes.isSuccess() && !boundRes.hasKind(StaticKind.NON_STATIC)) {
3429                 //the first search has at least one applicable static method
3430                 return boundRes;
3431             } else if (unboundRes.isSuccess() && !unboundRes.hasKind(StaticKind.STATIC)) {
3432                 //the second search has at least one applicable non-static method
3433                 return unboundRes;
3434             } else if (boundRes.isSuccess() || unboundRes.isSuccess()) {
3435                 //either the first search produces a non-static method, or second search produces
3436                 //a non-static method (error recovery)
3437                 return ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.isSuccess() ?
3438                         boundRes.sym : unboundRes.sym, true));
3439             } else {
3440                 //both searches fail to produce a result - pick 'better' error using heuristics (error recovery)
3441                 return (boundRes.canIgnore() && !unboundRes.canIgnore()) ?
3442                         unboundRes : boundRes;
3443             }
3444         }
3445     };
3446 
3447     /**
3448      * Helper for defining custom method-like lookup logic; a lookup helper
3449      * provides hooks for (i) the actual lookup logic and (ii) accessing the
3450      * lookup result (this step might result in compiler diagnostics to be generated)
3451      */
3452     abstract class LookupHelper {
3453 
3454         /** name of the symbol to lookup */
3455         Name name;
3456 
3457         /** location in which the lookup takes place */
3458         Type site;
3459 
3460         /** actual types used during the lookup */
3461         List<Type> argtypes;
3462 
3463         /** type arguments used during the lookup */
3464         List<Type> typeargtypes;
3465 
3466         /** Max overload resolution phase handled by this helper */
3467         MethodResolutionPhase maxPhase;
3468 
3469         LookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3470             this.name = name;
3471             this.site = site;
3472             this.argtypes = argtypes;
3473             this.typeargtypes = typeargtypes;
3474             this.maxPhase = maxPhase;
3475         }
3476 
3477         /**
3478          * Should lookup stop at given phase with given result
3479          */
3480         final boolean shouldStop(Symbol sym, MethodResolutionPhase phase) {
3481             return phase.ordinal() > maxPhase.ordinal() ||
3482                  !sym.kind.isResolutionError() || sym.kind == AMBIGUOUS || sym.kind == STATICERR;
3483         }
3484 
3485         /**
3486          * Search for a symbol under a given overload resolution phase - this method
3487          * is usually called several times, once per each overload resolution phase
3488          */
3489         abstract Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase);
3490 
3491         /**
3492          * Dump overload resolution info
3493          */
3494         void debug(DiagnosticPosition pos, Symbol sym) {
3495             //do nothing
3496         }
3497 
3498         /**
3499          * Validate the result of the lookup
3500          */
3501         abstract Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym);
3502     }
3503 
3504     abstract class BasicLookupHelper extends LookupHelper {
3505 
3506         BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes) {
3507             this(name, site, argtypes, typeargtypes, MethodResolutionPhase.VARARITY);
3508         }
3509 
3510         BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3511             super(name, site, argtypes, typeargtypes, maxPhase);
3512         }
3513 
3514         @Override
3515         final Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3516             Symbol sym = doLookup(env, phase);
3517             if (sym.kind == AMBIGUOUS) {
3518                 AmbiguityError a_err = (AmbiguityError)sym.baseSymbol();
3519                 sym = a_err.mergeAbstracts(site);
3520             }
3521             return sym;
3522         }
3523 
3524         abstract Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase);
3525 
3526         @Override
3527         Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
3528             if (sym.kind.isResolutionError()) {
3529                 //if nothing is found return the 'first' error
3530                 sym = accessMethod(sym, pos, location, site, name, true, argtypes, typeargtypes);
3531             }
3532             return sym;
3533         }
3534 
3535         @Override
3536         void debug(DiagnosticPosition pos, Symbol sym) {
3537             reportVerboseResolutionDiagnostic(pos, name, site, argtypes, typeargtypes, sym);
3538         }
3539     }
3540 
3541     /**
3542      * Helper class for member reference lookup. A reference lookup helper
3543      * defines the basic logic for member reference lookup; a method gives
3544      * access to an 'unbound' helper used to perform an unbound member
3545      * reference lookup.
3546      */
3547     abstract class ReferenceLookupHelper extends LookupHelper {
3548 
3549         /** The member reference tree */
3550         JCMemberReference referenceTree;
3551 
3552         ReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3553                 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3554             super(name, site, argtypes, typeargtypes, maxPhase);
3555             this.referenceTree = referenceTree;
3556         }
3557 
3558         /**
3559          * Returns an unbound version of this lookup helper. By default, this
3560          * method returns an dummy lookup helper.
3561          */
3562         ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3563             return null;
3564         }
3565 
3566         /**
3567          * Get the kind of the member reference
3568          */
3569         abstract JCMemberReference.ReferenceKind referenceKind(Symbol sym);
3570 
3571         Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
3572             if (sym.kind == AMBIGUOUS) {
3573                 AmbiguityError a_err = (AmbiguityError)sym.baseSymbol();
3574                 sym = a_err.mergeAbstracts(site);
3575             }
3576             //skip error reporting
3577             return sym;
3578         }
3579     }
3580 
3581     /**
3582      * Helper class for method reference lookup. The lookup logic is based
3583      * upon Resolve.findMethod; in certain cases, this helper class has a
3584      * corresponding unbound helper class (see UnboundMethodReferenceLookupHelper).
3585      * In such cases, non-static lookup results are thrown away.
3586      */
3587     class MethodReferenceLookupHelper extends ReferenceLookupHelper {
3588 
3589         /** The original method reference lookup site. */
3590         Type originalSite;
3591 
3592         MethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3593                 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3594             super(referenceTree, name, types.skipTypeVars(site, true), argtypes, typeargtypes, maxPhase);
3595             this.originalSite = site;
3596         }
3597 
3598         @Override
3599         final Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3600             return findMethod(env, site, name, argtypes, typeargtypes,
3601                     phase.isBoxingRequired(), phase.isVarargsRequired());
3602         }
3603 
3604         @Override
3605         ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3606             if (TreeInfo.isStaticSelector(referenceTree.expr, names)) {
3607                 if (argtypes.nonEmpty() &&
3608                         (argtypes.head.hasTag(NONE) ||
3609                         types.isSubtypeUnchecked(inferenceContext.asUndetVar(argtypes.head), originalSite))) {
3610                     return new UnboundMethodReferenceLookupHelper(referenceTree, name,
3611                             originalSite, argtypes, typeargtypes, maxPhase);
3612                 } else {
3613                     return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) {
3614                         @Override
3615                         ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3616                             return this;
3617                         }
3618 
3619                         @Override
3620                         Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3621                             return methodNotFound;
3622                         }
3623 
3624                         @Override
3625                         ReferenceKind referenceKind(Symbol sym) {
3626                             Assert.error();
3627                             return null;
3628                         }
3629                     };
3630                 }
3631             } else {
3632                 return super.unboundLookup(inferenceContext);
3633             }
3634         }
3635 
3636         @Override
3637         ReferenceKind referenceKind(Symbol sym) {
3638             if (sym.isStatic()) {
3639                 return ReferenceKind.STATIC;
3640             } else {
3641                 Name selName = TreeInfo.name(referenceTree.getQualifierExpression());
3642                 return selName != null && selName == names._super ?
3643                         ReferenceKind.SUPER :
3644                         ReferenceKind.BOUND;
3645             }
3646         }
3647 
3648         @Override
3649         Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
3650             if (originalSite.hasTag(TYPEVAR) && sym.kind == MTH) {
3651                 sym = (sym.flags() & Flags.PRIVATE) != 0 ?
3652                         new AccessError(env, site, sym) :
3653                         sym;
3654                 return accessBase(sym, pos, location, originalSite, name, true);
3655             } else {
3656                 return super.access(env, pos, location, sym);
3657             }
3658         }
3659     }
3660 
3661     /**
3662      * Helper class for unbound method reference lookup. Essentially the same
3663      * as the basic method reference lookup helper; main difference is that static
3664      * lookup results are thrown away. If qualifier type is raw, an attempt to
3665      * infer a parameterized type is made using the first actual argument (that
3666      * would otherwise be ignored during the lookup).
3667      */
3668     class UnboundMethodReferenceLookupHelper extends MethodReferenceLookupHelper {
3669 
3670         UnboundMethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3671                 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3672             super(referenceTree, name, site, argtypes.tail, typeargtypes, maxPhase);
3673             if (site.isRaw() && !argtypes.head.hasTag(NONE)) {
3674                 Type asSuperSite = types.asSuper(argtypes.head, site.tsym);
3675                 this.site = types.skipTypeVars(asSuperSite, true);
3676             }
3677         }
3678 
3679         @Override
3680         ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3681             return this;
3682         }
3683 
3684         @Override
3685         ReferenceKind referenceKind(Symbol sym) {
3686             return ReferenceKind.UNBOUND;
3687         }
3688     }
3689 
3690     /**
3691      * Helper class for array constructor lookup; an array constructor lookup
3692      * is simulated by looking up a method that returns the array type specified
3693      * as qualifier, and that accepts a single int parameter (size of the array).
3694      */
3695     class ArrayConstructorReferenceLookupHelper extends ReferenceLookupHelper {
3696 
3697         ArrayConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
3698                 List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3699             super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
3700         }
3701 
3702         @Override
3703         protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3704             WriteableScope sc = WriteableScope.create(syms.arrayClass);
3705             MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym);
3706             arrayConstr.type = new MethodType(List.of(syms.intType), site, List.nil(), syms.methodClass);
3707             sc.enter(arrayConstr);
3708             return findMethodInScope(env, site, name, argtypes, typeargtypes, sc, methodNotFound, phase.isBoxingRequired(), phase.isVarargsRequired(), false);
3709         }
3710 
3711         @Override
3712         ReferenceKind referenceKind(Symbol sym) {
3713             return ReferenceKind.ARRAY_CTOR;
3714         }
3715     }
3716 
3717     /**
3718      * Helper class for constructor reference lookup. The lookup logic is based
3719      * upon either Resolve.findMethod or Resolve.findDiamond - depending on
3720      * whether the constructor reference needs diamond inference (this is the case
3721      * if the qualifier type is raw). A special erroneous symbol is returned
3722      * if the lookup returns the constructor of an inner class and there's no
3723      * enclosing instance in scope.
3724      */
3725     class ConstructorReferenceLookupHelper extends ReferenceLookupHelper {
3726 
3727         boolean needsInference;
3728 
3729         ConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
3730                 List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3731             super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
3732             if (site.isRaw()) {
3733                 this.site = new ClassType(site.getEnclosingType(),
3734                         !(site.tsym.isInner() && site.getEnclosingType().isRaw()) ?
3735                                 site.tsym.type.getTypeArguments() : List.nil(), site.tsym, site.getMetadata());
3736                 needsInference = true;
3737             }
3738         }
3739 
3740         @Override
3741         protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3742             Symbol sym = needsInference ?
3743                 findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) :
3744                 findMethod(env, site, name, argtypes, typeargtypes,
3745                         phase.isBoxingRequired(), phase.isVarargsRequired());
3746             return enclosingInstanceMissing(env, site) ? new BadConstructorReferenceError(sym) : sym;
3747         }
3748 
3749         @Override
3750         ReferenceKind referenceKind(Symbol sym) {
3751             return site.getEnclosingType().hasTag(NONE) ?
3752                     ReferenceKind.TOPLEVEL : ReferenceKind.IMPLICIT_INNER;
3753         }
3754     }
3755 
3756     /**
3757      * Main overload resolution routine. On each overload resolution step, a
3758      * lookup helper class is used to perform the method/constructor lookup;
3759      * at the end of the lookup, the helper is used to validate the results
3760      * (this last step might trigger overload resolution diagnostics).
3761      */
3762     Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, MethodCheck methodCheck, LookupHelper lookupHelper) {
3763         MethodResolutionContext resolveContext = new MethodResolutionContext();
3764         resolveContext.methodCheck = methodCheck;
3765         return lookupMethod(env, pos, location, resolveContext, lookupHelper);
3766     }
3767 
3768     Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location,
3769             MethodResolutionContext resolveContext, LookupHelper lookupHelper) {
3770         MethodResolutionContext prevResolutionContext = currentResolutionContext;
3771         try {
3772             Symbol bestSoFar = methodNotFound;
3773             currentResolutionContext = resolveContext;
3774             for (MethodResolutionPhase phase : methodResolutionSteps) {
3775                 if (lookupHelper.shouldStop(bestSoFar, phase))
3776                     break;
3777                 MethodResolutionPhase prevPhase = currentResolutionContext.step;
3778                 Symbol prevBest = bestSoFar;
3779                 currentResolutionContext.step = phase;
3780                 Symbol sym = lookupHelper.lookup(env, phase);
3781                 lookupHelper.debug(pos, sym);
3782                 bestSoFar = phase.mergeResults(bestSoFar, sym);
3783                 env.info.pendingResolutionPhase = (prevBest == bestSoFar) ? prevPhase : phase;
3784             }
3785             return lookupHelper.access(env, pos, location, bestSoFar);
3786         } finally {
3787             currentResolutionContext = prevResolutionContext;
3788         }
3789     }
3790 
3791     /**
3792      * Resolve `c.name' where name == this or name == super.
3793      * @param pos           The position to use for error reporting.
3794      * @param env           The environment current at the expression.
3795      * @param c             The qualifier.
3796      * @param name          The identifier's name.
3797      */
3798     Symbol resolveSelf(DiagnosticPosition pos,
3799                        Env<AttrContext> env,
3800                        TypeSymbol c,
3801                        Name name) {
3802         Assert.check(name == names._this || name == names._super);
3803         Env<AttrContext> env1 = env;
3804         boolean staticOnly = false;
3805         while (env1.outer != null) {
3806             if (isStatic(env1)) staticOnly = true;
3807             if (env1.enclClass.sym == c) {
3808                 Symbol sym = env1.info.scope.findFirst(name);
3809                 if (sym != null) {
3810                     if (staticOnly)
3811                         sym = new StaticError(sym);
3812                     else if (env1.info.ctorPrologue && !isAllowedEarlyReference(pos, env1, (VarSymbol)sym))
3813                         sym = new RefBeforeCtorCalledError(sym);
3814                     return accessBase(sym, pos, env.enclClass.sym.type,
3815                                   name, true);
3816                 }
3817             }
3818             if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
3819             env1 = env1.outer;
3820         }
3821         if (c.isInterface() &&
3822             name == names._super && !isStatic(env) &&
3823             types.isDirectSuperInterface(c, env.enclClass.sym)) {
3824             //this might be a default super call if one of the superinterfaces is 'c'
3825             for (Type t : pruneInterfaces(env.enclClass.type)) {
3826                 if (t.tsym == c) {
3827                     if (env.info.ctorPrologue)
3828                         log.error(pos, Errors.CantRefBeforeCtorCalled(name));
3829                     env.info.defaultSuperCallSite = t;
3830                     return new VarSymbol(0, names._super,
3831                             types.asSuper(env.enclClass.type, c), env.enclClass.sym);
3832                 }
3833             }
3834             //find a direct supertype that is a subtype of 'c'
3835             for (Type i : types.directSupertypes(env.enclClass.type)) {
3836                 if (i.tsym.isSubClass(c, types) && i.tsym != c) {
3837                     log.error(pos,
3838                               Errors.IllegalDefaultSuperCall(c,
3839                                                              Fragments.RedundantSupertype(c, i)));
3840                     return syms.errSymbol;
3841                 }
3842             }
3843             Assert.error();
3844         }
3845         log.error(pos, Errors.NotEnclClass(c));
3846         return syms.errSymbol;
3847     }
3848     //where
3849     private List<Type> pruneInterfaces(Type t) {
3850         ListBuffer<Type> result = new ListBuffer<>();
3851         for (Type t1 : types.interfaces(t)) {
3852             boolean shouldAdd = true;
3853             for (Type t2 : types.directSupertypes(t)) {
3854                 if (t1 != t2 && !t2.hasTag(ERROR) && types.isSubtypeNoCapture(t2, t1)) {
3855                     shouldAdd = false;
3856                 }
3857             }
3858             if (shouldAdd) {
3859                 result.append(t1);
3860             }
3861         }
3862         return result.toList();
3863     }
3864 
3865     /**
3866      * Determine if an early instance field reference may appear in a constructor prologue.
3867      *
3868      * <p>
3869      * This is only allowed when:
3870      *  - The field is being assigned a value (i.e., written but not read)
3871      *  - The field is not inherited from a superclass
3872      *  - The assignment is not within a lambda, because that would require
3873      *    capturing 'this' which is not allowed prior to super().
3874      *
3875      * <p>
3876      * Note, this method doesn't catch all such scenarios, because this method
3877      * is invoked for symbol "x" only for "x = 42" but not for "this.x = 42".
3878      * We also don't verify that the field has no initializer, which is required.
3879      * To catch those cases, we rely on similar logic in Attr.checkAssignable().
3880      */
3881     private boolean isAllowedEarlyReference(DiagnosticPosition pos, Env<AttrContext> env, VarSymbol v) {
3882 
3883         // Check assumptions
3884         Assert.check(env.info.ctorPrologue);
3885         Assert.check((v.flags_field & STATIC) == 0);
3886 
3887         // The symbol must appear in the LHS of an assignment statement
3888         if (!(env.tree instanceof JCAssign assign))
3889             return false;
3890 
3891         // The assignment statement must not be within a lambda
3892         if (env.info.isLambda)
3893             return false;
3894 
3895         // Get the symbol's qualifier, if any
3896         JCExpression lhs = TreeInfo.skipParens(assign.lhs);
3897         JCExpression base;
3898         switch (lhs.getTag()) {
3899         case IDENT:
3900             base = null;
3901             break;
3902         case SELECT:
3903             JCFieldAccess select = (JCFieldAccess)lhs;
3904             base = select.selected;
3905             if (!TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, base))
3906                 return false;
3907             break;
3908         default:
3909             return false;
3910         }
3911 
3912         // If an early reference, the field must not be declared in a superclass
3913         if (isEarlyReference(env, base, v) && v.owner != env.enclClass.sym)
3914             return false;
3915 
3916         // The flexible constructors feature must be enabled
3917         preview.checkSourceLevel(pos, Feature.FLEXIBLE_CONSTRUCTORS);
3918 
3919         // OK
3920         return true;
3921     }
3922 
3923     /**
3924      * Determine if the variable appearance constitutes an early reference to the current class.
3925      *
3926      * <p>
3927      * This means the variable is an instance field of the current class and it appears
3928      * in an early initialization context of it (i.e., one of its constructor prologues).
3929      *
3930      * <p>
3931      * Such a reference is only allowed for assignments to non-initialized fields that are
3932      * not inherited from a superclass, though that is not enforced by this method.
3933      *
3934      * @param env    The current environment
3935      * @param base   Variable qualifier, if any, otherwise null
3936      * @param v      The variable
3937      */
3938     public boolean isEarlyReference(Env<AttrContext> env, JCTree base, VarSymbol v) {
3939         return env.info.ctorPrologue &&
3940             (v.flags() & STATIC) == 0 &&
3941             v.owner.kind == TYP &&
3942             types.isSubtype(env.enclClass.type, v.owner.type) &&
3943             (base == null || TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, base));
3944     }
3945 
3946     /**
3947      * Resolve `c.this' for an enclosing class c that contains the
3948      * named member.
3949      * @param pos           The position to use for error reporting.
3950      * @param env           The environment current at the expression.
3951      * @param member        The member that must be contained in the result.
3952      */
3953     Symbol resolveSelfContaining(DiagnosticPosition pos,
3954                                  Env<AttrContext> env,
3955                                  Symbol member,
3956                                  boolean isSuperCall) {
3957         Symbol sym = resolveSelfContainingInternal(env, member, isSuperCall);
3958         if (sym == null) {
3959             log.error(pos, Errors.EnclClassRequired(member));
3960             return syms.errSymbol;
3961         } else {
3962             return accessBase(sym, pos, env.enclClass.sym.type, sym.name, true);
3963         }
3964     }
3965 
3966     boolean enclosingInstanceMissing(Env<AttrContext> env, Type type) {
3967         if (type.hasTag(CLASS) && type.getEnclosingType().hasTag(CLASS)) {
3968             Symbol encl = resolveSelfContainingInternal(env, type.tsym, false);
3969             return encl == null || encl.kind.isResolutionError();
3970         }
3971         return false;
3972     }
3973 
3974     private Symbol resolveSelfContainingInternal(Env<AttrContext> env,
3975                                  Symbol member,
3976                                  boolean isSuperCall) {
3977         Name name = names._this;
3978         Env<AttrContext> env1 = isSuperCall ? env.outer : env;
3979         boolean staticOnly = false;
3980         if (env1 != null) {
3981             while (env1 != null && env1.outer != null) {
3982                 if (isStatic(env1)) staticOnly = true;
3983                 if (env1.enclClass.sym.isSubClass(member.owner.enclClass(), types)) {
3984                     Symbol sym = env1.info.scope.findFirst(name);
3985                     if (sym != null) {
3986                         if (staticOnly) sym = new StaticError(sym);
3987                         return sym;
3988                     }
3989                 }
3990                 if ((env1.enclClass.sym.flags() & STATIC) != 0)
3991                     staticOnly = true;
3992                 env1 = env1.outer;
3993             }
3994         }
3995         return null;
3996     }
3997 
3998     /**
3999      * Resolve an appropriate implicit this instance for t's container.
4000      * JLS 8.8.5.1 and 15.9.2
4001      */
4002     Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t) {
4003         return resolveImplicitThis(pos, env, t, false);
4004     }
4005 
4006     Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t, boolean isSuperCall) {
4007         Type thisType = (t.tsym.owner.kind.matches(KindSelector.VAL_MTH)
4008                          ? resolveSelf(pos, env, t.getEnclosingType().tsym, names._this)
4009                          : resolveSelfContaining(pos, env, t.tsym, isSuperCall)).type;
4010         if (env.info.ctorPrologue && thisType.tsym == env.enclClass.sym) {
4011             log.error(pos, Errors.CantRefBeforeCtorCalled(names._this));
4012         }
4013         return thisType;
4014     }
4015 
4016 /* ***************************************************************************
4017  *  ResolveError classes, indicating error situations when accessing symbols
4018  ****************************************************************************/
4019 
4020     //used by TransTypes when checking target type of synthetic cast
4021     public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) {
4022         AccessError error = new AccessError(env, env.enclClass.type, type.tsym);
4023         logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null);
4024     }
4025     //where
4026     private void logResolveError(ResolveError error,
4027             DiagnosticPosition pos,
4028             Symbol location,
4029             Type site,
4030             Name name,
4031             List<Type> argtypes,
4032             List<Type> typeargtypes) {
4033         JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
4034                 pos, location, site, name, argtypes, typeargtypes);
4035         if (d != null) {
4036             d.setFlag(DiagnosticFlag.RESOLVE_ERROR);
4037             log.report(d);
4038         }
4039     }
4040 
4041     private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
4042 
4043     public Object methodArguments(List<Type> argtypes) {
4044         if (argtypes == null || argtypes.isEmpty()) {
4045             return noArgs;
4046         } else {
4047             ListBuffer<Object> diagArgs = new ListBuffer<>();
4048             for (Type t : argtypes) {
4049                 if (t.hasTag(DEFERRED)) {
4050                     diagArgs.append(((DeferredAttr.DeferredType)t).tree);
4051                 } else {
4052                     diagArgs.append(t);
4053                 }
4054             }
4055             return diagArgs;
4056         }
4057     }
4058 
4059     /** check if a type is a subtype of Serializable, if that is available.*/
4060     boolean isSerializable(Type t) {
4061         try {
4062             syms.serializableType.complete();
4063         }
4064         catch (CompletionFailure e) {
4065             return false;
4066         }
4067         return types.isSubtype(t, syms.serializableType);
4068     }
4069 
4070     /**
4071      * Root class for resolution errors. Subclass of ResolveError
4072      * represent a different kinds of resolution error - as such they must
4073      * specify how they map into concrete compiler diagnostics.
4074      */
4075     abstract class ResolveError extends Symbol {
4076 
4077         /** The name of the kind of error, for debugging only. */
4078         final String debugName;
4079 
4080         ResolveError(Kind kind, String debugName) {
4081             super(kind, 0, null, null, null);
4082             this.debugName = debugName;
4083         }
4084 
4085         @Override @DefinedBy(Api.LANGUAGE_MODEL)
4086         public <R, P> R accept(ElementVisitor<R, P> v, P p) {
4087             throw new AssertionError();
4088         }
4089 
4090         @Override
4091         public String toString() {
4092             return debugName;
4093         }
4094 
4095         @Override
4096         public boolean exists() {
4097             return false;
4098         }
4099 
4100         @Override
4101         public boolean isStatic() {
4102             return false;
4103         }
4104 
4105         /**
4106          * Create an external representation for this erroneous symbol to be
4107          * used during attribution - by default this returns the symbol of a
4108          * brand new error type which stores the original type found
4109          * during resolution.
4110          *
4111          * @param name     the name used during resolution
4112          * @param location the location from which the symbol is accessed
4113          */
4114         protected Symbol access(Name name, TypeSymbol location) {
4115             return types.createErrorType(name, location, syms.errSymbol.type).tsym;
4116         }
4117 
4118         /**
4119          * Create a diagnostic representing this resolution error.
4120          *
4121          * @param dkind     The kind of the diagnostic to be created (e.g error).
4122          * @param pos       The position to be used for error reporting.
4123          * @param site      The original type from where the selection took place.
4124          * @param name      The name of the symbol to be resolved.
4125          * @param argtypes  The invocation's value arguments,
4126          *                  if we looked for a method.
4127          * @param typeargtypes  The invocation's type arguments,
4128          *                      if we looked for a method.
4129          */
4130         abstract JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4131                 DiagnosticPosition pos,
4132                 Symbol location,
4133                 Type site,
4134                 Name name,
4135                 List<Type> argtypes,
4136                 List<Type> typeargtypes);
4137     }
4138 
4139     /**
4140      * This class is the root class of all resolution errors caused by
4141      * an invalid symbol being found during resolution.
4142      */
4143     abstract class InvalidSymbolError extends ResolveError {
4144 
4145         /** The invalid symbol found during resolution */
4146         Symbol sym;
4147 
4148         InvalidSymbolError(Kind kind, Symbol sym, String debugName) {
4149             super(kind, debugName);
4150             this.sym = sym;
4151         }
4152 
4153         @Override
4154         public boolean exists() {
4155             return true;
4156         }
4157 
4158         @Override
4159         public String toString() {
4160              return super.toString() + " wrongSym=" + sym;
4161         }
4162 
4163         @Override
4164         public Symbol access(Name name, TypeSymbol location) {
4165             if (!sym.kind.isResolutionError() && sym.kind.matches(KindSelector.TYP))
4166                 return types.createErrorType(name, location, sym.type).tsym;
4167             else
4168                 return sym;
4169         }
4170     }
4171 
4172     class BadRestrictedTypeError extends ResolveError {
4173         private final Name typeName;
4174         BadRestrictedTypeError(Name typeName) {
4175             super(Kind.BAD_RESTRICTED_TYPE, "bad var use");
4176             this.typeName = typeName;
4177         }
4178 
4179         @Override
4180         JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4181             return diags.create(dkind, log.currentSource(), pos, "illegal.ref.to.restricted.type", typeName);
4182         }
4183     }
4184 
4185     /**
4186      * InvalidSymbolError error class indicating that a symbol matching a
4187      * given name does not exists in a given site.
4188      */
4189     class SymbolNotFoundError extends ResolveError {
4190 
4191         SymbolNotFoundError(Kind kind) {
4192             this(kind, "symbol not found error");
4193         }
4194 
4195         SymbolNotFoundError(Kind kind, String debugName) {
4196             super(kind, debugName);
4197         }
4198 
4199         @Override
4200         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4201                 DiagnosticPosition pos,
4202                 Symbol location,
4203                 Type site,
4204                 Name name,
4205                 List<Type> argtypes,
4206                 List<Type> typeargtypes) {
4207             argtypes = argtypes == null ? List.nil() : argtypes;
4208             typeargtypes = typeargtypes == null ? List.nil() : typeargtypes;
4209             if (name == names.error)
4210                 return null;
4211 
4212             boolean hasLocation = false;
4213             if (location == null) {
4214                 location = site.tsym;
4215             }
4216             if (!location.name.isEmpty()) {
4217                 if (location.kind == PCK && !site.tsym.exists() && location.name != names.java) {
4218                     return diags.create(dkind, log.currentSource(), pos,
4219                         "doesnt.exist", location);
4220                 }
4221                 hasLocation = !location.name.equals(names._this) &&
4222                         !location.name.equals(names._super);
4223             }
4224             boolean isConstructor = name == names.init;
4225             KindName kindname = isConstructor ? KindName.CONSTRUCTOR : kind.absentKind();
4226             Name idname = isConstructor ? site.tsym.name : name;
4227             String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation);
4228             if (hasLocation) {
4229                 return diags.create(dkind, log.currentSource(), pos,
4230                         errKey, kindname, idname, //symbol kindname, name
4231                         typeargtypes, args(argtypes), //type parameters and arguments (if any)
4232                         getLocationDiag(location, site)); //location kindname, type
4233             }
4234             else {
4235                 return diags.create(dkind, log.currentSource(), pos,
4236                         errKey, kindname, idname, //symbol kindname, name
4237                         typeargtypes, args(argtypes)); //type parameters and arguments (if any)
4238             }
4239         }
4240         //where
4241         private Object args(List<Type> args) {
4242             return args.isEmpty() ? args : methodArguments(args);
4243         }
4244 
4245         private String getErrorKey(KindName kindname, boolean hasTypeArgs, boolean hasLocation) {
4246             String key = "cant.resolve";
4247             String suffix = hasLocation ? ".location" : "";
4248             switch (kindname) {
4249                 case METHOD:
4250                 case CONSTRUCTOR: {
4251                     suffix += ".args";
4252                     suffix += hasTypeArgs ? ".params" : "";
4253                 }
4254             }
4255             return key + suffix;
4256         }
4257         private JCDiagnostic getLocationDiag(Symbol location, Type site) {
4258             if (location.kind == VAR) {
4259                 return diags.fragment(Fragments.Location1(kindName(location),
4260                                                           location,
4261                                                           location.type));
4262             } else {
4263                 return diags.fragment(Fragments.Location(typeKindName(site),
4264                                       site,
4265                                       null));
4266             }
4267         }
4268     }
4269 
4270     /**
4271      * InvalidSymbolError error class indicating that a given symbol
4272      * (either a method, a constructor or an operand) is not applicable
4273      * given an actual arguments/type argument list.
4274      */
4275     class InapplicableSymbolError extends ResolveError {
4276 
4277         protected MethodResolutionContext resolveContext;
4278 
4279         InapplicableSymbolError(MethodResolutionContext context) {
4280             this(WRONG_MTH, "inapplicable symbol error", context);
4281         }
4282 
4283         protected InapplicableSymbolError(Kind kind, String debugName, MethodResolutionContext context) {
4284             super(kind, debugName);
4285             this.resolveContext = context;
4286         }
4287 
4288         @Override
4289         public String toString() {
4290             return super.toString();
4291         }
4292 
4293         @Override
4294         public boolean exists() {
4295             return true;
4296         }
4297 
4298         @Override
4299         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4300                 DiagnosticPosition pos,
4301                 Symbol location,
4302                 Type site,
4303                 Name name,
4304                 List<Type> argtypes,
4305                 List<Type> typeargtypes) {
4306             if (name == names.error)
4307                 return null;
4308 
4309             Pair<Symbol, JCDiagnostic> c = errCandidate();
4310             Symbol ws = c.fst.asMemberOf(site, types);
4311             UnaryOperator<JCDiagnostic> rewriter = compactMethodDiags ?
4312               d -> MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, c.snd) : null;
4313 
4314             // If the problem is due to type arguments, then the method parameters aren't relevant,
4315             // so use the error message that omits them to avoid confusion.
4316             switch (c.snd.getCode()) {
4317                 case "compiler.misc.wrong.number.type.args":
4318                 case "compiler.misc.explicit.param.do.not.conform.to.bounds":
4319                     return diags.create(dkind, log.currentSource(), pos,
4320                               "cant.apply.symbol.noargs",
4321                               rewriter,
4322                               kindName(ws),
4323                               ws.name == names.init ? ws.owner.name : ws.name,
4324                               ws.owner.type,
4325                               c.snd);
4326                 default:
4327                     // Avoid saying "constructor Array in class Array"
4328                     if (ws.owner == syms.arrayClass && ws.name == names.init) {
4329                         return diags.create(dkind, log.currentSource(), pos,
4330                                   "cant.apply.array.ctor",
4331                                   rewriter,
4332                                   methodArguments(ws.type.getParameterTypes()),
4333                                   methodArguments(argtypes),
4334                                   c.snd);
4335                     }
4336                     return diags.create(dkind, log.currentSource(), pos,
4337                               "cant.apply.symbol",
4338                               rewriter,
4339                               kindName(ws),
4340                               ws.name == names.init ? ws.owner.name : ws.name,
4341                               methodArguments(ws.type.getParameterTypes()),
4342                               methodArguments(argtypes),
4343                               kindName(ws.owner),
4344                               ws.owner.type,
4345                               c.snd);
4346             }
4347         }
4348 
4349         @Override
4350         public Symbol access(Name name, TypeSymbol location) {
4351             Pair<Symbol, JCDiagnostic> cand = errCandidate();
4352             TypeSymbol errSymbol = types.createErrorType(name, location, cand != null ? cand.fst.type : syms.errSymbol.type).tsym;
4353             if (cand != null) {
4354                 attrRecover.wrongMethodSymbolCandidate(errSymbol, cand.fst, cand.snd);
4355             }
4356             return errSymbol;
4357         }
4358 
4359         protected Pair<Symbol, JCDiagnostic> errCandidate() {
4360             Candidate bestSoFar = null;
4361             for (Candidate c : resolveContext.candidates) {
4362                 if (c.isApplicable()) continue;
4363                 bestSoFar = c;
4364             }
4365             Assert.checkNonNull(bestSoFar);
4366             return new Pair<>(bestSoFar.sym, bestSoFar.details);
4367         }
4368     }
4369 
4370     /**
4371      * ResolveError error class indicating that a symbol (either methods, constructors or operand)
4372      * is not applicable given an actual arguments/type argument list.
4373      */
4374     class InapplicableSymbolsError extends InapplicableSymbolError {
4375 
4376         InapplicableSymbolsError(MethodResolutionContext context) {
4377             super(WRONG_MTHS, "inapplicable symbols", context);
4378         }
4379 
4380         @Override
4381         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4382                 DiagnosticPosition pos,
4383                 Symbol location,
4384                 Type site,
4385                 Name name,
4386                 List<Type> argtypes,
4387                 List<Type> typeargtypes) {
4388             Map<Symbol, JCDiagnostic> candidatesMap = mapCandidates();
4389             Map<Symbol, JCDiagnostic> filteredCandidates = compactMethodDiags ?
4390                     filterCandidates(candidatesMap) :
4391                     mapCandidates();
4392             if (filteredCandidates.isEmpty()) {
4393                 filteredCandidates = candidatesMap;
4394             }
4395             boolean truncatedDiag = candidatesMap.size() != filteredCandidates.size();
4396             if (filteredCandidates.size() > 1) {
4397                 JCDiagnostic err = diags.create(dkind,
4398                         null,
4399                         truncatedDiag ?
4400                                 EnumSet.of(DiagnosticFlag.COMPRESSED) :
4401                                 EnumSet.noneOf(DiagnosticFlag.class),
4402                         log.currentSource(),
4403                         pos,
4404                         "cant.apply.symbols",
4405                         name == names.init ? KindName.CONSTRUCTOR : kind.absentKind(),
4406                         name == names.init ? site.tsym.name : name,
4407                         methodArguments(argtypes));
4408                 return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(filteredCandidates, site));
4409             } else if (filteredCandidates.size() == 1) {
4410                 Map.Entry<Symbol, JCDiagnostic> _e =
4411                                 filteredCandidates.entrySet().iterator().next();
4412                 final Pair<Symbol, JCDiagnostic> p = new Pair<>(_e.getKey(), _e.getValue());
4413                 JCDiagnostic d = new InapplicableSymbolError(resolveContext) {
4414                     @Override
4415                     protected Pair<Symbol, JCDiagnostic> errCandidate() {
4416                         return p;
4417                     }
4418                 }.getDiagnostic(dkind, pos,
4419                     location, site, name, argtypes, typeargtypes);
4420                 if (truncatedDiag) {
4421                     d.setFlag(DiagnosticFlag.COMPRESSED);
4422                 }
4423                 return d;
4424             } else {
4425                 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos,
4426                     location, site, name, argtypes, typeargtypes);
4427             }
4428         }
4429         //where
4430             private Map<Symbol, JCDiagnostic> mapCandidates() {
4431                 MostSpecificMap candidates = new MostSpecificMap();
4432                 for (Candidate c : resolveContext.candidates) {
4433                     if (c.isApplicable()) continue;
4434                     candidates.put(c);
4435                 }
4436                 return candidates;
4437             }
4438 
4439             @SuppressWarnings("serial")
4440             private class MostSpecificMap extends LinkedHashMap<Symbol, JCDiagnostic> {
4441                 private void put(Candidate c) {
4442                     ListBuffer<Symbol> overridden = new ListBuffer<>();
4443                     for (Symbol s : keySet()) {
4444                         if (s == c.sym) {
4445                             continue;
4446                         }
4447                         if (c.sym.overrides(s, (TypeSymbol)s.owner, types, false)) {
4448                             overridden.add(s);
4449                         } else if (s.overrides(c.sym, (TypeSymbol)c.sym.owner, types, false)) {
4450                             return;
4451                         }
4452                     }
4453                     for (Symbol s : overridden) {
4454                         remove(s);
4455                     }
4456                     put(c.sym, c.details);
4457                 }
4458             }
4459 
4460             Map<Symbol, JCDiagnostic> filterCandidates(Map<Symbol, JCDiagnostic> candidatesMap) {
4461                 Map<Symbol, JCDiagnostic> candidates = new LinkedHashMap<>();
4462                 for (Map.Entry<Symbol, JCDiagnostic> _entry : candidatesMap.entrySet()) {
4463                     JCDiagnostic d = _entry.getValue();
4464                     if (!new Template(MethodCheckDiag.ARITY_MISMATCH.regex()).matches(d)) {
4465                         candidates.put(_entry.getKey(), d);
4466                     }
4467                 }
4468                 return candidates;
4469             }
4470 
4471             private List<JCDiagnostic> candidateDetails(Map<Symbol, JCDiagnostic> candidatesMap, Type site) {
4472                 List<JCDiagnostic> details = List.nil();
4473                 for (Map.Entry<Symbol, JCDiagnostic> _entry : candidatesMap.entrySet()) {
4474                     Symbol sym = _entry.getKey();
4475                     JCDiagnostic detailDiag =
4476                             diags.fragment(Fragments.InapplicableMethod(Kinds.kindName(sym),
4477                                                                         sym.location(site, types),
4478                                                                         sym.asMemberOf(site, types),
4479                                                                         _entry.getValue()));
4480                     details = details.prepend(detailDiag);
4481                 }
4482                 //typically members are visited in reverse order (see Scope)
4483                 //so we need to reverse the candidate list so that candidates
4484                 //conform to source order
4485                 return details;
4486             }
4487 
4488         @Override
4489         protected Pair<Symbol, JCDiagnostic> errCandidate() {
4490             Map<Symbol, JCDiagnostic> candidatesMap = mapCandidates();
4491             Map<Symbol, JCDiagnostic> filteredCandidates = filterCandidates(candidatesMap);
4492             if (filteredCandidates.size() == 1) {
4493                 return Pair.of(filteredCandidates.keySet().iterator().next(),
4494                                filteredCandidates.values().iterator().next());
4495             }
4496             return null;
4497         }
4498     }
4499 
4500     /**
4501      * DiamondError error class indicating that a constructor symbol is not applicable
4502      * given an actual arguments/type argument list using diamond inference.
4503      */
4504     class DiamondError extends InapplicableSymbolError {
4505 
4506         Symbol sym;
4507 
4508         public DiamondError(Symbol sym, MethodResolutionContext context) {
4509             super(sym.kind, "diamondError", context);
4510             this.sym = sym;
4511         }
4512 
4513         JCDiagnostic getDetails() {
4514             return (sym.kind == WRONG_MTH) ?
4515                     ((InapplicableSymbolError)sym.baseSymbol()).errCandidate().snd :
4516                     null;
4517         }
4518 
4519         @Override
4520         JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
4521                 Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4522             JCDiagnostic details = getDetails();
4523             if (details != null && compactMethodDiags) {
4524                 JCDiagnostic simpleDiag =
4525                         MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, details);
4526                 if (simpleDiag != null) {
4527                     return simpleDiag;
4528                 }
4529             }
4530             String key = details == null ?
4531                 "cant.apply.diamond" :
4532                 "cant.apply.diamond.1";
4533             return diags.create(dkind, log.currentSource(), pos, key,
4534                     Fragments.Diamond(site.tsym), details);
4535         }
4536     }
4537 
4538     /**
4539      * An InvalidSymbolError error class indicating that a symbol is not
4540      * accessible from a given site
4541      */
4542     class AccessError extends InvalidSymbolError {
4543 
4544         private Env<AttrContext> env;
4545         private Type site;
4546 
4547         AccessError(Env<AttrContext> env, Type site, Symbol sym) {
4548             super(HIDDEN, sym, "access error");
4549             this.env = env;
4550             this.site = site;
4551         }
4552 
4553         @Override
4554         public boolean exists() {
4555             return false;
4556         }
4557 
4558         @Override
4559         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4560                 DiagnosticPosition pos,
4561                 Symbol location,
4562                 Type site,
4563                 Name name,
4564                 List<Type> argtypes,
4565                 List<Type> typeargtypes) {
4566             if (sym.name == names.init && sym.owner != site.tsym) {
4567                 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind,
4568                         pos, location, site, name, argtypes, typeargtypes);
4569             }
4570             else if ((sym.flags() & PUBLIC) != 0
4571                 || (env != null && this.site != null
4572                     && !isAccessible(env, this.site))) {
4573                 if (sym.owner.kind == PCK) {
4574                     return diags.create(dkind, log.currentSource(),
4575                             pos, "not.def.access.package.cant.access",
4576                         sym, sym.location(), inaccessiblePackageReason(env, sym.packge()));
4577                 } else if (   sym.packge() != syms.rootPackage
4578                            && !symbolPackageVisible(env, sym)) {
4579                     return diags.create(dkind, log.currentSource(),
4580                             pos, "not.def.access.class.intf.cant.access.reason",
4581                             sym, sym.location(), sym.location().packge(),
4582                             inaccessiblePackageReason(env, sym.packge()));
4583                 } else {
4584                     return diags.create(dkind, log.currentSource(),
4585                             pos, "not.def.access.class.intf.cant.access",
4586                         sym, sym.location());
4587                 }
4588             }
4589             else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) {
4590                 return diags.create(dkind, log.currentSource(),
4591                         pos, "report.access", sym,
4592                         asFlagSet(sym.flags() & (PRIVATE | PROTECTED)),
4593                         sym.location());
4594             }
4595             else {
4596                 return diags.create(dkind, log.currentSource(),
4597                         pos, "not.def.public.cant.access", sym, sym.location());
4598             }
4599         }
4600 
4601         private String toString(Type type) {
4602             StringBuilder sb = new StringBuilder();
4603             sb.append(type);
4604             if (type != null) {
4605                 sb.append("[tsym:").append(type.tsym);
4606                 if (type.tsym != null)
4607                     sb.append("packge:").append(type.tsym.packge());
4608                 sb.append("]");
4609             }
4610             return sb.toString();
4611         }
4612     }
4613 
4614     class InvisibleSymbolError extends InvalidSymbolError {
4615 
4616         private final Env<AttrContext> env;
4617         private final boolean suppressError;
4618 
4619         InvisibleSymbolError(Env<AttrContext> env, boolean suppressError, Symbol sym) {
4620             super(HIDDEN, sym, "invisible class error");
4621             this.env = env;
4622             this.suppressError = suppressError;
4623             this.name = sym.name;
4624         }
4625 
4626         @Override
4627         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4628                 DiagnosticPosition pos,
4629                 Symbol location,
4630                 Type site,
4631                 Name name,
4632                 List<Type> argtypes,
4633                 List<Type> typeargtypes) {
4634             if (suppressError)
4635                 return null;
4636 
4637             if (sym.kind == PCK) {
4638                 JCDiagnostic details = inaccessiblePackageReason(env, sym.packge());
4639                 return diags.create(dkind, log.currentSource(),
4640                         pos, "package.not.visible", sym, details);
4641             }
4642 
4643             JCDiagnostic details = inaccessiblePackageReason(env, sym.packge());
4644 
4645             if (pos.getTree() != null) {
4646                 Symbol o = sym;
4647                 JCTree tree = pos.getTree();
4648 
4649                 while (o.kind != PCK && tree.hasTag(SELECT)) {
4650                     o = o.owner;
4651                     tree = ((JCFieldAccess) tree).selected;
4652                 }
4653 
4654                 if (o.kind == PCK) {
4655                     pos = tree.pos();
4656 
4657                     return diags.create(dkind, log.currentSource(),
4658                             pos, "package.not.visible", o, details);
4659                 }
4660             }
4661 
4662             return diags.create(dkind, log.currentSource(),
4663                     pos, "not.def.access.package.cant.access", sym, sym.packge(), details);
4664         }
4665     }
4666 
4667     JCDiagnostic inaccessiblePackageReason(Env<AttrContext> env, PackageSymbol sym) {
4668         //no dependency:
4669         if (!env.toplevel.modle.readModules.contains(sym.modle)) {
4670             //does not read:
4671             if (sym.modle != syms.unnamedModule) {
4672                 if (env.toplevel.modle != syms.unnamedModule) {
4673                     return diags.fragment(Fragments.NotDefAccessDoesNotRead(env.toplevel.modle,
4674                                                                             sym,
4675                                                                             sym.modle));
4676                 } else {
4677                     return diags.fragment(Fragments.NotDefAccessDoesNotReadFromUnnamed(sym,
4678                                                                                        sym.modle));
4679                 }
4680             } else {
4681                 return diags.fragment(Fragments.NotDefAccessDoesNotReadUnnamed(sym,
4682                                                                                env.toplevel.modle));
4683             }
4684         } else {
4685             if (sym.packge().modle.exports.stream().anyMatch(e -> e.packge == sym)) {
4686                 //not exported to this module:
4687                 if (env.toplevel.modle != syms.unnamedModule) {
4688                     return diags.fragment(Fragments.NotDefAccessNotExportedToModule(sym,
4689                                                                                     sym.modle,
4690                                                                                     env.toplevel.modle));
4691                 } else {
4692                     return diags.fragment(Fragments.NotDefAccessNotExportedToModuleFromUnnamed(sym,
4693                                                                                                sym.modle));
4694                 }
4695             } else {
4696                 //not exported:
4697                 if (env.toplevel.modle != syms.unnamedModule) {
4698                     return diags.fragment(Fragments.NotDefAccessNotExported(sym,
4699                                                                             sym.modle));
4700                 } else {
4701                     return diags.fragment(Fragments.NotDefAccessNotExportedFromUnnamed(sym,
4702                                                                                        sym.modle));
4703                 }
4704             }
4705         }
4706     }
4707 
4708     /**
4709      * InvalidSymbolError error class indicating that an instance member
4710      * has erroneously been accessed from a static context.
4711      */
4712     class StaticError extends InvalidSymbolError {
4713 
4714         StaticError(Symbol sym) {
4715             this(sym, "static error");
4716         }
4717 
4718         StaticError(Symbol sym, String debugName) {
4719             super(STATICERR, sym, debugName);
4720         }
4721 
4722         @Override
4723         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4724                 DiagnosticPosition pos,
4725                 Symbol location,
4726                 Type site,
4727                 Name name,
4728                 List<Type> argtypes,
4729                 List<Type> typeargtypes) {
4730             Symbol errSym = ((sym.kind == TYP && sym.type.hasTag(CLASS))
4731                 ? types.erasure(sym.type).tsym
4732                 : sym);
4733             return diags.create(dkind, log.currentSource(), pos,
4734                     "non-static.cant.be.ref", kindName(sym), errSym);
4735         }
4736     }
4737 
4738     /**
4739      * Specialization of {@link InvalidSymbolError} for illegal
4740      * early accesses within a constructor prologue.
4741      */
4742     class RefBeforeCtorCalledError extends StaticError {
4743 
4744         RefBeforeCtorCalledError(Symbol sym) {
4745             super(sym, "prologue error");
4746         }
4747 
4748         @Override
4749         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4750                 DiagnosticPosition pos,
4751                 Symbol location,
4752                 Type site,
4753                 Name name,
4754                 List<Type> argtypes,
4755                 List<Type> typeargtypes) {
4756             Symbol errSym = ((sym.kind == TYP && sym.type.hasTag(CLASS))
4757                 ? types.erasure(sym.type).tsym
4758                 : sym);
4759             return diags.create(dkind, log.currentSource(), pos,
4760                     "cant.ref.before.ctor.called", errSym);
4761         }
4762     }
4763 
4764     /**
4765      * InvalidSymbolError error class indicating that a pair of symbols
4766      * (either methods, constructors or operands) are ambiguous
4767      * given an actual arguments/type argument list.
4768      */
4769     class AmbiguityError extends ResolveError {
4770 
4771         /** The other maximally specific symbol */
4772         List<Symbol> ambiguousSyms = List.nil();
4773 
4774         @Override
4775         public boolean exists() {
4776             return true;
4777         }
4778 
4779         AmbiguityError(Symbol sym1, Symbol sym2) {
4780             super(AMBIGUOUS, "ambiguity error");
4781             ambiguousSyms = flatten(sym2).appendList(flatten(sym1));
4782         }
4783 
4784         private List<Symbol> flatten(Symbol sym) {
4785             if (sym.kind == AMBIGUOUS) {
4786                 return ((AmbiguityError)sym.baseSymbol()).ambiguousSyms;
4787             } else {
4788                 return List.of(sym);
4789             }
4790         }
4791 
4792         AmbiguityError addAmbiguousSymbol(Symbol s) {
4793             ambiguousSyms = ambiguousSyms.prepend(s);
4794             return this;
4795         }
4796 
4797         @Override
4798         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4799                 DiagnosticPosition pos,
4800                 Symbol location,
4801                 Type site,
4802                 Name name,
4803                 List<Type> argtypes,
4804                 List<Type> typeargtypes) {
4805             List<Symbol> diagSyms = ambiguousSyms.reverse();
4806             Symbol s1 = diagSyms.head;
4807             Symbol s2 = diagSyms.tail.head;
4808             Name sname = s1.name;
4809             if (sname == names.init) sname = s1.owner.name;
4810             return diags.create(dkind, log.currentSource(),
4811                     pos, "ref.ambiguous", sname,
4812                     kindName(s1),
4813                     s1,
4814                     s1.location(site, types),
4815                     kindName(s2),
4816                     s2,
4817                     s2.location(site, types));
4818         }
4819 
4820         /**
4821          * If multiple applicable methods are found during overload and none of them
4822          * is more specific than the others, attempt to merge their signatures.
4823          */
4824         Symbol mergeAbstracts(Type site) {
4825             List<Symbol> ambiguousInOrder = ambiguousSyms.reverse();
4826             return types.mergeAbstracts(ambiguousInOrder, site, true).orElse(this);
4827         }
4828 
4829         @Override
4830         protected Symbol access(Name name, TypeSymbol location) {
4831             Symbol firstAmbiguity = ambiguousSyms.last();
4832             return firstAmbiguity.kind == TYP ?
4833                     types.createErrorType(name, location, firstAmbiguity.type).tsym :
4834                     firstAmbiguity;
4835         }
4836     }
4837 
4838     class BadVarargsMethod extends ResolveError {
4839 
4840         ResolveError delegatedError;
4841 
4842         BadVarargsMethod(ResolveError delegatedError) {
4843             super(delegatedError.kind, "badVarargs");
4844             this.delegatedError = delegatedError;
4845         }
4846 
4847         @Override
4848         public Symbol baseSymbol() {
4849             return delegatedError.baseSymbol();
4850         }
4851 
4852         @Override
4853         protected Symbol access(Name name, TypeSymbol location) {
4854             return delegatedError.access(name, location);
4855         }
4856 
4857         @Override
4858         public boolean exists() {
4859             return true;
4860         }
4861 
4862         @Override
4863         JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4864             return delegatedError.getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes);
4865         }
4866     }
4867 
4868     /**
4869      * BadMethodReferenceError error class indicating that a method reference symbol has been found,
4870      * but with the wrong staticness.
4871      */
4872     class BadMethodReferenceError extends StaticError {
4873 
4874         boolean unboundLookup;
4875 
4876         public BadMethodReferenceError(Symbol sym, boolean unboundLookup) {
4877             super(sym, "bad method ref error");
4878             this.unboundLookup = unboundLookup;
4879         }
4880 
4881         @Override
4882         JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4883             final String key;
4884             if (!unboundLookup) {
4885                 key = "bad.static.method.in.bound.lookup";
4886             } else if (sym.isStatic()) {
4887                 key = "bad.static.method.in.unbound.lookup";
4888             } else {
4889                 key = "bad.instance.method.in.unbound.lookup";
4890             }
4891             return sym.kind.isResolutionError() ?
4892                     ((ResolveError)sym).getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes) :
4893                     diags.create(dkind, log.currentSource(), pos, key, Kinds.kindName(sym), sym);
4894         }
4895     }
4896 
4897     /**
4898      * BadConstructorReferenceError error class indicating that a constructor reference symbol has been found,
4899      * but pointing to a class for which an enclosing instance is not available.
4900      */
4901     class BadConstructorReferenceError extends InvalidSymbolError {
4902 
4903         public BadConstructorReferenceError(Symbol sym) {
4904             super(MISSING_ENCL, sym, "BadConstructorReferenceError");
4905         }
4906 
4907         @Override
4908         JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4909            return diags.create(dkind, log.currentSource(), pos,
4910                 "cant.access.inner.cls.constr", site.tsym.name, argtypes, site.getEnclosingType());
4911         }
4912     }
4913 
4914     class BadClassFileError extends InvalidSymbolError {
4915 
4916         private final CompletionFailure ex;
4917 
4918         public BadClassFileError(CompletionFailure ex) {
4919             super(HIDDEN, ex.sym, "BadClassFileError");
4920             this.name = sym.name;
4921             this.ex = ex;
4922         }
4923 
4924         @Override
4925         JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4926             JCDiagnostic d = diags.create(dkind, log.currentSource(), pos,
4927                 "cant.access", ex.sym, ex.getDetailValue());
4928 
4929             d.setFlag(DiagnosticFlag.NON_DEFERRABLE);
4930             return d;
4931         }
4932 
4933     }
4934 
4935     /**
4936      * Helper class for method resolution diagnostic simplification.
4937      * Certain resolution diagnostic are rewritten as simpler diagnostic
4938      * where the enclosing resolution diagnostic (i.e. 'inapplicable method')
4939      * is stripped away, as it doesn't carry additional info. The logic
4940      * for matching a given diagnostic is given in terms of a template
4941      * hierarchy: a diagnostic template can be specified programmatically,
4942      * so that only certain diagnostics are matched. Each templete is then
4943      * associated with a rewriter object that carries out the task of rewtiting
4944      * the diagnostic to a simpler one.
4945      */
4946     static class MethodResolutionDiagHelper {
4947 
4948         /**
4949          * A diagnostic rewriter transforms a method resolution diagnostic
4950          * into a simpler one
4951          */
4952         interface DiagnosticRewriter {
4953             JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags,
4954                     DiagnosticPosition preferredPos, DiagnosticSource preferredSource,
4955                     DiagnosticType preferredKind, JCDiagnostic d);
4956         }
4957 
4958         /**
4959          * A diagnostic template is made up of two ingredients: (i) a regular
4960          * expression for matching a diagnostic key and (ii) a list of sub-templates
4961          * for matching diagnostic arguments.
4962          */
4963         static class Template {
4964 
4965             /** regex used to match diag key */
4966             String regex;
4967 
4968             /** templates used to match diagnostic args */
4969             Template[] subTemplates;
4970 
4971             Template(String key, Template... subTemplates) {
4972                 this.regex = key;
4973                 this.subTemplates = subTemplates;
4974             }
4975 
4976             /**
4977              * Returns true if the regex matches the diagnostic key and if
4978              * all diagnostic arguments are matches by corresponding sub-templates.
4979              */
4980             boolean matches(Object o) {
4981                 JCDiagnostic d = (JCDiagnostic)o;
4982                 Object[] args = d.getArgs();
4983                 if (!d.getCode().matches(regex) ||
4984                         subTemplates.length != d.getArgs().length) {
4985                     return false;
4986                 }
4987                 for (int i = 0; i < args.length ; i++) {
4988                     if (!subTemplates[i].matches(args[i])) {
4989                         return false;
4990                     }
4991                 }
4992                 return true;
4993             }
4994         }
4995 
4996         /**
4997          * Common rewriter for all argument mismatch simplifications.
4998          */
4999         static class ArgMismatchRewriter implements DiagnosticRewriter {
5000 
5001             /** the index of the subdiagnostic to be used as primary. */
5002             int causeIndex;
5003 
5004             public ArgMismatchRewriter(int causeIndex) {
5005                 this.causeIndex = causeIndex;
5006             }
5007 
5008             @Override
5009             public JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags,
5010                     DiagnosticPosition preferredPos, DiagnosticSource preferredSource,
5011                     DiagnosticType preferredKind, JCDiagnostic d) {
5012                 JCDiagnostic cause = (JCDiagnostic)d.getArgs()[causeIndex];
5013                 DiagnosticPosition pos = d.getDiagnosticPosition();
5014                 if (pos == null) {
5015                     pos = preferredPos;
5016                 }
5017                 return diags.create(preferredKind, preferredSource, pos,
5018                         "prob.found.req", cause);
5019             }
5020         }
5021 
5022         /** a dummy template that match any diagnostic argument */
5023         static final Template skip = new Template("") {
5024             @Override
5025             boolean matches(Object d) {
5026                 return true;
5027             }
5028         };
5029 
5030         /** template for matching inference-free arguments mismatch failures */
5031         static final Template argMismatchTemplate = new Template(MethodCheckDiag.ARG_MISMATCH.regex(), skip);
5032 
5033         /** template for matching inference related arguments mismatch failures */
5034         static final Template inferArgMismatchTemplate = new Template(MethodCheckDiag.ARG_MISMATCH.regex(), skip, skip) {
5035             @Override
5036             boolean matches(Object o) {
5037                 if (!super.matches(o)) {
5038                     return false;
5039                 }
5040                 JCDiagnostic d = (JCDiagnostic)o;
5041                 @SuppressWarnings("unchecked")
5042                 List<Type> tvars = (List<Type>)d.getArgs()[0];
5043                 return !containsAny(d, tvars);
5044             }
5045 
5046             BiPredicate<Object, List<Type>> containsPredicate = (o, ts) -> {
5047                 if (o instanceof Type type) {
5048                     return type.containsAny(ts);
5049                 } else if (o instanceof JCDiagnostic diagnostic) {
5050                     return containsAny(diagnostic, ts);
5051                 } else {
5052                     return false;
5053                 }
5054             };
5055 
5056             boolean containsAny(JCDiagnostic d, List<Type> ts) {
5057                 return Stream.of(d.getArgs())
5058                         .anyMatch(o -> containsPredicate.test(o, ts));
5059             }
5060         };
5061 
5062         /** rewriter map used for method resolution simplification */
5063         static final Map<Template, DiagnosticRewriter> rewriters = new LinkedHashMap<>();
5064 
5065         static {
5066             rewriters.put(argMismatchTemplate, new ArgMismatchRewriter(0));
5067             rewriters.put(inferArgMismatchTemplate, new ArgMismatchRewriter(1));
5068         }
5069 
5070         /**
5071          * Main entry point for diagnostic rewriting - given a diagnostic, see if any templates matches it,
5072          * and rewrite it accordingly.
5073          */
5074         static JCDiagnostic rewrite(JCDiagnostic.Factory diags, DiagnosticPosition pos, DiagnosticSource source,
5075                                     DiagnosticType dkind, JCDiagnostic d) {
5076             for (Map.Entry<Template, DiagnosticRewriter> _entry : rewriters.entrySet()) {
5077                 if (_entry.getKey().matches(d)) {
5078                     JCDiagnostic simpleDiag =
5079                             _entry.getValue().rewriteDiagnostic(diags, pos, source, dkind, d);
5080                     simpleDiag.setFlag(DiagnosticFlag.COMPRESSED);
5081                     return simpleDiag;
5082                 }
5083             }
5084             return null;
5085         }
5086     }
5087 
5088     enum MethodResolutionPhase {
5089         BASIC(false, false),
5090         BOX(true, false),
5091         VARARITY(true, true) {
5092             @Override
5093             public Symbol mergeResults(Symbol bestSoFar, Symbol sym) {
5094                 //Check invariants (see {@code LookupHelper.shouldStop})
5095                 Assert.check(bestSoFar.kind.isResolutionError() && bestSoFar.kind != AMBIGUOUS);
5096                 if (!sym.kind.isResolutionError()) {
5097                     //varargs resolution successful
5098                     return sym;
5099                 } else {
5100                     //pick best error
5101                     switch (bestSoFar.kind) {
5102                         case WRONG_MTH:
5103                         case WRONG_MTHS:
5104                             //Override previous errors if they were caused by argument mismatch.
5105                             //This generally means preferring current symbols - but we need to pay
5106                             //attention to the fact that the varargs lookup returns 'less' candidates
5107                             //than the previous rounds, and adjust that accordingly.
5108                             switch (sym.kind) {
5109                                 case WRONG_MTH:
5110                                     //if the previous round matched more than one method, return that
5111                                     //result instead
5112                                     return bestSoFar.kind == WRONG_MTHS ?
5113                                             bestSoFar : sym;
5114                                 case ABSENT_MTH:
5115                                     //do not override erroneous symbol if the arity lookup did not
5116                                     //match any method
5117                                     return bestSoFar;
5118                                 case WRONG_MTHS:
5119                                 default:
5120                                     //safe to override
5121                                     return sym;
5122                             }
5123                         default:
5124                             //otherwise, return first error
5125                             return bestSoFar;
5126                     }
5127                 }
5128             }
5129         };
5130 
5131         final boolean isBoxingRequired;
5132         final boolean isVarargsRequired;
5133 
5134         MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) {
5135            this.isBoxingRequired = isBoxingRequired;
5136            this.isVarargsRequired = isVarargsRequired;
5137         }
5138 
5139         public boolean isBoxingRequired() {
5140             return isBoxingRequired;
5141         }
5142 
5143         public boolean isVarargsRequired() {
5144             return isVarargsRequired;
5145         }
5146 
5147         public Symbol mergeResults(Symbol prev, Symbol sym) {
5148             return sym;
5149         }
5150     }
5151 
5152     final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
5153 
5154     /**
5155      * A resolution context is used to keep track of intermediate results of
5156      * overload resolution, such as list of method that are not applicable
5157      * (used to generate more precise diagnostics) and so on. Resolution contexts
5158      * can be nested - this means that when each overload resolution routine should
5159      * work within the resolution context it created.
5160      */
5161     class MethodResolutionContext {
5162 
5163         private List<Candidate> candidates = List.nil();
5164 
5165         MethodResolutionPhase step = null;
5166 
5167         MethodCheck methodCheck = resolveMethodCheck;
5168 
5169         private boolean internalResolution = false;
5170         private DeferredAttr.AttrMode attrMode = DeferredAttr.AttrMode.SPECULATIVE;
5171 
5172         void addInapplicableCandidate(Symbol sym, JCDiagnostic details) {
5173             Candidate c = new Candidate(currentResolutionContext.step, sym, details, null);
5174             candidates = candidates.append(c);
5175         }
5176 
5177         void addApplicableCandidate(Symbol sym, Type mtype) {
5178             Candidate c = new Candidate(currentResolutionContext.step, sym, null, mtype);
5179             candidates = candidates.append(c);
5180         }
5181 
5182         DeferredAttrContext deferredAttrContext(Symbol sym, InferenceContext inferenceContext, ResultInfo pendingResult, Warner warn) {
5183             DeferredAttrContext parent = (pendingResult == null)
5184                 ? deferredAttr.emptyDeferredAttrContext
5185                 : pendingResult.checkContext.deferredAttrContext();
5186             return deferredAttr.new DeferredAttrContext(attrMode, sym, step,
5187                     inferenceContext, parent, warn);
5188         }
5189 
5190         /**
5191          * This class represents an overload resolution candidate. There are two
5192          * kinds of candidates: applicable methods and inapplicable methods;
5193          * applicable methods have a pointer to the instantiated method type,
5194          * while inapplicable candidates contain further details about the
5195          * reason why the method has been considered inapplicable.
5196          */
5197         @SuppressWarnings("overrides")
5198         class Candidate {
5199 
5200             final MethodResolutionPhase step;
5201             final Symbol sym;
5202             final JCDiagnostic details;
5203             final Type mtype;
5204 
5205             private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) {
5206                 this.step = step;
5207                 this.sym = sym;
5208                 this.details = details;
5209                 this.mtype = mtype;
5210             }
5211 
5212             boolean isApplicable() {
5213                 return mtype != null;
5214             }
5215         }
5216 
5217         DeferredAttr.AttrMode attrMode() {
5218             return attrMode;
5219         }
5220     }
5221 
5222     MethodResolutionContext currentResolutionContext = null;
5223 }