1 /*
   2  * Copyright (c) 1999, 2012, 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.Type.*;
  31 import com.sun.tools.javac.code.Symbol.*;
  32 import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
  33 import com.sun.tools.javac.file.JavacFileManager;
  34 import com.sun.tools.javac.jvm.*;
  35 import com.sun.tools.javac.tree.*;
  36 import com.sun.tools.javac.tree.JCTree.*;
  37 import com.sun.tools.javac.util.*;
  38 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
  39 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  40 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
  41 import javax.tools.JavaFileManager;
  42 
  43 import java.util.Arrays;
  44 import java.util.Collection;
  45 import java.util.EnumMap;
  46 import java.util.EnumSet;
  47 import java.util.HashSet;
  48 import java.util.Map;
  49 import java.util.Set;
  50 
  51 import javax.lang.model.element.ElementVisitor;
  52 
  53 import static com.sun.tools.javac.code.Flags.*;
  54 import static com.sun.tools.javac.code.Flags.BLOCK;
  55 import static com.sun.tools.javac.code.Kinds.*;
  56 import static com.sun.tools.javac.code.Kinds.ERRONEOUS;
  57 import static com.sun.tools.javac.code.TypeTags.*;
  58 import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
  59 import static com.sun.tools.javac.tree.JCTree.Tag.*;
  60 import javax.tools.JavaFileObject;
  61 
  62 /** Helper class for name resolution, used mostly by the attribution phase.
  63  *
  64  *  <p><b>This is NOT part of any supported API.
  65  *  If you write code that depends on this, you do so at your own risk.
  66  *  This code and its internal interfaces are subject to change or
  67  *  deletion without notice.</b>
  68  */
  69 public class Resolve {
  70     protected static final Context.Key<Resolve> resolveKey =
  71         new Context.Key<Resolve>();
  72 
  73     Names names;
  74     Log log;
  75     Symtab syms;
  76     Check chk;
  77     Infer infer;
  78     JavacFileManager fm;
  79     Lint lint;
  80     ClassReader reader;
  81     TreeInfo treeinfo;
  82     Types types;
  83     JCDiagnostic.Factory diags;
  84     public final boolean boxingEnabled; // = source.allowBoxing();
  85     public final boolean varargsEnabled; // = source.allowVarargs();
  86     public final boolean allowMethodHandles;
  87     private final boolean debugResolve;
  88     final EnumSet<VerboseResolutionMode> verboseResolutionMode;
  89 
  90     Scope polymorphicSignatureScope;
  91 
  92     protected Resolve(Context context) {
  93         context.put(resolveKey, this);
  94         syms = Symtab.instance(context);
  95 
  96         varNotFound = new
  97             SymbolNotFoundError(ABSENT_VAR);
  98         wrongMethod = new
  99             InapplicableSymbolError();
 100         wrongMethods = new
 101             InapplicableSymbolsError();
 102         methodNotFound = new
 103             SymbolNotFoundError(ABSENT_MTH);
 104         typeNotFound = new
 105             SymbolNotFoundError(ABSENT_TYP);
 106 
 107         names = Names.instance(context);
 108         log = Log.instance(context);
 109         chk = Check.instance(context);
 110         infer = Infer.instance(context);
 111         if (context.get(JavaFileManager.class) instanceof JavacFileManager) {
 112             fm = (JavacFileManager)context.get(JavaFileManager.class);
 113         } else {
 114             fm = null;
 115         }
 116         lint = Lint.instance(context);
 117         reader = ClassReader.instance(context);
 118         treeinfo = TreeInfo.instance(context);
 119         types = Types.instance(context);
 120         diags = JCDiagnostic.Factory.instance(context);
 121         Source source = Source.instance(context);
 122         boxingEnabled = source.allowBoxing();
 123         varargsEnabled = source.allowVarargs();
 124         Options options = Options.instance(context);
 125         debugResolve = options.isSet("debugresolve");
 126         verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
 127         Target target = Target.instance(context);
 128         allowMethodHandles = target.hasMethodHandles();
 129         polymorphicSignatureScope = new Scope(syms.noSymbol);
 130 
 131         inapplicableMethodException = new InapplicableMethodException(diags);
 132     }
 133 
 134     /** error symbols, which are returned when resolution fails
 135      */
 136     private final SymbolNotFoundError varNotFound;
 137     private final InapplicableSymbolError wrongMethod;
 138     private final InapplicableSymbolsError wrongMethods;
 139     private final SymbolNotFoundError methodNotFound;
 140     private final SymbolNotFoundError typeNotFound;
 141 
 142     public static Resolve instance(Context context) {
 143         Resolve instance = context.get(resolveKey);
 144         if (instance == null)
 145             instance = new Resolve(context);
 146         return instance;
 147     }
 148 
 149     // <editor-fold defaultstate="collapsed" desc="Verbose resolution diagnostics support">
 150     enum VerboseResolutionMode {
 151         SUCCESS("success"),
 152         FAILURE("failure"),
 153         APPLICABLE("applicable"),
 154         INAPPLICABLE("inapplicable"),
 155         DEFERRED_INST("deferred-inference"),
 156         PREDEF("predef"),
 157         OBJECT_INIT("object-init"),
 158         INTERNAL("internal");
 159 
 160         String opt;
 161 
 162         private VerboseResolutionMode(String opt) {
 163             this.opt = opt;
 164         }
 165 
 166         static EnumSet<VerboseResolutionMode> getVerboseResolutionMode(Options opts) {
 167             String s = opts.get("verboseResolution");
 168             EnumSet<VerboseResolutionMode> res = EnumSet.noneOf(VerboseResolutionMode.class);
 169             if (s == null) return res;
 170             if (s.contains("all")) {
 171                 res = EnumSet.allOf(VerboseResolutionMode.class);
 172             }
 173             Collection<String> args = Arrays.asList(s.split(","));
 174             for (VerboseResolutionMode mode : values()) {
 175                 if (args.contains(mode.opt)) {
 176                     res.add(mode);
 177                 } else if (args.contains("-" + mode.opt)) {
 178                     res.remove(mode);
 179                 }
 180             }
 181             return res;
 182         }
 183     }
 184 
 185     void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site,
 186             List<Type> argtypes, List<Type> typeargtypes, Symbol bestSoFar) {
 187         boolean success = bestSoFar.kind < ERRONEOUS;
 188 
 189         if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) {
 190             return;
 191         } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) {
 192             return;
 193         }
 194 
 195         if (bestSoFar.name == names.init &&
 196                 bestSoFar.owner == syms.objectType.tsym &&
 197                 !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) {
 198             return; //skip diags for Object constructor resolution
 199         } else if (site == syms.predefClass.type &&
 200                 !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) {
 201             return; //skip spurious diags for predef symbols (i.e. operators)
 202         } else if (currentResolutionContext.internalResolution &&
 203                 !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) {
 204             return;
 205         }
 206 
 207         int pos = 0;
 208         int mostSpecificPos = -1;
 209         ListBuffer<JCDiagnostic> subDiags = ListBuffer.lb();
 210         for (Candidate c : currentResolutionContext.candidates) {
 211             if (currentResolutionContext.step != c.step ||
 212                     (c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE)) ||
 213                     (!c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))) {
 214                 continue;
 215             } else {
 216                 subDiags.append(c.isApplicable() ?
 217                         getVerboseApplicableCandidateDiag(pos, c.sym, c.mtype) :
 218                         getVerboseInapplicableCandidateDiag(pos, c.sym, c.details));
 219                 if (c.sym == bestSoFar)
 220                     mostSpecificPos = pos;
 221                 pos++;
 222             }
 223         }
 224         String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1";
 225         JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name,
 226                 site.tsym, mostSpecificPos, currentResolutionContext.step,
 227                 methodArguments(argtypes), methodArguments(typeargtypes));
 228         JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList());
 229         log.report(d);
 230     }
 231 
 232     JCDiagnostic getVerboseApplicableCandidateDiag(int pos, Symbol sym, Type inst) {
 233         JCDiagnostic subDiag = null;
 234         if (inst.getReturnType().tag == FORALL) {
 235             Type diagType = types.createMethodTypeWithReturn(inst.asMethodType(),
 236                                                             ((ForAll)inst.getReturnType()).qtype);
 237             subDiag = diags.fragment("partial.inst.sig", diagType);
 238         } else if (sym.type.tag == FORALL) {
 239             subDiag = diags.fragment("full.inst.sig", inst.asMethodType());
 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     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.tag == 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                     s2.isPolymorphicSignatureGeneric() ||
 410                     !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym)));
 411         }
 412     }
 413     //where
 414         /** Is given protected symbol accessible if it is selected from given site
 415          *  and the selection takes place in given class?
 416          *  @param sym     The symbol with protected access
 417          *  @param c       The class where the access takes place
 418          *  @site          The type of the qualifier
 419          */
 420         private
 421         boolean isProtectedAccessible(Symbol sym, ClassSymbol c, Type site) {
 422             while (c != null &&
 423                    !(c.isSubClass(sym.owner, types) &&
 424                      (c.flags() & INTERFACE) == 0 &&
 425                      // In JLS 2e 6.6.2.1, the subclass restriction applies
 426                      // only to instance fields and methods -- types are excluded
 427                      // regardless of whether they are declared 'static' or not.
 428                      ((sym.flags() & STATIC) != 0 || sym.kind == TYP || site.tsym.isSubClass(c, types))))
 429                 c = c.owner.enclClass();
 430             return c != null;
 431         }
 432 
 433     /** Try to instantiate the type of a method so that it fits
 434      *  given type arguments and argument types. If succesful, return
 435      *  the method's instantiated type, else return null.
 436      *  The instantiation will take into account an additional leading
 437      *  formal parameter if the method is an instance method seen as a member
 438      *  of un underdetermined site In this case, we treat site as an additional
 439      *  parameter and the parameters of the class containing the method as
 440      *  additional type variables that get instantiated.
 441      *
 442      *  @param env         The current environment
 443      *  @param site        The type of which the method is a member.
 444      *  @param m           The method symbol.
 445      *  @param argtypes    The invocation's given value arguments.
 446      *  @param typeargtypes    The invocation's given type arguments.
 447      *  @param allowBoxing Allow boxing conversions of arguments.
 448      *  @param useVarargs Box trailing arguments into an array for varargs.
 449      */
 450     Type rawInstantiate(Env<AttrContext> env,
 451                         Type site,
 452                         Symbol m,
 453                         List<Type> argtypes,
 454                         List<Type> typeargtypes,
 455                         boolean allowBoxing,
 456                         boolean useVarargs,
 457                         Warner warn)
 458         throws Infer.InferenceException {
 459         boolean polymorphicSignature = m.isPolymorphicSignatureGeneric() && allowMethodHandles;
 460         if (useVarargs && (m.flags() & VARARGS) == 0)
 461             throw inapplicableMethodException.setMessage();
 462         Type mt = types.memberType(site, m);
 463 
 464         // tvars is the list of formal type variables for which type arguments
 465         // need to inferred.
 466         List<Type> tvars = null;
 467         if (env.info.tvars != null) {
 468             tvars = types.newInstances(env.info.tvars);
 469             mt = types.subst(mt, env.info.tvars, tvars);
 470         }
 471         if (typeargtypes == null) typeargtypes = List.nil();
 472         if (mt.tag != FORALL && typeargtypes.nonEmpty()) {
 473             // This is not a polymorphic method, but typeargs are supplied
 474             // which is fine, see JLS 15.12.2.1
 475         } else if (mt.tag == FORALL && typeargtypes.nonEmpty()) {
 476             ForAll pmt = (ForAll) mt;
 477             if (typeargtypes.length() != pmt.tvars.length())
 478                 throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args
 479             // Check type arguments are within bounds
 480             List<Type> formals = pmt.tvars;
 481             List<Type> actuals = typeargtypes;
 482             while (formals.nonEmpty() && actuals.nonEmpty()) {
 483                 List<Type> bounds = types.subst(types.getBounds((TypeVar)formals.head),
 484                                                 pmt.tvars, typeargtypes);
 485                 for (; bounds.nonEmpty(); bounds = bounds.tail)
 486                     if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn))
 487                         throw inapplicableMethodException.setMessage("explicit.param.do.not.conform.to.bounds",actuals.head, bounds);
 488                 formals = formals.tail;
 489                 actuals = actuals.tail;
 490             }
 491             mt = types.subst(pmt.qtype, pmt.tvars, typeargtypes);
 492         } else if (mt.tag == FORALL) {
 493             ForAll pmt = (ForAll) mt;
 494             List<Type> tvars1 = types.newInstances(pmt.tvars);
 495             tvars = tvars.appendList(tvars1);
 496             mt = types.subst(pmt.qtype, pmt.tvars, tvars1);
 497         }
 498 
 499         // find out whether we need to go the slow route via infer
 500         boolean instNeeded = tvars.tail != null || /*inlined: tvars.nonEmpty()*/
 501                 polymorphicSignature;
 502         for (List<Type> l = argtypes;
 503              l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded;
 504              l = l.tail) {
 505             if (l.head.tag == FORALL) instNeeded = true;
 506         }
 507 
 508         if (instNeeded)
 509             return polymorphicSignature ?
 510                 infer.instantiatePolymorphicSignatureInstance(env, site, m.name, (MethodSymbol)m, argtypes) :
 511                 infer.instantiateMethod(env,
 512                                     tvars,
 513                                     (MethodType)mt,
 514                                     m,
 515                                     argtypes,
 516                                     allowBoxing,
 517                                     useVarargs,
 518                                     warn);
 519 
 520         checkRawArgumentsAcceptable(env, argtypes, mt.getParameterTypes(),
 521                                 allowBoxing, useVarargs, warn);
 522         return mt;
 523     }
 524 
 525     /** Same but returns null instead throwing a NoInstanceException
 526      */
 527     Type instantiate(Env<AttrContext> env,
 528                      Type site,
 529                      Symbol m,
 530                      List<Type> argtypes,
 531                      List<Type> typeargtypes,
 532                      boolean allowBoxing,
 533                      boolean useVarargs,
 534                      Warner warn) {
 535         try {
 536             return rawInstantiate(env, site, m, argtypes, typeargtypes,
 537                                   allowBoxing, useVarargs, warn);
 538         } catch (InapplicableMethodException ex) {
 539             return null;
 540         }
 541     }
 542 
 543     /** Check if a parameter list accepts a list of args.
 544      */
 545     boolean argumentsAcceptable(Env<AttrContext> env,
 546                                 List<Type> argtypes,
 547                                 List<Type> formals,
 548                                 boolean allowBoxing,
 549                                 boolean useVarargs,
 550                                 Warner warn) {
 551         try {
 552             checkRawArgumentsAcceptable(env, argtypes, formals, allowBoxing, useVarargs, warn);
 553             return true;
 554         } catch (InapplicableMethodException ex) {
 555             return false;
 556         }
 557     }
 558     /**
 559      * A check handler is used by the main method applicability routine in order
 560      * to handle specific method applicability failures. It is assumed that a class
 561      * implementing this interface should throw exceptions that are a subtype of
 562      * InapplicableMethodException (see below). Such exception will terminate the
 563      * method applicability check and propagate important info outwards (for the
 564      * purpose of generating better diagnostics).
 565      */
 566     interface MethodCheckHandler {
 567         /* The number of actuals and formals differ */
 568         InapplicableMethodException arityMismatch();
 569         /* An actual argument type does not conform to the corresponding formal type */
 570         InapplicableMethodException argumentMismatch(boolean varargs, Type found, Type expected);
 571         /* The element type of a varargs is not accessible in the current context */
 572         InapplicableMethodException inaccessibleVarargs(Symbol location, Type expected);
 573     }
 574 
 575     /**
 576      * Basic method check handler used within Resolve - all methods end up
 577      * throwing InapplicableMethodException; a diagnostic fragment that describes
 578      * the cause as to why the method is not applicable is set on the exception
 579      * before it is thrown.
 580      */
 581     MethodCheckHandler resolveHandler = new MethodCheckHandler() {
 582             public InapplicableMethodException arityMismatch() {
 583                 return inapplicableMethodException.setMessage("arg.length.mismatch");
 584             }
 585             public InapplicableMethodException argumentMismatch(boolean varargs, Type found, Type expected) {
 586                 String key = varargs ?
 587                         "varargs.argument.mismatch" :
 588                         "no.conforming.assignment.exists";
 589                 return inapplicableMethodException.setMessage(key,
 590                         found, expected);
 591             }
 592             public InapplicableMethodException inaccessibleVarargs(Symbol location, Type expected) {
 593                 return inapplicableMethodException.setMessage("inaccessible.varargs.type",
 594                         expected, Kinds.kindName(location), location);
 595             }
 596     };
 597 
 598     void checkRawArgumentsAcceptable(Env<AttrContext> env,
 599                                 List<Type> argtypes,
 600                                 List<Type> formals,
 601                                 boolean allowBoxing,
 602                                 boolean useVarargs,
 603                                 Warner warn) {
 604         checkRawArgumentsAcceptable(env, List.<Type>nil(), argtypes, formals,
 605                 allowBoxing, useVarargs, warn, resolveHandler);
 606     }
 607 
 608     /**
 609      * Main method applicability routine. Given a list of actual types A,
 610      * a list of formal types F, determines whether the types in A are
 611      * compatible (by method invocation conversion) with the types in F.
 612      *
 613      * Since this routine is shared between overload resolution and method
 614      * type-inference, it is crucial that actual types are converted to the
 615      * corresponding 'undet' form (i.e. where inference variables are replaced
 616      * with undetvars) so that constraints can be propagated and collected.
 617      *
 618      * Moreover, if one or more types in A is a poly type, this routine calls
 619      * Infer.instantiateArg in order to complete the poly type (this might involve
 620      * deferred attribution).
 621      *
 622      * A method check handler (see above) is used in order to report errors.
 623      */
 624     List<Type> checkRawArgumentsAcceptable(Env<AttrContext> env,
 625                                 List<Type> undetvars,
 626                                 List<Type> argtypes,
 627                                 List<Type> formals,
 628                                 boolean allowBoxing,
 629                                 boolean useVarargs,
 630                                 Warner warn,
 631                                 MethodCheckHandler handler) {
 632         Type varargsFormal = useVarargs ? formals.last() : null;
 633         ListBuffer<Type> checkedArgs = ListBuffer.lb();
 634 
 635         if (varargsFormal == null &&
 636                 argtypes.size() != formals.size()) {
 637             throw handler.arityMismatch(); // not enough args
 638         }
 639 
 640         while (argtypes.nonEmpty() && formals.head != varargsFormal) {
 641             Type undetFormal = infer.asUndetType(formals.head, undetvars);
 642             Type capturedActual = types.capture(argtypes.head);
 643             boolean works = allowBoxing ?
 644                     types.isConvertible(capturedActual, undetFormal, warn) :
 645                     types.isSubtypeUnchecked(capturedActual, undetFormal, warn);
 646             if (!works) {
 647                 throw handler.argumentMismatch(false, argtypes.head, formals.head);
 648             }
 649             checkedArgs.append(capturedActual);
 650             argtypes = argtypes.tail;
 651             formals = formals.tail;
 652         }
 653 
 654         if (formals.head != varargsFormal) {
 655             throw handler.arityMismatch(); // not enough args
 656         }
 657 
 658         if (useVarargs) {
 659             //note: if applicability check is triggered by most specific test,
 660             //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
 661             Type elt = types.elemtype(varargsFormal);
 662             Type eltUndet = infer.asUndetType(elt, undetvars);
 663             while (argtypes.nonEmpty()) {
 664                 Type capturedActual = types.capture(argtypes.head);
 665                 if (!types.isConvertible(capturedActual, eltUndet, warn)) {
 666                     throw handler.argumentMismatch(true, argtypes.head, elt);
 667                 }
 668                 checkedArgs.append(capturedActual);
 669                 argtypes = argtypes.tail;
 670             }
 671             //check varargs element type accessibility
 672             if (undetvars.isEmpty() && !isAccessible(env, elt)) {
 673                 Symbol location = env.enclClass.sym;
 674                 throw handler.inaccessibleVarargs(location, elt);
 675             }
 676         }
 677         return checkedArgs.toList();
 678     }
 679     // where
 680         public static class InapplicableMethodException extends RuntimeException {
 681             private static final long serialVersionUID = 0;
 682 
 683             JCDiagnostic diagnostic;
 684             JCDiagnostic.Factory diags;
 685 
 686             InapplicableMethodException(JCDiagnostic.Factory diags) {
 687                 this.diagnostic = null;
 688                 this.diags = diags;
 689             }
 690             InapplicableMethodException setMessage() {
 691                 this.diagnostic = null;
 692                 return this;
 693             }
 694             InapplicableMethodException setMessage(String key) {
 695                 this.diagnostic = key != null ? diags.fragment(key) : null;
 696                 return this;
 697             }
 698             InapplicableMethodException setMessage(String key, Object... args) {
 699                 this.diagnostic = key != null ? diags.fragment(key, args) : null;
 700                 return this;
 701             }
 702             InapplicableMethodException setMessage(JCDiagnostic diag) {
 703                 this.diagnostic = diag;
 704                 return this;
 705             }
 706 
 707             public JCDiagnostic getDiagnostic() {
 708                 return diagnostic;
 709             }
 710         }
 711         private final InapplicableMethodException inapplicableMethodException;
 712 
 713 /* ***************************************************************************
 714  *  Symbol lookup
 715  *  the following naming conventions for arguments are used
 716  *
 717  *       env      is the environment where the symbol was mentioned
 718  *       site     is the type of which the symbol is a member
 719  *       name     is the symbol's name
 720  *                if no arguments are given
 721  *       argtypes are the value arguments, if we search for a method
 722  *
 723  *  If no symbol was found, a ResolveError detailing the problem is returned.
 724  ****************************************************************************/
 725 
 726     /** Find field. Synthetic fields are always skipped.
 727      *  @param env     The current environment.
 728      *  @param site    The original type from where the selection takes place.
 729      *  @param name    The name of the field.
 730      *  @param c       The class to search for the field. This is always
 731      *                 a superclass or implemented interface of site's class.
 732      */
 733     Symbol findField(Env<AttrContext> env,
 734                      Type site,
 735                      Name name,
 736                      TypeSymbol c) {
 737         while (c.type.tag == TYPEVAR)
 738             c = c.type.getUpperBound().tsym;
 739         Symbol bestSoFar = varNotFound;
 740         Symbol sym;
 741         Scope.Entry e = c.members().lookup(name);
 742         while (e.scope != null) {
 743             if (e.sym.kind == VAR && (e.sym.flags_field & SYNTHETIC) == 0) {
 744                 return isAccessible(env, site, e.sym)
 745                     ? e.sym : new AccessError(env, site, e.sym);
 746             }
 747             e = e.next();
 748         }
 749         Type st = types.supertype(c.type);
 750         if (st != null && (st.tag == CLASS || st.tag == TYPEVAR)) {
 751             sym = findField(env, site, name, st.tsym);
 752             if (sym.kind < bestSoFar.kind) bestSoFar = sym;
 753         }
 754         for (List<Type> l = types.interfaces(c.type);
 755              bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
 756              l = l.tail) {
 757             sym = findField(env, site, name, l.head.tsym);
 758             if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS &&
 759                 sym.owner != bestSoFar.owner)
 760                 bestSoFar = new AmbiguityError(bestSoFar, sym);
 761             else if (sym.kind < bestSoFar.kind)
 762                 bestSoFar = sym;
 763         }
 764         return bestSoFar;
 765     }
 766 
 767     /** Resolve a field identifier, throw a fatal error if not found.
 768      *  @param pos       The position to use for error reporting.
 769      *  @param env       The environment current at the method invocation.
 770      *  @param site      The type of the qualifying expression, in which
 771      *                   identifier is searched.
 772      *  @param name      The identifier's name.
 773      */
 774     public VarSymbol resolveInternalField(DiagnosticPosition pos, Env<AttrContext> env,
 775                                           Type site, Name name) {
 776         Symbol sym = findField(env, site, name, site.tsym);
 777         if (sym.kind == VAR) return (VarSymbol)sym;
 778         else throw new FatalError(
 779                  diags.fragment("fatal.err.cant.locate.field",
 780                                 name));
 781     }
 782 
 783     /** Find unqualified variable or field with given name.
 784      *  Synthetic fields always skipped.
 785      *  @param env     The current environment.
 786      *  @param name    The name of the variable or field.
 787      */
 788     Symbol findVar(Env<AttrContext> env, Name name) {
 789         Symbol bestSoFar = varNotFound;
 790         Symbol sym;
 791         Env<AttrContext> env1 = env;
 792         boolean staticOnly = false;
 793         while (env1.outer != null) {
 794             if (isStatic(env1)) staticOnly = true;
 795             Scope.Entry e = env1.info.scope.lookup(name);
 796             while (e.scope != null &&
 797                    (e.sym.kind != VAR ||
 798                     (e.sym.flags_field & SYNTHETIC) != 0))
 799                 e = e.next();
 800             sym = (e.scope != null)
 801                 ? e.sym
 802                 : findField(
 803                     env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
 804             if (sym.exists()) {
 805                 if (staticOnly &&
 806                     sym.kind == VAR &&
 807                     sym.owner.kind == TYP &&
 808                     (sym.flags() & STATIC) == 0)
 809                     return new StaticError(sym);
 810                 else
 811                     return sym;
 812             } else if (sym.kind < bestSoFar.kind) {
 813                 bestSoFar = sym;
 814             }
 815 
 816             if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
 817             env1 = env1.outer;
 818         }
 819 
 820         sym = findField(env, syms.predefClass.type, name, syms.predefClass);
 821         if (sym.exists())
 822             return sym;
 823         if (bestSoFar.exists())
 824             return bestSoFar;
 825 
 826         Scope.Entry e = env.toplevel.namedImportScope.lookup(name);
 827         for (; e.scope != null; e = e.next()) {
 828             sym = e.sym;
 829             Type origin = e.getOrigin().owner.type;
 830             if (sym.kind == VAR) {
 831                 if (e.sym.owner.type != origin)
 832                     sym = sym.clone(e.getOrigin().owner);
 833                 return isAccessible(env, origin, sym)
 834                     ? sym : new AccessError(env, origin, sym);
 835             }
 836         }
 837 
 838         Symbol origin = null;
 839         e = env.toplevel.starImportScope.lookup(name);
 840         for (; e.scope != null; e = e.next()) {
 841             sym = e.sym;
 842             if (sym.kind != VAR)
 843                 continue;
 844             // invariant: sym.kind == VAR
 845             if (bestSoFar.kind < AMBIGUOUS && sym.owner != bestSoFar.owner)
 846                 return new AmbiguityError(bestSoFar, sym);
 847             else if (bestSoFar.kind >= VAR) {
 848                 origin = e.getOrigin().owner;
 849                 bestSoFar = isAccessible(env, origin.type, sym)
 850                     ? sym : new AccessError(env, origin.type, sym);
 851             }
 852         }
 853         if (bestSoFar.kind == VAR && bestSoFar.owner.type != origin.type)
 854             return bestSoFar.clone(origin);
 855         else
 856             return bestSoFar;
 857     }
 858 
 859     Warner noteWarner = new Warner();
 860 
 861     /** Select the best method for a call site among two choices.
 862      *  @param env              The current environment.
 863      *  @param site             The original type from where the
 864      *                          selection takes place.
 865      *  @param argtypes         The invocation's value arguments,
 866      *  @param typeargtypes     The invocation's type arguments,
 867      *  @param sym              Proposed new best match.
 868      *  @param bestSoFar        Previously found best match.
 869      *  @param allowBoxing Allow boxing conversions of arguments.
 870      *  @param useVarargs Box trailing arguments into an array for varargs.
 871      */
 872     @SuppressWarnings("fallthrough")
 873     Symbol selectBest(Env<AttrContext> env,
 874                       Type site,
 875                       List<Type> argtypes,
 876                       List<Type> typeargtypes,
 877                       Symbol sym,
 878                       Symbol bestSoFar,
 879                       boolean allowBoxing,
 880                       boolean useVarargs,
 881                       boolean operator) {
 882         if (sym.kind == ERR) return bestSoFar;
 883         if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar;
 884         Assert.check(sym.kind < AMBIGUOUS);
 885         try {
 886             Type mt = rawInstantiate(env, site, sym, argtypes, typeargtypes,
 887                                allowBoxing, useVarargs, Warner.noWarnings);
 888             if (!operator)
 889                 currentResolutionContext.addApplicableCandidate(sym, mt);
 890         } catch (InapplicableMethodException ex) {
 891             if (!operator)
 892                 currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic());
 893             switch (bestSoFar.kind) {
 894             case ABSENT_MTH:
 895                 return wrongMethod;
 896             case WRONG_MTH:
 897                 if (operator) return bestSoFar;
 898             case WRONG_MTHS:
 899                 return wrongMethods;
 900             default:
 901                 return bestSoFar;
 902             }
 903         }
 904         if (!isAccessible(env, site, sym)) {
 905             return (bestSoFar.kind == ABSENT_MTH)
 906                 ? new AccessError(env, site, sym)
 907                 : bestSoFar;
 908         }
 909         return (bestSoFar.kind > AMBIGUOUS)
 910             ? sym
 911             : mostSpecific(sym, bestSoFar, env, site,
 912                            allowBoxing && operator, useVarargs);
 913     }
 914 
 915     /* Return the most specific of the two methods for a call,
 916      *  given that both are accessible and applicable.
 917      *  @param m1               A new candidate for most specific.
 918      *  @param m2               The previous most specific candidate.
 919      *  @param env              The current environment.
 920      *  @param site             The original type from where the selection
 921      *                          takes place.
 922      *  @param allowBoxing Allow boxing conversions of arguments.
 923      *  @param useVarargs Box trailing arguments into an array for varargs.
 924      */
 925     Symbol mostSpecific(Symbol m1,
 926                         Symbol m2,
 927                         Env<AttrContext> env,
 928                         final Type site,
 929                         boolean allowBoxing,
 930                         boolean useVarargs) {
 931         switch (m2.kind) {
 932         case MTH:
 933             if (m1 == m2) return m1;
 934             boolean m1SignatureMoreSpecific = signatureMoreSpecific(env, site, m1, m2, allowBoxing, useVarargs);
 935             boolean m2SignatureMoreSpecific = signatureMoreSpecific(env, site, m2, m1, allowBoxing, useVarargs);
 936             if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) {
 937                 Type mt1 = types.memberType(site, m1);
 938                 Type mt2 = types.memberType(site, m2);
 939                 if (!types.overrideEquivalent(mt1, mt2))
 940                     return ambiguityError(m1, m2);
 941 
 942                 // same signature; select (a) the non-bridge method, or
 943                 // (b) the one that overrides the other, or (c) the concrete
 944                 // one, or (d) merge both abstract signatures
 945                 if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE))
 946                     return ((m1.flags() & BRIDGE) != 0) ? m2 : m1;
 947 
 948                 // if one overrides or hides the other, use it
 949                 TypeSymbol m1Owner = (TypeSymbol)m1.owner;
 950                 TypeSymbol m2Owner = (TypeSymbol)m2.owner;
 951                 if (types.asSuper(m1Owner.type, m2Owner) != null &&
 952                     ((m1.owner.flags_field & INTERFACE) == 0 ||
 953                      (m2.owner.flags_field & INTERFACE) != 0) &&
 954                     m1.overrides(m2, m1Owner, types, false))
 955                     return m1;
 956                 if (types.asSuper(m2Owner.type, m1Owner) != null &&
 957                     ((m2.owner.flags_field & INTERFACE) == 0 ||
 958                      (m1.owner.flags_field & INTERFACE) != 0) &&
 959                     m2.overrides(m1, m2Owner, types, false))
 960                     return m2;
 961                 boolean m1Abstract = (m1.flags() & ABSTRACT) != 0;
 962                 boolean m2Abstract = (m2.flags() & ABSTRACT) != 0;
 963                 if (m1Abstract && !m2Abstract) return m2;
 964                 if (m2Abstract && !m1Abstract) return m1;
 965                 // both abstract or both concrete
 966                 if (!m1Abstract && !m2Abstract)
 967                     return ambiguityError(m1, m2);
 968                 // check that both signatures have the same erasure
 969                 if (!types.isSameTypes(m1.erasure(types).getParameterTypes(),
 970                                        m2.erasure(types).getParameterTypes()))
 971                     return ambiguityError(m1, m2);
 972                 // both abstract, neither overridden; merge throws clause and result type
 973                 Type mst = mostSpecificReturnType(mt1, mt2);
 974                 if (mst == null) {
 975                     // Theoretically, this can't happen, but it is possible
 976                     // due to error recovery or mixing incompatible class files
 977                     return ambiguityError(m1, m2);
 978                 }
 979                 Symbol mostSpecific = mst == mt1 ? m1 : m2;
 980                 List<Type> allThrown = chk.intersect(mt1.getThrownTypes(), mt2.getThrownTypes());
 981                 Type newSig = types.createMethodTypeWithThrown(mostSpecific.type, allThrown);
 982                 MethodSymbol result = new MethodSymbol(
 983                         mostSpecific.flags(),
 984                         mostSpecific.name,
 985                         newSig,
 986                         mostSpecific.owner) {
 987                     @Override
 988                     public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
 989                         if (origin == site.tsym)
 990                             return this;
 991                         else
 992                             return super.implementation(origin, types, checkResult);
 993                     }
 994                 };
 995                 return result;
 996             }
 997             if (m1SignatureMoreSpecific) return m1;
 998             if (m2SignatureMoreSpecific) return m2;
 999             return ambiguityError(m1, m2);
1000         case AMBIGUOUS:
1001             AmbiguityError e = (AmbiguityError)m2;
1002             Symbol err1 = mostSpecific(m1, e.sym, env, site, allowBoxing, useVarargs);
1003             Symbol err2 = mostSpecific(m1, e.sym2, env, site, allowBoxing, useVarargs);
1004             if (err1 == err2) return err1;
1005             if (err1 == e.sym && err2 == e.sym2) return m2;
1006             if (err1 instanceof AmbiguityError &&
1007                 err2 instanceof AmbiguityError &&
1008                 ((AmbiguityError)err1).sym == ((AmbiguityError)err2).sym)
1009                 return ambiguityError(m1, m2);
1010             else
1011                 return ambiguityError(err1, err2);
1012         default:
1013             throw new AssertionError();
1014         }
1015     }
1016     //where
1017     private boolean signatureMoreSpecific(Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean allowBoxing, boolean useVarargs) {
1018         noteWarner.clear();
1019         Type mtype1 = types.memberType(site, adjustVarargs(m1, m2, useVarargs));
1020         Type mtype2 = instantiate(env, site, adjustVarargs(m2, m1, useVarargs),
1021                 types.lowerBoundArgtypes(mtype1), null,
1022                 allowBoxing, false, noteWarner);
1023         return mtype2 != null &&
1024                 !noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
1025     }
1026     //where
1027     private Symbol adjustVarargs(Symbol to, Symbol from, boolean useVarargs) {
1028         List<Type> fromArgs = from.type.getParameterTypes();
1029         List<Type> toArgs = to.type.getParameterTypes();
1030         if (useVarargs &&
1031                 (from.flags() & VARARGS) != 0 &&
1032                 (to.flags() & VARARGS) != 0) {
1033             Type varargsTypeFrom = fromArgs.last();
1034             Type varargsTypeTo = toArgs.last();
1035             ListBuffer<Type> args = ListBuffer.lb();
1036             if (toArgs.length() < fromArgs.length()) {
1037                 //if we are checking a varargs method 'from' against another varargs
1038                 //method 'to' (where arity of 'to' < arity of 'from') then expand signature
1039                 //of 'to' to 'fit' arity of 'from' (this means adding fake formals to 'to'
1040                 //until 'to' signature has the same arity as 'from')
1041                 while (fromArgs.head != varargsTypeFrom) {
1042                     args.append(toArgs.head == varargsTypeTo ? types.elemtype(varargsTypeTo) : toArgs.head);
1043                     fromArgs = fromArgs.tail;
1044                     toArgs = toArgs.head == varargsTypeTo ?
1045                         toArgs :
1046                         toArgs.tail;
1047                 }
1048             } else {
1049                 //formal argument list is same as original list where last
1050                 //argument (array type) is removed
1051                 args.appendList(toArgs.reverse().tail.reverse());
1052             }
1053             //append varargs element type as last synthetic formal
1054             args.append(types.elemtype(varargsTypeTo));
1055             Type mtype = types.createMethodTypeWithParameters(to.type, args.toList());
1056             return new MethodSymbol(to.flags_field & ~VARARGS, to.name, mtype, to.owner);
1057         } else {
1058             return to;
1059         }
1060     }
1061     //where
1062     Type mostSpecificReturnType(Type mt1, Type mt2) {
1063         Type rt1 = mt1.getReturnType();
1064         Type rt2 = mt2.getReturnType();
1065 
1066         if (mt1.tag == FORALL && mt2.tag == FORALL) {
1067             //if both are generic methods, adjust return type ahead of subtyping check
1068             rt1 = types.subst(rt1, mt1.getTypeArguments(), mt2.getTypeArguments());
1069         }
1070         //first use subtyping, then return type substitutability
1071         if (types.isSubtype(rt1, rt2)) {
1072             return mt1;
1073         } else if (types.isSubtype(rt2, rt1)) {
1074             return mt2;
1075         } else if (types.returnTypeSubstitutable(mt1, mt2)) {
1076             return mt1;
1077         } else if (types.returnTypeSubstitutable(mt2, mt1)) {
1078             return mt2;
1079         } else {
1080             return null;
1081         }
1082     }
1083     //where
1084     Symbol ambiguityError(Symbol m1, Symbol m2) {
1085         if (((m1.flags() | m2.flags()) & CLASH) != 0) {
1086             return (m1.flags() & CLASH) == 0 ? m1 : m2;
1087         } else {
1088             return new AmbiguityError(m1, m2);
1089         }
1090     }
1091 
1092     /** Find best qualified method matching given name, type and value
1093      *  arguments.
1094      *  @param env       The current environment.
1095      *  @param site      The original type from where the selection
1096      *                   takes place.
1097      *  @param name      The method's name.
1098      *  @param argtypes  The method's value arguments.
1099      *  @param typeargtypes The method's type arguments
1100      *  @param allowBoxing Allow boxing conversions of arguments.
1101      *  @param useVarargs Box trailing arguments into an array for varargs.
1102      */
1103     Symbol findMethod(Env<AttrContext> env,
1104                       Type site,
1105                       Name name,
1106                       List<Type> argtypes,
1107                       List<Type> typeargtypes,
1108                       boolean allowBoxing,
1109                       boolean useVarargs,
1110                       boolean operator) {
1111         Symbol bestSoFar = methodNotFound;
1112         bestSoFar = findMethod(env,
1113                           site,
1114                           name,
1115                           argtypes,
1116                           typeargtypes,
1117                           site.tsym.type,
1118                           true,
1119                           bestSoFar,
1120                           allowBoxing,
1121                           useVarargs,
1122                           operator,
1123                           new HashSet<TypeSymbol>());
1124         reportVerboseResolutionDiagnostic(env.tree.pos(), name, site, argtypes, typeargtypes, bestSoFar);
1125         return bestSoFar;
1126     }
1127     // where
1128     private Symbol findMethod(Env<AttrContext> env,
1129                               Type site,
1130                               Name name,
1131                               List<Type> argtypes,
1132                               List<Type> typeargtypes,
1133                               Type intype,
1134                               boolean abstractok,
1135                               Symbol bestSoFar,
1136                               boolean allowBoxing,
1137                               boolean useVarargs,
1138                               boolean operator,
1139                               Set<TypeSymbol> seen) {
1140         for (Type ct = intype; ct.tag == CLASS || ct.tag == TYPEVAR; ct = types.supertype(ct)) {
1141             while (ct.tag == TYPEVAR)
1142                 ct = ct.getUpperBound();
1143             ClassSymbol c = (ClassSymbol)ct.tsym;
1144             if (!seen.add(c)) return bestSoFar;
1145             if ((c.flags() & (ABSTRACT | INTERFACE | ENUM)) == 0)
1146                 abstractok = false;
1147             for (Scope.Entry e = c.members().lookup(name);
1148                  e.scope != null;
1149                  e = e.next()) {
1150                 //- System.out.println(" e " + e.sym);
1151                 if (e.sym.kind == MTH &&
1152                     (e.sym.flags_field & SYNTHETIC) == 0) {
1153                     bestSoFar = selectBest(env, site, argtypes, typeargtypes,
1154                                            e.sym, bestSoFar,
1155                                            allowBoxing,
1156                                            useVarargs,
1157                                            operator);
1158                 }
1159             }
1160             if (name == names.init)
1161                 break;
1162             //- System.out.println(" - " + bestSoFar);
1163             if (abstractok) {
1164                 Symbol concrete = methodNotFound;
1165                 if ((bestSoFar.flags() & ABSTRACT) == 0)
1166                     concrete = bestSoFar;
1167                 for (List<Type> l = types.interfaces(c.type);
1168                      l.nonEmpty();
1169                      l = l.tail) {
1170                     bestSoFar = findMethod(env, site, name, argtypes,
1171                                            typeargtypes,
1172                                            l.head, abstractok, bestSoFar,
1173                                            allowBoxing, useVarargs, operator, seen);
1174                 }
1175                 if (concrete != bestSoFar &&
1176                     concrete.kind < ERR  && bestSoFar.kind < ERR &&
1177                     types.isSubSignature(concrete.type, bestSoFar.type))
1178                     bestSoFar = concrete;
1179             }
1180         }
1181         return bestSoFar;
1182     }
1183 
1184     /** Find unqualified method matching given name, type and value arguments.
1185      *  @param env       The current environment.
1186      *  @param name      The method's name.
1187      *  @param argtypes  The method's value arguments.
1188      *  @param typeargtypes  The method's type arguments.
1189      *  @param allowBoxing Allow boxing conversions of arguments.
1190      *  @param useVarargs Box trailing arguments into an array for varargs.
1191      */
1192     Symbol findFun(Env<AttrContext> env, Name name,
1193                    List<Type> argtypes, List<Type> typeargtypes,
1194                    boolean allowBoxing, boolean useVarargs) {
1195         Symbol bestSoFar = methodNotFound;
1196         Symbol sym;
1197         Env<AttrContext> env1 = env;
1198         boolean staticOnly = false;
1199         while (env1.outer != null) {
1200             if (isStatic(env1)) staticOnly = true;
1201             sym = findMethod(
1202                 env1, env1.enclClass.sym.type, name, argtypes, typeargtypes,
1203                 allowBoxing, useVarargs, false);
1204             if (sym.exists()) {
1205                 if (staticOnly &&
1206                     sym.kind == MTH &&
1207                     sym.owner.kind == TYP &&
1208                     (sym.flags() & STATIC) == 0) return new StaticError(sym);
1209                 else return sym;
1210             } else if (sym.kind < bestSoFar.kind) {
1211                 bestSoFar = sym;
1212             }
1213             if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
1214             env1 = env1.outer;
1215         }
1216 
1217         sym = findMethod(env, syms.predefClass.type, name, argtypes,
1218                          typeargtypes, allowBoxing, useVarargs, false);
1219         if (sym.exists())
1220             return sym;
1221 
1222         Scope.Entry e = env.toplevel.namedImportScope.lookup(name);
1223         for (; e.scope != null; e = e.next()) {
1224             sym = e.sym;
1225             Type origin = e.getOrigin().owner.type;
1226             if (sym.kind == MTH) {
1227                 if (e.sym.owner.type != origin)
1228                     sym = sym.clone(e.getOrigin().owner);
1229                 if (!isAccessible(env, origin, sym))
1230                     sym = new AccessError(env, origin, sym);
1231                 bestSoFar = selectBest(env, origin,
1232                                        argtypes, typeargtypes,
1233                                        sym, bestSoFar,
1234                                        allowBoxing, useVarargs, false);
1235             }
1236         }
1237         if (bestSoFar.exists())
1238             return bestSoFar;
1239 
1240         e = env.toplevel.starImportScope.lookup(name);
1241         for (; e.scope != null; e = e.next()) {
1242             sym = e.sym;
1243             Type origin = e.getOrigin().owner.type;
1244             if (sym.kind == MTH) {
1245                 if (e.sym.owner.type != origin)
1246                     sym = sym.clone(e.getOrigin().owner);
1247                 if (!isAccessible(env, origin, sym))
1248                     sym = new AccessError(env, origin, sym);
1249                 bestSoFar = selectBest(env, origin,
1250                                        argtypes, typeargtypes,
1251                                        sym, bestSoFar,
1252                                        allowBoxing, useVarargs, false);
1253             }
1254         }
1255         return bestSoFar;
1256     }
1257 
1258     /** Load toplevel or member class with given fully qualified name and
1259      *  verify that it is accessible.
1260      *  @param env       The current environment.
1261      *  @param name      The fully qualified name of the class to be loaded.
1262      */
1263     Symbol loadClass(Env<AttrContext> env, Name name) {
1264         try {
1265             ClassSymbol c = reader.loadClass(name);
1266             checkForHiddenAccess(env, c);
1267             return isAccessible(env, c) ? c : new AccessError(c);
1268         } catch (ClassReader.BadClassFile err) {
1269             throw err;
1270         } catch (CompletionFailure ex) {
1271             return typeNotFound;
1272         }
1273     }
1274 
1275     /** Check that a hidden class is not accessed from any other file than its own.
1276      */
1277     void checkForHiddenAccess(Env<AttrContext> env, ClassSymbol c) {
1278         // If we are warning about hidden classes, verify that the class is package private (0)
1279         // and that the code that refers to the class belongs to the same package, this is necessary
1280         // because this warning should not trigger on normal access errors. Those are handled by isAccessible.
1281         //
1282         // If the class name is hidden (ie stored in a source file with a different name than the class and 
1283         // it is not an inner class) and the code that refers to the hidden class resides in a different source
1284         // file, then warn!
1285 
1286         if (lint.isEnabled(Lint.LintCategory.HIDDENCLASS) &&
1287             (short)(c.flags() & AccessFlags) == 0 &&
1288             env.toplevel.packge == c.packge() &&
1289             c.owner instanceof PackageSymbol &&
1290             !c.sourcefile.isNameCompatible(c.getSimpleName().toString(), JavaFileObject.Kind.SOURCE) &&
1291             !fm.isSameFile(c.sourcefile, env.toplevel.sourcefile))
1292         {
1293             log.warning("hidden.class.accessed.from.outside.of.its.source.file",
1294                         c, c.sourcefile, env.toplevel.sourcefile);
1295         }
1296     }
1297 
1298     /** Find qualified member type.
1299      *  @param env       The current environment.
1300      *  @param site      The original type from where the selection takes
1301      *                   place.
1302      *  @param name      The type's name.
1303      *  @param c         The class to search for the member type. This is
1304      *                   always a superclass or implemented interface of
1305      *                   site's class.
1306      */
1307     Symbol findMemberType(Env<AttrContext> env,
1308                           Type site,
1309                           Name name,
1310                           TypeSymbol c) {
1311         Symbol bestSoFar = typeNotFound;
1312         Symbol sym;
1313         Scope.Entry e = c.members().lookup(name);
1314         while (e.scope != null) {
1315             if (e.sym.kind == TYP) {
1316                 return isAccessible(env, site, e.sym)
1317                     ? e.sym
1318                     : new AccessError(env, site, e.sym);
1319             }
1320             e = e.next();
1321         }
1322         Type st = types.supertype(c.type);
1323         if (st != null && st.tag == CLASS) {
1324             sym = findMemberType(env, site, name, st.tsym);
1325             if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1326         }
1327         for (List<Type> l = types.interfaces(c.type);
1328              bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
1329              l = l.tail) {
1330             sym = findMemberType(env, site, name, l.head.tsym);
1331             if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS &&
1332                 sym.owner != bestSoFar.owner)
1333                 bestSoFar = new AmbiguityError(bestSoFar, sym);
1334             else if (sym.kind < bestSoFar.kind)
1335                 bestSoFar = sym;
1336         }
1337         return bestSoFar;
1338     }
1339 
1340     /** Find a global type in given scope and load corresponding class.
1341      *  @param env       The current environment.
1342      *  @param scope     The scope in which to look for the type.
1343      *  @param name      The type's name.
1344      */
1345     Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) {
1346         Symbol bestSoFar = typeNotFound;
1347         for (Scope.Entry e = scope.lookup(name); e.scope != null; e = e.next()) {
1348             Symbol sym = loadClass(env, e.sym.flatName());
1349             if (bestSoFar.kind == TYP && sym.kind == TYP &&
1350                 bestSoFar != sym)
1351                 return new AmbiguityError(bestSoFar, sym);
1352             else if (sym.kind < bestSoFar.kind)
1353                 bestSoFar = sym;
1354         }
1355         return bestSoFar;
1356     }
1357 
1358     /** Find an unqualified type symbol.
1359      *  @param env       The current environment.
1360      *  @param name      The type's name.
1361      */
1362     Symbol findType(Env<AttrContext> env, Name name) {
1363         Symbol bestSoFar = typeNotFound;
1364         Symbol sym;
1365         boolean staticOnly = false;
1366         for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) {
1367             if (isStatic(env1)) staticOnly = true;
1368             for (Scope.Entry e = env1.info.scope.lookup(name);
1369                  e.scope != null;
1370                  e = e.next()) {
1371                 if (e.sym.kind == TYP) {
1372                     if (staticOnly &&
1373                         e.sym.type.tag == TYPEVAR &&
1374                         e.sym.owner.kind == TYP) return new StaticError(e.sym);
1375                     return e.sym;
1376                 }
1377             }
1378 
1379             sym = findMemberType(env1, env1.enclClass.sym.type, name,
1380                                  env1.enclClass.sym);
1381             if (staticOnly && sym.kind == TYP &&
1382                 sym.type.tag == CLASS &&
1383                 sym.type.getEnclosingType().tag == CLASS &&
1384                 env1.enclClass.sym.type.isParameterized() &&
1385                 sym.type.getEnclosingType().isParameterized())
1386                 return new StaticError(sym);
1387             else if (sym.exists()) return sym;
1388             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1389 
1390             JCClassDecl encl = env1.baseClause ? (JCClassDecl)env1.tree : env1.enclClass;
1391             if ((encl.sym.flags() & STATIC) != 0)
1392                 staticOnly = true;
1393         }
1394 
1395         if (!env.tree.hasTag(IMPORT)) {
1396             sym = findGlobalType(env, env.toplevel.namedImportScope, name);
1397             if (sym.exists()) return sym;
1398             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1399 
1400             sym = findGlobalType(env, env.toplevel.packge.members(), name);
1401             if (sym.exists()) return sym;
1402             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1403 
1404             sym = findGlobalType(env, env.toplevel.starImportScope, name);
1405             if (sym.exists()) return sym;
1406             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1407         }
1408 
1409         return bestSoFar;
1410     }
1411 
1412     /** Find an unqualified identifier which matches a specified kind set.
1413      *  @param env       The current environment.
1414      *  @param name      The indentifier's name.
1415      *  @param kind      Indicates the possible symbol kinds
1416      *                   (a subset of VAL, TYP, PCK).
1417      */
1418     Symbol findIdent(Env<AttrContext> env, Name name, int kind) {
1419         Symbol bestSoFar = typeNotFound;
1420         Symbol sym;
1421 
1422         if ((kind & VAR) != 0) {
1423             sym = findVar(env, name);
1424             if (sym.exists()) return sym;
1425             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1426         }
1427 
1428         if ((kind & TYP) != 0) {
1429             sym = findType(env, name);
1430             if (sym.exists()) return sym;
1431             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1432         }
1433 
1434         if ((kind & PCK) != 0) return reader.enterPackage(name);
1435         else return bestSoFar;
1436     }
1437 
1438     /** Find an identifier in a package which matches a specified kind set.
1439      *  @param env       The current environment.
1440      *  @param name      The identifier's name.
1441      *  @param kind      Indicates the possible symbol kinds
1442      *                   (a nonempty subset of TYP, PCK).
1443      */
1444     Symbol findIdentInPackage(Env<AttrContext> env, TypeSymbol pck,
1445                               Name name, int kind) {
1446         Name fullname = TypeSymbol.formFullName(name, pck);
1447         Symbol bestSoFar = typeNotFound;
1448         PackageSymbol pack = null;
1449         if ((kind & PCK) != 0) {
1450             pack = reader.enterPackage(fullname);
1451             if (pack.exists()) return pack;
1452         }
1453         if ((kind & TYP) != 0) {
1454             Symbol sym = loadClass(env, fullname);
1455             if (sym.exists()) {
1456                 // don't allow programs to use flatnames
1457                 if (name == sym.name) return sym;
1458             }
1459             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1460         }
1461         return (pack != null) ? pack : bestSoFar;
1462     }
1463 
1464     /** Find an identifier among the members of a given type `site'.
1465      *  @param env       The current environment.
1466      *  @param site      The type containing the symbol to be found.
1467      *  @param name      The identifier's name.
1468      *  @param kind      Indicates the possible symbol kinds
1469      *                   (a subset of VAL, TYP).
1470      */
1471     Symbol findIdentInType(Env<AttrContext> env, Type site,
1472                            Name name, int kind) {
1473         Symbol bestSoFar = typeNotFound;
1474         Symbol sym;
1475         if ((kind & VAR) != 0) {
1476             sym = findField(env, site, name, site.tsym);
1477             if (sym.exists()) return sym;
1478             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1479         }
1480 
1481         if ((kind & TYP) != 0) {
1482             sym = findMemberType(env, site, name, site.tsym);
1483             if (sym.exists()) return sym;
1484             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1485         }
1486         return bestSoFar;
1487     }
1488 
1489 /* ***************************************************************************
1490  *  Access checking
1491  *  The following methods convert ResolveErrors to ErrorSymbols, issuing
1492  *  an error message in the process
1493  ****************************************************************************/
1494 
1495     /** If `sym' is a bad symbol: report error and return errSymbol
1496      *  else pass through unchanged,
1497      *  additional arguments duplicate what has been used in trying to find the
1498      *  symbol (--> flyweight pattern). This improves performance since we
1499      *  expect misses to happen frequently.
1500      *
1501      *  @param sym       The symbol that was found, or a ResolveError.
1502      *  @param pos       The position to use for error reporting.
1503      *  @param site      The original type from where the selection took place.
1504      *  @param name      The symbol's name.
1505      *  @param argtypes  The invocation's value arguments,
1506      *                   if we looked for a method.
1507      *  @param typeargtypes  The invocation's type arguments,
1508      *                   if we looked for a method.
1509      */
1510     Symbol access(Symbol sym,
1511                   DiagnosticPosition pos,
1512                   Symbol location,
1513                   Type site,
1514                   Name name,
1515                   boolean qualified,
1516                   List<Type> argtypes,
1517                   List<Type> typeargtypes) {
1518         if (sym.kind >= AMBIGUOUS) {
1519             ResolveError errSym = (ResolveError)sym;
1520             if (!site.isErroneous() &&
1521                 !Type.isErroneous(argtypes) &&
1522                 (typeargtypes==null || !Type.isErroneous(typeargtypes)))
1523                 logResolveError(errSym, pos, location, site, name, argtypes, typeargtypes);
1524             sym = errSym.access(name, qualified ? site.tsym : syms.noSymbol);
1525         }
1526         return sym;
1527     }
1528 
1529     /** Same as original access(), but without location.
1530      */
1531     Symbol access(Symbol sym,
1532                   DiagnosticPosition pos,
1533                   Type site,
1534                   Name name,
1535                   boolean qualified,
1536                   List<Type> argtypes,
1537                   List<Type> typeargtypes) {
1538         return access(sym, pos, site.tsym, site, name, qualified, argtypes, typeargtypes);
1539     }
1540 
1541     /** Same as original access(), but without type arguments and arguments.
1542      */
1543     Symbol access(Symbol sym,
1544                   DiagnosticPosition pos,
1545                   Symbol location,
1546                   Type site,
1547                   Name name,
1548                   boolean qualified) {
1549         if (sym.kind >= AMBIGUOUS)
1550             return access(sym, pos, location, site, name, qualified, List.<Type>nil(), null);
1551         else
1552             return sym;
1553     }
1554 
1555     /** Same as original access(), but without location, type arguments and arguments.
1556      */
1557     Symbol access(Symbol sym,
1558                   DiagnosticPosition pos,
1559                   Type site,
1560                   Name name,
1561                   boolean qualified) {
1562         return access(sym, pos, site.tsym, site, name, qualified);
1563     }
1564 
1565     /** Check that sym is not an abstract method.
1566      */
1567     void checkNonAbstract(DiagnosticPosition pos, Symbol sym) {
1568         if ((sym.flags() & ABSTRACT) != 0)
1569             log.error(pos, "abstract.cant.be.accessed.directly",
1570                       kindName(sym), sym, sym.location());
1571     }
1572 
1573 /* ***************************************************************************
1574  *  Debugging
1575  ****************************************************************************/
1576 
1577     /** print all scopes starting with scope s and proceeding outwards.
1578      *  used for debugging.
1579      */
1580     public void printscopes(Scope s) {
1581         while (s != null) {
1582             if (s.owner != null)
1583                 System.err.print(s.owner + ": ");
1584             for (Scope.Entry e = s.elems; e != null; e = e.sibling) {
1585                 if ((e.sym.flags() & ABSTRACT) != 0)
1586                     System.err.print("abstract ");
1587                 System.err.print(e.sym + " ");
1588             }
1589             System.err.println();
1590             s = s.next;
1591         }
1592     }
1593 
1594     void printscopes(Env<AttrContext> env) {
1595         while (env.outer != null) {
1596             System.err.println("------------------------------");
1597             printscopes(env.info.scope);
1598             env = env.outer;
1599         }
1600     }
1601 
1602     public void printscopes(Type t) {
1603         while (t.tag == CLASS) {
1604             printscopes(t.tsym.members());
1605             t = types.supertype(t);
1606         }
1607     }
1608 
1609 /* ***************************************************************************
1610  *  Name resolution
1611  *  Naming conventions are as for symbol lookup
1612  *  Unlike the find... methods these methods will report access errors
1613  ****************************************************************************/
1614 
1615     /** Resolve an unqualified (non-method) identifier.
1616      *  @param pos       The position to use for error reporting.
1617      *  @param env       The environment current at the identifier use.
1618      *  @param name      The identifier's name.
1619      *  @param kind      The set of admissible symbol kinds for the identifier.
1620      */
1621     Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env,
1622                         Name name, int kind) {
1623         return access(
1624             findIdent(env, name, kind),
1625             pos, env.enclClass.sym.type, name, false);
1626     }
1627 
1628     /** Resolve an unqualified method identifier.
1629      *  @param pos       The position to use for error reporting.
1630      *  @param env       The environment current at the method invocation.
1631      *  @param name      The identifier's name.
1632      *  @param argtypes  The types of the invocation's value arguments.
1633      *  @param typeargtypes  The types of the invocation's type arguments.
1634      */
1635     Symbol resolveMethod(DiagnosticPosition pos,
1636                          Env<AttrContext> env,
1637                          Name name,
1638                          List<Type> argtypes,
1639                          List<Type> typeargtypes) {
1640         MethodResolutionContext prevResolutionContext = currentResolutionContext;
1641         try {
1642             currentResolutionContext = new MethodResolutionContext();
1643             Symbol sym = methodNotFound;
1644             List<MethodResolutionPhase> steps = methodResolutionSteps;
1645             while (steps.nonEmpty() &&
1646                    steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
1647                    sym.kind >= ERRONEOUS) {
1648                 currentResolutionContext.step = steps.head;
1649                 sym = findFun(env, name, argtypes, typeargtypes,
1650                         steps.head.isBoxingRequired,
1651                         env.info.varArgs = steps.head.isVarargsRequired);
1652                 currentResolutionContext.resolutionCache.put(steps.head, sym);
1653                 steps = steps.tail;
1654             }
1655             if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
1656                 MethodResolutionPhase errPhase =
1657                         currentResolutionContext.firstErroneousResolutionPhase();
1658                 sym = access(currentResolutionContext.resolutionCache.get(errPhase),
1659                         pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes);
1660                 env.info.varArgs = errPhase.isVarargsRequired;
1661             }
1662             return sym;
1663         }
1664         finally {
1665             currentResolutionContext = prevResolutionContext;
1666         }
1667     }
1668 
1669     /** Resolve a qualified method identifier
1670      *  @param pos       The position to use for error reporting.
1671      *  @param env       The environment current at the method invocation.
1672      *  @param site      The type of the qualifying expression, in which
1673      *                   identifier is searched.
1674      *  @param name      The identifier's name.
1675      *  @param argtypes  The types of the invocation's value arguments.
1676      *  @param typeargtypes  The types of the invocation's type arguments.
1677      */
1678     Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
1679                                   Type site, Name name, List<Type> argtypes,
1680                                   List<Type> typeargtypes) {
1681         return resolveQualifiedMethod(pos, env, site.tsym, site, name, argtypes, typeargtypes);
1682     }
1683     Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
1684                                   Symbol location, Type site, Name name, List<Type> argtypes,
1685                                   List<Type> typeargtypes) {
1686         return resolveQualifiedMethod(new MethodResolutionContext(), pos, env, location, site, name, argtypes, typeargtypes);
1687     }
1688     private Symbol resolveQualifiedMethod(MethodResolutionContext resolveContext,
1689                                   DiagnosticPosition pos, Env<AttrContext> env,
1690                                   Symbol location, Type site, Name name, List<Type> argtypes,
1691                                   List<Type> typeargtypes) {
1692         MethodResolutionContext prevResolutionContext = currentResolutionContext;
1693         try {
1694             currentResolutionContext = resolveContext;
1695             Symbol sym = methodNotFound;
1696             List<MethodResolutionPhase> steps = methodResolutionSteps;
1697             while (steps.nonEmpty() &&
1698                    steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
1699                    sym.kind >= ERRONEOUS) {
1700                 currentResolutionContext.step = steps.head;
1701                 sym = findMethod(env, site, name, argtypes, typeargtypes,
1702                         steps.head.isBoxingRequired(),
1703                         env.info.varArgs = steps.head.isVarargsRequired(), false);
1704                 currentResolutionContext.resolutionCache.put(steps.head, sym);
1705                 steps = steps.tail;
1706             }
1707             if (sym.kind >= AMBIGUOUS) {
1708                 if (site.tsym.isPolymorphicSignatureGeneric()) {
1709                     //polymorphic receiver - synthesize new method symbol
1710                     env.info.varArgs = false;
1711                     sym = findPolymorphicSignatureInstance(env,
1712                             site, name, null, argtypes);
1713                 }
1714                 else {
1715                     //if nothing is found return the 'first' error
1716                     MethodResolutionPhase errPhase =
1717                             currentResolutionContext.firstErroneousResolutionPhase();
1718                     sym = access(currentResolutionContext.resolutionCache.get(errPhase),
1719                             pos, location, site, name, true, argtypes, typeargtypes);
1720                     env.info.varArgs = errPhase.isVarargsRequired;
1721                 }
1722             } else if (allowMethodHandles && sym.isPolymorphicSignatureGeneric()) {
1723                 //non-instantiated polymorphic signature - synthesize new method symbol
1724                 env.info.varArgs = false;
1725                 sym = findPolymorphicSignatureInstance(env,
1726                         site, name, (MethodSymbol)sym, argtypes);
1727             }
1728             return sym;
1729         }
1730         finally {
1731             currentResolutionContext = prevResolutionContext;
1732         }
1733     }
1734 
1735     /** Find or create an implicit method of exactly the given type (after erasure).
1736      *  Searches in a side table, not the main scope of the site.
1737      *  This emulates the lookup process required by JSR 292 in JVM.
1738      *  @param env       Attribution environment
1739      *  @param site      The original type from where the selection takes place.
1740      *  @param name      The method's name.
1741      *  @param spMethod  A template for the implicit method, or null.
1742      *  @param argtypes  The required argument types.
1743      *  @param typeargtypes  The required type arguments.
1744      */
1745     Symbol findPolymorphicSignatureInstance(Env<AttrContext> env, Type site,
1746                                             Name name,
1747                                             MethodSymbol spMethod,  // sig. poly. method or null if none
1748                                             List<Type> argtypes) {
1749         Type mtype = infer.instantiatePolymorphicSignatureInstance(env,
1750                 site, name, spMethod, argtypes);
1751         long flags = ABSTRACT | HYPOTHETICAL | POLYMORPHIC_SIGNATURE |
1752                     (spMethod != null ?
1753                         spMethod.flags() & Flags.AccessFlags :
1754                         Flags.PUBLIC | Flags.STATIC);
1755         Symbol m = null;
1756         for (Scope.Entry e = polymorphicSignatureScope.lookup(name);
1757              e.scope != null;
1758              e = e.next()) {
1759             Symbol sym = e.sym;
1760             if (types.isSameType(mtype, sym.type) &&
1761                 (sym.flags() & Flags.STATIC) == (flags & Flags.STATIC) &&
1762                 types.isSameType(sym.owner.type, site)) {
1763                m = sym;
1764                break;
1765             }
1766         }
1767         if (m == null) {
1768             // create the desired method
1769             m = new MethodSymbol(flags, name, mtype, site.tsym);
1770             polymorphicSignatureScope.enter(m);
1771         }
1772         return m;
1773     }
1774 
1775     /** Resolve a qualified method identifier, throw a fatal error if not
1776      *  found.
1777      *  @param pos       The position to use for error reporting.
1778      *  @param env       The environment current at the method invocation.
1779      *  @param site      The type of the qualifying expression, in which
1780      *                   identifier is searched.
1781      *  @param name      The identifier's name.
1782      *  @param argtypes  The types of the invocation's value arguments.
1783      *  @param typeargtypes  The types of the invocation's type arguments.
1784      */
1785     public MethodSymbol resolveInternalMethod(DiagnosticPosition pos, Env<AttrContext> env,
1786                                         Type site, Name name,
1787                                         List<Type> argtypes,
1788                                         List<Type> typeargtypes) {
1789         MethodResolutionContext resolveContext = new MethodResolutionContext();
1790         resolveContext.internalResolution = true;
1791         Symbol sym = resolveQualifiedMethod(resolveContext, pos, env, site.tsym,
1792                 site, name, argtypes, typeargtypes);
1793         if (sym.kind == MTH) return (MethodSymbol)sym;
1794         else throw new FatalError(
1795                  diags.fragment("fatal.err.cant.locate.meth",
1796                                 name));
1797     }
1798 
1799     /** Resolve constructor.
1800      *  @param pos       The position to use for error reporting.
1801      *  @param env       The environment current at the constructor invocation.
1802      *  @param site      The type of class for which a constructor is searched.
1803      *  @param argtypes  The types of the constructor invocation's value
1804      *                   arguments.
1805      *  @param typeargtypes  The types of the constructor invocation's type
1806      *                   arguments.
1807      */
1808     Symbol resolveConstructor(DiagnosticPosition pos,
1809                               Env<AttrContext> env,
1810                               Type site,
1811                               List<Type> argtypes,
1812                               List<Type> typeargtypes) {
1813         return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes);
1814     }
1815     private Symbol resolveConstructor(MethodResolutionContext resolveContext,
1816                               DiagnosticPosition pos,
1817                               Env<AttrContext> env,
1818                               Type site,
1819                               List<Type> argtypes,
1820                               List<Type> typeargtypes) {
1821         MethodResolutionContext prevResolutionContext = currentResolutionContext;
1822         try {
1823             currentResolutionContext = resolveContext;
1824             Symbol sym = methodNotFound;
1825             List<MethodResolutionPhase> steps = methodResolutionSteps;
1826             while (steps.nonEmpty() &&
1827                    steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
1828                    sym.kind >= ERRONEOUS) {
1829                 currentResolutionContext.step = steps.head;
1830                 sym = findConstructor(pos, env, site, argtypes, typeargtypes,
1831                         steps.head.isBoxingRequired(),
1832                         env.info.varArgs = steps.head.isVarargsRequired());
1833                 currentResolutionContext.resolutionCache.put(steps.head, sym);
1834                 steps = steps.tail;
1835             }
1836             if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
1837                 MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase();
1838                 sym = access(currentResolutionContext.resolutionCache.get(errPhase),
1839                         pos, site, names.init, true, argtypes, typeargtypes);
1840                 env.info.varArgs = errPhase.isVarargsRequired();
1841             }
1842             return sym;
1843         }
1844         finally {
1845             currentResolutionContext = prevResolutionContext;
1846         }
1847     }
1848 
1849     /** Resolve constructor using diamond inference.
1850      *  @param pos       The position to use for error reporting.
1851      *  @param env       The environment current at the constructor invocation.
1852      *  @param site      The type of class for which a constructor is searched.
1853      *                   The scope of this class has been touched in attribution.
1854      *  @param argtypes  The types of the constructor invocation's value
1855      *                   arguments.
1856      *  @param typeargtypes  The types of the constructor invocation's type
1857      *                   arguments.
1858      */
1859     Symbol resolveDiamond(DiagnosticPosition pos,
1860                               Env<AttrContext> env,
1861                               Type site,
1862                               List<Type> argtypes,
1863                               List<Type> typeargtypes) {
1864         MethodResolutionContext prevResolutionContext = currentResolutionContext;
1865         try {
1866             currentResolutionContext = new MethodResolutionContext();
1867             Symbol sym = methodNotFound;
1868             List<MethodResolutionPhase> steps = methodResolutionSteps;
1869             while (steps.nonEmpty() &&
1870                    steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
1871                    sym.kind >= ERRONEOUS) {
1872                 currentResolutionContext.step = steps.head;
1873                 sym = findDiamond(env, site, argtypes, typeargtypes,
1874                         steps.head.isBoxingRequired(),
1875                         env.info.varArgs = steps.head.isVarargsRequired());
1876                 currentResolutionContext.resolutionCache.put(steps.head, sym);
1877                 steps = steps.tail;
1878             }
1879             if (sym.kind >= AMBIGUOUS) {
1880                 final JCDiagnostic details = sym.kind == WRONG_MTH ?
1881                                 currentResolutionContext.candidates.head.details :
1882                                 null;
1883                 Symbol errSym = new ResolveError(WRONG_MTH, "diamond error") {
1884                     @Override
1885                     JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
1886                             Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
1887                         String key = details == null ?
1888                             "cant.apply.diamond" :
1889                             "cant.apply.diamond.1";
1890                         return diags.create(dkind, log.currentSource(), pos, key,
1891                                 diags.fragment("diamond", site.tsym), details);
1892                     }
1893                 };
1894                 MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase();
1895                 sym = access(errSym, pos, site, names.init, true, argtypes, typeargtypes);
1896                 env.info.varArgs = errPhase.isVarargsRequired();
1897             }
1898             return sym;
1899         }
1900         finally {
1901             currentResolutionContext = prevResolutionContext;
1902         }
1903     }
1904 
1905     /** This method scans all the constructor symbol in a given class scope -
1906      *  assuming that the original scope contains a constructor of the kind:
1907      *  Foo(X x, Y y), where X,Y are class type-variables declared in Foo,
1908      *  a method check is executed against the modified constructor type:
1909      *  <X,Y>Foo<X,Y>(X x, Y y). This is crucial in order to enable diamond
1910      *  inference. The inferred return type of the synthetic constructor IS
1911      *  the inferred type for the diamond operator.
1912      */
1913     private Symbol findDiamond(Env<AttrContext> env,
1914                               Type site,
1915                               List<Type> argtypes,
1916                               List<Type> typeargtypes,
1917                               boolean allowBoxing,
1918                               boolean useVarargs) {
1919         Symbol bestSoFar = methodNotFound;
1920         for (Scope.Entry e = site.tsym.members().lookup(names.init);
1921              e.scope != null;
1922              e = e.next()) {
1923             //- System.out.println(" e " + e.sym);
1924             if (e.sym.kind == MTH &&
1925                 (e.sym.flags_field & SYNTHETIC) == 0) {
1926                     List<Type> oldParams = e.sym.type.tag == FORALL ?
1927                             ((ForAll)e.sym.type).tvars :
1928                             List.<Type>nil();
1929                     Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams),
1930                             types.createMethodTypeWithReturn(e.sym.type.asMethodType(), site));
1931                     bestSoFar = selectBest(env, site, argtypes, typeargtypes,
1932                             new MethodSymbol(e.sym.flags(), names.init, constrType, site.tsym),
1933                             bestSoFar,
1934                             allowBoxing,
1935                             useVarargs,
1936                             false);
1937             }
1938         }
1939         return bestSoFar;
1940     }
1941 
1942     /** Resolve constructor.
1943      *  @param pos       The position to use for error reporting.
1944      *  @param env       The environment current at the constructor invocation.
1945      *  @param site      The type of class for which a constructor is searched.
1946      *  @param argtypes  The types of the constructor invocation's value
1947      *                   arguments.
1948      *  @param typeargtypes  The types of the constructor invocation's type
1949      *                   arguments.
1950      *  @param allowBoxing Allow boxing and varargs conversions.
1951      *  @param useVarargs Box trailing arguments into an array for varargs.
1952      */
1953     Symbol resolveConstructor(DiagnosticPosition pos, Env<AttrContext> env,
1954                               Type site, List<Type> argtypes,
1955                               List<Type> typeargtypes,
1956                               boolean allowBoxing,
1957                               boolean useVarargs) {
1958         MethodResolutionContext prevResolutionContext = currentResolutionContext;
1959         try {
1960             currentResolutionContext = new MethodResolutionContext();
1961             return findConstructor(pos, env, site, argtypes, typeargtypes, allowBoxing, useVarargs);
1962         }
1963         finally {
1964             currentResolutionContext = prevResolutionContext;
1965         }
1966     }
1967 
1968     Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env,
1969                               Type site, List<Type> argtypes,
1970                               List<Type> typeargtypes,
1971                               boolean allowBoxing,
1972                               boolean useVarargs) {
1973         Symbol sym = findMethod(env, site,
1974                                     names.init, argtypes,
1975                                     typeargtypes, allowBoxing,
1976                                     useVarargs, false);
1977         chk.checkDeprecated(pos, env.info.scope.owner, sym);
1978         return sym;
1979     }
1980 
1981     /** Resolve a constructor, throw a fatal error if not found.
1982      *  @param pos       The position to use for error reporting.
1983      *  @param env       The environment current at the method invocation.
1984      *  @param site      The type to be constructed.
1985      *  @param argtypes  The types of the invocation's value arguments.
1986      *  @param typeargtypes  The types of the invocation's type arguments.
1987      */
1988     public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env,
1989                                         Type site,
1990                                         List<Type> argtypes,
1991                                         List<Type> typeargtypes) {
1992         MethodResolutionContext resolveContext = new MethodResolutionContext();
1993         resolveContext.internalResolution = true;
1994         Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes);
1995         if (sym.kind == MTH) return (MethodSymbol)sym;
1996         else throw new FatalError(
1997                  diags.fragment("fatal.err.cant.locate.ctor", site));
1998     }
1999 
2000     /** Resolve operator.
2001      *  @param pos       The position to use for error reporting.
2002      *  @param optag     The tag of the operation tree.
2003      *  @param env       The environment current at the operation.
2004      *  @param argtypes  The types of the operands.
2005      */
2006     Symbol resolveOperator(DiagnosticPosition pos, JCTree.Tag optag,
2007                            Env<AttrContext> env, List<Type> argtypes) {
2008         MethodResolutionContext prevResolutionContext = currentResolutionContext;
2009         try {
2010             currentResolutionContext = new MethodResolutionContext();
2011             Name name = treeinfo.operatorName(optag);
2012             Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
2013                                     null, false, false, true);
2014             if (boxingEnabled && sym.kind >= WRONG_MTHS)
2015                 sym = findMethod(env, syms.predefClass.type, name, argtypes,
2016                                  null, true, false, true);
2017             return access(sym, pos, env.enclClass.sym.type, name,
2018                           false, argtypes, null);
2019         }
2020         finally {
2021             currentResolutionContext = prevResolutionContext;
2022         }
2023     }
2024 
2025     /** Resolve operator.
2026      *  @param pos       The position to use for error reporting.
2027      *  @param optag     The tag of the operation tree.
2028      *  @param env       The environment current at the operation.
2029      *  @param arg       The type of the operand.
2030      */
2031     Symbol resolveUnaryOperator(DiagnosticPosition pos, JCTree.Tag optag, Env<AttrContext> env, Type arg) {
2032         return resolveOperator(pos, optag, env, List.of(arg));
2033     }
2034 
2035     /** Resolve binary operator.
2036      *  @param pos       The position to use for error reporting.
2037      *  @param optag     The tag of the operation tree.
2038      *  @param env       The environment current at the operation.
2039      *  @param left      The types of the left operand.
2040      *  @param right     The types of the right operand.
2041      */
2042     Symbol resolveBinaryOperator(DiagnosticPosition pos,
2043                                  JCTree.Tag optag,
2044                                  Env<AttrContext> env,
2045                                  Type left,
2046                                  Type right) {
2047         return resolveOperator(pos, optag, env, List.of(left, right));
2048     }
2049 
2050     /**
2051      * Resolve `c.name' where name == this or name == super.
2052      * @param pos           The position to use for error reporting.
2053      * @param env           The environment current at the expression.
2054      * @param c             The qualifier.
2055      * @param name          The identifier's name.
2056      */
2057     Symbol resolveSelf(DiagnosticPosition pos,
2058                        Env<AttrContext> env,
2059                        TypeSymbol c,
2060                        Name name) {
2061         Env<AttrContext> env1 = env;
2062         boolean staticOnly = false;
2063         while (env1.outer != null) {
2064             if (isStatic(env1)) staticOnly = true;
2065             if (env1.enclClass.sym == c) {
2066                 Symbol sym = env1.info.scope.lookup(name).sym;
2067                 if (sym != null) {
2068                     if (staticOnly) sym = new StaticError(sym);
2069                     return access(sym, pos, env.enclClass.sym.type,
2070                                   name, true);
2071                 }
2072             }
2073             if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
2074             env1 = env1.outer;
2075         }
2076         log.error(pos, "not.encl.class", c);
2077         return syms.errSymbol;
2078     }
2079 
2080     /**
2081      * Resolve `c.this' for an enclosing class c that contains the
2082      * named member.
2083      * @param pos           The position to use for error reporting.
2084      * @param env           The environment current at the expression.
2085      * @param member        The member that must be contained in the result.
2086      */
2087     Symbol resolveSelfContaining(DiagnosticPosition pos,
2088                                  Env<AttrContext> env,
2089                                  Symbol member,
2090                                  boolean isSuperCall) {
2091         Name name = names._this;
2092         Env<AttrContext> env1 = isSuperCall ? env.outer : env;
2093         boolean staticOnly = false;
2094         if (env1 != null) {
2095             while (env1 != null && env1.outer != null) {
2096                 if (isStatic(env1)) staticOnly = true;
2097                 if (env1.enclClass.sym.isSubClass(member.owner, types)) {
2098                     Symbol sym = env1.info.scope.lookup(name).sym;
2099                     if (sym != null) {
2100                         if (staticOnly) sym = new StaticError(sym);
2101                         return access(sym, pos, env.enclClass.sym.type,
2102                                       name, true);
2103                     }
2104                 }
2105                 if ((env1.enclClass.sym.flags() & STATIC) != 0)
2106                     staticOnly = true;
2107                 env1 = env1.outer;
2108             }
2109         }
2110         log.error(pos, "encl.class.required", member);
2111         return syms.errSymbol;
2112     }
2113 
2114     /**
2115      * Resolve an appropriate implicit this instance for t's container.
2116      * JLS 8.8.5.1 and 15.9.2
2117      */
2118     Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t) {
2119         return resolveImplicitThis(pos, env, t, false);
2120     }
2121 
2122     Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t, boolean isSuperCall) {
2123         Type thisType = (((t.tsym.owner.kind & (MTH|VAR)) != 0)
2124                          ? resolveSelf(pos, env, t.getEnclosingType().tsym, names._this)
2125                          : resolveSelfContaining(pos, env, t.tsym, isSuperCall)).type;
2126         if (env.info.isSelfCall && thisType.tsym == env.enclClass.sym)
2127             log.error(pos, "cant.ref.before.ctor.called", "this");
2128         return thisType;
2129     }
2130 
2131 /* ***************************************************************************
2132  *  ResolveError classes, indicating error situations when accessing symbols
2133  ****************************************************************************/
2134 
2135     //used by TransTypes when checking target type of synthetic cast
2136     public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) {
2137         AccessError error = new AccessError(env, env.enclClass.type, type.tsym);
2138         logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null);
2139     }
2140     //where
2141     private void logResolveError(ResolveError error,
2142             DiagnosticPosition pos,
2143             Symbol location,
2144             Type site,
2145             Name name,
2146             List<Type> argtypes,
2147             List<Type> typeargtypes) {
2148         JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
2149                 pos, location, site, name, argtypes, typeargtypes);
2150         if (d != null) {
2151             d.setFlag(DiagnosticFlag.RESOLVE_ERROR);
2152             log.report(d);
2153         }
2154     }
2155 
2156     private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
2157 
2158     public Object methodArguments(List<Type> argtypes) {
2159         return argtypes == null || argtypes.isEmpty() ? noArgs : argtypes;
2160     }
2161 
2162     /**
2163      * Root class for resolution errors. Subclass of ResolveError
2164      * represent a different kinds of resolution error - as such they must
2165      * specify how they map into concrete compiler diagnostics.
2166      */
2167     private abstract class ResolveError extends Symbol {
2168 
2169         /** The name of the kind of error, for debugging only. */
2170         final String debugName;
2171 
2172         ResolveError(int kind, String debugName) {
2173             super(kind, 0, null, null, null);
2174             this.debugName = debugName;
2175         }
2176 
2177         @Override
2178         public <R, P> R accept(ElementVisitor<R, P> v, P p) {
2179             throw new AssertionError();
2180         }
2181 
2182         @Override
2183         public String toString() {
2184             return debugName;
2185         }
2186 
2187         @Override
2188         public boolean exists() {
2189             return false;
2190         }
2191 
2192         /**
2193          * Create an external representation for this erroneous symbol to be
2194          * used during attribution - by default this returns the symbol of a
2195          * brand new error type which stores the original type found
2196          * during resolution.
2197          *
2198          * @param name     the name used during resolution
2199          * @param location the location from which the symbol is accessed
2200          */
2201         protected Symbol access(Name name, TypeSymbol location) {
2202             return types.createErrorType(name, location, syms.errSymbol.type).tsym;
2203         }
2204 
2205         /**
2206          * Create a diagnostic representing this resolution error.
2207          *
2208          * @param dkind     The kind of the diagnostic to be created (e.g error).
2209          * @param pos       The position to be used for error reporting.
2210          * @param site      The original type from where the selection took place.
2211          * @param name      The name of the symbol to be resolved.
2212          * @param argtypes  The invocation's value arguments,
2213          *                  if we looked for a method.
2214          * @param typeargtypes  The invocation's type arguments,
2215          *                      if we looked for a method.
2216          */
2217         abstract JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
2218                 DiagnosticPosition pos,
2219                 Symbol location,
2220                 Type site,
2221                 Name name,
2222                 List<Type> argtypes,
2223                 List<Type> typeargtypes);
2224 
2225         /**
2226          * A name designates an operator if it consists
2227          * of a non-empty sequence of operator symbols +-~!/*%&|^<>=
2228          */
2229         boolean isOperator(Name name) {
2230             int i = 0;
2231             while (i < name.getByteLength() &&
2232                    "+-~!*/%&|^<>=".indexOf(name.getByteAt(i)) >= 0) i++;
2233             return i > 0 && i == name.getByteLength();
2234         }
2235     }
2236 
2237     /**
2238      * This class is the root class of all resolution errors caused by
2239      * an invalid symbol being found during resolution.
2240      */
2241     abstract class InvalidSymbolError extends ResolveError {
2242 
2243         /** The invalid symbol found during resolution */
2244         Symbol sym;
2245 
2246         InvalidSymbolError(int kind, Symbol sym, String debugName) {
2247             super(kind, debugName);
2248             this.sym = sym;
2249         }
2250 
2251         @Override
2252         public boolean exists() {
2253             return true;
2254         }
2255 
2256         @Override
2257         public String toString() {
2258              return super.toString() + " wrongSym=" + sym;
2259         }
2260 
2261         @Override
2262         public Symbol access(Name name, TypeSymbol location) {
2263             if (sym.kind >= AMBIGUOUS)
2264                 return ((ResolveError)sym).access(name, location);
2265             else if ((sym.kind & ERRONEOUS) == 0 && (sym.kind & TYP) != 0)
2266                 return types.createErrorType(name, location, sym.type).tsym;
2267             else
2268                 return sym;
2269         }
2270     }
2271 
2272     /**
2273      * InvalidSymbolError error class indicating that a symbol matching a
2274      * given name does not exists in a given site.
2275      */
2276     class SymbolNotFoundError extends ResolveError {
2277 
2278         SymbolNotFoundError(int kind) {
2279             super(kind, "symbol not found error");
2280         }
2281 
2282         @Override
2283         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
2284                 DiagnosticPosition pos,
2285                 Symbol location,
2286                 Type site,
2287                 Name name,
2288                 List<Type> argtypes,
2289                 List<Type> typeargtypes) {
2290             argtypes = argtypes == null ? List.<Type>nil() : argtypes;
2291             typeargtypes = typeargtypes == null ? List.<Type>nil() : typeargtypes;
2292             if (name == names.error)
2293                 return null;
2294 
2295             if (isOperator(name)) {
2296                 boolean isUnaryOp = argtypes.size() == 1;
2297                 String key = argtypes.size() == 1 ?
2298                     "operator.cant.be.applied" :
2299                     "operator.cant.be.applied.1";
2300                 Type first = argtypes.head;
2301                 Type second = !isUnaryOp ? argtypes.tail.head : null;
2302                 return diags.create(dkind, log.currentSource(), pos,
2303                         key, name, first, second);
2304             }
2305             boolean hasLocation = false;
2306             if (location == null) {
2307                 location = site.tsym;
2308             }
2309             if (!location.name.isEmpty()) {
2310                 if (location.kind == PCK && !site.tsym.exists()) {
2311                     return diags.create(dkind, log.currentSource(), pos,
2312                         "doesnt.exist", location);
2313                 }
2314                 hasLocation = !location.name.equals(names._this) &&
2315                         !location.name.equals(names._super);
2316             }
2317             boolean isConstructor = kind == ABSENT_MTH &&
2318                     name == names.table.names.init;
2319             KindName kindname = isConstructor ? KindName.CONSTRUCTOR : absentKind(kind);
2320             Name idname = isConstructor ? site.tsym.name : name;
2321             String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation);
2322             if (hasLocation) {
2323                 return diags.create(dkind, log.currentSource(), pos,
2324                         errKey, kindname, idname, //symbol kindname, name
2325                         typeargtypes, argtypes, //type parameters and arguments (if any)
2326                         getLocationDiag(location, site)); //location kindname, type
2327             }
2328             else {
2329                 return diags.create(dkind, log.currentSource(), pos,
2330                         errKey, kindname, idname, //symbol kindname, name
2331                         typeargtypes, argtypes); //type parameters and arguments (if any)
2332             }
2333         }
2334         //where
2335         private String getErrorKey(KindName kindname, boolean hasTypeArgs, boolean hasLocation) {
2336             String key = "cant.resolve";
2337             String suffix = hasLocation ? ".location" : "";
2338             switch (kindname) {
2339                 case METHOD:
2340                 case CONSTRUCTOR: {
2341                     suffix += ".args";
2342                     suffix += hasTypeArgs ? ".params" : "";
2343                 }
2344             }
2345             return key + suffix;
2346         }
2347         private JCDiagnostic getLocationDiag(Symbol location, Type site) {
2348             if (location.kind == VAR) {
2349                 return diags.fragment("location.1",
2350                     kindName(location),
2351                     location,
2352                     location.type);
2353             } else {
2354                 return diags.fragment("location",
2355                     typeKindName(site),
2356                     site,
2357                     null);
2358             }
2359         }
2360     }
2361 
2362     /**
2363      * InvalidSymbolError error class indicating that a given symbol
2364      * (either a method, a constructor or an operand) is not applicable
2365      * given an actual arguments/type argument list.
2366      */
2367     class InapplicableSymbolError extends ResolveError {
2368 
2369         InapplicableSymbolError() {
2370             super(WRONG_MTH, "inapplicable symbol error");
2371         }
2372 
2373         protected InapplicableSymbolError(int kind, String debugName) {
2374             super(kind, debugName);
2375         }
2376 
2377         @Override
2378         public String toString() {
2379             return super.toString();
2380         }
2381 
2382         @Override
2383         public boolean exists() {
2384             return true;
2385         }
2386 
2387         @Override
2388         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
2389                 DiagnosticPosition pos,
2390                 Symbol location,
2391                 Type site,
2392                 Name name,
2393                 List<Type> argtypes,
2394                 List<Type> typeargtypes) {
2395             if (name == names.error)
2396                 return null;
2397 
2398             if (isOperator(name)) {
2399                 boolean isUnaryOp = argtypes.size() == 1;
2400                 String key = argtypes.size() == 1 ?
2401                     "operator.cant.be.applied" :
2402                     "operator.cant.be.applied.1";
2403                 Type first = argtypes.head;
2404                 Type second = !isUnaryOp ? argtypes.tail.head : null;
2405                 return diags.create(dkind, log.currentSource(), pos,
2406                         key, name, first, second);
2407             }
2408             else {
2409                 Candidate c = errCandidate();
2410                 Symbol ws = c.sym.asMemberOf(site, types);
2411                 return diags.create(dkind, log.currentSource(), pos,
2412                           "cant.apply.symbol" + (c.details != null ? ".1" : ""),
2413                           kindName(ws),
2414                           ws.name == names.init ? ws.owner.name : ws.name,
2415                           methodArguments(ws.type.getParameterTypes()),
2416                           methodArguments(argtypes),
2417                           kindName(ws.owner),
2418                           ws.owner.type,
2419                           c.details);
2420             }
2421         }
2422 
2423         @Override
2424         public Symbol access(Name name, TypeSymbol location) {
2425             return types.createErrorType(name, location, syms.errSymbol.type).tsym;
2426         }
2427 
2428         protected boolean shouldReport(Candidate c) {
2429             return !c.isApplicable() &&
2430                     (((c.sym.flags() & VARARGS) != 0 && c.step == VARARITY) ||
2431                       (c.sym.flags() & VARARGS) == 0 && c.step == (boxingEnabled ? BOX : BASIC));
2432         }
2433 
2434         private Candidate errCandidate() {
2435             for (Candidate c : currentResolutionContext.candidates) {
2436                 if (shouldReport(c)) {
2437                     return c;
2438                 }
2439             }
2440             Assert.error();
2441             return null;
2442         }
2443     }
2444 
2445     /**
2446      * ResolveError error class indicating that a set of symbols
2447      * (either methods, constructors or operands) is not applicable
2448      * given an actual arguments/type argument list.
2449      */
2450     class InapplicableSymbolsError extends InapplicableSymbolError {
2451 
2452         InapplicableSymbolsError() {
2453             super(WRONG_MTHS, "inapplicable symbols");
2454         }
2455 
2456         @Override
2457         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
2458                 DiagnosticPosition pos,
2459                 Symbol location,
2460                 Type site,
2461                 Name name,
2462                 List<Type> argtypes,
2463                 List<Type> typeargtypes) {
2464             if (currentResolutionContext.candidates.nonEmpty()) {
2465                 JCDiagnostic err = diags.create(dkind,
2466                         log.currentSource(),
2467                         pos,
2468                         "cant.apply.symbols",
2469                         name == names.init ? KindName.CONSTRUCTOR : absentKind(kind),
2470                         getName(),
2471                         argtypes);
2472                 return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(site));
2473             } else {
2474                 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos,
2475                     location, site, name, argtypes, typeargtypes);
2476             }
2477         }
2478 
2479         //where
2480         List<JCDiagnostic> candidateDetails(Type site) {
2481             List<JCDiagnostic> details = List.nil();
2482             for (Candidate c : currentResolutionContext.candidates) {
2483                 if (!shouldReport(c)) continue;
2484                 JCDiagnostic detailDiag = diags.fragment("inapplicable.method",
2485                         Kinds.kindName(c.sym),
2486                         c.sym.location(site, types),
2487                         c.sym.asMemberOf(site, types),
2488                         c.details);
2489                 details = details.prepend(detailDiag);
2490             }
2491             return details.reverse();
2492         }
2493 
2494         private Name getName() {
2495             Symbol sym = currentResolutionContext.candidates.head.sym;
2496             return sym.name == names.init ?
2497                 sym.owner.name :
2498                 sym.name;
2499         }
2500     }
2501 
2502     /**
2503      * An InvalidSymbolError error class indicating that a symbol is not
2504      * accessible from a given site
2505      */
2506     class AccessError extends InvalidSymbolError {
2507 
2508         private Env<AttrContext> env;
2509         private Type site;
2510 
2511         AccessError(Symbol sym) {
2512             this(null, null, sym);
2513         }
2514 
2515         AccessError(Env<AttrContext> env, Type site, Symbol sym) {
2516             super(HIDDEN, sym, "access error");
2517             this.env = env;
2518             this.site = site;
2519             if (debugResolve)
2520                 log.error("proc.messager", sym + " @ " + site + " is inaccessible.");
2521         }
2522 
2523         @Override
2524         public boolean exists() {
2525             return false;
2526         }
2527 
2528         @Override
2529         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
2530                 DiagnosticPosition pos,
2531                 Symbol location,
2532                 Type site,
2533                 Name name,
2534                 List<Type> argtypes,
2535                 List<Type> typeargtypes) {
2536             if (sym.owner.type.tag == ERROR)
2537                 return null;
2538 
2539             if (sym.name == names.init && sym.owner != site.tsym) {
2540                 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind,
2541                         pos, location, site, name, argtypes, typeargtypes);
2542             }
2543             else if ((sym.flags() & PUBLIC) != 0
2544                 || (env != null && this.site != null
2545                     && !isAccessible(env, this.site))) {
2546                 return diags.create(dkind, log.currentSource(),
2547                         pos, "not.def.access.class.intf.cant.access",
2548                     sym, sym.location());
2549             }
2550             else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) {
2551                 return diags.create(dkind, log.currentSource(),
2552                         pos, "report.access", sym,
2553                         asFlagSet(sym.flags() & (PRIVATE | PROTECTED)),
2554                         sym.location());
2555             }
2556             else {
2557                 return diags.create(dkind, log.currentSource(),
2558                         pos, "not.def.public.cant.access", sym, sym.location());
2559             }
2560         }
2561     }
2562 
2563     /**
2564      * InvalidSymbolError error class indicating that an instance member
2565      * has erroneously been accessed from a static context.
2566      */
2567     class StaticError extends InvalidSymbolError {
2568 
2569         StaticError(Symbol sym) {
2570             super(STATICERR, sym, "static error");
2571         }
2572 
2573         @Override
2574         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
2575                 DiagnosticPosition pos,
2576                 Symbol location,
2577                 Type site,
2578                 Name name,
2579                 List<Type> argtypes,
2580                 List<Type> typeargtypes) {
2581             Symbol errSym = ((sym.kind == TYP && sym.type.tag == CLASS)
2582                 ? types.erasure(sym.type).tsym
2583                 : sym);
2584             return diags.create(dkind, log.currentSource(), pos,
2585                     "non-static.cant.be.ref", kindName(sym), errSym);
2586         }
2587     }
2588 
2589     /**
2590      * InvalidSymbolError error class indicating that a pair of symbols
2591      * (either methods, constructors or operands) are ambiguous
2592      * given an actual arguments/type argument list.
2593      */
2594     class AmbiguityError extends InvalidSymbolError {
2595 
2596         /** The other maximally specific symbol */
2597         Symbol sym2;
2598 
2599         AmbiguityError(Symbol sym1, Symbol sym2) {
2600             super(AMBIGUOUS, sym1, "ambiguity error");
2601             this.sym2 = sym2;
2602         }
2603 
2604         @Override
2605         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
2606                 DiagnosticPosition pos,
2607                 Symbol location,
2608                 Type site,
2609                 Name name,
2610                 List<Type> argtypes,
2611                 List<Type> typeargtypes) {
2612             AmbiguityError pair = this;
2613             while (true) {
2614                 if (pair.sym.kind == AMBIGUOUS)
2615                     pair = (AmbiguityError)pair.sym;
2616                 else if (pair.sym2.kind == AMBIGUOUS)
2617                     pair = (AmbiguityError)pair.sym2;
2618                 else break;
2619             }
2620             Name sname = pair.sym.name;
2621             if (sname == names.init) sname = pair.sym.owner.name;
2622             return diags.create(dkind, log.currentSource(),
2623                       pos, "ref.ambiguous", sname,
2624                       kindName(pair.sym),
2625                       pair.sym,
2626                       pair.sym.location(site, types),
2627                       kindName(pair.sym2),
2628                       pair.sym2,
2629                       pair.sym2.location(site, types));
2630         }
2631     }
2632 
2633     enum MethodResolutionPhase {
2634         BASIC(false, false),
2635         BOX(true, false),
2636         VARARITY(true, true);
2637 
2638         boolean isBoxingRequired;
2639         boolean isVarargsRequired;
2640 
2641         MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) {
2642            this.isBoxingRequired = isBoxingRequired;
2643            this.isVarargsRequired = isVarargsRequired;
2644         }
2645 
2646         public boolean isBoxingRequired() {
2647             return isBoxingRequired;
2648         }
2649 
2650         public boolean isVarargsRequired() {
2651             return isVarargsRequired;
2652         }
2653 
2654         public boolean isApplicable(boolean boxingEnabled, boolean varargsEnabled) {
2655             return (varargsEnabled || !isVarargsRequired) &&
2656                    (boxingEnabled || !isBoxingRequired);
2657         }
2658     }
2659 
2660     final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
2661 
2662     /**
2663      * A resolution context is used to keep track of intermediate results of
2664      * overload resolution, such as list of method that are not applicable
2665      * (used to generate more precise diagnostics) and so on. Resolution contexts
2666      * can be nested - this means that when each overload resolution routine should
2667      * work within the resolution context it created.
2668      */
2669     class MethodResolutionContext {
2670 
2671         private List<Candidate> candidates = List.nil();
2672 
2673         private Map<MethodResolutionPhase, Symbol> resolutionCache =
2674             new EnumMap<MethodResolutionPhase, Symbol>(MethodResolutionPhase.class);
2675 
2676         private MethodResolutionPhase step = null;
2677 
2678         private boolean internalResolution = false;
2679 
2680         private MethodResolutionPhase firstErroneousResolutionPhase() {
2681             MethodResolutionPhase bestSoFar = BASIC;
2682             Symbol sym = methodNotFound;
2683             List<MethodResolutionPhase> steps = methodResolutionSteps;
2684             while (steps.nonEmpty() &&
2685                    steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
2686                    sym.kind >= WRONG_MTHS) {
2687                 sym = resolutionCache.get(steps.head);
2688                 bestSoFar = steps.head;
2689                 steps = steps.tail;
2690             }
2691             return bestSoFar;
2692         }
2693 
2694         void addInapplicableCandidate(Symbol sym, JCDiagnostic details) {
2695             Candidate c = new Candidate(currentResolutionContext.step, sym, details, null);
2696             if (!candidates.contains(c))
2697                 candidates = candidates.append(c);
2698         }
2699 
2700         void addApplicableCandidate(Symbol sym, Type mtype) {
2701             Candidate c = new Candidate(currentResolutionContext.step, sym, null, mtype);
2702             candidates = candidates.append(c);
2703         }
2704 
2705         /**
2706          * This class represents an overload resolution candidate. There are two
2707          * kinds of candidates: applicable methods and inapplicable methods;
2708          * applicable methods have a pointer to the instantiated method type,
2709          * while inapplicable candidates contain further details about the
2710          * reason why the method has been considered inapplicable.
2711          */
2712         class Candidate {
2713 
2714             final MethodResolutionPhase step;
2715             final Symbol sym;
2716             final JCDiagnostic details;
2717             final Type mtype;
2718 
2719             private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) {
2720                 this.step = step;
2721                 this.sym = sym;
2722                 this.details = details;
2723                 this.mtype = mtype;
2724             }
2725 
2726             @Override
2727             public boolean equals(Object o) {
2728                 if (o instanceof Candidate) {
2729                     Symbol s1 = this.sym;
2730                     Symbol s2 = ((Candidate)o).sym;
2731                     if  ((s1 != s2 &&
2732                         (s1.overrides(s2, s1.owner.type.tsym, types, false) ||
2733                         (s2.overrides(s1, s2.owner.type.tsym, types, false)))) ||
2734                         ((s1.isConstructor() || s2.isConstructor()) && s1.owner != s2.owner))
2735                         return true;
2736                 }
2737                 return false;
2738             }
2739 
2740             boolean isApplicable() {
2741                 return mtype != null;
2742             }
2743         }
2744     }
2745 
2746     MethodResolutionContext currentResolutionContext = null;
2747 }