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