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