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