1 /*
   2  * Copyright (c) 1999, 2013, 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.Symbol.*;
  31 import com.sun.tools.javac.code.Type.*;
  32 import com.sun.tools.javac.comp.Attr.ResultInfo;
  33 import com.sun.tools.javac.comp.Check.CheckContext;
  34 import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
  35 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
  36 import com.sun.tools.javac.comp.DeferredAttr.DeferredType;
  37 import com.sun.tools.javac.comp.Infer.InferenceContext;
  38 import com.sun.tools.javac.comp.Infer.FreeTypeListener;
  39 import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
  40 import com.sun.tools.javac.jvm.*;
  41 import com.sun.tools.javac.tree.*;
  42 import com.sun.tools.javac.tree.JCTree.*;
  43 import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
  44 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
  45 import com.sun.tools.javac.util.*;
  46 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
  47 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  48 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
  49 
  50 import java.util.Arrays;
  51 import java.util.Collection;
  52 import java.util.EnumMap;
  53 import java.util.EnumSet;
  54 import java.util.Iterator;
  55 import java.util.LinkedHashMap;
  56 import java.util.LinkedHashSet;
  57 import java.util.Map;
  58 
  59 import javax.lang.model.element.ElementVisitor;
  60 
  61 import static com.sun.tools.javac.code.Flags.*;
  62 import static com.sun.tools.javac.code.Flags.BLOCK;
  63 import static com.sun.tools.javac.code.Kinds.*;
  64 import static com.sun.tools.javac.code.Kinds.ERRONEOUS;
  65 import static com.sun.tools.javac.code.TypeTag.*;
  66 import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
  67 import static com.sun.tools.javac.tree.JCTree.Tag.*;
  68 
  69 /** Helper class for name resolution, used mostly by the attribution phase.
  70  *
  71  *  <p><b>This is NOT part of any supported API.
  72  *  If you write code that depends on this, you do so at your own risk.
  73  *  This code and its internal interfaces are subject to change or
  74  *  deletion without notice.</b>
  75  */
  76 public class Resolve {
  77     protected static final Context.Key<Resolve> resolveKey =
  78         new Context.Key<Resolve>();
  79 
  80     Names names;
  81     Log log;
  82     Symtab syms;
  83     Attr attr;
  84     DeferredAttr deferredAttr;
  85     Check chk;
  86     Infer infer;
  87     ClassReader reader;
  88     TreeInfo treeinfo;
  89     Types types;
  90     JCDiagnostic.Factory diags;
  91     public final boolean boxingEnabled; // = source.allowBoxing();
  92     public final boolean varargsEnabled; // = source.allowVarargs();
  93     public final boolean allowMethodHandles;
  94     public final boolean allowDefaultMethods;
  95     public final boolean allowStructuralMostSpecific;
  96     private final boolean debugResolve;
  97     final EnumSet<VerboseResolutionMode> verboseResolutionMode;
  98 
  99     Scope polymorphicSignatureScope;
 100 
 101     protected Resolve(Context context) {
 102         context.put(resolveKey, this);
 103         syms = Symtab.instance(context);
 104 
 105         varNotFound = new
 106             SymbolNotFoundError(ABSENT_VAR);
 107         methodNotFound = new
 108             SymbolNotFoundError(ABSENT_MTH);
 109         typeNotFound = new
 110             SymbolNotFoundError(ABSENT_TYP);
 111 
 112         names = Names.instance(context);
 113         log = Log.instance(context);
 114         attr = Attr.instance(context);
 115         deferredAttr = DeferredAttr.instance(context);
 116         chk = Check.instance(context);
 117         infer = Infer.instance(context);
 118         reader = ClassReader.instance(context);
 119         treeinfo = TreeInfo.instance(context);
 120         types = Types.instance(context);
 121         diags = JCDiagnostic.Factory.instance(context);
 122         Source source = Source.instance(context);
 123         boxingEnabled = source.allowBoxing();
 124         varargsEnabled = source.allowVarargs();
 125         Options options = Options.instance(context);
 126         debugResolve = options.isSet("debugresolve");
 127         verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
 128         Target target = Target.instance(context);
 129         allowMethodHandles = target.hasMethodHandles();
 130         allowDefaultMethods = source.allowDefaultMethods();
 131         allowStructuralMostSpecific = source.allowStructuralMostSpecific();
 132         polymorphicSignatureScope = new Scope(syms.noSymbol);
 133 
 134         inapplicableMethodException = new InapplicableMethodException(diags);
 135     }
 136 
 137     /** error symbols, which are returned when resolution fails
 138      */
 139     private final SymbolNotFoundError varNotFound;
 140     private final SymbolNotFoundError methodNotFound;
 141     private final SymbolNotFoundError typeNotFound;
 142 
 143     public static Resolve instance(Context context) {
 144         Resolve instance = context.get(resolveKey);
 145         if (instance == null)
 146             instance = new Resolve(context);
 147         return instance;
 148     }
 149 
 150     // <editor-fold defaultstate="collapsed" desc="Verbose resolution diagnostics support">
 151     enum VerboseResolutionMode {
 152         SUCCESS("success"),
 153         FAILURE("failure"),
 154         APPLICABLE("applicable"),
 155         INAPPLICABLE("inapplicable"),
 156         DEFERRED_INST("deferred-inference"),
 157         PREDEF("predef"),
 158         OBJECT_INIT("object-init"),
 159         INTERNAL("internal");
 160 
 161         final String opt;
 162 
 163         private VerboseResolutionMode(String opt) {
 164             this.opt = opt;
 165         }
 166 
 167         static EnumSet<VerboseResolutionMode> getVerboseResolutionMode(Options opts) {
 168             String s = opts.get("verboseResolution");
 169             EnumSet<VerboseResolutionMode> res = EnumSet.noneOf(VerboseResolutionMode.class);
 170             if (s == null) return res;
 171             if (s.contains("all")) {
 172                 res = EnumSet.allOf(VerboseResolutionMode.class);
 173             }
 174             Collection<String> args = Arrays.asList(s.split(","));
 175             for (VerboseResolutionMode mode : values()) {
 176                 if (args.contains(mode.opt)) {
 177                     res.add(mode);
 178                 } else if (args.contains("-" + mode.opt)) {
 179                     res.remove(mode);
 180                 }
 181             }
 182             return res;
 183         }
 184     }
 185 
 186     void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site,
 187             List<Type> argtypes, List<Type> typeargtypes, Symbol bestSoFar) {
 188         boolean success = bestSoFar.kind < ERRONEOUS;
 189 
 190         if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) {
 191             return;
 192         } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) {
 193             return;
 194         }
 195 
 196         if (bestSoFar.name == names.init &&
 197                 bestSoFar.owner == syms.objectType.tsym &&
 198                 !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) {
 199             return; //skip diags for Object constructor resolution
 200         } else if (site == syms.predefClass.type &&
 201                 !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) {
 202             return; //skip spurious diags for predef symbols (i.e. operators)
 203         } else if (currentResolutionContext.internalResolution &&
 204                 !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) {
 205             return;
 206         }
 207 
 208         int pos = 0;
 209         int mostSpecificPos = -1;
 210         ListBuffer<JCDiagnostic> subDiags = ListBuffer.lb();
 211         for (Candidate c : currentResolutionContext.candidates) {
 212             if (currentResolutionContext.step != c.step ||
 213                     (c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE)) ||
 214                     (!c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))) {
 215                 continue;
 216             } else {
 217                 subDiags.append(c.isApplicable() ?
 218                         getVerboseApplicableCandidateDiag(pos, c.sym, c.mtype) :
 219                         getVerboseInapplicableCandidateDiag(pos, c.sym, c.details));
 220                 if (c.sym == bestSoFar)
 221                     mostSpecificPos = pos;
 222                 pos++;
 223             }
 224         }
 225         String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1";
 226         List<Type> argtypes2 = Type.map(argtypes,
 227                     deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, bestSoFar, currentResolutionContext.step));
 228         JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name,
 229                 site.tsym, mostSpecificPos, currentResolutionContext.step,
 230                 methodArguments(argtypes2),
 231                 methodArguments(typeargtypes));
 232         JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList());
 233         log.report(d);
 234     }
 235 
 236     JCDiagnostic getVerboseApplicableCandidateDiag(int pos, Symbol sym, Type inst) {
 237         JCDiagnostic subDiag = null;
 238         if (sym.type.hasTag(FORALL)) {
 239             subDiag = diags.fragment("partial.inst.sig", inst);
 240         }
 241 
 242         String key = subDiag == null ?
 243                 "applicable.method.found" :
 244                 "applicable.method.found.1";
 245 
 246         return diags.fragment(key, pos, sym, subDiag);
 247     }
 248 
 249     JCDiagnostic getVerboseInapplicableCandidateDiag(int pos, Symbol sym, JCDiagnostic subDiag) {
 250         return diags.fragment("not.applicable.method.found", pos, sym, subDiag);
 251     }
 252     // </editor-fold>
 253 
 254 /* ************************************************************************
 255  * Identifier resolution
 256  *************************************************************************/
 257 
 258     /** An environment is "static" if its static level is greater than
 259      *  the one of its outer environment
 260      */
 261     protected static boolean isStatic(Env<AttrContext> env) {
 262         return env.info.staticLevel > env.outer.info.staticLevel;
 263     }
 264 
 265     /** An environment is an "initializer" if it is a constructor or
 266      *  an instance initializer.
 267      */
 268     static boolean isInitializer(Env<AttrContext> env) {
 269         Symbol owner = env.info.scope.owner;
 270         return owner.isConstructor() ||
 271             owner.owner.kind == TYP &&
 272             (owner.kind == VAR ||
 273              owner.kind == MTH && (owner.flags() & BLOCK) != 0) &&
 274             (owner.flags() & STATIC) == 0;
 275     }
 276 
 277     /** Is class accessible in given evironment?
 278      *  @param env    The current environment.
 279      *  @param c      The class whose accessibility is checked.
 280      */
 281     public boolean isAccessible(Env<AttrContext> env, TypeSymbol c) {
 282         return isAccessible(env, c, false);
 283     }
 284 
 285     public boolean isAccessible(Env<AttrContext> env, TypeSymbol c, boolean checkInner) {
 286         boolean isAccessible = false;
 287         switch ((short)(c.flags() & AccessFlags)) {
 288             case PRIVATE:
 289                 isAccessible =
 290                     env.enclClass.sym.outermostClass() ==
 291                     c.owner.outermostClass();
 292                 break;
 293             case 0:
 294                 isAccessible =
 295                     env.toplevel.packge == c.owner // fast special case
 296                     ||
 297                     env.toplevel.packge == c.packge()
 298                     ||
 299                     // Hack: this case is added since synthesized default constructors
 300                     // of anonymous classes should be allowed to access
 301                     // classes which would be inaccessible otherwise.
 302                     env.enclMethod != null &&
 303                     (env.enclMethod.mods.flags & ANONCONSTR) != 0;
 304                 break;
 305             default: // error recovery
 306             case PUBLIC:
 307                 isAccessible = true;
 308                 break;
 309             case PROTECTED:
 310                 isAccessible =
 311                     env.toplevel.packge == c.owner // fast special case
 312                     ||
 313                     env.toplevel.packge == c.packge()
 314                     ||
 315                     isInnerSubClass(env.enclClass.sym, c.owner);
 316                 break;
 317         }
 318         return (checkInner == false || c.type.getEnclosingType() == Type.noType) ?
 319             isAccessible :
 320             isAccessible && isAccessible(env, c.type.getEnclosingType(), checkInner);
 321     }
 322     //where
 323         /** Is given class a subclass of given base class, or an inner class
 324          *  of a subclass?
 325          *  Return null if no such class exists.
 326          *  @param c     The class which is the subclass or is contained in it.
 327          *  @param base  The base class
 328          */
 329         private boolean isInnerSubClass(ClassSymbol c, Symbol base) {
 330             while (c != null && !c.isSubClass(base, types)) {
 331                 c = c.owner.enclClass();
 332             }
 333             return c != null;
 334         }
 335 
 336     boolean isAccessible(Env<AttrContext> env, Type t) {
 337         return isAccessible(env, t, false);
 338     }
 339 
 340     boolean isAccessible(Env<AttrContext> env, Type t, boolean checkInner) {
 341         return (t.hasTag(ARRAY))
 342             ? isAccessible(env, types.elemtype(t))
 343             : isAccessible(env, t.tsym, checkInner);
 344     }
 345 
 346     /** Is symbol accessible as a member of given type in given evironment?
 347      *  @param env    The current environment.
 348      *  @param site   The type of which the tested symbol is regarded
 349      *                as a member.
 350      *  @param sym    The symbol.
 351      */
 352     public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym) {
 353         return isAccessible(env, site, sym, false);
 354     }
 355     public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym, boolean checkInner) {
 356         if (sym.name == names.init && sym.owner != site.tsym) return false;
 357         switch ((short)(sym.flags() & AccessFlags)) {
 358         case PRIVATE:
 359             return
 360                 (env.enclClass.sym == sym.owner // fast special case
 361                  ||
 362                  env.enclClass.sym.outermostClass() ==
 363                  sym.owner.outermostClass())
 364                 &&
 365                 sym.isInheritedIn(site.tsym, types);
 366         case 0:
 367             return
 368                 (env.toplevel.packge == sym.owner.owner // fast special case
 369                  ||
 370                  env.toplevel.packge == sym.packge())
 371                 &&
 372                 isAccessible(env, site, checkInner)
 373                 &&
 374                 sym.isInheritedIn(site.tsym, types)
 375                 &&
 376                 notOverriddenIn(site, sym);
 377         case PROTECTED:
 378             return
 379                 (env.toplevel.packge == sym.owner.owner // fast special case
 380                  ||
 381                  env.toplevel.packge == sym.packge()
 382                  ||
 383                  isProtectedAccessible(sym, env.enclClass.sym, site)
 384                  ||
 385                  // OK to select instance method or field from 'super' or type name
 386                  // (but type names should be disallowed elsewhere!)
 387                  env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP)
 388                 &&
 389                 isAccessible(env, site, checkInner)
 390                 &&
 391                 notOverriddenIn(site, sym);
 392         default: // this case includes erroneous combinations as well
 393             return isAccessible(env, site, checkInner) && notOverriddenIn(site, sym);
 394         }
 395     }
 396     //where
 397     /* `sym' is accessible only if not overridden by
 398      * another symbol which is a member of `site'
 399      * (because, if it is overridden, `sym' is not strictly
 400      * speaking a member of `site'). A polymorphic signature method
 401      * cannot be overridden (e.g. MH.invokeExact(Object[])).
 402      */
 403     private boolean notOverriddenIn(Type site, Symbol sym) {
 404         if (sym.kind != MTH || sym.isConstructor() || sym.isStatic())
 405             return true;
 406         else {
 407             Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true);
 408             return (s2 == null || s2 == sym || sym.owner == s2.owner ||
 409                     !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym)));
 410         }
 411     }
 412     //where
 413         /** Is given protected symbol accessible if it is selected from given site
 414          *  and the selection takes place in given class?
 415          *  @param sym     The symbol with protected access
 416          *  @param c       The class where the access takes place
 417          *  @site          The type of the qualifier
 418          */
 419         private
 420         boolean isProtectedAccessible(Symbol sym, ClassSymbol c, Type site) {
 421             while (c != null &&
 422                    !(c.isSubClass(sym.owner, types) &&
 423                      (c.flags() & INTERFACE) == 0 &&
 424                      // In JLS 2e 6.6.2.1, the subclass restriction applies
 425                      // only to instance fields and methods -- types are excluded
 426                      // regardless of whether they are declared 'static' or not.
 427                      ((sym.flags() & STATIC) != 0 || sym.kind == TYP || site.tsym.isSubClass(c, types))))
 428                 c = c.owner.enclClass();
 429             return c != null;
 430         }
 431 
 432     /**
 433      * Performs a recursive scan of a type looking for accessibility problems
 434      * from current attribution environment
 435      */
 436     void checkAccessibleType(Env<AttrContext> env, Type t) {
 437         accessibilityChecker.visit(t, env);
 438     }
 439 
 440     /**
 441      * Accessibility type-visitor
 442      */
 443     Types.SimpleVisitor<Void, Env<AttrContext>> accessibilityChecker =
 444             new Types.SimpleVisitor<Void, Env<AttrContext>>() {
 445 
 446         void visit(List<Type> ts, Env<AttrContext> env) {
 447             for (Type t : ts) {
 448                 visit(t, env);
 449             }
 450         }
 451 
 452         public Void visitType(Type t, Env<AttrContext> env) {
 453             return null;
 454         }
 455 
 456         @Override
 457         public Void visitArrayType(ArrayType t, Env<AttrContext> env) {
 458             visit(t.elemtype, env);
 459             return null;
 460         }
 461 
 462         @Override
 463         public Void visitClassType(ClassType t, Env<AttrContext> env) {
 464             visit(t.getTypeArguments(), env);
 465             if (!isAccessible(env, t, true)) {
 466                 accessBase(new AccessError(t.tsym), env.tree.pos(), env.enclClass.sym, t, t.tsym.name, true);
 467             }
 468             return null;
 469         }
 470 
 471         @Override
 472         public Void visitWildcardType(WildcardType t, Env<AttrContext> env) {
 473             visit(t.type, env);
 474             return null;
 475         }
 476 
 477         @Override
 478         public Void visitMethodType(MethodType t, Env<AttrContext> env) {
 479             visit(t.getParameterTypes(), env);
 480             visit(t.getReturnType(), env);
 481             visit(t.getThrownTypes(), env);
 482             return null;
 483         }
 484     };
 485 
 486     /** Try to instantiate the type of a method so that it fits
 487      *  given type arguments and argument types. If succesful, return
 488      *  the method's instantiated type, else return null.
 489      *  The instantiation will take into account an additional leading
 490      *  formal parameter if the method is an instance method seen as a member
 491      *  of un underdetermined site In this case, we treat site as an additional
 492      *  parameter and the parameters of the class containing the method as
 493      *  additional type variables that get instantiated.
 494      *
 495      *  @param env         The current environment
 496      *  @param site        The type of which the method is a member.
 497      *  @param m           The method symbol.
 498      *  @param argtypes    The invocation's given value arguments.
 499      *  @param typeargtypes    The invocation's given type arguments.
 500      *  @param allowBoxing Allow boxing conversions of arguments.
 501      *  @param useVarargs Box trailing arguments into an array for varargs.
 502      */
 503     Type rawInstantiate(Env<AttrContext> env,
 504                         Type site,
 505                         Symbol m,
 506                         ResultInfo resultInfo,
 507                         List<Type> argtypes,
 508                         List<Type> typeargtypes,
 509                         boolean allowBoxing,
 510                         boolean useVarargs,
 511                         Warner warn) throws Infer.InferenceException {
 512 
 513         Type mt = types.memberType(site, m);
 514         // tvars is the list of formal type variables for which type arguments
 515         // need to inferred.
 516         List<Type> tvars = List.nil();
 517         if (typeargtypes == null) typeargtypes = List.nil();
 518         if (!mt.hasTag(FORALL) && typeargtypes.nonEmpty()) {
 519             // This is not a polymorphic method, but typeargs are supplied
 520             // which is fine, see JLS 15.12.2.1
 521         } else if (mt.hasTag(FORALL) && typeargtypes.nonEmpty()) {
 522             ForAll pmt = (ForAll) mt;
 523             if (typeargtypes.length() != pmt.tvars.length())
 524                 throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args
 525             // Check type arguments are within bounds
 526             List<Type> formals = pmt.tvars;
 527             List<Type> actuals = typeargtypes;
 528             while (formals.nonEmpty() && actuals.nonEmpty()) {
 529                 List<Type> bounds = types.subst(types.getBounds((TypeVar)formals.head),
 530                                                 pmt.tvars, typeargtypes);
 531                 for (; bounds.nonEmpty(); bounds = bounds.tail)
 532                     if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn))
 533                         throw inapplicableMethodException.setMessage("explicit.param.do.not.conform.to.bounds",actuals.head, bounds);
 534                 formals = formals.tail;
 535                 actuals = actuals.tail;
 536             }
 537             mt = types.subst(pmt.qtype, pmt.tvars, typeargtypes);
 538         } else if (mt.hasTag(FORALL)) {
 539             ForAll pmt = (ForAll) mt;
 540             List<Type> tvars1 = types.newInstances(pmt.tvars);
 541             tvars = tvars.appendList(tvars1);
 542             mt = types.subst(pmt.qtype, pmt.tvars, tvars1);
 543         }
 544 
 545         // find out whether we need to go the slow route via infer
 546         boolean instNeeded = tvars.tail != null; /*inlined: tvars.nonEmpty()*/
 547         for (List<Type> l = argtypes;
 548              l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded;
 549              l = l.tail) {
 550             if (l.head.hasTag(FORALL)) instNeeded = true;
 551         }
 552 
 553         if (instNeeded)
 554             return infer.instantiateMethod(env,
 555                                     tvars,
 556                                     (MethodType)mt,
 557                                     resultInfo,
 558                                     m,
 559                                     argtypes,
 560                                     allowBoxing,
 561                                     useVarargs,
 562                                     currentResolutionContext,
 563                                     warn);
 564 
 565         currentResolutionContext.methodCheck.argumentsAcceptable(env, currentResolutionContext.deferredAttrContext(m, infer.emptyContext, resultInfo, warn),
 566                                 argtypes, mt.getParameterTypes(), warn);
 567         return mt;
 568     }
 569 
 570     Type checkMethod(Env<AttrContext> env,
 571                      Type site,
 572                      Symbol m,
 573                      ResultInfo resultInfo,
 574                      List<Type> argtypes,
 575                      List<Type> typeargtypes,
 576                      Warner warn) {
 577         MethodResolutionContext prevContext = currentResolutionContext;
 578         try {
 579             currentResolutionContext = new MethodResolutionContext();
 580             currentResolutionContext.attrMode = DeferredAttr.AttrMode.CHECK;
 581             MethodResolutionPhase step = currentResolutionContext.step = env.info.pendingResolutionPhase;
 582             return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes,
 583                     step.isBoxingRequired(), step.isVarargsRequired(), warn);
 584         }
 585         finally {
 586             currentResolutionContext = prevContext;
 587         }
 588     }
 589 
 590     /** Same but returns null instead throwing a NoInstanceException
 591      */
 592     Type instantiate(Env<AttrContext> env,
 593                      Type site,
 594                      Symbol m,
 595                      ResultInfo resultInfo,
 596                      List<Type> argtypes,
 597                      List<Type> typeargtypes,
 598                      boolean allowBoxing,
 599                      boolean useVarargs,
 600                      Warner warn) {
 601         try {
 602             return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes,
 603                                   allowBoxing, useVarargs, warn);
 604         } catch (InapplicableMethodException ex) {
 605             return null;
 606         }
 607     }
 608 
 609     /**
 610      * This interface defines an entry point that should be used to perform a
 611      * method check. A method check usually consist in determining as to whether
 612      * a set of types (actuals) is compatible with another set of types (formals).
 613      * Since the notion of compatibility can vary depending on the circumstances,
 614      * this interfaces allows to easily add new pluggable method check routines.
 615      */
 616     interface MethodCheck {
 617         /**
 618          * Main method check routine. A method check usually consist in determining
 619          * as to whether a set of types (actuals) is compatible with another set of
 620          * types (formals). If an incompatibility is found, an unchecked exception
 621          * is assumed to be thrown.
 622          */
 623         void argumentsAcceptable(Env<AttrContext> env,
 624                                 DeferredAttrContext deferredAttrContext,
 625                                 List<Type> argtypes,
 626                                 List<Type> formals,
 627                                 Warner warn);
 628 
 629         /**
 630          * Retrieve the method check object that will be used during a
 631          * most specific check.
 632          */
 633         MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict);
 634     }
 635 
 636     /**
 637      * Helper enum defining all method check diagnostics (used by resolveMethodCheck).
 638      */
 639     enum MethodCheckDiag {
 640         /**
 641          * Actuals and formals differs in length.
 642          */
 643         ARITY_MISMATCH("arg.length.mismatch", "infer.arg.length.mismatch"),
 644         /**
 645          * An actual is incompatible with a formal.
 646          */
 647         ARG_MISMATCH("no.conforming.assignment.exists", "infer.no.conforming.assignment.exists"),
 648         /**
 649          * An actual is incompatible with the varargs element type.
 650          */
 651         VARARG_MISMATCH("varargs.argument.mismatch", "infer.varargs.argument.mismatch"),
 652         /**
 653          * The varargs element type is inaccessible.
 654          */
 655         INACCESSIBLE_VARARGS("inaccessible.varargs.type", "inaccessible.varargs.type");
 656 
 657         final String basicKey;
 658         final String inferKey;
 659 
 660         MethodCheckDiag(String basicKey, String inferKey) {
 661             this.basicKey = basicKey;
 662             this.inferKey = inferKey;
 663         }
 664     }
 665 
 666     /**
 667      * Dummy method check object. All methods are deemed applicable, regardless
 668      * of their formal parameter types.
 669      */
 670     MethodCheck nilMethodCheck = new MethodCheck() {
 671         public void argumentsAcceptable(Env<AttrContext> env, DeferredAttrContext deferredAttrContext, List<Type> argtypes, List<Type> formals, Warner warn) {
 672             //do nothing - method always applicable regardless of actuals
 673         }
 674 
 675         public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
 676             return this;
 677         }
 678     };
 679 
 680     /**
 681      * Base class for 'real' method checks. The class defines the logic for
 682      * iterating through formals and actuals and provides and entry point
 683      * that can be used by subclasses in order to define the actual check logic.
 684      */
 685     abstract class AbstractMethodCheck implements MethodCheck {
 686         @Override
 687         public void argumentsAcceptable(final Env<AttrContext> env,
 688                                     DeferredAttrContext deferredAttrContext,
 689                                     List<Type> argtypes,
 690                                     List<Type> formals,
 691                                     Warner warn) {
 692             //should we expand formals?
 693             boolean useVarargs = deferredAttrContext.phase.isVarargsRequired();
 694 
 695             //inference context used during this method check
 696             InferenceContext inferenceContext = deferredAttrContext.inferenceContext;
 697 
 698             Type varargsFormal = useVarargs ? formals.last() : null;
 699 
 700             if (varargsFormal == null &&
 701                     argtypes.size() != formals.size()) {
 702                 reportMC(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
 703             }
 704 
 705             while (argtypes.nonEmpty() && formals.head != varargsFormal) {
 706                 checkArg(false, argtypes.head, formals.head, deferredAttrContext, warn);
 707                 argtypes = argtypes.tail;
 708                 formals = formals.tail;
 709             }
 710 
 711             if (formals.head != varargsFormal) {
 712                 reportMC(MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
 713             }
 714 
 715             if (useVarargs) {
 716                 //note: if applicability check is triggered by most specific test,
 717                 //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
 718                 final Type elt = types.elemtype(varargsFormal);
 719                 while (argtypes.nonEmpty()) {
 720                     checkArg(true, argtypes.head, elt, deferredAttrContext, warn);
 721                     argtypes = argtypes.tail;
 722                 }
 723             }
 724         }
 725 
 726         /**
 727          * Does the actual argument conforms to the corresponding formal?
 728          */
 729         abstract void checkArg(boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn);
 730 
 731         protected void reportMC(MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) {
 732             boolean inferDiag = inferenceContext != infer.emptyContext;
 733             InapplicableMethodException ex = inferDiag ?
 734                     infer.inferenceException : inapplicableMethodException;
 735             if (inferDiag && (!diag.inferKey.equals(diag.basicKey))) {
 736                 Object[] args2 = new Object[args.length + 1];
 737                 System.arraycopy(args, 0, args2, 1, args.length);
 738                 args2[0] = inferenceContext.inferenceVars();
 739                 args = args2;
 740             }
 741             throw ex.setMessage(inferDiag ? diag.inferKey : diag.basicKey, args);
 742         }
 743 
 744         public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
 745             return nilMethodCheck;
 746         }
 747     }
 748 
 749     /**
 750      * Arity-based method check. A method is applicable if the number of actuals
 751      * supplied conforms to the method signature.
 752      */
 753     MethodCheck arityMethodCheck = new AbstractMethodCheck() {
 754         @Override
 755         void checkArg(boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
 756             //do nothing - actual always compatible to formals
 757         }
 758     };
 759 
 760     /**
 761      * Main method applicability routine. Given a list of actual types A,
 762      * a list of formal types F, determines whether the types in A are
 763      * compatible (by method invocation conversion) with the types in F.
 764      *
 765      * Since this routine is shared between overload resolution and method
 766      * type-inference, a (possibly empty) inference context is used to convert
 767      * formal types to the corresponding 'undet' form ahead of a compatibility
 768      * check so that constraints can be propagated and collected.
 769      *
 770      * Moreover, if one or more types in A is a deferred type, this routine uses
 771      * DeferredAttr in order to perform deferred attribution. If one or more actual
 772      * deferred types are stuck, they are placed in a queue and revisited later
 773      * after the remainder of the arguments have been seen. If this is not sufficient
 774      * to 'unstuck' the argument, a cyclic inference error is called out.
 775      *
 776      * A method check handler (see above) is used in order to report errors.
 777      */
 778     MethodCheck resolveMethodCheck = new AbstractMethodCheck() {
 779 
 780         @Override
 781         void checkArg(boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
 782             ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn);
 783             mresult.check(null, actual);
 784         }
 785 
 786         @Override
 787         public void argumentsAcceptable(final Env<AttrContext> env,
 788                                     DeferredAttrContext deferredAttrContext,
 789                                     List<Type> argtypes,
 790                                     List<Type> formals,
 791                                     Warner warn) {
 792             super.argumentsAcceptable(env, deferredAttrContext, argtypes, formals, warn);
 793             //should we expand formals?
 794             if (deferredAttrContext.phase.isVarargsRequired()) {
 795                 //check varargs element type accessibility
 796                 varargsAccessible(env, types.elemtype(formals.last()),
 797                         deferredAttrContext.inferenceContext);
 798             }
 799         }
 800 
 801         private void varargsAccessible(final Env<AttrContext> env, final Type t, final InferenceContext inferenceContext) {
 802             if (inferenceContext.free(t)) {
 803                 inferenceContext.addFreeTypeListener(List.of(t), new FreeTypeListener() {
 804                     @Override
 805                     public void typesInferred(InferenceContext inferenceContext) {
 806                         varargsAccessible(env, inferenceContext.asInstType(t), inferenceContext);
 807                     }
 808                 });
 809             } else {
 810                 if (!isAccessible(env, t)) {
 811                     Symbol location = env.enclClass.sym;
 812                     reportMC(MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location);
 813                 }
 814             }
 815         }
 816 
 817         private ResultInfo methodCheckResult(final boolean varargsCheck, Type to,
 818                 final DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner) {
 819             CheckContext checkContext = new MethodCheckContext(!deferredAttrContext.phase.isBoxingRequired(), deferredAttrContext, rsWarner) {
 820                 MethodCheckDiag methodDiag = varargsCheck ?
 821                                  MethodCheckDiag.VARARG_MISMATCH : MethodCheckDiag.ARG_MISMATCH;
 822 
 823                 @Override
 824                 public void report(DiagnosticPosition pos, JCDiagnostic details) {
 825                     reportMC(methodDiag, deferredAttrContext.inferenceContext, details);
 826                 }
 827             };
 828             return new MethodResultInfo(to, checkContext);
 829         }
 830 
 831         @Override
 832         public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
 833             return new MostSpecificCheck(strict, actuals);
 834         }
 835     };
 836 
 837     /**
 838      * Check context to be used during method applicability checks. A method check
 839      * context might contain inference variables.
 840      */
 841     abstract class MethodCheckContext implements CheckContext {
 842 
 843         boolean strict;
 844         DeferredAttrContext deferredAttrContext;
 845         Warner rsWarner;
 846 
 847         public MethodCheckContext(boolean strict, DeferredAttrContext deferredAttrContext, Warner rsWarner) {
 848            this.strict = strict;
 849            this.deferredAttrContext = deferredAttrContext;
 850            this.rsWarner = rsWarner;
 851         }
 852 
 853         public boolean compatible(Type found, Type req, Warner warn) {
 854             return strict ?
 855                     types.isSubtypeUnchecked(found, deferredAttrContext.inferenceContext.asFree(req), warn) :
 856                     types.isConvertible(found, deferredAttrContext.inferenceContext.asFree(req), warn);
 857         }
 858 
 859         public void report(DiagnosticPosition pos, JCDiagnostic details) {
 860             throw inapplicableMethodException.setMessage(details);
 861         }
 862 
 863         public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
 864             return rsWarner;
 865         }
 866 
 867         public InferenceContext inferenceContext() {
 868             return deferredAttrContext.inferenceContext;
 869         }
 870 
 871         public DeferredAttrContext deferredAttrContext() {
 872             return deferredAttrContext;
 873         }
 874     }
 875 
 876     /**
 877      * ResultInfo class to be used during method applicability checks. Check
 878      * for deferred types goes through special path.
 879      */
 880     class MethodResultInfo extends ResultInfo {
 881 
 882         public MethodResultInfo(Type pt, CheckContext checkContext) {
 883             attr.super(VAL, pt, checkContext);
 884         }
 885 
 886         @Override
 887         protected Type check(DiagnosticPosition pos, Type found) {
 888             if (found.hasTag(DEFERRED)) {
 889                 DeferredType dt = (DeferredType)found;
 890                 return dt.check(this);
 891             } else {
 892                 return super.check(pos, chk.checkNonVoid(pos, types.capture(types.upperBound(found.baseType()))));
 893             }
 894         }
 895 
 896         @Override
 897         protected MethodResultInfo dup(Type newPt) {
 898             return new MethodResultInfo(newPt, checkContext);
 899         }
 900 
 901         @Override
 902         protected ResultInfo dup(CheckContext newContext) {
 903             return new MethodResultInfo(pt, newContext);
 904         }
 905     }
 906 
 907     /**
 908      * Most specific method applicability routine. Given a list of actual types A,
 909      * a list of formal types F1, and a list of formal types F2, the routine determines
 910      * as to whether the types in F1 can be considered more specific than those in F2 w.r.t.
 911      * argument types A.
 912      */
 913     class MostSpecificCheck implements MethodCheck {
 914 
 915         boolean strict;
 916         List<Type> actuals;
 917 
 918         MostSpecificCheck(boolean strict, List<Type> actuals) {
 919             this.strict = strict;
 920             this.actuals = actuals;
 921         }
 922 
 923         @Override
 924         public void argumentsAcceptable(final Env<AttrContext> env,
 925                                     DeferredAttrContext deferredAttrContext,
 926                                     List<Type> formals1,
 927                                     List<Type> formals2,
 928                                     Warner warn) {
 929             formals2 = adjustArgs(formals2, deferredAttrContext.msym, formals1.length(), deferredAttrContext.phase.isVarargsRequired());
 930             while (formals2.nonEmpty()) {
 931                 ResultInfo mresult = methodCheckResult(formals2.head, deferredAttrContext, warn, actuals.head);
 932                 mresult.check(null, formals1.head);
 933                 formals1 = formals1.tail;
 934                 formals2 = formals2.tail;
 935                 actuals = actuals.isEmpty() ? actuals : actuals.tail;
 936             }
 937         }
 938 
 939        /**
 940         * Create a method check context to be used during the most specific applicability check
 941         */
 942         ResultInfo methodCheckResult(Type to, DeferredAttr.DeferredAttrContext deferredAttrContext,
 943                Warner rsWarner, Type actual) {
 944            return attr.new ResultInfo(Kinds.VAL, to,
 945                    new MostSpecificCheckContext(strict, deferredAttrContext, rsWarner, actual));
 946         }
 947 
 948         /**
 949          * Subclass of method check context class that implements most specific
 950          * method conversion. If the actual type under analysis is a deferred type
 951          * a full blown structural analysis is carried out.
 952          */
 953         class MostSpecificCheckContext extends MethodCheckContext {
 954 
 955             Type actual;
 956 
 957             public MostSpecificCheckContext(boolean strict, DeferredAttrContext deferredAttrContext, Warner rsWarner, Type actual) {
 958                 super(strict, deferredAttrContext, rsWarner);
 959                 this.actual = actual;
 960             }
 961 
 962             public boolean compatible(Type found, Type req, Warner warn) {
 963                 if (!allowStructuralMostSpecific || actual == null) {
 964                     return super.compatible(found, req, warn);
 965                 } else {
 966                     switch (actual.getTag()) {
 967                         case DEFERRED:
 968                             DeferredType dt = (DeferredType) actual;
 969                             DeferredType.SpeculativeCache.Entry e = dt.speculativeCache.get(deferredAttrContext.msym, deferredAttrContext.phase);
 970                             return (e == null || e.speculativeTree == deferredAttr.stuckTree)
 971                                     ? false : mostSpecific(found, req, e.speculativeTree, warn);
 972                         default:
 973                             return standaloneMostSpecific(found, req, actual, warn);
 974                     }
 975                 }
 976             }
 977 
 978             private boolean mostSpecific(Type t, Type s, JCTree tree, Warner warn) {
 979                 MostSpecificChecker msc = new MostSpecificChecker(t, s, warn);
 980                 msc.scan(tree);
 981                 return msc.result;
 982             }
 983 
 984             boolean polyMostSpecific(Type t1, Type t2, Warner warn) {
 985                 return (!t1.isPrimitive() && t2.isPrimitive())
 986                         ? true : super.compatible(t1, t2, warn);
 987             }
 988 
 989             boolean standaloneMostSpecific(Type t1, Type t2, Type exprType, Warner warn) {
 990                 return (exprType.isPrimitive() == t1.isPrimitive()
 991                         && exprType.isPrimitive() != t2.isPrimitive())
 992                         ? true : super.compatible(t1, t2, warn);
 993             }
 994 
 995             /**
 996              * Structural checker for most specific.
 997              */
 998             class MostSpecificChecker extends DeferredAttr.PolyScanner {
 999 
1000                 final Type t;
1001                 final Type s;
1002                 final Warner warn;
1003                 boolean result;
1004 
1005                 MostSpecificChecker(Type t, Type s, Warner warn) {
1006                     this.t = t;
1007                     this.s = s;
1008                     this.warn = warn;
1009                     result = true;
1010                 }
1011 
1012                 @Override
1013                 void skip(JCTree tree) {
1014                     result &= standaloneMostSpecific(t, s, tree.type, warn);
1015                 }
1016 
1017                 @Override
1018                 public void visitConditional(JCConditional tree) {
1019                     if (tree.polyKind == PolyKind.STANDALONE) {
1020                         result &= standaloneMostSpecific(t, s, tree.type, warn);
1021                     } else {
1022                         super.visitConditional(tree);
1023                     }
1024                 }
1025 
1026                 @Override
1027                 public void visitApply(JCMethodInvocation tree) {
1028                     result &= (tree.polyKind == PolyKind.STANDALONE)
1029                             ? standaloneMostSpecific(t, s, tree.type, warn)
1030                             : polyMostSpecific(t, s, warn);
1031                 }
1032 
1033                 @Override
1034                 public void visitNewClass(JCNewClass tree) {
1035                     result &= (tree.polyKind == PolyKind.STANDALONE)
1036                             ? standaloneMostSpecific(t, s, tree.type, warn)
1037                             : polyMostSpecific(t, s, warn);
1038                 }
1039 
1040                 @Override
1041                 public void visitReference(JCMemberReference tree) {
1042                     if (types.isFunctionalInterface(t.tsym) &&
1043                             types.isFunctionalInterface(s.tsym) &&
1044                             types.asSuper(t, s.tsym) == null &&
1045                             types.asSuper(s, t.tsym) == null) {
1046                         Type desc_t = types.findDescriptorType(t);
1047                         Type desc_s = types.findDescriptorType(s);
1048                         if (types.isSameTypes(desc_t.getParameterTypes(), desc_s.getParameterTypes())) {
1049                             if (!desc_s.getReturnType().hasTag(VOID)) {
1050                                 //perform structural comparison
1051                                 Type ret_t = desc_t.getReturnType();
1052                                 Type ret_s = desc_s.getReturnType();
1053                                 result &= ((tree.refPolyKind == PolyKind.STANDALONE)
1054                                         ? standaloneMostSpecific(ret_t, ret_s, tree.sym.type.getReturnType(), warn)
1055                                         : polyMostSpecific(ret_t, ret_s, warn));
1056                             } else {
1057                                 return;
1058                             }
1059                         } else {
1060                             result &= false;
1061                         }
1062                     } else {
1063                         result &= MostSpecificCheckContext.super.compatible(t, s, warn);
1064                     }
1065                 }
1066 
1067                 @Override
1068                 public void visitLambda(JCLambda tree) {
1069                     if (types.isFunctionalInterface(t.tsym) &&
1070                             types.isFunctionalInterface(s.tsym) &&
1071                             types.asSuper(t, s.tsym) == null &&
1072                             types.asSuper(s, t.tsym) == null) {
1073                         Type desc_t = types.findDescriptorType(t);
1074                         Type desc_s = types.findDescriptorType(s);
1075                         if (tree.paramKind == JCLambda.ParameterKind.EXPLICIT
1076                                 || types.isSameTypes(desc_t.getParameterTypes(), desc_s.getParameterTypes())) {
1077                             if (!desc_s.getReturnType().hasTag(VOID)) {
1078                                 //perform structural comparison
1079                                 Type ret_t = desc_t.getReturnType();
1080                                 Type ret_s = desc_s.getReturnType();
1081                                 scanLambdaBody(tree, ret_t, ret_s);
1082                             } else {
1083                                 return;
1084                             }
1085                         } else {
1086                             result &= false;
1087                         }
1088                     } else {
1089                         result &= MostSpecificCheckContext.super.compatible(t, s, warn);
1090                     }
1091                 }
1092                 //where
1093 
1094                 void scanLambdaBody(JCLambda lambda, final Type t, final Type s) {
1095                     if (lambda.getBodyKind() == JCTree.JCLambda.BodyKind.EXPRESSION) {
1096                         result &= MostSpecificCheckContext.this.mostSpecific(t, s, lambda.body, warn);
1097                     } else {
1098                         DeferredAttr.LambdaReturnScanner lambdaScanner =
1099                                 new DeferredAttr.LambdaReturnScanner() {
1100                                     @Override
1101                                     public void visitReturn(JCReturn tree) {
1102                                         if (tree.expr != null) {
1103                                             result &= MostSpecificCheckContext.this.mostSpecific(t, s, tree.expr, warn);
1104                                         }
1105                                     }
1106                                 };
1107                         lambdaScanner.scan(lambda.body);
1108                     }
1109                 }
1110             }
1111         }
1112 
1113         public MethodCheck mostSpecificCheck(List<Type> actuals, boolean strict) {
1114             Assert.error("Cannot get here!");
1115             return null;
1116         }
1117     }
1118 
1119     public static class InapplicableMethodException extends RuntimeException {
1120         private static final long serialVersionUID = 0;
1121 
1122         JCDiagnostic diagnostic;
1123         JCDiagnostic.Factory diags;
1124 
1125         InapplicableMethodException(JCDiagnostic.Factory diags) {
1126             this.diagnostic = null;
1127             this.diags = diags;
1128         }
1129         InapplicableMethodException setMessage() {
1130             return setMessage((JCDiagnostic)null);
1131         }
1132         InapplicableMethodException setMessage(String key) {
1133             return setMessage(key != null ? diags.fragment(key) : null);
1134         }
1135         InapplicableMethodException setMessage(String key, Object... args) {
1136             return setMessage(key != null ? diags.fragment(key, args) : null);
1137         }
1138         InapplicableMethodException setMessage(JCDiagnostic diag) {
1139             this.diagnostic = diag;
1140             return this;
1141         }
1142 
1143         public JCDiagnostic getDiagnostic() {
1144             return diagnostic;
1145         }
1146     }
1147     private final InapplicableMethodException inapplicableMethodException;
1148 
1149 /* ***************************************************************************
1150  *  Symbol lookup
1151  *  the following naming conventions for arguments are used
1152  *
1153  *       env      is the environment where the symbol was mentioned
1154  *       site     is the type of which the symbol is a member
1155  *       name     is the symbol's name
1156  *                if no arguments are given
1157  *       argtypes are the value arguments, if we search for a method
1158  *
1159  *  If no symbol was found, a ResolveError detailing the problem is returned.
1160  ****************************************************************************/
1161 
1162     /** Find field. Synthetic fields are always skipped.
1163      *  @param env     The current environment.
1164      *  @param site    The original type from where the selection takes place.
1165      *  @param name    The name of the field.
1166      *  @param c       The class to search for the field. This is always
1167      *                 a superclass or implemented interface of site's class.
1168      */
1169     Symbol findField(Env<AttrContext> env,
1170                      Type site,
1171                      Name name,
1172                      TypeSymbol c) {
1173         while (c.type.hasTag(TYPEVAR))
1174             c = c.type.getUpperBound().tsym;
1175         Symbol bestSoFar = varNotFound;
1176         Symbol sym;
1177         Scope.Entry e = c.members().lookup(name);
1178         while (e.scope != null) {
1179             if (e.sym.kind == VAR && (e.sym.flags_field & SYNTHETIC) == 0) {
1180                 return isAccessible(env, site, e.sym)
1181                     ? e.sym : new AccessError(env, site, e.sym);
1182             }
1183             e = e.next();
1184         }
1185         Type st = types.supertype(c.type);
1186         if (st != null && (st.hasTag(CLASS) || st.hasTag(TYPEVAR))) {
1187             sym = findField(env, site, name, st.tsym);
1188             if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1189         }
1190         for (List<Type> l = types.interfaces(c.type);
1191              bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
1192              l = l.tail) {
1193             sym = findField(env, site, name, l.head.tsym);
1194             if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS &&
1195                 sym.owner != bestSoFar.owner)
1196                 bestSoFar = new AmbiguityError(bestSoFar, sym);
1197             else if (sym.kind < bestSoFar.kind)
1198                 bestSoFar = sym;
1199         }
1200         return bestSoFar;
1201     }
1202 
1203     /** Resolve a field identifier, throw a fatal error if not found.
1204      *  @param pos       The position to use for error reporting.
1205      *  @param env       The environment current at the method invocation.
1206      *  @param site      The type of the qualifying expression, in which
1207      *                   identifier is searched.
1208      *  @param name      The identifier's name.
1209      */
1210     public VarSymbol resolveInternalField(DiagnosticPosition pos, Env<AttrContext> env,
1211                                           Type site, Name name) {
1212         Symbol sym = findField(env, site, name, site.tsym);
1213         if (sym.kind == VAR) return (VarSymbol)sym;
1214         else throw new FatalError(
1215                  diags.fragment("fatal.err.cant.locate.field",
1216                                 name));
1217     }
1218 
1219     /** Find unqualified variable or field with given name.
1220      *  Synthetic fields always skipped.
1221      *  @param env     The current environment.
1222      *  @param name    The name of the variable or field.
1223      */
1224     Symbol findVar(Env<AttrContext> env, Name name) {
1225         Symbol bestSoFar = varNotFound;
1226         Symbol sym;
1227         Env<AttrContext> env1 = env;
1228         boolean staticOnly = false;
1229         while (env1.outer != null) {
1230             if (isStatic(env1)) staticOnly = true;
1231             Scope.Entry e = env1.info.scope.lookup(name);
1232             while (e.scope != null &&
1233                    (e.sym.kind != VAR ||
1234                     (e.sym.flags_field & SYNTHETIC) != 0))
1235                 e = e.next();
1236             sym = (e.scope != null)
1237                 ? e.sym
1238                 : findField(
1239                     env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
1240             if (sym.exists()) {
1241                 if (staticOnly &&
1242                     sym.kind == VAR &&
1243                     sym.owner.kind == TYP &&
1244                     (sym.flags() & STATIC) == 0)
1245                     return new StaticError(sym);
1246                 else
1247                     return sym;
1248             } else if (sym.kind < bestSoFar.kind) {
1249                 bestSoFar = sym;
1250             }
1251 
1252             if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
1253             env1 = env1.outer;
1254         }
1255 
1256         sym = findField(env, syms.predefClass.type, name, syms.predefClass);
1257         if (sym.exists())
1258             return sym;
1259         if (bestSoFar.exists())
1260             return bestSoFar;
1261 
1262         Scope.Entry e = env.toplevel.namedImportScope.lookup(name);
1263         for (; e.scope != null; e = e.next()) {
1264             sym = e.sym;
1265             Type origin = e.getOrigin().owner.type;
1266             if (sym.kind == VAR) {
1267                 if (e.sym.owner.type != origin)
1268                     sym = sym.clone(e.getOrigin().owner);
1269                 return isAccessible(env, origin, sym)
1270                     ? sym : new AccessError(env, origin, sym);
1271             }
1272         }
1273 
1274         Symbol origin = null;
1275         e = env.toplevel.starImportScope.lookup(name);
1276         for (; e.scope != null; e = e.next()) {
1277             sym = e.sym;
1278             if (sym.kind != VAR)
1279                 continue;
1280             // invariant: sym.kind == VAR
1281             if (bestSoFar.kind < AMBIGUOUS && sym.owner != bestSoFar.owner)
1282                 return new AmbiguityError(bestSoFar, sym);
1283             else if (bestSoFar.kind >= VAR) {
1284                 origin = e.getOrigin().owner;
1285                 bestSoFar = isAccessible(env, origin.type, sym)
1286                     ? sym : new AccessError(env, origin.type, sym);
1287             }
1288         }
1289         if (bestSoFar.kind == VAR && bestSoFar.owner.type != origin.type)
1290             return bestSoFar.clone(origin);
1291         else
1292             return bestSoFar;
1293     }
1294 
1295     Warner noteWarner = new Warner();
1296 
1297     /** Select the best method for a call site among two choices.
1298      *  @param env              The current environment.
1299      *  @param site             The original type from where the
1300      *                          selection takes place.
1301      *  @param argtypes         The invocation's value arguments,
1302      *  @param typeargtypes     The invocation's type arguments,
1303      *  @param sym              Proposed new best match.
1304      *  @param bestSoFar        Previously found best match.
1305      *  @param allowBoxing Allow boxing conversions of arguments.
1306      *  @param useVarargs Box trailing arguments into an array for varargs.
1307      */
1308     @SuppressWarnings("fallthrough")
1309     Symbol selectBest(Env<AttrContext> env,
1310                       Type site,
1311                       List<Type> argtypes,
1312                       List<Type> typeargtypes,
1313                       Symbol sym,
1314                       Symbol bestSoFar,
1315                       boolean allowBoxing,
1316                       boolean useVarargs,
1317                       boolean operator) {
1318         if (sym.kind == ERR ||
1319                 !sym.isInheritedIn(site.tsym, types)) {
1320             return bestSoFar;
1321         } else if (useVarargs && (sym.flags() & VARARGS) == 0) {
1322             return bestSoFar.kind >= ERRONEOUS ?
1323                     new BadVarargsMethod((ResolveError)bestSoFar) :
1324                     bestSoFar;
1325         }
1326         Assert.check(sym.kind < AMBIGUOUS);
1327         try {
1328             Type mt = rawInstantiate(env, site, sym, null, argtypes, typeargtypes,
1329                                allowBoxing, useVarargs, types.noWarnings);
1330             if (!operator)
1331                 currentResolutionContext.addApplicableCandidate(sym, mt);
1332         } catch (InapplicableMethodException ex) {
1333             if (!operator)
1334                 currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic());
1335             switch (bestSoFar.kind) {
1336                 case ABSENT_MTH:
1337                     return new InapplicableSymbolError(currentResolutionContext);
1338                 case WRONG_MTH:
1339                     if (operator) return bestSoFar;
1340                     bestSoFar = new InapplicableSymbolsError(currentResolutionContext);
1341                 default:
1342                     return bestSoFar;
1343             }
1344         }
1345         if (!isAccessible(env, site, sym)) {
1346             return (bestSoFar.kind == ABSENT_MTH)
1347                 ? new AccessError(env, site, sym)
1348                 : bestSoFar;
1349         }
1350         return (bestSoFar.kind > AMBIGUOUS)
1351             ? sym
1352             : mostSpecific(argtypes, sym, bestSoFar, env, site,
1353                            allowBoxing && operator, useVarargs);
1354     }
1355 
1356     /* Return the most specific of the two methods for a call,
1357      *  given that both are accessible and applicable.
1358      *  @param m1               A new candidate for most specific.
1359      *  @param m2               The previous most specific candidate.
1360      *  @param env              The current environment.
1361      *  @param site             The original type from where the selection
1362      *                          takes place.
1363      *  @param allowBoxing Allow boxing conversions of arguments.
1364      *  @param useVarargs Box trailing arguments into an array for varargs.
1365      */
1366     Symbol mostSpecific(List<Type> argtypes, Symbol m1,
1367                         Symbol m2,
1368                         Env<AttrContext> env,
1369                         final Type site,
1370                         boolean allowBoxing,
1371                         boolean useVarargs) {
1372         switch (m2.kind) {
1373         case MTH:
1374             if (m1 == m2) return m1;
1375             boolean m1SignatureMoreSpecific =
1376                     signatureMoreSpecific(argtypes, env, site, m1, m2, allowBoxing, useVarargs);
1377             boolean m2SignatureMoreSpecific =
1378                     signatureMoreSpecific(argtypes, env, site, m2, m1, allowBoxing, useVarargs);
1379             if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) {
1380                 Type mt1 = types.memberType(site, m1);
1381                 Type mt2 = types.memberType(site, m2);
1382                 if (!types.overrideEquivalent(mt1, mt2))
1383                     return ambiguityError(m1, m2);
1384 
1385                 // same signature; select (a) the non-bridge method, or
1386                 // (b) the one that overrides the other, or (c) the concrete
1387                 // one, or (d) merge both abstract signatures
1388                 if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE))
1389                     return ((m1.flags() & BRIDGE) != 0) ? m2 : m1;
1390 
1391                 // if one overrides or hides the other, use it
1392                 TypeSymbol m1Owner = (TypeSymbol)m1.owner;
1393                 TypeSymbol m2Owner = (TypeSymbol)m2.owner;
1394                 if (types.asSuper(m1Owner.type, m2Owner) != null &&
1395                     ((m1.owner.flags_field & INTERFACE) == 0 ||
1396                      (m2.owner.flags_field & INTERFACE) != 0) &&
1397                     m1.overrides(m2, m1Owner, types, false))
1398                     return m1;
1399                 if (types.asSuper(m2Owner.type, m1Owner) != null &&
1400                     ((m2.owner.flags_field & INTERFACE) == 0 ||
1401                      (m1.owner.flags_field & INTERFACE) != 0) &&
1402                     m2.overrides(m1, m2Owner, types, false))
1403                     return m2;
1404                 boolean m1Abstract = (m1.flags() & ABSTRACT) != 0;
1405                 boolean m2Abstract = (m2.flags() & ABSTRACT) != 0;
1406                 if (m1Abstract && !m2Abstract) return m2;
1407                 if (m2Abstract && !m1Abstract) return m1;
1408                 // both abstract or both concrete
1409                 return ambiguityError(m1, m2);
1410             }
1411             if (m1SignatureMoreSpecific) return m1;
1412             if (m2SignatureMoreSpecific) return m2;
1413             return ambiguityError(m1, m2);
1414         case AMBIGUOUS:
1415             //check if m1 is more specific than all ambiguous methods in m2
1416             AmbiguityError e = (AmbiguityError)m2;
1417             for (Symbol s : e.ambiguousSyms) {
1418                 if (mostSpecific(argtypes, m1, s, env, site, allowBoxing, useVarargs) != m1) {
1419                     return e.addAmbiguousSymbol(m1);
1420                 }
1421             }
1422             return m1;
1423         default:
1424             throw new AssertionError();
1425         }
1426     }
1427     //where
1428     private boolean signatureMoreSpecific(List<Type> actuals, Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean allowBoxing, boolean useVarargs) {
1429         noteWarner.clear();
1430         int maxLength = Math.max(
1431                             Math.max(m1.type.getParameterTypes().length(), actuals.length()),
1432                             m2.type.getParameterTypes().length());
1433         MethodResolutionContext prevResolutionContext = currentResolutionContext;
1434         try {
1435             currentResolutionContext = new MethodResolutionContext();
1436             currentResolutionContext.step = prevResolutionContext.step;
1437             currentResolutionContext.methodCheck =
1438                     prevResolutionContext.methodCheck.mostSpecificCheck(actuals, !allowBoxing);
1439             Type mst = instantiate(env, site, m2, null,
1440                     adjustArgs(types.lowerBounds(types.memberType(site, m1).getParameterTypes()), m1, maxLength, useVarargs), null,
1441                     allowBoxing, useVarargs, noteWarner);
1442             return mst != null &&
1443                     !noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
1444         } finally {
1445             currentResolutionContext = prevResolutionContext;
1446         }
1447     }
1448     private List<Type> adjustArgs(List<Type> args, Symbol msym, int length, boolean allowVarargs) {
1449         if ((msym.flags() & VARARGS) != 0 && allowVarargs) {
1450             Type varargsElem = types.elemtype(args.last());
1451             if (varargsElem == null) {
1452                 Assert.error("Bad varargs = " + args.last() + " " + msym);
1453             }
1454             List<Type> newArgs = args.reverse().tail.prepend(varargsElem).reverse();
1455             while (newArgs.length() < length) {
1456                 newArgs = newArgs.append(newArgs.last());
1457             }
1458             return newArgs;
1459         } else {
1460             return args;
1461         }
1462     }
1463     //where
1464     Type mostSpecificReturnType(Type mt1, Type mt2) {
1465         Type rt1 = mt1.getReturnType();
1466         Type rt2 = mt2.getReturnType();
1467 
1468         if (mt1.hasTag(FORALL) && mt2.hasTag(FORALL)) {
1469             //if both are generic methods, adjust return type ahead of subtyping check
1470             rt1 = types.subst(rt1, mt1.getTypeArguments(), mt2.getTypeArguments());
1471         }
1472         //first use subtyping, then return type substitutability
1473         if (types.isSubtype(rt1, rt2)) {
1474             return mt1;
1475         } else if (types.isSubtype(rt2, rt1)) {
1476             return mt2;
1477         } else if (types.returnTypeSubstitutable(mt1, mt2)) {
1478             return mt1;
1479         } else if (types.returnTypeSubstitutable(mt2, mt1)) {
1480             return mt2;
1481         } else {
1482             return null;
1483         }
1484     }
1485     //where
1486     Symbol ambiguityError(Symbol m1, Symbol m2) {
1487         if (((m1.flags() | m2.flags()) & CLASH) != 0) {
1488             return (m1.flags() & CLASH) == 0 ? m1 : m2;
1489         } else {
1490             return new AmbiguityError(m1, m2);
1491         }
1492     }
1493 
1494     Symbol findMethodInScope(Env<AttrContext> env,
1495             Type site,
1496             Name name,
1497             List<Type> argtypes,
1498             List<Type> typeargtypes,
1499             Scope sc,
1500             Symbol bestSoFar,
1501             boolean allowBoxing,
1502             boolean useVarargs,
1503             boolean operator,
1504             boolean abstractok) {
1505         for (Symbol s : sc.getElementsByName(name, new LookupFilter(abstractok))) {
1506             bestSoFar = selectBest(env, site, argtypes, typeargtypes, s,
1507                     bestSoFar, allowBoxing, useVarargs, operator);
1508         }
1509         return bestSoFar;
1510     }
1511     //where
1512         class LookupFilter implements Filter<Symbol> {
1513 
1514             boolean abstractOk;
1515 
1516             LookupFilter(boolean abstractOk) {
1517                 this.abstractOk = abstractOk;
1518             }
1519 
1520             public boolean accepts(Symbol s) {
1521                 long flags = s.flags();
1522                 return s.kind == MTH &&
1523                         (flags & SYNTHETIC) == 0 &&
1524                         (abstractOk ||
1525                         (flags & DEFAULT) != 0 ||
1526                         (flags & ABSTRACT) == 0);
1527             }
1528         };
1529 
1530     /** Find best qualified method matching given name, type and value
1531      *  arguments.
1532      *  @param env       The current environment.
1533      *  @param site      The original type from where the selection
1534      *                   takes place.
1535      *  @param name      The method's name.
1536      *  @param argtypes  The method's value arguments.
1537      *  @param typeargtypes The method's type arguments
1538      *  @param allowBoxing Allow boxing conversions of arguments.
1539      *  @param useVarargs Box trailing arguments into an array for varargs.
1540      */
1541     Symbol findMethod(Env<AttrContext> env,
1542                       Type site,
1543                       Name name,
1544                       List<Type> argtypes,
1545                       List<Type> typeargtypes,
1546                       boolean allowBoxing,
1547                       boolean useVarargs,
1548                       boolean operator) {
1549         Symbol bestSoFar = methodNotFound;
1550         bestSoFar = findMethod(env,
1551                           site,
1552                           name,
1553                           argtypes,
1554                           typeargtypes,
1555                           site.tsym.type,
1556                           bestSoFar,
1557                           allowBoxing,
1558                           useVarargs,
1559                           operator);
1560         reportVerboseResolutionDiagnostic(env.tree.pos(), name, site, argtypes, typeargtypes, bestSoFar);
1561         return bestSoFar;
1562     }
1563     // where
1564     private Symbol findMethod(Env<AttrContext> env,
1565                               Type site,
1566                               Name name,
1567                               List<Type> argtypes,
1568                               List<Type> typeargtypes,
1569                               Type intype,
1570                               Symbol bestSoFar,
1571                               boolean allowBoxing,
1572                               boolean useVarargs,
1573                               boolean operator) {
1574         @SuppressWarnings({"unchecked","rawtypes"})
1575         List<Type>[] itypes = (List<Type>[])new List[] { List.<Type>nil(), List.<Type>nil() };
1576         InterfaceLookupPhase iphase = InterfaceLookupPhase.ABSTRACT_OK;
1577         for (TypeSymbol s : superclasses(intype)) {
1578             bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
1579                     s.members(), bestSoFar, allowBoxing, useVarargs, operator, true);
1580             if (name == names.init) return bestSoFar;
1581             iphase = (iphase == null) ? null : iphase.update(s, this);
1582             if (iphase != null) {
1583                 for (Type itype : types.interfaces(s.type)) {
1584                     itypes[iphase.ordinal()] = types.union(types.closure(itype), itypes[iphase.ordinal()]);
1585                 }
1586             }
1587         }
1588 
1589         Symbol concrete = bestSoFar.kind < ERR &&
1590                 (bestSoFar.flags() & ABSTRACT) == 0 ?
1591                 bestSoFar : methodNotFound;
1592 
1593         for (InterfaceLookupPhase iphase2 : InterfaceLookupPhase.values()) {
1594             if (iphase2 == InterfaceLookupPhase.DEFAULT_OK && !allowDefaultMethods) break;
1595             //keep searching for abstract methods
1596             for (Type itype : itypes[iphase2.ordinal()]) {
1597                 if (!itype.isInterface()) continue; //skip j.l.Object (included by Types.closure())
1598                 if (iphase2 == InterfaceLookupPhase.DEFAULT_OK &&
1599                         (itype.tsym.flags() & DEFAULT) == 0) continue;
1600                 bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
1601                         itype.tsym.members(), bestSoFar, allowBoxing, useVarargs, operator, true);
1602                 if (concrete != bestSoFar &&
1603                         concrete.kind < ERR  && bestSoFar.kind < ERR &&
1604                         types.isSubSignature(concrete.type, bestSoFar.type)) {
1605                     //this is an hack - as javac does not do full membership checks
1606                     //most specific ends up comparing abstract methods that might have
1607                     //been implemented by some concrete method in a subclass and,
1608                     //because of raw override, it is possible for an abstract method
1609                     //to be more specific than the concrete method - so we need
1610                     //to explicitly call that out (see CR 6178365)
1611                     bestSoFar = concrete;
1612                 }
1613             }
1614         }
1615         return bestSoFar;
1616     }
1617 
1618     enum InterfaceLookupPhase {
1619         ABSTRACT_OK() {
1620             @Override
1621             InterfaceLookupPhase update(Symbol s, Resolve rs) {
1622                 //We should not look for abstract methods if receiver is a concrete class
1623                 //(as concrete classes are expected to implement all abstracts coming
1624                 //from superinterfaces)
1625                 if ((s.flags() & (ABSTRACT | INTERFACE | ENUM)) != 0) {
1626                     return this;
1627                 } else if (rs.allowDefaultMethods) {
1628                     return DEFAULT_OK;
1629                 } else {
1630                     return null;
1631                 }
1632             }
1633         },
1634         DEFAULT_OK() {
1635             @Override
1636             InterfaceLookupPhase update(Symbol s, Resolve rs) {
1637                 return this;
1638             }
1639         };
1640 
1641         abstract InterfaceLookupPhase update(Symbol s, Resolve rs);
1642     }
1643 
1644     /**
1645      * Return an Iterable object to scan the superclasses of a given type.
1646      * It's crucial that the scan is done lazily, as we don't want to accidentally
1647      * access more supertypes than strictly needed (as this could trigger completion
1648      * errors if some of the not-needed supertypes are missing/ill-formed).
1649      */
1650     Iterable<TypeSymbol> superclasses(final Type intype) {
1651         return new Iterable<TypeSymbol>() {
1652             public Iterator<TypeSymbol> iterator() {
1653                 return new Iterator<TypeSymbol>() {
1654 
1655                     List<TypeSymbol> seen = List.nil();
1656                     TypeSymbol currentSym = symbolFor(intype);
1657                     TypeSymbol prevSym = null;
1658 
1659                     public boolean hasNext() {
1660                         if (currentSym == syms.noSymbol) {
1661                             currentSym = symbolFor(types.supertype(prevSym.type));
1662                         }
1663                         return currentSym != null;
1664                     }
1665 
1666                     public TypeSymbol next() {
1667                         prevSym = currentSym;
1668                         currentSym = syms.noSymbol;
1669                         Assert.check(prevSym != null || prevSym != syms.noSymbol);
1670                         return prevSym;
1671                     }
1672 
1673                     public void remove() {
1674                         throw new UnsupportedOperationException();
1675                     }
1676 
1677                     TypeSymbol symbolFor(Type t) {
1678                         if (!t.hasTag(CLASS) &&
1679                                 !t.hasTag(TYPEVAR)) {
1680                             return null;
1681                         }
1682                         while (t.hasTag(TYPEVAR))
1683                             t = t.getUpperBound();
1684                         if (seen.contains(t.tsym)) {
1685                             //degenerate case in which we have a circular
1686                             //class hierarchy - because of ill-formed classfiles
1687                             return null;
1688                         }
1689                         seen = seen.prepend(t.tsym);
1690                         return t.tsym;
1691                     }
1692                 };
1693             }
1694         };
1695     }
1696 
1697     /** Find unqualified method matching given name, type and value arguments.
1698      *  @param env       The current environment.
1699      *  @param name      The method's name.
1700      *  @param argtypes  The method's value arguments.
1701      *  @param typeargtypes  The method's type arguments.
1702      *  @param allowBoxing Allow boxing conversions of arguments.
1703      *  @param useVarargs Box trailing arguments into an array for varargs.
1704      */
1705     Symbol findFun(Env<AttrContext> env, Name name,
1706                    List<Type> argtypes, List<Type> typeargtypes,
1707                    boolean allowBoxing, boolean useVarargs) {
1708         Symbol bestSoFar = methodNotFound;
1709         Symbol sym;
1710         Env<AttrContext> env1 = env;
1711         boolean staticOnly = false;
1712         while (env1.outer != null) {
1713             if (isStatic(env1)) staticOnly = true;
1714             sym = findMethod(
1715                 env1, env1.enclClass.sym.type, name, argtypes, typeargtypes,
1716                 allowBoxing, useVarargs, false);
1717             if (sym.exists()) {
1718                 if (staticOnly &&
1719                     sym.kind == MTH &&
1720                     sym.owner.kind == TYP &&
1721                     (sym.flags() & STATIC) == 0) return new StaticError(sym);
1722                 else return sym;
1723             } else if (sym.kind < bestSoFar.kind) {
1724                 bestSoFar = sym;
1725             }
1726             if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
1727             env1 = env1.outer;
1728         }
1729 
1730         sym = findMethod(env, syms.predefClass.type, name, argtypes,
1731                          typeargtypes, allowBoxing, useVarargs, false);
1732         if (sym.exists())
1733             return sym;
1734 
1735         Scope.Entry e = env.toplevel.namedImportScope.lookup(name);
1736         for (; e.scope != null; e = e.next()) {
1737             sym = e.sym;
1738             Type origin = e.getOrigin().owner.type;
1739             if (sym.kind == MTH) {
1740                 if (e.sym.owner.type != origin)
1741                     sym = sym.clone(e.getOrigin().owner);
1742                 if (!isAccessible(env, origin, sym))
1743                     sym = new AccessError(env, origin, sym);
1744                 bestSoFar = selectBest(env, origin,
1745                                        argtypes, typeargtypes,
1746                                        sym, bestSoFar,
1747                                        allowBoxing, useVarargs, false);
1748             }
1749         }
1750         if (bestSoFar.exists())
1751             return bestSoFar;
1752 
1753         e = env.toplevel.starImportScope.lookup(name);
1754         for (; e.scope != null; e = e.next()) {
1755             sym = e.sym;
1756             Type origin = e.getOrigin().owner.type;
1757             if (sym.kind == MTH) {
1758                 if (e.sym.owner.type != origin)
1759                     sym = sym.clone(e.getOrigin().owner);
1760                 if (!isAccessible(env, origin, sym))
1761                     sym = new AccessError(env, origin, sym);
1762                 bestSoFar = selectBest(env, origin,
1763                                        argtypes, typeargtypes,
1764                                        sym, bestSoFar,
1765                                        allowBoxing, useVarargs, false);
1766             }
1767         }
1768         return bestSoFar;
1769     }
1770 
1771     /** Load toplevel or member class with given fully qualified name and
1772      *  verify that it is accessible.
1773      *  @param env       The current environment.
1774      *  @param name      The fully qualified name of the class to be loaded.
1775      */
1776     Symbol loadClass(Env<AttrContext> env, Name name) {
1777         try {
1778             ClassSymbol c = reader.loadClass(name);
1779             return isAccessible(env, c) ? c : new AccessError(c);
1780         } catch (ClassReader.BadClassFile err) {
1781             throw err;
1782         } catch (CompletionFailure ex) {
1783             return typeNotFound;
1784         }
1785     }
1786 
1787     /** Find qualified member type.
1788      *  @param env       The current environment.
1789      *  @param site      The original type from where the selection takes
1790      *                   place.
1791      *  @param name      The type's name.
1792      *  @param c         The class to search for the member type. This is
1793      *                   always a superclass or implemented interface of
1794      *                   site's class.
1795      */
1796     Symbol findMemberType(Env<AttrContext> env,
1797                           Type site,
1798                           Name name,
1799                           TypeSymbol c) {
1800         Symbol bestSoFar = typeNotFound;
1801         Symbol sym;
1802         Scope.Entry e = c.members().lookup(name);
1803         while (e.scope != null) {
1804             if (e.sym.kind == TYP) {
1805                 return isAccessible(env, site, e.sym)
1806                     ? e.sym
1807                     : new AccessError(env, site, e.sym);
1808             }
1809             e = e.next();
1810         }
1811         Type st = types.supertype(c.type);
1812         if (st != null && st.hasTag(CLASS)) {
1813             sym = findMemberType(env, site, name, st.tsym);
1814             if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1815         }
1816         for (List<Type> l = types.interfaces(c.type);
1817              bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
1818              l = l.tail) {
1819             sym = findMemberType(env, site, name, l.head.tsym);
1820             if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS &&
1821                 sym.owner != bestSoFar.owner)
1822                 bestSoFar = new AmbiguityError(bestSoFar, sym);
1823             else if (sym.kind < bestSoFar.kind)
1824                 bestSoFar = sym;
1825         }
1826         return bestSoFar;
1827     }
1828 
1829     /** Find a global type in given scope and load corresponding class.
1830      *  @param env       The current environment.
1831      *  @param scope     The scope in which to look for the type.
1832      *  @param name      The type's name.
1833      */
1834     Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) {
1835         Symbol bestSoFar = typeNotFound;
1836         for (Scope.Entry e = scope.lookup(name); e.scope != null; e = e.next()) {
1837             Symbol sym = loadClass(env, e.sym.flatName());
1838             if (bestSoFar.kind == TYP && sym.kind == TYP &&
1839                 bestSoFar != sym)
1840                 return new AmbiguityError(bestSoFar, sym);
1841             else if (sym.kind < bestSoFar.kind)
1842                 bestSoFar = sym;
1843         }
1844         return bestSoFar;
1845     }
1846 
1847     /** Find an unqualified type symbol.
1848      *  @param env       The current environment.
1849      *  @param name      The type's name.
1850      */
1851     Symbol findType(Env<AttrContext> env, Name name) {
1852         Symbol bestSoFar = typeNotFound;
1853         Symbol sym;
1854         boolean staticOnly = false;
1855         for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) {
1856             if (isStatic(env1)) staticOnly = true;
1857             for (Scope.Entry e = env1.info.scope.lookup(name);
1858                  e.scope != null;
1859                  e = e.next()) {
1860                 if (e.sym.kind == TYP) {
1861                     if (staticOnly &&
1862                         e.sym.type.hasTag(TYPEVAR) &&
1863                         e.sym.owner.kind == TYP) return new StaticError(e.sym);
1864                     return e.sym;
1865                 }
1866             }
1867 
1868             sym = findMemberType(env1, env1.enclClass.sym.type, name,
1869                                  env1.enclClass.sym);
1870             if (staticOnly && sym.kind == TYP &&
1871                 sym.type.hasTag(CLASS) &&
1872                 sym.type.getEnclosingType().hasTag(CLASS) &&
1873                 env1.enclClass.sym.type.isParameterized() &&
1874                 sym.type.getEnclosingType().isParameterized())
1875                 return new StaticError(sym);
1876             else if (sym.exists()) return sym;
1877             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1878 
1879             JCClassDecl encl = env1.baseClause ? (JCClassDecl)env1.tree : env1.enclClass;
1880             if ((encl.sym.flags() & STATIC) != 0)
1881                 staticOnly = true;
1882         }
1883 
1884         if (!env.tree.hasTag(IMPORT)) {
1885             sym = findGlobalType(env, env.toplevel.namedImportScope, name);
1886             if (sym.exists()) return sym;
1887             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1888 
1889             sym = findGlobalType(env, env.toplevel.packge.members(), name);
1890             if (sym.exists()) return sym;
1891             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1892 
1893             sym = findGlobalType(env, env.toplevel.starImportScope, name);
1894             if (sym.exists()) return sym;
1895             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1896         }
1897 
1898         return bestSoFar;
1899     }
1900 
1901     /** Find an unqualified identifier which matches a specified kind set.
1902      *  @param env       The current environment.
1903      *  @param name      The identifier's name.
1904      *  @param kind      Indicates the possible symbol kinds
1905      *                   (a subset of VAL, TYP, PCK).
1906      */
1907     Symbol findIdent(Env<AttrContext> env, Name name, int kind) {
1908         Symbol bestSoFar = typeNotFound;
1909         Symbol sym;
1910 
1911         if ((kind & VAR) != 0) {
1912             sym = findVar(env, name);
1913             if (sym.exists()) return sym;
1914             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1915         }
1916 
1917         if ((kind & TYP) != 0) {
1918             sym = findType(env, name);
1919             if (sym.kind==TYP) {
1920                  reportDependence(env.enclClass.sym, sym);
1921             }
1922             if (sym.exists()) return sym;
1923             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1924         }
1925 
1926         if ((kind & PCK) != 0) return reader.enterPackage(name);
1927         else return bestSoFar;
1928     }
1929 
1930     /** Report dependencies.
1931      * @param from The enclosing class sym
1932      * @param to   The found identifier that the class depends on.
1933      */
1934     public void reportDependence(Symbol from, Symbol to) {
1935         // Override if you want to collect the reported dependencies.
1936     }
1937 
1938     /** Find an identifier in a package which matches a specified kind set.
1939      *  @param env       The current environment.
1940      *  @param name      The identifier's name.
1941      *  @param kind      Indicates the possible symbol kinds
1942      *                   (a nonempty subset of TYP, PCK).
1943      */
1944     Symbol findIdentInPackage(Env<AttrContext> env, TypeSymbol pck,
1945                               Name name, int kind) {
1946         Name fullname = TypeSymbol.formFullName(name, pck);
1947         Symbol bestSoFar = typeNotFound;
1948         PackageSymbol pack = null;
1949         if ((kind & PCK) != 0) {
1950             pack = reader.enterPackage(fullname);
1951             if (pack.exists()) return pack;
1952         }
1953         if ((kind & TYP) != 0) {
1954             Symbol sym = loadClass(env, fullname);
1955             if (sym.exists()) {
1956                 // don't allow programs to use flatnames
1957                 if (name == sym.name) return sym;
1958             }
1959             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1960         }
1961         return (pack != null) ? pack : bestSoFar;
1962     }
1963 
1964     /** Find an identifier among the members of a given type `site'.
1965      *  @param env       The current environment.
1966      *  @param site      The type containing the symbol to be found.
1967      *  @param name      The identifier's name.
1968      *  @param kind      Indicates the possible symbol kinds
1969      *                   (a subset of VAL, TYP).
1970      */
1971     Symbol findIdentInType(Env<AttrContext> env, Type site,
1972                            Name name, int kind) {
1973         Symbol bestSoFar = typeNotFound;
1974         Symbol sym;
1975         if ((kind & VAR) != 0) {
1976             sym = findField(env, site, name, site.tsym);
1977             if (sym.exists()) return sym;
1978             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1979         }
1980 
1981         if ((kind & TYP) != 0) {
1982             sym = findMemberType(env, site, name, site.tsym);
1983             if (sym.exists()) return sym;
1984             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1985         }
1986         return bestSoFar;
1987     }
1988 
1989 /* ***************************************************************************
1990  *  Access checking
1991  *  The following methods convert ResolveErrors to ErrorSymbols, issuing
1992  *  an error message in the process
1993  ****************************************************************************/
1994 
1995     /** If `sym' is a bad symbol: report error and return errSymbol
1996      *  else pass through unchanged,
1997      *  additional arguments duplicate what has been used in trying to find the
1998      *  symbol {@literal (--> flyweight pattern)}. This improves performance since we
1999      *  expect misses to happen frequently.
2000      *
2001      *  @param sym       The symbol that was found, or a ResolveError.
2002      *  @param pos       The position to use for error reporting.
2003      *  @param location  The symbol the served as a context for this lookup
2004      *  @param site      The original type from where the selection took place.
2005      *  @param name      The symbol's name.
2006      *  @param qualified Did we get here through a qualified expression resolution?
2007      *  @param argtypes  The invocation's value arguments,
2008      *                   if we looked for a method.
2009      *  @param typeargtypes  The invocation's type arguments,
2010      *                   if we looked for a method.
2011      *  @param logResolveHelper helper class used to log resolve errors
2012      */
2013     Symbol accessInternal(Symbol sym,
2014                   DiagnosticPosition pos,
2015                   Symbol location,
2016                   Type site,
2017                   Name name,
2018                   boolean qualified,
2019                   List<Type> argtypes,
2020                   List<Type> typeargtypes,
2021                   LogResolveHelper logResolveHelper) {
2022         if (sym.kind >= AMBIGUOUS) {
2023             ResolveError errSym = (ResolveError)sym;
2024             sym = errSym.access(name, qualified ? site.tsym : syms.noSymbol);
2025             argtypes = logResolveHelper.getArgumentTypes(errSym, sym, name, argtypes);
2026             if (logResolveHelper.resolveDiagnosticNeeded(site, argtypes, typeargtypes)) {
2027                 logResolveError(errSym, pos, location, site, name, argtypes, typeargtypes);
2028             }
2029         }
2030         return sym;
2031     }
2032 
2033     /**
2034      * Variant of the generalized access routine, to be used for generating method
2035      * resolution diagnostics
2036      */
2037     Symbol accessMethod(Symbol sym,
2038                   DiagnosticPosition pos,
2039                   Symbol location,
2040                   Type site,
2041                   Name name,
2042                   boolean qualified,
2043                   List<Type> argtypes,
2044                   List<Type> typeargtypes) {
2045         return accessInternal(sym, pos, location, site, name, qualified, argtypes, typeargtypes, methodLogResolveHelper);
2046     }
2047 
2048     /** Same as original accessMethod(), but without location.
2049      */
2050     Symbol accessMethod(Symbol sym,
2051                   DiagnosticPosition pos,
2052                   Type site,
2053                   Name name,
2054                   boolean qualified,
2055                   List<Type> argtypes,
2056                   List<Type> typeargtypes) {
2057         return accessMethod(sym, pos, site.tsym, site, name, qualified, argtypes, typeargtypes);
2058     }
2059 
2060     /**
2061      * Variant of the generalized access routine, to be used for generating variable,
2062      * type resolution diagnostics
2063      */
2064     Symbol accessBase(Symbol sym,
2065                   DiagnosticPosition pos,
2066                   Symbol location,
2067                   Type site,
2068                   Name name,
2069                   boolean qualified) {
2070         return accessInternal(sym, pos, location, site, name, qualified, List.<Type>nil(), null, basicLogResolveHelper);
2071     }
2072 
2073     /** Same as original accessBase(), but without location.
2074      */
2075     Symbol accessBase(Symbol sym,
2076                   DiagnosticPosition pos,
2077                   Type site,
2078                   Name name,
2079                   boolean qualified) {
2080         return accessBase(sym, pos, site.tsym, site, name, qualified);
2081     }
2082 
2083     interface LogResolveHelper {
2084         boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes);
2085         List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes);
2086     }
2087 
2088     LogResolveHelper basicLogResolveHelper = new LogResolveHelper() {
2089         public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) {
2090             return !site.isErroneous();
2091         }
2092         public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
2093             return argtypes;
2094         }
2095     };
2096 
2097     LogResolveHelper methodLogResolveHelper = new LogResolveHelper() {
2098         public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) {
2099             return !site.isErroneous() &&
2100                         !Type.isErroneous(argtypes) &&
2101                         (typeargtypes == null || !Type.isErroneous(typeargtypes));
2102         }
2103         public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
2104             return (syms.operatorNames.contains(name)) ?
2105                     argtypes :
2106                     Type.map(argtypes, new ResolveDeferredRecoveryMap(accessedSym));
2107         }
2108 
2109         class ResolveDeferredRecoveryMap extends DeferredAttr.RecoveryDeferredTypeMap {
2110 
2111             public ResolveDeferredRecoveryMap(Symbol msym) {
2112                 deferredAttr.super(AttrMode.SPECULATIVE, msym, currentResolutionContext.step);
2113             }
2114 
2115             @Override
2116             protected Type typeOf(DeferredType dt) {
2117                 Type res = super.typeOf(dt);
2118                 if (!res.isErroneous()) {
2119                     switch (TreeInfo.skipParens(dt.tree).getTag()) {
2120                         case LAMBDA:
2121                         case REFERENCE:
2122                             return dt;
2123                         case CONDEXPR:
2124                             return res == Type.recoveryType ?
2125                                     dt : res;
2126                     }
2127                 }
2128                 return res;
2129             }
2130         }
2131     };
2132 
2133     /** Check that sym is not an abstract method.
2134      */
2135     void checkNonAbstract(DiagnosticPosition pos, Symbol sym) {
2136         if ((sym.flags() & ABSTRACT) != 0 && (sym.flags() & DEFAULT) == 0)
2137             log.error(pos, "abstract.cant.be.accessed.directly",
2138                       kindName(sym), sym, sym.location());
2139     }
2140 
2141 /* ***************************************************************************
2142  *  Debugging
2143  ****************************************************************************/
2144 
2145     /** print all scopes starting with scope s and proceeding outwards.
2146      *  used for debugging.
2147      */
2148     public void printscopes(Scope s) {
2149         while (s != null) {
2150             if (s.owner != null)
2151                 System.err.print(s.owner + ": ");
2152             for (Scope.Entry e = s.elems; e != null; e = e.sibling) {
2153                 if ((e.sym.flags() & ABSTRACT) != 0)
2154                     System.err.print("abstract ");
2155                 System.err.print(e.sym + " ");
2156             }
2157             System.err.println();
2158             s = s.next;
2159         }
2160     }
2161 
2162     void printscopes(Env<AttrContext> env) {
2163         while (env.outer != null) {
2164             System.err.println("------------------------------");
2165             printscopes(env.info.scope);
2166             env = env.outer;
2167         }
2168     }
2169 
2170     public void printscopes(Type t) {
2171         while (t.hasTag(CLASS)) {
2172             printscopes(t.tsym.members());
2173             t = types.supertype(t);
2174         }
2175     }
2176 
2177 /* ***************************************************************************
2178  *  Name resolution
2179  *  Naming conventions are as for symbol lookup
2180  *  Unlike the find... methods these methods will report access errors
2181  ****************************************************************************/
2182 
2183     /** Resolve an unqualified (non-method) identifier.
2184      *  @param pos       The position to use for error reporting.
2185      *  @param env       The environment current at the identifier use.
2186      *  @param name      The identifier's name.
2187      *  @param kind      The set of admissible symbol kinds for the identifier.
2188      */
2189     Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env,
2190                         Name name, int kind) {
2191         return accessBase(
2192             findIdent(env, name, kind),
2193             pos, env.enclClass.sym.type, name, false);
2194     }
2195 
2196     /** Resolve an unqualified method identifier.
2197      *  @param pos       The position to use for error reporting.
2198      *  @param env       The environment current at the method invocation.
2199      *  @param name      The identifier's name.
2200      *  @param argtypes  The types of the invocation's value arguments.
2201      *  @param typeargtypes  The types of the invocation's type arguments.
2202      */
2203     Symbol resolveMethod(DiagnosticPosition pos,
2204                          Env<AttrContext> env,
2205                          Name name,
2206                          List<Type> argtypes,
2207                          List<Type> typeargtypes) {
2208         return lookupMethod(env, pos, env.enclClass.sym, resolveMethodCheck,
2209                 new BasicLookupHelper(name, env.enclClass.sym.type, argtypes, typeargtypes) {
2210                     @Override
2211                     Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2212                         return findFun(env, name, argtypes, typeargtypes,
2213                                 phase.isBoxingRequired(),
2214                                 phase.isVarargsRequired());
2215                     }});
2216     }
2217 
2218     /** Resolve a qualified method identifier
2219      *  @param pos       The position to use for error reporting.
2220      *  @param env       The environment current at the method invocation.
2221      *  @param site      The type of the qualifying expression, in which
2222      *                   identifier is searched.
2223      *  @param name      The identifier's name.
2224      *  @param argtypes  The types of the invocation's value arguments.
2225      *  @param typeargtypes  The types of the invocation's type arguments.
2226      */
2227     Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
2228                                   Type site, Name name, List<Type> argtypes,
2229                                   List<Type> typeargtypes) {
2230         return resolveQualifiedMethod(pos, env, site.tsym, site, name, argtypes, typeargtypes);
2231     }
2232     Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
2233                                   Symbol location, Type site, Name name, List<Type> argtypes,
2234                                   List<Type> typeargtypes) {
2235         return resolveQualifiedMethod(new MethodResolutionContext(), pos, env, location, site, name, argtypes, typeargtypes);
2236     }
2237     private Symbol resolveQualifiedMethod(MethodResolutionContext resolveContext,
2238                                   DiagnosticPosition pos, Env<AttrContext> env,
2239                                   Symbol location, Type site, Name name, List<Type> argtypes,
2240                                   List<Type> typeargtypes) {
2241         return lookupMethod(env, pos, location, resolveContext, new BasicLookupHelper(name, site, argtypes, typeargtypes) {
2242             @Override
2243             Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2244                 return findMethod(env, site, name, argtypes, typeargtypes,
2245                         phase.isBoxingRequired(),
2246                         phase.isVarargsRequired(), false);
2247             }
2248             @Override
2249             Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2250                 if (sym.kind >= AMBIGUOUS) {
2251                     sym = super.access(env, pos, location, sym);
2252                 } else if (allowMethodHandles) {
2253                     MethodSymbol msym = (MethodSymbol)sym;
2254                     if (msym.isSignaturePolymorphic(types)) {
2255                         return findPolymorphicSignatureInstance(env, sym, argtypes);
2256                     }
2257                 }
2258                 return sym;
2259             }
2260         });
2261     }
2262 
2263     /** Find or create an implicit method of exactly the given type (after erasure).
2264      *  Searches in a side table, not the main scope of the site.
2265      *  This emulates the lookup process required by JSR 292 in JVM.
2266      *  @param env       Attribution environment
2267      *  @param spMethod  signature polymorphic method - i.e. MH.invokeExact
2268      *  @param argtypes  The required argument types
2269      */
2270     Symbol findPolymorphicSignatureInstance(Env<AttrContext> env,
2271                                             final Symbol spMethod,
2272                                             List<Type> argtypes) {
2273         Type mtype = infer.instantiatePolymorphicSignatureInstance(env,
2274                 (MethodSymbol)spMethod, currentResolutionContext, argtypes);
2275         for (Symbol sym : polymorphicSignatureScope.getElementsByName(spMethod.name)) {
2276             if (types.isSameType(mtype, sym.type)) {
2277                return sym;
2278             }
2279         }
2280 
2281         // create the desired method
2282         long flags = ABSTRACT | HYPOTHETICAL | spMethod.flags() & Flags.AccessFlags;
2283         Symbol msym = new MethodSymbol(flags, spMethod.name, mtype, spMethod.owner) {
2284             @Override
2285             public Symbol baseSymbol() {
2286                 return spMethod;
2287             }
2288         };
2289         polymorphicSignatureScope.enter(msym);
2290         return msym;
2291     }
2292 
2293     /** Resolve a qualified method identifier, throw a fatal error if not
2294      *  found.
2295      *  @param pos       The position to use for error reporting.
2296      *  @param env       The environment current at the method invocation.
2297      *  @param site      The type of the qualifying expression, in which
2298      *                   identifier is searched.
2299      *  @param name      The identifier's name.
2300      *  @param argtypes  The types of the invocation's value arguments.
2301      *  @param typeargtypes  The types of the invocation's type arguments.
2302      */
2303     public MethodSymbol resolveInternalMethod(DiagnosticPosition pos, Env<AttrContext> env,
2304                                         Type site, Name name,
2305                                         List<Type> argtypes,
2306                                         List<Type> typeargtypes) {
2307         MethodResolutionContext resolveContext = new MethodResolutionContext();
2308         resolveContext.internalResolution = true;
2309         Symbol sym = resolveQualifiedMethod(resolveContext, pos, env, site.tsym,
2310                 site, name, argtypes, typeargtypes);
2311         if (sym.kind == MTH) return (MethodSymbol)sym;
2312         else throw new FatalError(
2313                  diags.fragment("fatal.err.cant.locate.meth",
2314                                 name));
2315     }
2316 
2317     /** Resolve constructor.
2318      *  @param pos       The position to use for error reporting.
2319      *  @param env       The environment current at the constructor invocation.
2320      *  @param site      The type of class for which a constructor is searched.
2321      *  @param argtypes  The types of the constructor invocation's value
2322      *                   arguments.
2323      *  @param typeargtypes  The types of the constructor invocation's type
2324      *                   arguments.
2325      */
2326     Symbol resolveConstructor(DiagnosticPosition pos,
2327                               Env<AttrContext> env,
2328                               Type site,
2329                               List<Type> argtypes,
2330                               List<Type> typeargtypes) {
2331         return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes);
2332     }
2333 
2334     private Symbol resolveConstructor(MethodResolutionContext resolveContext,
2335                               final DiagnosticPosition pos,
2336                               Env<AttrContext> env,
2337                               Type site,
2338                               List<Type> argtypes,
2339                               List<Type> typeargtypes) {
2340         return lookupMethod(env, pos, site.tsym, resolveContext, new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
2341             @Override
2342             Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2343                 return findConstructor(pos, env, site, argtypes, typeargtypes,
2344                         phase.isBoxingRequired(),
2345                         phase.isVarargsRequired());
2346             }
2347         });
2348     }
2349 
2350     /** Resolve a constructor, throw a fatal error if not found.
2351      *  @param pos       The position to use for error reporting.
2352      *  @param env       The environment current at the method invocation.
2353      *  @param site      The type to be constructed.
2354      *  @param argtypes  The types of the invocation's value arguments.
2355      *  @param typeargtypes  The types of the invocation's type arguments.
2356      */
2357     public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2358                                         Type site,
2359                                         List<Type> argtypes,
2360                                         List<Type> typeargtypes) {
2361         MethodResolutionContext resolveContext = new MethodResolutionContext();
2362         resolveContext.internalResolution = true;
2363         Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes);
2364         if (sym.kind == MTH) return (MethodSymbol)sym;
2365         else throw new FatalError(
2366                  diags.fragment("fatal.err.cant.locate.ctor", site));
2367     }
2368 
2369     Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2370                               Type site, List<Type> argtypes,
2371                               List<Type> typeargtypes,
2372                               boolean allowBoxing,
2373                               boolean useVarargs) {
2374         Symbol sym = findMethod(env, site,
2375                                     names.init, argtypes,
2376                                     typeargtypes, allowBoxing,
2377                                     useVarargs, false);
2378         chk.checkDeprecated(pos, env.info.scope.owner, sym);
2379         return sym;
2380     }
2381 
2382     /** Resolve constructor using diamond inference.
2383      *  @param pos       The position to use for error reporting.
2384      *  @param env       The environment current at the constructor invocation.
2385      *  @param site      The type of class for which a constructor is searched.
2386      *                   The scope of this class has been touched in attribution.
2387      *  @param argtypes  The types of the constructor invocation's value
2388      *                   arguments.
2389      *  @param typeargtypes  The types of the constructor invocation's type
2390      *                   arguments.
2391      */
2392     Symbol resolveDiamond(DiagnosticPosition pos,
2393                               Env<AttrContext> env,
2394                               Type site,
2395                               List<Type> argtypes,
2396                               List<Type> typeargtypes) {
2397         return lookupMethod(env, pos, site.tsym, resolveMethodCheck,
2398                 new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
2399                     @Override
2400                     Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2401                         return findDiamond(env, site, argtypes, typeargtypes,
2402                                 phase.isBoxingRequired(),
2403                                 phase.isVarargsRequired());
2404                     }
2405                     @Override
2406                     Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2407                         if (sym.kind >= AMBIGUOUS) {
2408                             final JCDiagnostic details = sym.kind == WRONG_MTH ?
2409                                             ((InapplicableSymbolError)sym).errCandidate().details :
2410                                             null;
2411                             sym = new InapplicableSymbolError(sym.kind, "diamondError", currentResolutionContext) {
2412                                 @Override
2413                                 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
2414                                         Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
2415                                     String key = details == null ?
2416                                         "cant.apply.diamond" :
2417                                         "cant.apply.diamond.1";
2418                                     return diags.create(dkind, log.currentSource(), pos, key,
2419                                             diags.fragment("diamond", site.tsym), details);
2420                                 }
2421                             };
2422                             sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes);
2423                             env.info.pendingResolutionPhase = currentResolutionContext.step;
2424                         }
2425                         return sym;
2426                     }});
2427     }
2428 
2429     /** This method scans all the constructor symbol in a given class scope -
2430      *  assuming that the original scope contains a constructor of the kind:
2431      *  {@code Foo(X x, Y y)}, where X,Y are class type-variables declared in Foo,
2432      *  a method check is executed against the modified constructor type:
2433      *  {@code <X,Y>Foo<X,Y>(X x, Y y)}. This is crucial in order to enable diamond
2434      *  inference. The inferred return type of the synthetic constructor IS
2435      *  the inferred type for the diamond operator.
2436      */
2437     private Symbol findDiamond(Env<AttrContext> env,
2438                               Type site,
2439                               List<Type> argtypes,
2440                               List<Type> typeargtypes,
2441                               boolean allowBoxing,
2442                               boolean useVarargs) {
2443         Symbol bestSoFar = methodNotFound;
2444         for (Scope.Entry e = site.tsym.members().lookup(names.init);
2445              e.scope != null;
2446              e = e.next()) {
2447             final Symbol sym = e.sym;
2448             //- System.out.println(" e " + e.sym);
2449             if (sym.kind == MTH &&
2450                 (sym.flags_field & SYNTHETIC) == 0) {
2451                     List<Type> oldParams = e.sym.type.hasTag(FORALL) ?
2452                             ((ForAll)sym.type).tvars :
2453                             List.<Type>nil();
2454                     Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams),
2455                             types.createMethodTypeWithReturn(sym.type.asMethodType(), site));
2456                     MethodSymbol newConstr = new MethodSymbol(sym.flags(), names.init, constrType, site.tsym) {
2457                         @Override
2458                         public Symbol baseSymbol() {
2459                             return sym;
2460                         }
2461                     };
2462                     bestSoFar = selectBest(env, site, argtypes, typeargtypes,
2463                             newConstr,
2464                             bestSoFar,
2465                             allowBoxing,
2466                             useVarargs,
2467                             false);
2468             }
2469         }
2470         return bestSoFar;
2471     }
2472 
2473 
2474 
2475     /** Resolve operator.
2476      *  @param pos       The position to use for error reporting.
2477      *  @param optag     The tag of the operation tree.
2478      *  @param env       The environment current at the operation.
2479      *  @param argtypes  The types of the operands.
2480      */
2481     Symbol resolveOperator(DiagnosticPosition pos, JCTree.Tag optag,
2482                            Env<AttrContext> env, List<Type> argtypes) {
2483         MethodResolutionContext prevResolutionContext = currentResolutionContext;
2484         try {
2485             currentResolutionContext = new MethodResolutionContext();
2486             Name name = treeinfo.operatorName(optag);
2487             env.info.pendingResolutionPhase = currentResolutionContext.step = BASIC;
2488             Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
2489                                     null, false, false, true);
2490             if (boxingEnabled && sym.kind >= WRONG_MTHS)
2491                 env.info.pendingResolutionPhase = currentResolutionContext.step = BOX;
2492                 sym = findMethod(env, syms.predefClass.type, name, argtypes,
2493                                  null, true, false, true);
2494             return accessMethod(sym, pos, env.enclClass.sym.type, name,
2495                           false, argtypes, null);
2496         }
2497         finally {
2498             currentResolutionContext = prevResolutionContext;
2499         }
2500     }
2501 
2502     /** Resolve operator.
2503      *  @param pos       The position to use for error reporting.
2504      *  @param optag     The tag of the operation tree.
2505      *  @param env       The environment current at the operation.
2506      *  @param arg       The type of the operand.
2507      */
2508     Symbol resolveUnaryOperator(DiagnosticPosition pos, JCTree.Tag optag, Env<AttrContext> env, Type arg) {
2509         return resolveOperator(pos, optag, env, List.of(arg));
2510     }
2511 
2512     /** Resolve binary operator.
2513      *  @param pos       The position to use for error reporting.
2514      *  @param optag     The tag of the operation tree.
2515      *  @param env       The environment current at the operation.
2516      *  @param left      The types of the left operand.
2517      *  @param right     The types of the right operand.
2518      */
2519     Symbol resolveBinaryOperator(DiagnosticPosition pos,
2520                                  JCTree.Tag optag,
2521                                  Env<AttrContext> env,
2522                                  Type left,
2523                                  Type right) {
2524         return resolveOperator(pos, optag, env, List.of(left, right));
2525     }
2526 
2527     /**
2528      * Resolution of member references is typically done as a single
2529      * overload resolution step, where the argument types A are inferred from
2530      * the target functional descriptor.
2531      *
2532      * If the member reference is a method reference with a type qualifier,
2533      * a two-step lookup process is performed. The first step uses the
2534      * expected argument list A, while the second step discards the first
2535      * type from A (which is treated as a receiver type).
2536      *
2537      * There are two cases in which inference is performed: (i) if the member
2538      * reference is a constructor reference and the qualifier type is raw - in
2539      * which case diamond inference is used to infer a parameterization for the
2540      * type qualifier; (ii) if the member reference is an unbound reference
2541      * where the type qualifier is raw - in that case, during the unbound lookup
2542      * the receiver argument type is used to infer an instantiation for the raw
2543      * qualifier type.
2544      *
2545      * When a multi-step resolution process is exploited, it is an error
2546      * if two candidates are found (ambiguity).
2547      *
2548      * This routine returns a pair (T,S), where S is the member reference symbol,
2549      * and T is the type of the class in which S is defined. This is necessary as
2550      * the type T might be dynamically inferred (i.e. if constructor reference
2551      * has a raw qualifier).
2552      */
2553     Pair<Symbol, ReferenceLookupHelper> resolveMemberReference(DiagnosticPosition pos,
2554                                   Env<AttrContext> env,
2555                                   JCMemberReference referenceTree,
2556                                   Type site,
2557                                   Name name, List<Type> argtypes,
2558                                   List<Type> typeargtypes,
2559                                   boolean boxingAllowed,
2560                                   MethodCheck methodCheck) {
2561         MethodResolutionPhase maxPhase = boxingAllowed ? VARARITY : BASIC;
2562 
2563         ReferenceLookupHelper boundLookupHelper;
2564         if (!name.equals(names.init)) {
2565             //method reference
2566             boundLookupHelper =
2567                     new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
2568         } else if (site.hasTag(ARRAY)) {
2569             //array constructor reference
2570             boundLookupHelper =
2571                     new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
2572         } else {
2573             //class constructor reference
2574             boundLookupHelper =
2575                     new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
2576         }
2577 
2578         //step 1 - bound lookup
2579         Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
2580         Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, methodCheck, boundLookupHelper);
2581 
2582         //step 2 - unbound lookup
2583         ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup();
2584         Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup());
2585         Symbol unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym, methodCheck, unboundLookupHelper);
2586 
2587         //merge results
2588         Pair<Symbol, ReferenceLookupHelper> res;
2589         if (!lookupSuccess(unboundSym)) {
2590             res = new Pair<Symbol, ReferenceLookupHelper>(boundSym, boundLookupHelper);
2591             env.info.pendingResolutionPhase = boundEnv.info.pendingResolutionPhase;
2592         } else if (lookupSuccess(boundSym)) {
2593             res = new Pair<Symbol, ReferenceLookupHelper>(ambiguityError(boundSym, unboundSym), boundLookupHelper);
2594             env.info.pendingResolutionPhase = boundEnv.info.pendingResolutionPhase;
2595         } else {
2596             res = new Pair<Symbol, ReferenceLookupHelper>(unboundSym, unboundLookupHelper);
2597             env.info.pendingResolutionPhase = unboundEnv.info.pendingResolutionPhase;
2598         }
2599 
2600         return res;
2601     }
2602     //private
2603         boolean lookupSuccess(Symbol s) {
2604             return s.kind == MTH || s.kind == AMBIGUOUS;
2605         }
2606 
2607     /**
2608      * Helper for defining custom method-like lookup logic; a lookup helper
2609      * provides hooks for (i) the actual lookup logic and (ii) accessing the
2610      * lookup result (this step might result in compiler diagnostics to be generated)
2611      */
2612     abstract class LookupHelper {
2613 
2614         /** name of the symbol to lookup */
2615         Name name;
2616 
2617         /** location in which the lookup takes place */
2618         Type site;
2619 
2620         /** actual types used during the lookup */
2621         List<Type> argtypes;
2622 
2623         /** type arguments used during the lookup */
2624         List<Type> typeargtypes;
2625 
2626         /** Max overload resolution phase handled by this helper */
2627         MethodResolutionPhase maxPhase;
2628 
2629         LookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
2630             this.name = name;
2631             this.site = site;
2632             this.argtypes = argtypes;
2633             this.typeargtypes = typeargtypes;
2634             this.maxPhase = maxPhase;
2635         }
2636 
2637         /**
2638          * Should lookup stop at given phase with given result
2639          */
2640         protected boolean shouldStop(Symbol sym, MethodResolutionPhase phase) {
2641             return phase.ordinal() > maxPhase.ordinal() ||
2642                     sym.kind < ERRONEOUS || sym.kind == AMBIGUOUS;
2643         }
2644 
2645         /**
2646          * Search for a symbol under a given overload resolution phase - this method
2647          * is usually called several times, once per each overload resolution phase
2648          */
2649         abstract Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase);
2650 
2651         /**
2652          * Validate the result of the lookup
2653          */
2654         abstract Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym);
2655     }
2656 
2657     abstract class BasicLookupHelper extends LookupHelper {
2658 
2659         BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes) {
2660             super(name, site, argtypes, typeargtypes, MethodResolutionPhase.VARARITY);
2661         }
2662 
2663         @Override
2664         Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2665             if (sym.kind == AMBIGUOUS) {
2666                 AmbiguityError a_err = (AmbiguityError)sym;
2667                 sym = a_err.mergeAbstracts(site);
2668             }
2669             if (sym.kind >= AMBIGUOUS) {
2670                 //if nothing is found return the 'first' error
2671                 sym = accessMethod(sym, pos, location, site, name, true, argtypes, typeargtypes);
2672             }
2673             return sym;
2674         }
2675     }
2676 
2677     /**
2678      * Helper class for member reference lookup. A reference lookup helper
2679      * defines the basic logic for member reference lookup; a method gives
2680      * access to an 'unbound' helper used to perform an unbound member
2681      * reference lookup.
2682      */
2683     abstract class ReferenceLookupHelper extends LookupHelper {
2684 
2685         /** The member reference tree */
2686         JCMemberReference referenceTree;
2687 
2688         ReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
2689                 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
2690             super(name, site, argtypes, typeargtypes, maxPhase);
2691             this.referenceTree = referenceTree;
2692 
2693         }
2694 
2695         /**
2696          * Returns an unbound version of this lookup helper. By default, this
2697          * method returns an dummy lookup helper.
2698          */
2699         ReferenceLookupHelper unboundLookup() {
2700             //dummy loopkup helper that always return 'methodNotFound'
2701             return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) {
2702                 @Override
2703                 ReferenceLookupHelper unboundLookup() {
2704                     return this;
2705                 }
2706                 @Override
2707                 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2708                     return methodNotFound;
2709                 }
2710                 @Override
2711                 ReferenceKind referenceKind(Symbol sym) {
2712                     Assert.error();
2713                     return null;
2714                 }
2715             };
2716         }
2717 
2718         /**
2719          * Get the kind of the member reference
2720          */
2721         abstract JCMemberReference.ReferenceKind referenceKind(Symbol sym);
2722 
2723         Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2724             if (sym.kind == AMBIGUOUS) {
2725                 AmbiguityError a_err = (AmbiguityError)sym;
2726                 sym = a_err.mergeAbstracts(site);
2727             }
2728             //skip error reporting
2729             return sym;
2730         }
2731     }
2732 
2733     /**
2734      * Helper class for method reference lookup. The lookup logic is based
2735      * upon Resolve.findMethod; in certain cases, this helper class has a
2736      * corresponding unbound helper class (see UnboundMethodReferenceLookupHelper).
2737      * In such cases, non-static lookup results are thrown away.
2738      */
2739     class MethodReferenceLookupHelper extends ReferenceLookupHelper {
2740 
2741         MethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
2742                 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
2743             super(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
2744         }
2745 
2746         @Override
2747         final Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2748             return findMethod(env, site, name, argtypes, typeargtypes,
2749                     phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name));
2750         }
2751 
2752         @Override
2753         ReferenceLookupHelper unboundLookup() {
2754             if (TreeInfo.isStaticSelector(referenceTree.expr, names) &&
2755                     argtypes.nonEmpty() &&
2756                     (argtypes.head.hasTag(NONE) || types.isSubtypeUnchecked(argtypes.head, site))) {
2757                 return new UnboundMethodReferenceLookupHelper(referenceTree, name,
2758                         site, argtypes, typeargtypes, maxPhase);
2759             } else {
2760                 return super.unboundLookup();
2761             }
2762         }
2763 
2764         @Override
2765         ReferenceKind referenceKind(Symbol sym) {
2766             if (sym.isStatic()) {
2767                 return ReferenceKind.STATIC;
2768             } else {
2769                 Name selName = TreeInfo.name(referenceTree.getQualifierExpression());
2770                 return selName != null && selName == names._super ?
2771                         ReferenceKind.SUPER :
2772                         ReferenceKind.BOUND;
2773             }
2774         }
2775     }
2776 
2777     /**
2778      * Helper class for unbound method reference lookup. Essentially the same
2779      * as the basic method reference lookup helper; main difference is that static
2780      * lookup results are thrown away. If qualifier type is raw, an attempt to
2781      * infer a parameterized type is made using the first actual argument (that
2782      * would otherwise be ignored during the lookup).
2783      */
2784     class UnboundMethodReferenceLookupHelper extends MethodReferenceLookupHelper {
2785 
2786         UnboundMethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
2787                 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
2788             super(referenceTree, name, site, argtypes.tail, typeargtypes, maxPhase);
2789             if (site.isRaw() && !argtypes.head.hasTag(NONE)) {
2790                 Type asSuperSite = types.asSuper(argtypes.head, site.tsym);
2791                 this.site = asSuperSite;
2792             }
2793         }
2794 
2795         @Override
2796         ReferenceLookupHelper unboundLookup() {
2797             return this;
2798         }
2799 
2800         @Override
2801         ReferenceKind referenceKind(Symbol sym) {
2802             return ReferenceKind.UNBOUND;
2803         }
2804     }
2805 
2806     /**
2807      * Helper class for array constructor lookup; an array constructor lookup
2808      * is simulated by looking up a method that returns the array type specified
2809      * as qualifier, and that accepts a single int parameter (size of the array).
2810      */
2811     class ArrayConstructorReferenceLookupHelper extends ReferenceLookupHelper {
2812 
2813         ArrayConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
2814                 List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
2815             super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
2816         }
2817 
2818         @Override
2819         protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2820             Scope sc = new Scope(syms.arrayClass);
2821             MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym);
2822             arrayConstr.type = new MethodType(List.of(syms.intType), site, List.<Type>nil(), syms.methodClass);
2823             sc.enter(arrayConstr);
2824             return findMethodInScope(env, site, name, argtypes, typeargtypes, sc, methodNotFound, phase.isBoxingRequired(), phase.isVarargsRequired(), false, false);
2825         }
2826 
2827         @Override
2828         ReferenceKind referenceKind(Symbol sym) {
2829             return ReferenceKind.ARRAY_CTOR;
2830         }
2831     }
2832 
2833     /**
2834      * Helper class for constructor reference lookup. The lookup logic is based
2835      * upon either Resolve.findMethod or Resolve.findDiamond - depending on
2836      * whether the constructor reference needs diamond inference (this is the case
2837      * if the qualifier type is raw). A special erroneous symbol is returned
2838      * if the lookup returns the constructor of an inner class and there's no
2839      * enclosing instance in scope.
2840      */
2841     class ConstructorReferenceLookupHelper extends ReferenceLookupHelper {
2842 
2843         boolean needsInference;
2844 
2845         ConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
2846                 List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
2847             super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
2848             if (site.isRaw()) {
2849                 this.site = new ClassType(site.getEnclosingType(), site.tsym.type.getTypeArguments(), site.tsym);
2850                 needsInference = true;
2851             }
2852         }
2853 
2854         @Override
2855         protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2856             Symbol sym = needsInference ?
2857                 findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) :
2858                 findMethod(env, site, name, argtypes, typeargtypes,
2859                         phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name));
2860             return sym.kind != MTH ||
2861                           site.getEnclosingType().hasTag(NONE) ||
2862                           hasEnclosingInstance(env, site) ?
2863                           sym : new InvalidSymbolError(Kinds.MISSING_ENCL, sym, null) {
2864                     @Override
2865                     JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
2866                        return diags.create(dkind, log.currentSource(), pos,
2867                             "cant.access.inner.cls.constr", site.tsym.name, argtypes, site.getEnclosingType());
2868                     }
2869                 };
2870         }
2871 
2872         @Override
2873         ReferenceKind referenceKind(Symbol sym) {
2874             return site.getEnclosingType().hasTag(NONE) ?
2875                     ReferenceKind.TOPLEVEL : ReferenceKind.IMPLICIT_INNER;
2876         }
2877     }
2878 
2879     /**
2880      * Main overload resolution routine. On each overload resolution step, a
2881      * lookup helper class is used to perform the method/constructor lookup;
2882      * at the end of the lookup, the helper is used to validate the results
2883      * (this last step might trigger overload resolution diagnostics).
2884      */
2885     Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, MethodCheck methodCheck, LookupHelper lookupHelper) {
2886         MethodResolutionContext resolveContext = new MethodResolutionContext();
2887         resolveContext.methodCheck = methodCheck;
2888         return lookupMethod(env, pos, location, resolveContext, lookupHelper);
2889     }
2890 
2891     Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location,
2892             MethodResolutionContext resolveContext, LookupHelper lookupHelper) {
2893         MethodResolutionContext prevResolutionContext = currentResolutionContext;
2894         try {
2895             Symbol bestSoFar = methodNotFound;
2896             currentResolutionContext = resolveContext;
2897             for (MethodResolutionPhase phase : methodResolutionSteps) {
2898                 if (!phase.isApplicable(boxingEnabled, varargsEnabled) ||
2899                         lookupHelper.shouldStop(bestSoFar, phase)) break;
2900                 MethodResolutionPhase prevPhase = currentResolutionContext.step;
2901                 Symbol prevBest = bestSoFar;
2902                 currentResolutionContext.step = phase;
2903                 bestSoFar = phase.mergeResults(bestSoFar, lookupHelper.lookup(env, phase));
2904                 env.info.pendingResolutionPhase = (prevBest == bestSoFar) ? prevPhase : phase;
2905             }
2906             return lookupHelper.access(env, pos, location, bestSoFar);
2907         } finally {
2908             currentResolutionContext = prevResolutionContext;
2909         }
2910     }
2911 
2912     /**
2913      * Resolve `c.name' where name == this or name == super.
2914      * @param pos           The position to use for error reporting.
2915      * @param env           The environment current at the expression.
2916      * @param c             The qualifier.
2917      * @param name          The identifier's name.
2918      */
2919     Symbol resolveSelf(DiagnosticPosition pos,
2920                        Env<AttrContext> env,
2921                        TypeSymbol c,
2922                        Name name) {
2923         Env<AttrContext> env1 = env;
2924         boolean staticOnly = false;
2925         while (env1.outer != null) {
2926             if (isStatic(env1)) staticOnly = true;
2927             if (env1.enclClass.sym == c) {
2928                 Symbol sym = env1.info.scope.lookup(name).sym;
2929                 if (sym != null) {
2930                     if (staticOnly) sym = new StaticError(sym);
2931                     return accessBase(sym, pos, env.enclClass.sym.type,
2932                                   name, true);
2933                 }
2934             }
2935             if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
2936             env1 = env1.outer;
2937         }
2938         if (allowDefaultMethods && c.isInterface() &&
2939                 name == names._super && !isStatic(env) &&
2940                 types.isDirectSuperInterface(c, env.enclClass.sym)) {
2941             //this might be a default super call if one of the superinterfaces is 'c'
2942             for (Type t : pruneInterfaces(env.enclClass.type)) {
2943                 if (t.tsym == c) {
2944                     env.info.defaultSuperCallSite = t;
2945                     return new VarSymbol(0, names._super,
2946                             types.asSuper(env.enclClass.type, c), env.enclClass.sym);
2947                 }
2948             }
2949             //find a direct superinterface that is a subtype of 'c'
2950             for (Type i : types.interfaces(env.enclClass.type)) {
2951                 if (i.tsym.isSubClass(c, types) && i.tsym != c) {
2952                     log.error(pos, "illegal.default.super.call", c,
2953                             diags.fragment("redundant.supertype", c, i));
2954                     return syms.errSymbol;
2955                 }
2956             }
2957             Assert.error();
2958         }
2959         log.error(pos, "not.encl.class", c);
2960         return syms.errSymbol;
2961     }
2962     //where
2963     private List<Type> pruneInterfaces(Type t) {
2964         ListBuffer<Type> result = ListBuffer.lb();
2965         for (Type t1 : types.interfaces(t)) {
2966             boolean shouldAdd = true;
2967             for (Type t2 : types.interfaces(t)) {
2968                 if (t1 != t2 && types.isSubtypeNoCapture(t2, t1)) {
2969                     shouldAdd = false;
2970                 }
2971             }
2972             if (shouldAdd) {
2973                 result.append(t1);
2974             }
2975         }
2976         return result.toList();
2977     }
2978 
2979 
2980     /**
2981      * Resolve `c.this' for an enclosing class c that contains the
2982      * named member.
2983      * @param pos           The position to use for error reporting.
2984      * @param env           The environment current at the expression.
2985      * @param member        The member that must be contained in the result.
2986      */
2987     Symbol resolveSelfContaining(DiagnosticPosition pos,
2988                                  Env<AttrContext> env,
2989                                  Symbol member,
2990                                  boolean isSuperCall) {
2991         Symbol sym = resolveSelfContainingInternal(env, member, isSuperCall);
2992         if (sym == null) {
2993             log.error(pos, "encl.class.required", member);
2994             return syms.errSymbol;
2995         } else {
2996             return accessBase(sym, pos, env.enclClass.sym.type, sym.name, true);
2997         }
2998     }
2999 
3000     boolean hasEnclosingInstance(Env<AttrContext> env, Type type) {
3001         Symbol encl = resolveSelfContainingInternal(env, type.tsym, false);
3002         return encl != null && encl.kind < ERRONEOUS;
3003     }
3004 
3005     private Symbol resolveSelfContainingInternal(Env<AttrContext> env,
3006                                  Symbol member,
3007                                  boolean isSuperCall) {
3008         Name name = names._this;
3009         Env<AttrContext> env1 = isSuperCall ? env.outer : env;
3010         boolean staticOnly = false;
3011         if (env1 != null) {
3012             while (env1 != null && env1.outer != null) {
3013                 if (isStatic(env1)) staticOnly = true;
3014                 if (env1.enclClass.sym.isSubClass(member.owner, types)) {
3015                     Symbol sym = env1.info.scope.lookup(name).sym;
3016                     if (sym != null) {
3017                         if (staticOnly) sym = new StaticError(sym);
3018                         return sym;
3019                     }
3020                 }
3021                 if ((env1.enclClass.sym.flags() & STATIC) != 0)
3022                     staticOnly = true;
3023                 env1 = env1.outer;
3024             }
3025         }
3026         return null;
3027     }
3028 
3029     /**
3030      * Resolve an appropriate implicit this instance for t's container.
3031      * JLS 8.8.5.1 and 15.9.2
3032      */
3033     Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t) {
3034         return resolveImplicitThis(pos, env, t, false);
3035     }
3036 
3037     Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t, boolean isSuperCall) {
3038         Type thisType = (((t.tsym.owner.kind & (MTH|VAR)) != 0)
3039                          ? resolveSelf(pos, env, t.getEnclosingType().tsym, names._this)
3040                          : resolveSelfContaining(pos, env, t.tsym, isSuperCall)).type;
3041         if (env.info.isSelfCall && thisType.tsym == env.enclClass.sym)
3042             log.error(pos, "cant.ref.before.ctor.called", "this");
3043         return thisType;
3044     }
3045 
3046 /* ***************************************************************************
3047  *  ResolveError classes, indicating error situations when accessing symbols
3048  ****************************************************************************/
3049 
3050     //used by TransTypes when checking target type of synthetic cast
3051     public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) {
3052         AccessError error = new AccessError(env, env.enclClass.type, type.tsym);
3053         logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null);
3054     }
3055     //where
3056     private void logResolveError(ResolveError error,
3057             DiagnosticPosition pos,
3058             Symbol location,
3059             Type site,
3060             Name name,
3061             List<Type> argtypes,
3062             List<Type> typeargtypes) {
3063         JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
3064                 pos, location, site, name, argtypes, typeargtypes);
3065         if (d != null) {
3066             d.setFlag(DiagnosticFlag.RESOLVE_ERROR);
3067             log.report(d);
3068         }
3069     }
3070 
3071     private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
3072 
3073     public Object methodArguments(List<Type> argtypes) {
3074         if (argtypes == null || argtypes.isEmpty()) {
3075             return noArgs;
3076         } else {
3077             ListBuffer<Object> diagArgs = ListBuffer.lb();
3078             for (Type t : argtypes) {
3079                 if (t.hasTag(DEFERRED)) {
3080                     diagArgs.append(((DeferredAttr.DeferredType)t).tree);
3081                 } else {
3082                     diagArgs.append(t);
3083                 }
3084             }
3085             return diagArgs;
3086         }
3087     }
3088 
3089     /**
3090      * Root class for resolution errors. Subclass of ResolveError
3091      * represent a different kinds of resolution error - as such they must
3092      * specify how they map into concrete compiler diagnostics.
3093      */
3094     abstract class ResolveError extends Symbol {
3095 
3096         /** The name of the kind of error, for debugging only. */
3097         final String debugName;
3098 
3099         ResolveError(int kind, String debugName) {
3100             super(kind, 0, null, null, null);
3101             this.debugName = debugName;
3102         }
3103 
3104         @Override
3105         public <R, P> R accept(ElementVisitor<R, P> v, P p) {
3106             throw new AssertionError();
3107         }
3108 
3109         @Override
3110         public String toString() {
3111             return debugName;
3112         }
3113 
3114         @Override
3115         public boolean exists() {
3116             return false;
3117         }
3118 
3119         /**
3120          * Create an external representation for this erroneous symbol to be
3121          * used during attribution - by default this returns the symbol of a
3122          * brand new error type which stores the original type found
3123          * during resolution.
3124          *
3125          * @param name     the name used during resolution
3126          * @param location the location from which the symbol is accessed
3127          */
3128         protected Symbol access(Name name, TypeSymbol location) {
3129             return types.createErrorType(name, location, syms.errSymbol.type).tsym;
3130         }
3131 
3132         /**
3133          * Create a diagnostic representing this resolution error.
3134          *
3135          * @param dkind     The kind of the diagnostic to be created (e.g error).
3136          * @param pos       The position to be used for error reporting.
3137          * @param site      The original type from where the selection took place.
3138          * @param name      The name of the symbol to be resolved.
3139          * @param argtypes  The invocation's value arguments,
3140          *                  if we looked for a method.
3141          * @param typeargtypes  The invocation's type arguments,
3142          *                      if we looked for a method.
3143          */
3144         abstract JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3145                 DiagnosticPosition pos,
3146                 Symbol location,
3147                 Type site,
3148                 Name name,
3149                 List<Type> argtypes,
3150                 List<Type> typeargtypes);
3151     }
3152 
3153     /**
3154      * This class is the root class of all resolution errors caused by
3155      * an invalid symbol being found during resolution.
3156      */
3157     abstract class InvalidSymbolError extends ResolveError {
3158 
3159         /** The invalid symbol found during resolution */
3160         Symbol sym;
3161 
3162         InvalidSymbolError(int kind, Symbol sym, String debugName) {
3163             super(kind, debugName);
3164             this.sym = sym;
3165         }
3166 
3167         @Override
3168         public boolean exists() {
3169             return true;
3170         }
3171 
3172         @Override
3173         public String toString() {
3174              return super.toString() + " wrongSym=" + sym;
3175         }
3176 
3177         @Override
3178         public Symbol access(Name name, TypeSymbol location) {
3179             if ((sym.kind & ERRONEOUS) == 0 && (sym.kind & TYP) != 0)
3180                 return types.createErrorType(name, location, sym.type).tsym;
3181             else
3182                 return sym;
3183         }
3184     }
3185 
3186     /**
3187      * InvalidSymbolError error class indicating that a symbol matching a
3188      * given name does not exists in a given site.
3189      */
3190     class SymbolNotFoundError extends ResolveError {
3191 
3192         SymbolNotFoundError(int kind) {
3193             super(kind, "symbol not found error");
3194         }
3195 
3196         @Override
3197         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3198                 DiagnosticPosition pos,
3199                 Symbol location,
3200                 Type site,
3201                 Name name,
3202                 List<Type> argtypes,
3203                 List<Type> typeargtypes) {
3204             argtypes = argtypes == null ? List.<Type>nil() : argtypes;
3205             typeargtypes = typeargtypes == null ? List.<Type>nil() : typeargtypes;
3206             if (name == names.error)
3207                 return null;
3208 
3209             if (syms.operatorNames.contains(name)) {
3210                 boolean isUnaryOp = argtypes.size() == 1;
3211                 String key = argtypes.size() == 1 ?
3212                     "operator.cant.be.applied" :
3213                     "operator.cant.be.applied.1";
3214                 Type first = argtypes.head;
3215                 Type second = !isUnaryOp ? argtypes.tail.head : null;
3216                 return diags.create(dkind, log.currentSource(), pos,
3217                         key, name, first, second);
3218             }
3219             boolean hasLocation = false;
3220             if (location == null) {
3221                 location = site.tsym;
3222             }
3223             if (!location.name.isEmpty()) {
3224                 if (location.kind == PCK && !site.tsym.exists()) {
3225                     return diags.create(dkind, log.currentSource(), pos,
3226                         "doesnt.exist", location);
3227                 }
3228                 hasLocation = !location.name.equals(names._this) &&
3229                         !location.name.equals(names._super);
3230             }
3231             boolean isConstructor = kind == ABSENT_MTH && name == names.init;
3232             KindName kindname = isConstructor ? KindName.CONSTRUCTOR : absentKind(kind);
3233             Name idname = isConstructor ? site.tsym.name : name;
3234             String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation);
3235             if (hasLocation) {
3236                 return diags.create(dkind, log.currentSource(), pos,
3237                         errKey, kindname, idname, //symbol kindname, name
3238                         typeargtypes, args(argtypes), //type parameters and arguments (if any)
3239                         getLocationDiag(location, site)); //location kindname, type
3240             }
3241             else {
3242                 return diags.create(dkind, log.currentSource(), pos,
3243                         errKey, kindname, idname, //symbol kindname, name
3244                         typeargtypes, args(argtypes)); //type parameters and arguments (if any)
3245             }
3246         }
3247         //where
3248         private Object args(List<Type> args) {
3249             return args.isEmpty() ? args : methodArguments(args);
3250         }
3251 
3252         private String getErrorKey(KindName kindname, boolean hasTypeArgs, boolean hasLocation) {
3253             String key = "cant.resolve";
3254             String suffix = hasLocation ? ".location" : "";
3255             switch (kindname) {
3256                 case METHOD:
3257                 case CONSTRUCTOR: {
3258                     suffix += ".args";
3259                     suffix += hasTypeArgs ? ".params" : "";
3260                 }
3261             }
3262             return key + suffix;
3263         }
3264         private JCDiagnostic getLocationDiag(Symbol location, Type site) {
3265             if (location.kind == VAR) {
3266                 return diags.fragment("location.1",
3267                     kindName(location),
3268                     location,
3269                     location.type);
3270             } else {
3271                 return diags.fragment("location",
3272                     typeKindName(site),
3273                     site,
3274                     null);
3275             }
3276         }
3277     }
3278 
3279     /**
3280      * InvalidSymbolError error class indicating that a given symbol
3281      * (either a method, a constructor or an operand) is not applicable
3282      * given an actual arguments/type argument list.
3283      */
3284     class InapplicableSymbolError extends ResolveError {
3285 
3286         protected MethodResolutionContext resolveContext;
3287 
3288         InapplicableSymbolError(MethodResolutionContext context) {
3289             this(WRONG_MTH, "inapplicable symbol error", context);
3290         }
3291 
3292         protected InapplicableSymbolError(int kind, String debugName, MethodResolutionContext context) {
3293             super(kind, debugName);
3294             this.resolveContext = context;
3295         }
3296 
3297         @Override
3298         public String toString() {
3299             return super.toString();
3300         }
3301 
3302         @Override
3303         public boolean exists() {
3304             return true;
3305         }
3306 
3307         @Override
3308         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3309                 DiagnosticPosition pos,
3310                 Symbol location,
3311                 Type site,
3312                 Name name,
3313                 List<Type> argtypes,
3314                 List<Type> typeargtypes) {
3315             if (name == names.error)
3316                 return null;
3317 
3318             if (syms.operatorNames.contains(name)) {
3319                 boolean isUnaryOp = argtypes.size() == 1;
3320                 String key = argtypes.size() == 1 ?
3321                     "operator.cant.be.applied" :
3322                     "operator.cant.be.applied.1";
3323                 Type first = argtypes.head;
3324                 Type second = !isUnaryOp ? argtypes.tail.head : null;
3325                 return diags.create(dkind, log.currentSource(), pos,
3326                         key, name, first, second);
3327             }
3328             else {
3329                 Candidate c = errCandidate();
3330                 Symbol ws = c.sym.asMemberOf(site, types);
3331                 return diags.create(dkind, log.currentSource(), pos,
3332                           "cant.apply.symbol",
3333                           kindName(ws),
3334                           ws.name == names.init ? ws.owner.name : ws.name,
3335                           methodArguments(ws.type.getParameterTypes()),
3336                           methodArguments(argtypes),
3337                           kindName(ws.owner),
3338                           ws.owner.type,
3339                           c.details);
3340             }
3341         }
3342 
3343         @Override
3344         public Symbol access(Name name, TypeSymbol location) {
3345             return types.createErrorType(name, location, syms.errSymbol.type).tsym;
3346         }
3347 
3348         private Candidate errCandidate() {
3349             Candidate bestSoFar = null;
3350             for (Candidate c : resolveContext.candidates) {
3351                 if (c.isApplicable()) continue;
3352                 bestSoFar = c;
3353             }
3354             Assert.checkNonNull(bestSoFar);
3355             return bestSoFar;
3356         }
3357     }
3358 
3359     /**
3360      * ResolveError error class indicating that a set of symbols
3361      * (either methods, constructors or operands) is not applicable
3362      * given an actual arguments/type argument list.
3363      */
3364     class InapplicableSymbolsError extends InapplicableSymbolError {
3365 
3366         InapplicableSymbolsError(MethodResolutionContext context) {
3367             super(WRONG_MTHS, "inapplicable symbols", context);
3368         }
3369 
3370         @Override
3371         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3372                 DiagnosticPosition pos,
3373                 Symbol location,
3374                 Type site,
3375                 Name name,
3376                 List<Type> argtypes,
3377                 List<Type> typeargtypes) {
3378             if (!resolveContext.candidates.isEmpty()) {
3379                 JCDiagnostic err = diags.create(dkind,
3380                         log.currentSource(),
3381                         pos,
3382                         "cant.apply.symbols",
3383                         name == names.init ? KindName.CONSTRUCTOR : absentKind(kind),
3384                         name == names.init ? site.tsym.name : name,
3385                         methodArguments(argtypes));
3386                 return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(site));
3387             } else {
3388                 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos,
3389                     location, site, name, argtypes, typeargtypes);
3390             }
3391         }
3392 
3393         //where
3394         List<JCDiagnostic> candidateDetails(Type site) {
3395             Map<Symbol, JCDiagnostic> details = new LinkedHashMap<Symbol, JCDiagnostic>();
3396             for (Candidate c : resolveContext.candidates) {
3397                 if (c.isApplicable()) continue;
3398                 JCDiagnostic detailDiag = diags.fragment("inapplicable.method",
3399                         Kinds.kindName(c.sym),
3400                         c.sym.location(site, types),
3401                         c.sym.asMemberOf(site, types),
3402                         c.details);
3403                 details.put(c.sym, detailDiag);
3404             }
3405             return List.from(details.values());
3406         }
3407     }
3408 
3409     /**
3410      * An InvalidSymbolError error class indicating that a symbol is not
3411      * accessible from a given site
3412      */
3413     class AccessError extends InvalidSymbolError {
3414 
3415         private Env<AttrContext> env;
3416         private Type site;
3417 
3418         AccessError(Symbol sym) {
3419             this(null, null, sym);
3420         }
3421 
3422         AccessError(Env<AttrContext> env, Type site, Symbol sym) {
3423             super(HIDDEN, sym, "access error");
3424             this.env = env;
3425             this.site = site;
3426             if (debugResolve)
3427                 log.error("proc.messager", sym + " @ " + site + " is inaccessible.");
3428         }
3429 
3430         @Override
3431         public boolean exists() {
3432             return false;
3433         }
3434 
3435         @Override
3436         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3437                 DiagnosticPosition pos,
3438                 Symbol location,
3439                 Type site,
3440                 Name name,
3441                 List<Type> argtypes,
3442                 List<Type> typeargtypes) {
3443             if (sym.owner.type.hasTag(ERROR))
3444                 return null;
3445 
3446             if (sym.name == names.init && sym.owner != site.tsym) {
3447                 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind,
3448                         pos, location, site, name, argtypes, typeargtypes);
3449             }
3450             else if ((sym.flags() & PUBLIC) != 0
3451                 || (env != null && this.site != null
3452                     && !isAccessible(env, this.site))) {
3453                 return diags.create(dkind, log.currentSource(),
3454                         pos, "not.def.access.class.intf.cant.access",
3455                     sym, sym.location());
3456             }
3457             else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) {
3458                 return diags.create(dkind, log.currentSource(),
3459                         pos, "report.access", sym,
3460                         asFlagSet(sym.flags() & (PRIVATE | PROTECTED)),
3461                         sym.location());
3462             }
3463             else {
3464                 return diags.create(dkind, log.currentSource(),
3465                         pos, "not.def.public.cant.access", sym, sym.location());
3466             }
3467         }
3468     }
3469 
3470     /**
3471      * InvalidSymbolError error class indicating that an instance member
3472      * has erroneously been accessed from a static context.
3473      */
3474     class StaticError extends InvalidSymbolError {
3475 
3476         StaticError(Symbol sym) {
3477             super(STATICERR, sym, "static error");
3478         }
3479 
3480         @Override
3481         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3482                 DiagnosticPosition pos,
3483                 Symbol location,
3484                 Type site,
3485                 Name name,
3486                 List<Type> argtypes,
3487                 List<Type> typeargtypes) {
3488             Symbol errSym = ((sym.kind == TYP && sym.type.hasTag(CLASS))
3489                 ? types.erasure(sym.type).tsym
3490                 : sym);
3491             return diags.create(dkind, log.currentSource(), pos,
3492                     "non-static.cant.be.ref", kindName(sym), errSym);
3493         }
3494     }
3495 
3496     /**
3497      * InvalidSymbolError error class indicating that a pair of symbols
3498      * (either methods, constructors or operands) are ambiguous
3499      * given an actual arguments/type argument list.
3500      */
3501     class AmbiguityError extends ResolveError {
3502 
3503         /** The other maximally specific symbol */
3504         List<Symbol> ambiguousSyms = List.nil();
3505 
3506         @Override
3507         public boolean exists() {
3508             return true;
3509         }
3510 
3511         AmbiguityError(Symbol sym1, Symbol sym2) {
3512             super(AMBIGUOUS, "ambiguity error");
3513             ambiguousSyms = flatten(sym2).appendList(flatten(sym1));
3514         }
3515 
3516         private List<Symbol> flatten(Symbol sym) {
3517             if (sym.kind == AMBIGUOUS) {
3518                 return ((AmbiguityError)sym).ambiguousSyms;
3519             } else {
3520                 return List.of(sym);
3521             }
3522         }
3523 
3524         AmbiguityError addAmbiguousSymbol(Symbol s) {
3525             ambiguousSyms = ambiguousSyms.prepend(s);
3526             return this;
3527         }
3528 
3529         @Override
3530         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3531                 DiagnosticPosition pos,
3532                 Symbol location,
3533                 Type site,
3534                 Name name,
3535                 List<Type> argtypes,
3536                 List<Type> typeargtypes) {
3537             List<Symbol> diagSyms = ambiguousSyms.reverse();
3538             Symbol s1 = diagSyms.head;
3539             Symbol s2 = diagSyms.tail.head;
3540             Name sname = s1.name;
3541             if (sname == names.init) sname = s1.owner.name;
3542             return diags.create(dkind, log.currentSource(),
3543                       pos, "ref.ambiguous", sname,
3544                       kindName(s1),
3545                       s1,
3546                       s1.location(site, types),
3547                       kindName(s2),
3548                       s2,
3549                       s2.location(site, types));
3550         }
3551 
3552         /**
3553          * If multiple applicable methods are found during overload and none of them
3554          * is more specific than the others, attempt to merge their signatures.
3555          */
3556         Symbol mergeAbstracts(Type site) {
3557             Symbol fst = ambiguousSyms.last();
3558             Symbol res = fst;
3559             for (Symbol s : ambiguousSyms.reverse()) {
3560                 Type mt1 = types.memberType(site, res);
3561                 Type mt2 = types.memberType(site, s);
3562                 if ((s.flags() & ABSTRACT) == 0 ||
3563                         !types.overrideEquivalent(mt1, mt2) ||
3564                         !types.isSameTypes(fst.erasure(types).getParameterTypes(),
3565                                        s.erasure(types).getParameterTypes())) {
3566                     //ambiguity cannot be resolved
3567                     return this;
3568                 } else {
3569                     Type mst = mostSpecificReturnType(mt1, mt2);
3570                     if (mst == null) {
3571                         // Theoretically, this can't happen, but it is possible
3572                         // due to error recovery or mixing incompatible class files
3573                         return this;
3574                     }
3575                     Symbol mostSpecific = mst == mt1 ? res : s;
3576                     List<Type> allThrown = chk.intersect(mt1.getThrownTypes(), mt2.getThrownTypes());
3577                     Type newSig = types.createMethodTypeWithThrown(mostSpecific.type, allThrown);
3578                     res = new MethodSymbol(
3579                             mostSpecific.flags(),
3580                             mostSpecific.name,
3581                             newSig,
3582                             mostSpecific.owner);
3583                 }
3584             }
3585             return res;
3586         }
3587 
3588         @Override
3589         protected Symbol access(Name name, TypeSymbol location) {
3590             Symbol firstAmbiguity = ambiguousSyms.last();
3591             return firstAmbiguity.kind == TYP ?
3592                     types.createErrorType(name, location, firstAmbiguity.type).tsym :
3593                     firstAmbiguity;
3594         }
3595     }
3596 
3597     class BadVarargsMethod extends ResolveError {
3598 
3599         ResolveError delegatedError;
3600 
3601         BadVarargsMethod(ResolveError delegatedError) {
3602             super(delegatedError.kind, "badVarargs");
3603             this.delegatedError = delegatedError;
3604         }
3605 
3606         @Override
3607         public Symbol baseSymbol() {
3608             return delegatedError.baseSymbol();
3609         }
3610 
3611         @Override
3612         protected Symbol access(Name name, TypeSymbol location) {
3613             return delegatedError.access(name, location);
3614         }
3615 
3616         @Override
3617         public boolean exists() {
3618             return true;
3619         }
3620 
3621         @Override
3622         JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
3623             return delegatedError.getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes);
3624         }
3625     }
3626 
3627     enum MethodResolutionPhase {
3628         BASIC(false, false),
3629         BOX(true, false),
3630         VARARITY(true, true) {
3631             @Override
3632             public Symbol mergeResults(Symbol bestSoFar, Symbol sym) {
3633                 switch (sym.kind) {
3634                     case WRONG_MTH:
3635                         return (bestSoFar.kind == WRONG_MTH || bestSoFar.kind == WRONG_MTHS) ?
3636                             bestSoFar :
3637                             sym;
3638                     case ABSENT_MTH:
3639                         return bestSoFar;
3640                     default:
3641                         return sym;
3642                 }
3643             }
3644         };
3645 
3646         final boolean isBoxingRequired;
3647         final boolean isVarargsRequired;
3648 
3649         MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) {
3650            this.isBoxingRequired = isBoxingRequired;
3651            this.isVarargsRequired = isVarargsRequired;
3652         }
3653 
3654         public boolean isBoxingRequired() {
3655             return isBoxingRequired;
3656         }
3657 
3658         public boolean isVarargsRequired() {
3659             return isVarargsRequired;
3660         }
3661 
3662         public boolean isApplicable(boolean boxingEnabled, boolean varargsEnabled) {
3663             return (varargsEnabled || !isVarargsRequired) &&
3664                    (boxingEnabled || !isBoxingRequired);
3665         }
3666 
3667         public Symbol mergeResults(Symbol prev, Symbol sym) {
3668             return sym;
3669         }
3670     }
3671 
3672     final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
3673 
3674     /**
3675      * A resolution context is used to keep track of intermediate results of
3676      * overload resolution, such as list of method that are not applicable
3677      * (used to generate more precise diagnostics) and so on. Resolution contexts
3678      * can be nested - this means that when each overload resolution routine should
3679      * work within the resolution context it created.
3680      */
3681     class MethodResolutionContext {
3682 
3683         private List<Candidate> candidates = List.nil();
3684 
3685         MethodResolutionPhase step = null;
3686 
3687         MethodCheck methodCheck = resolveMethodCheck;
3688 
3689         private boolean internalResolution = false;
3690         private DeferredAttr.AttrMode attrMode = DeferredAttr.AttrMode.SPECULATIVE;
3691 
3692         void addInapplicableCandidate(Symbol sym, JCDiagnostic details) {
3693             Candidate c = new Candidate(currentResolutionContext.step, sym, details, null);
3694             candidates = candidates.append(c);
3695         }
3696 
3697         void addApplicableCandidate(Symbol sym, Type mtype) {
3698             Candidate c = new Candidate(currentResolutionContext.step, sym, null, mtype);
3699             candidates = candidates.append(c);
3700         }
3701 
3702         DeferredAttrContext deferredAttrContext(Symbol sym, InferenceContext inferenceContext, ResultInfo pendingResult, Warner warn) {
3703             return deferredAttr.new DeferredAttrContext(attrMode, sym, step, inferenceContext, pendingResult != null ? pendingResult.checkContext.deferredAttrContext() : deferredAttr.emptyDeferredAttrContext, warn);
3704         }
3705 
3706         /**
3707          * This class represents an overload resolution candidate. There are two
3708          * kinds of candidates: applicable methods and inapplicable methods;
3709          * applicable methods have a pointer to the instantiated method type,
3710          * while inapplicable candidates contain further details about the
3711          * reason why the method has been considered inapplicable.
3712          */
3713         @SuppressWarnings("overrides")
3714         class Candidate {
3715 
3716             final MethodResolutionPhase step;
3717             final Symbol sym;
3718             final JCDiagnostic details;
3719             final Type mtype;
3720 
3721             private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) {
3722                 this.step = step;
3723                 this.sym = sym;
3724                 this.details = details;
3725                 this.mtype = mtype;
3726             }
3727 
3728             @Override
3729             public boolean equals(Object o) {
3730                 if (o instanceof Candidate) {
3731                     Symbol s1 = this.sym;
3732                     Symbol s2 = ((Candidate)o).sym;
3733                     if  ((s1 != s2 &&
3734                             (s1.overrides(s2, s1.owner.type.tsym, types, false) ||
3735                             (s2.overrides(s1, s2.owner.type.tsym, types, false)))) ||
3736                             ((s1.isConstructor() || s2.isConstructor()) && s1.owner != s2.owner))
3737                         return true;
3738                 }
3739                 return false;
3740             }
3741 
3742             boolean isApplicable() {
3743                 return mtype != null;
3744             }
3745         }
3746 
3747         DeferredAttr.AttrMode attrMode() {
3748             return attrMode;
3749         }
3750 
3751         boolean internal() {
3752             return internalResolution;
3753         }
3754     }
3755 
3756     MethodResolutionContext currentResolutionContext = null;
3757 }