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