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