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