src/share/classes/com/sun/tools/javac/comp/Resolve.java

Tue, 16 Jun 2009 10:46:16 +0100

author
mcimadamore
date
Tue, 16 Jun 2009 10:46:16 +0100
changeset 298
3ac205ad1f05
parent 267
e2722bd43f3a
child 299
22872b24d38c
permissions
-rw-r--r--

6835428: regression: return-type inference rejects valid code
Summary: Redundant subtyping test during type-inference ends up in rejecting legal code
Reviewed-by: jjg

     1 /*
     2  * Copyright 1999-2008 Sun Microsystems, Inc.  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.  Sun designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
    23  * have any questions.
    24  */
    26 package com.sun.tools.javac.comp;
    28 import com.sun.tools.javac.util.*;
    29 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    30 import com.sun.tools.javac.code.*;
    31 import com.sun.tools.javac.jvm.*;
    32 import com.sun.tools.javac.tree.*;
    33 import com.sun.tools.javac.api.Formattable.LocalizedString;
    34 import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
    36 import com.sun.tools.javac.code.Type.*;
    37 import com.sun.tools.javac.code.Symbol.*;
    38 import com.sun.tools.javac.tree.JCTree.*;
    40 import static com.sun.tools.javac.code.Flags.*;
    41 import static com.sun.tools.javac.code.Kinds.*;
    42 import static com.sun.tools.javac.code.TypeTags.*;
    43 import javax.lang.model.element.ElementVisitor;
    45 import java.util.Map;
    46 import java.util.HashMap;
    48 /** Helper class for name resolution, used mostly by the attribution phase.
    49  *
    50  *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
    51  *  you write code that depends on this, you do so at your own risk.
    52  *  This code and its internal interfaces are subject to change or
    53  *  deletion without notice.</b>
    54  */
    55 public class Resolve {
    56     protected static final Context.Key<Resolve> resolveKey =
    57         new Context.Key<Resolve>();
    59     Names names;
    60     Log log;
    61     Symtab syms;
    62     Check chk;
    63     Infer infer;
    64     ClassReader reader;
    65     TreeInfo treeinfo;
    66     Types types;
    67     JCDiagnostic.Factory diags;
    68     public final boolean boxingEnabled; // = source.allowBoxing();
    69     public final boolean varargsEnabled; // = source.allowVarargs();
    70     public final boolean allowInvokedynamic; // = options.get("invokedynamic");
    71     private final boolean debugResolve;
    73     public static Resolve instance(Context context) {
    74         Resolve instance = context.get(resolveKey);
    75         if (instance == null)
    76             instance = new Resolve(context);
    77         return instance;
    78     }
    80     protected Resolve(Context context) {
    81         context.put(resolveKey, this);
    82         syms = Symtab.instance(context);
    84         varNotFound = new
    85             ResolveError(ABSENT_VAR, syms.errSymbol, "variable not found");
    86         wrongMethod = new
    87             ResolveError(WRONG_MTH, syms.errSymbol, "method not found");
    88         wrongMethods = new
    89             ResolveError(WRONG_MTHS, syms.errSymbol, "wrong methods");
    90         methodNotFound = new
    91             ResolveError(ABSENT_MTH, syms.errSymbol, "method not found");
    92         typeNotFound = new
    93             ResolveError(ABSENT_TYP, syms.errSymbol, "type not found");
    95         names = Names.instance(context);
    96         log = Log.instance(context);
    97         chk = Check.instance(context);
    98         infer = Infer.instance(context);
    99         reader = ClassReader.instance(context);
   100         treeinfo = TreeInfo.instance(context);
   101         types = Types.instance(context);
   102         diags = JCDiagnostic.Factory.instance(context);
   103         Source source = Source.instance(context);
   104         boxingEnabled = source.allowBoxing();
   105         varargsEnabled = source.allowVarargs();
   106         Options options = Options.instance(context);
   107         debugResolve = options.get("debugresolve") != null;
   108         allowInvokedynamic = options.get("invokedynamic") != null;
   109     }
   111     /** error symbols, which are returned when resolution fails
   112      */
   113     final ResolveError varNotFound;
   114     final ResolveError wrongMethod;
   115     final ResolveError wrongMethods;
   116     final ResolveError methodNotFound;
   117     final ResolveError typeNotFound;
   119 /* ************************************************************************
   120  * Identifier resolution
   121  *************************************************************************/
   123     /** An environment is "static" if its static level is greater than
   124      *  the one of its outer environment
   125      */
   126     static boolean isStatic(Env<AttrContext> env) {
   127         return env.info.staticLevel > env.outer.info.staticLevel;
   128     }
   130     /** An environment is an "initializer" if it is a constructor or
   131      *  an instance initializer.
   132      */
   133     static boolean isInitializer(Env<AttrContext> env) {
   134         Symbol owner = env.info.scope.owner;
   135         return owner.isConstructor() ||
   136             owner.owner.kind == TYP &&
   137             (owner.kind == VAR ||
   138              owner.kind == MTH && (owner.flags() & BLOCK) != 0) &&
   139             (owner.flags() & STATIC) == 0;
   140     }
   142     /** Is class accessible in given evironment?
   143      *  @param env    The current environment.
   144      *  @param c      The class whose accessibility is checked.
   145      */
   146     public boolean isAccessible(Env<AttrContext> env, TypeSymbol c) {
   147         switch ((short)(c.flags() & AccessFlags)) {
   148         case PRIVATE:
   149             return
   150                 env.enclClass.sym.outermostClass() ==
   151                 c.owner.outermostClass();
   152         case 0:
   153             return
   154                 env.toplevel.packge == c.owner // fast special case
   155                 ||
   156                 env.toplevel.packge == c.packge()
   157                 ||
   158                 // Hack: this case is added since synthesized default constructors
   159                 // of anonymous classes should be allowed to access
   160                 // classes which would be inaccessible otherwise.
   161                 env.enclMethod != null &&
   162                 (env.enclMethod.mods.flags & ANONCONSTR) != 0;
   163         default: // error recovery
   164         case PUBLIC:
   165             return true;
   166         case PROTECTED:
   167             return
   168                 env.toplevel.packge == c.owner // fast special case
   169                 ||
   170                 env.toplevel.packge == c.packge()
   171                 ||
   172                 isInnerSubClass(env.enclClass.sym, c.owner);
   173         }
   174     }
   175     //where
   176         /** Is given class a subclass of given base class, or an inner class
   177          *  of a subclass?
   178          *  Return null if no such class exists.
   179          *  @param c     The class which is the subclass or is contained in it.
   180          *  @param base  The base class
   181          */
   182         private boolean isInnerSubClass(ClassSymbol c, Symbol base) {
   183             while (c != null && !c.isSubClass(base, types)) {
   184                 c = c.owner.enclClass();
   185             }
   186             return c != null;
   187         }
   189     boolean isAccessible(Env<AttrContext> env, Type t) {
   190         return (t.tag == ARRAY)
   191             ? isAccessible(env, types.elemtype(t))
   192             : isAccessible(env, t.tsym);
   193     }
   195     /** Is symbol accessible as a member of given type in given evironment?
   196      *  @param env    The current environment.
   197      *  @param site   The type of which the tested symbol is regarded
   198      *                as a member.
   199      *  @param sym    The symbol.
   200      */
   201     public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym) {
   202         if (sym.name == names.init && sym.owner != site.tsym) return false;
   203         ClassSymbol sub;
   204         switch ((short)(sym.flags() & AccessFlags)) {
   205         case PRIVATE:
   206             return
   207                 (env.enclClass.sym == sym.owner // fast special case
   208                  ||
   209                  env.enclClass.sym.outermostClass() ==
   210                  sym.owner.outermostClass())
   211                 &&
   212                 sym.isInheritedIn(site.tsym, types);
   213         case 0:
   214             return
   215                 (env.toplevel.packge == sym.owner.owner // fast special case
   216                  ||
   217                  env.toplevel.packge == sym.packge())
   218                 &&
   219                 isAccessible(env, site)
   220                 &&
   221                 sym.isInheritedIn(site.tsym, types)
   222                 &&
   223                 notOverriddenIn(site, sym);
   224         case PROTECTED:
   225             return
   226                 (env.toplevel.packge == sym.owner.owner // fast special case
   227                  ||
   228                  env.toplevel.packge == sym.packge()
   229                  ||
   230                  isProtectedAccessible(sym, env.enclClass.sym, site)
   231                  ||
   232                  // OK to select instance method or field from 'super' or type name
   233                  // (but type names should be disallowed elsewhere!)
   234                  env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP)
   235                 &&
   236                 isAccessible(env, site)
   237                 &&
   238                 notOverriddenIn(site, sym);
   239         default: // this case includes erroneous combinations as well
   240             return isAccessible(env, site) && notOverriddenIn(site, sym);
   241         }
   242     }
   243     //where
   244     /* `sym' is accessible only if not overridden by
   245      * another symbol which is a member of `site'
   246      * (because, if it is overridden, `sym' is not strictly
   247      * speaking a member of `site'.)
   248      */
   249     private boolean notOverriddenIn(Type site, Symbol sym) {
   250         if (sym.kind != MTH || sym.isConstructor() || sym.isStatic())
   251             return true;
   252         else {
   253             Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true);
   254             return (s2 == null || s2 == sym);
   255         }
   256     }
   257     //where
   258         /** Is given protected symbol accessible if it is selected from given site
   259          *  and the selection takes place in given class?
   260          *  @param sym     The symbol with protected access
   261          *  @param c       The class where the access takes place
   262          *  @site          The type of the qualifier
   263          */
   264         private
   265         boolean isProtectedAccessible(Symbol sym, ClassSymbol c, Type site) {
   266             while (c != null &&
   267                    !(c.isSubClass(sym.owner, types) &&
   268                      (c.flags() & INTERFACE) == 0 &&
   269                      // In JLS 2e 6.6.2.1, the subclass restriction applies
   270                      // only to instance fields and methods -- types are excluded
   271                      // regardless of whether they are declared 'static' or not.
   272                      ((sym.flags() & STATIC) != 0 || sym.kind == TYP || site.tsym.isSubClass(c, types))))
   273                 c = c.owner.enclClass();
   274             return c != null;
   275         }
   277     /** Try to instantiate the type of a method so that it fits
   278      *  given type arguments and argument types. If succesful, return
   279      *  the method's instantiated type, else return null.
   280      *  The instantiation will take into account an additional leading
   281      *  formal parameter if the method is an instance method seen as a member
   282      *  of un underdetermined site In this case, we treat site as an additional
   283      *  parameter and the parameters of the class containing the method as
   284      *  additional type variables that get instantiated.
   285      *
   286      *  @param env         The current environment
   287      *  @param site        The type of which the method is a member.
   288      *  @param m           The method symbol.
   289      *  @param argtypes    The invocation's given value arguments.
   290      *  @param typeargtypes    The invocation's given type arguments.
   291      *  @param allowBoxing Allow boxing conversions of arguments.
   292      *  @param useVarargs Box trailing arguments into an array for varargs.
   293      */
   294     Type rawInstantiate(Env<AttrContext> env,
   295                         Type site,
   296                         Symbol m,
   297                         List<Type> argtypes,
   298                         List<Type> typeargtypes,
   299                         boolean allowBoxing,
   300                         boolean useVarargs,
   301                         Warner warn)
   302         throws Infer.NoInstanceException {
   303         if (useVarargs && (m.flags() & VARARGS) == 0) return null;
   304         Type mt = types.memberType(site, m);
   306         // tvars is the list of formal type variables for which type arguments
   307         // need to inferred.
   308         List<Type> tvars = env.info.tvars;
   309         if (typeargtypes == null) typeargtypes = List.nil();
   310         if (mt.tag != FORALL && typeargtypes.nonEmpty()) {
   311             // This is not a polymorphic method, but typeargs are supplied
   312             // which is fine, see JLS3 15.12.2.1
   313         } else if (mt.tag == FORALL && typeargtypes.nonEmpty()) {
   314             ForAll pmt = (ForAll) mt;
   315             if (typeargtypes.length() != pmt.tvars.length())
   316                 return null;
   317             // Check type arguments are within bounds
   318             List<Type> formals = pmt.tvars;
   319             List<Type> actuals = typeargtypes;
   320             while (formals.nonEmpty() && actuals.nonEmpty()) {
   321                 List<Type> bounds = types.subst(types.getBounds((TypeVar)formals.head),
   322                                                 pmt.tvars, typeargtypes);
   323                 for (; bounds.nonEmpty(); bounds = bounds.tail)
   324                     if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn))
   325                         return null;
   326                 formals = formals.tail;
   327                 actuals = actuals.tail;
   328             }
   329             mt = types.subst(pmt.qtype, pmt.tvars, typeargtypes);
   330         } else if (mt.tag == FORALL) {
   331             ForAll pmt = (ForAll) mt;
   332             List<Type> tvars1 = types.newInstances(pmt.tvars);
   333             tvars = tvars.appendList(tvars1);
   334             mt = types.subst(pmt.qtype, pmt.tvars, tvars1);
   335         }
   337         // find out whether we need to go the slow route via infer
   338         boolean instNeeded = tvars.tail != null/*inlined: tvars.nonEmpty()*/;
   339         for (List<Type> l = argtypes;
   340              l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded;
   341              l = l.tail) {
   342             if (l.head.tag == FORALL) instNeeded = true;
   343         }
   345         if (instNeeded)
   346             return
   347             infer.instantiateMethod(tvars,
   348                                     (MethodType)mt,
   349                                     argtypes,
   350                                     allowBoxing,
   351                                     useVarargs,
   352                                     warn);
   353         return
   354             argumentsAcceptable(argtypes, mt.getParameterTypes(),
   355                                 allowBoxing, useVarargs, warn)
   356             ? mt
   357             : null;
   358     }
   360     /** Same but returns null instead throwing a NoInstanceException
   361      */
   362     Type instantiate(Env<AttrContext> env,
   363                      Type site,
   364                      Symbol m,
   365                      List<Type> argtypes,
   366                      List<Type> typeargtypes,
   367                      boolean allowBoxing,
   368                      boolean useVarargs,
   369                      Warner warn) {
   370         try {
   371             return rawInstantiate(env, site, m, argtypes, typeargtypes,
   372                                   allowBoxing, useVarargs, warn);
   373         } catch (Infer.NoInstanceException ex) {
   374             return null;
   375         }
   376     }
   378     /** Check if a parameter list accepts a list of args.
   379      */
   380     boolean argumentsAcceptable(List<Type> argtypes,
   381                                 List<Type> formals,
   382                                 boolean allowBoxing,
   383                                 boolean useVarargs,
   384                                 Warner warn) {
   385         Type varargsFormal = useVarargs ? formals.last() : null;
   386         while (argtypes.nonEmpty() && formals.head != varargsFormal) {
   387             boolean works = allowBoxing
   388                 ? types.isConvertible(argtypes.head, formals.head, warn)
   389                 : types.isSubtypeUnchecked(argtypes.head, formals.head, warn);
   390             if (!works) return false;
   391             argtypes = argtypes.tail;
   392             formals = formals.tail;
   393         }
   394         if (formals.head != varargsFormal) return false; // not enough args
   395         if (!useVarargs)
   396             return argtypes.isEmpty();
   397         Type elt = types.elemtype(varargsFormal);
   398         while (argtypes.nonEmpty()) {
   399             if (!types.isConvertible(argtypes.head, elt, warn))
   400                 return false;
   401             argtypes = argtypes.tail;
   402         }
   403         return true;
   404     }
   406 /* ***************************************************************************
   407  *  Symbol lookup
   408  *  the following naming conventions for arguments are used
   409  *
   410  *       env      is the environment where the symbol was mentioned
   411  *       site     is the type of which the symbol is a member
   412  *       name     is the symbol's name
   413  *                if no arguments are given
   414  *       argtypes are the value arguments, if we search for a method
   415  *
   416  *  If no symbol was found, a ResolveError detailing the problem is returned.
   417  ****************************************************************************/
   419     /** Find field. Synthetic fields are always skipped.
   420      *  @param env     The current environment.
   421      *  @param site    The original type from where the selection takes place.
   422      *  @param name    The name of the field.
   423      *  @param c       The class to search for the field. This is always
   424      *                 a superclass or implemented interface of site's class.
   425      */
   426     Symbol findField(Env<AttrContext> env,
   427                      Type site,
   428                      Name name,
   429                      TypeSymbol c) {
   430         while (c.type.tag == TYPEVAR)
   431             c = c.type.getUpperBound().tsym;
   432         Symbol bestSoFar = varNotFound;
   433         Symbol sym;
   434         Scope.Entry e = c.members().lookup(name);
   435         while (e.scope != null) {
   436             if (e.sym.kind == VAR && (e.sym.flags_field & SYNTHETIC) == 0) {
   437                 return isAccessible(env, site, e.sym)
   438                     ? e.sym : new AccessError(env, site, e.sym);
   439             }
   440             e = e.next();
   441         }
   442         Type st = types.supertype(c.type);
   443         if (st != null && (st.tag == CLASS || st.tag == TYPEVAR)) {
   444             sym = findField(env, site, name, st.tsym);
   445             if (sym.kind < bestSoFar.kind) bestSoFar = sym;
   446         }
   447         for (List<Type> l = types.interfaces(c.type);
   448              bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
   449              l = l.tail) {
   450             sym = findField(env, site, name, l.head.tsym);
   451             if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS &&
   452                 sym.owner != bestSoFar.owner)
   453                 bestSoFar = new AmbiguityError(bestSoFar, sym);
   454             else if (sym.kind < bestSoFar.kind)
   455                 bestSoFar = sym;
   456         }
   457         return bestSoFar;
   458     }
   460     /** Resolve a field identifier, throw a fatal error if not found.
   461      *  @param pos       The position to use for error reporting.
   462      *  @param env       The environment current at the method invocation.
   463      *  @param site      The type of the qualifying expression, in which
   464      *                   identifier is searched.
   465      *  @param name      The identifier's name.
   466      */
   467     public VarSymbol resolveInternalField(DiagnosticPosition pos, Env<AttrContext> env,
   468                                           Type site, Name name) {
   469         Symbol sym = findField(env, site, name, site.tsym);
   470         if (sym.kind == VAR) return (VarSymbol)sym;
   471         else throw new FatalError(
   472                  diags.fragment("fatal.err.cant.locate.field",
   473                                 name));
   474     }
   476     /** Find unqualified variable or field with given name.
   477      *  Synthetic fields always skipped.
   478      *  @param env     The current environment.
   479      *  @param name    The name of the variable or field.
   480      */
   481     Symbol findVar(Env<AttrContext> env, Name name) {
   482         Symbol bestSoFar = varNotFound;
   483         Symbol sym;
   484         Env<AttrContext> env1 = env;
   485         boolean staticOnly = false;
   486         while (env1.outer != null) {
   487             if (isStatic(env1)) staticOnly = true;
   488             Scope.Entry e = env1.info.scope.lookup(name);
   489             while (e.scope != null &&
   490                    (e.sym.kind != VAR ||
   491                     (e.sym.flags_field & SYNTHETIC) != 0))
   492                 e = e.next();
   493             sym = (e.scope != null)
   494                 ? e.sym
   495                 : findField(
   496                     env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
   497             if (sym.exists()) {
   498                 if (staticOnly &&
   499                     sym.kind == VAR &&
   500                     sym.owner.kind == TYP &&
   501                     (sym.flags() & STATIC) == 0)
   502                     return new StaticError(sym);
   503                 else
   504                     return sym;
   505             } else if (sym.kind < bestSoFar.kind) {
   506                 bestSoFar = sym;
   507             }
   509             if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
   510             env1 = env1.outer;
   511         }
   513         sym = findField(env, syms.predefClass.type, name, syms.predefClass);
   514         if (sym.exists())
   515             return sym;
   516         if (bestSoFar.exists())
   517             return bestSoFar;
   519         Scope.Entry e = env.toplevel.namedImportScope.lookup(name);
   520         for (; e.scope != null; e = e.next()) {
   521             sym = e.sym;
   522             Type origin = e.getOrigin().owner.type;
   523             if (sym.kind == VAR) {
   524                 if (e.sym.owner.type != origin)
   525                     sym = sym.clone(e.getOrigin().owner);
   526                 return isAccessible(env, origin, sym)
   527                     ? sym : new AccessError(env, origin, sym);
   528             }
   529         }
   531         Symbol origin = null;
   532         e = env.toplevel.starImportScope.lookup(name);
   533         for (; e.scope != null; e = e.next()) {
   534             sym = e.sym;
   535             if (sym.kind != VAR)
   536                 continue;
   537             // invariant: sym.kind == VAR
   538             if (bestSoFar.kind < AMBIGUOUS && sym.owner != bestSoFar.owner)
   539                 return new AmbiguityError(bestSoFar, sym);
   540             else if (bestSoFar.kind >= VAR) {
   541                 origin = e.getOrigin().owner;
   542                 bestSoFar = isAccessible(env, origin.type, sym)
   543                     ? sym : new AccessError(env, origin.type, sym);
   544             }
   545         }
   546         if (bestSoFar.kind == VAR && bestSoFar.owner.type != origin.type)
   547             return bestSoFar.clone(origin);
   548         else
   549             return bestSoFar;
   550     }
   552     Warner noteWarner = new Warner();
   554     /** Select the best method for a call site among two choices.
   555      *  @param env              The current environment.
   556      *  @param site             The original type from where the
   557      *                          selection takes place.
   558      *  @param argtypes         The invocation's value arguments,
   559      *  @param typeargtypes     The invocation's type arguments,
   560      *  @param sym              Proposed new best match.
   561      *  @param bestSoFar        Previously found best match.
   562      *  @param allowBoxing Allow boxing conversions of arguments.
   563      *  @param useVarargs Box trailing arguments into an array for varargs.
   564      */
   565     Symbol selectBest(Env<AttrContext> env,
   566                       Type site,
   567                       List<Type> argtypes,
   568                       List<Type> typeargtypes,
   569                       Symbol sym,
   570                       Symbol bestSoFar,
   571                       boolean allowBoxing,
   572                       boolean useVarargs,
   573                       boolean operator) {
   574         if (sym.kind == ERR) return bestSoFar;
   575         if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar;
   576         assert sym.kind < AMBIGUOUS;
   577         try {
   578             if (rawInstantiate(env, site, sym, argtypes, typeargtypes,
   579                                allowBoxing, useVarargs, Warner.noWarnings) == null) {
   580                 // inapplicable
   581                 switch (bestSoFar.kind) {
   582                 case ABSENT_MTH: return wrongMethod.setWrongSym(sym);
   583                 case WRONG_MTH: return wrongMethods;
   584                 default: return bestSoFar;
   585                 }
   586             }
   587         } catch (Infer.NoInstanceException ex) {
   588             switch (bestSoFar.kind) {
   589             case ABSENT_MTH:
   590                 return wrongMethod.setWrongSym(sym, ex.getDiagnostic());
   591             case WRONG_MTH:
   592                 return wrongMethods;
   593             default:
   594                 return bestSoFar;
   595             }
   596         }
   597         if (!isAccessible(env, site, sym)) {
   598             return (bestSoFar.kind == ABSENT_MTH)
   599                 ? new AccessError(env, site, sym)
   600                 : bestSoFar;
   601         }
   602         return (bestSoFar.kind > AMBIGUOUS)
   603             ? sym
   604             : mostSpecific(sym, bestSoFar, env, site,
   605                            allowBoxing && operator, useVarargs);
   606     }
   608     /* Return the most specific of the two methods for a call,
   609      *  given that both are accessible and applicable.
   610      *  @param m1               A new candidate for most specific.
   611      *  @param m2               The previous most specific candidate.
   612      *  @param env              The current environment.
   613      *  @param site             The original type from where the selection
   614      *                          takes place.
   615      *  @param allowBoxing Allow boxing conversions of arguments.
   616      *  @param useVarargs Box trailing arguments into an array for varargs.
   617      */
   618     Symbol mostSpecific(Symbol m1,
   619                         Symbol m2,
   620                         Env<AttrContext> env,
   621                         final Type site,
   622                         boolean allowBoxing,
   623                         boolean useVarargs) {
   624         switch (m2.kind) {
   625         case MTH:
   626             if (m1 == m2) return m1;
   627             Type mt1 = types.memberType(site, m1);
   628             noteWarner.unchecked = false;
   629             boolean m1SignatureMoreSpecific =
   630                 (instantiate(env, site, m2, types.lowerBoundArgtypes(mt1), null,
   631                              allowBoxing, false, noteWarner) != null ||
   632                  useVarargs && instantiate(env, site, m2, types.lowerBoundArgtypes(mt1), null,
   633                                            allowBoxing, true, noteWarner) != null) &&
   634                 !noteWarner.unchecked;
   635             Type mt2 = types.memberType(site, m2);
   636             noteWarner.unchecked = false;
   637             boolean m2SignatureMoreSpecific =
   638                 (instantiate(env, site, m1, types.lowerBoundArgtypes(mt2), null,
   639                              allowBoxing, false, noteWarner) != null ||
   640                  useVarargs && instantiate(env, site, m1, types.lowerBoundArgtypes(mt2), null,
   641                                            allowBoxing, true, noteWarner) != null) &&
   642                 !noteWarner.unchecked;
   643             if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) {
   644                 if (!types.overrideEquivalent(mt1, mt2))
   645                     return new AmbiguityError(m1, m2);
   646                 // same signature; select (a) the non-bridge method, or
   647                 // (b) the one that overrides the other, or (c) the concrete
   648                 // one, or (d) merge both abstract signatures
   649                 if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE)) {
   650                     return ((m1.flags() & BRIDGE) != 0) ? m2 : m1;
   651                 }
   652                 // if one overrides or hides the other, use it
   653                 TypeSymbol m1Owner = (TypeSymbol)m1.owner;
   654                 TypeSymbol m2Owner = (TypeSymbol)m2.owner;
   655                 if (types.asSuper(m1Owner.type, m2Owner) != null &&
   656                     ((m1.owner.flags_field & INTERFACE) == 0 ||
   657                      (m2.owner.flags_field & INTERFACE) != 0) &&
   658                     m1.overrides(m2, m1Owner, types, false))
   659                     return m1;
   660                 if (types.asSuper(m2Owner.type, m1Owner) != null &&
   661                     ((m2.owner.flags_field & INTERFACE) == 0 ||
   662                      (m1.owner.flags_field & INTERFACE) != 0) &&
   663                     m2.overrides(m1, m2Owner, types, false))
   664                     return m2;
   665                 boolean m1Abstract = (m1.flags() & ABSTRACT) != 0;
   666                 boolean m2Abstract = (m2.flags() & ABSTRACT) != 0;
   667                 if (m1Abstract && !m2Abstract) return m2;
   668                 if (m2Abstract && !m1Abstract) return m1;
   669                 // both abstract or both concrete
   670                 if (!m1Abstract && !m2Abstract)
   671                     return new AmbiguityError(m1, m2);
   672                 // check that both signatures have the same erasure
   673                 if (!types.isSameTypes(m1.erasure(types).getParameterTypes(),
   674                                        m2.erasure(types).getParameterTypes()))
   675                     return new AmbiguityError(m1, m2);
   676                 // both abstract, neither overridden; merge throws clause and result type
   677                 Symbol mostSpecific;
   678                 Type result2 = mt2.getReturnType();
   679                 if (mt2.tag == FORALL)
   680                     result2 = types.subst(result2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars);
   681                 if (types.isSubtype(mt1.getReturnType(), result2)) {
   682                     mostSpecific = m1;
   683                 } else if (types.isSubtype(result2, mt1.getReturnType())) {
   684                     mostSpecific = m2;
   685                 } else {
   686                     // Theoretically, this can't happen, but it is possible
   687                     // due to error recovery or mixing incompatible class files
   688                     return new AmbiguityError(m1, m2);
   689                 }
   690                 MethodSymbol result = new MethodSymbol(
   691                         mostSpecific.flags(),
   692                         mostSpecific.name,
   693                         null,
   694                         mostSpecific.owner) {
   695                     @Override
   696                     public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
   697                         if (origin == site.tsym)
   698                             return this;
   699                         else
   700                             return super.implementation(origin, types, checkResult);
   701                     }
   702                 };
   703                 result.type = (Type)mostSpecific.type.clone();
   704                 result.type.setThrown(chk.intersect(mt1.getThrownTypes(),
   705                                                     mt2.getThrownTypes()));
   706                 return result;
   707             }
   708             if (m1SignatureMoreSpecific) return m1;
   709             if (m2SignatureMoreSpecific) return m2;
   710             return new AmbiguityError(m1, m2);
   711         case AMBIGUOUS:
   712             AmbiguityError e = (AmbiguityError)m2;
   713             Symbol err1 = mostSpecific(m1, e.sym1, env, site, allowBoxing, useVarargs);
   714             Symbol err2 = mostSpecific(m1, e.sym2, env, site, allowBoxing, useVarargs);
   715             if (err1 == err2) return err1;
   716             if (err1 == e.sym1 && err2 == e.sym2) return m2;
   717             if (err1 instanceof AmbiguityError &&
   718                 err2 instanceof AmbiguityError &&
   719                 ((AmbiguityError)err1).sym1 == ((AmbiguityError)err2).sym1)
   720                 return new AmbiguityError(m1, m2);
   721             else
   722                 return new AmbiguityError(err1, err2);
   723         default:
   724             throw new AssertionError();
   725         }
   726     }
   728     /** Find best qualified method matching given name, type and value
   729      *  arguments.
   730      *  @param env       The current environment.
   731      *  @param site      The original type from where the selection
   732      *                   takes place.
   733      *  @param name      The method's name.
   734      *  @param argtypes  The method's value arguments.
   735      *  @param typeargtypes The method's type arguments
   736      *  @param allowBoxing Allow boxing conversions of arguments.
   737      *  @param useVarargs Box trailing arguments into an array for varargs.
   738      */
   739     Symbol findMethod(Env<AttrContext> env,
   740                       Type site,
   741                       Name name,
   742                       List<Type> argtypes,
   743                       List<Type> typeargtypes,
   744                       boolean allowBoxing,
   745                       boolean useVarargs,
   746                       boolean operator) {
   747         return findMethod(env,
   748                           site,
   749                           name,
   750                           argtypes,
   751                           typeargtypes,
   752                           site.tsym.type,
   753                           true,
   754                           methodNotFound,
   755                           allowBoxing,
   756                           useVarargs,
   757                           operator);
   758     }
   759     // where
   760     private Symbol findMethod(Env<AttrContext> env,
   761                               Type site,
   762                               Name name,
   763                               List<Type> argtypes,
   764                               List<Type> typeargtypes,
   765                               Type intype,
   766                               boolean abstractok,
   767                               Symbol bestSoFar,
   768                               boolean allowBoxing,
   769                               boolean useVarargs,
   770                               boolean operator) {
   771         for (Type ct = intype; ct.tag == CLASS || ct.tag == TYPEVAR; ct = types.supertype(ct)) {
   772             while (ct.tag == TYPEVAR)
   773                 ct = ct.getUpperBound();
   774             ClassSymbol c = (ClassSymbol)ct.tsym;
   775             if ((c.flags() & (ABSTRACT | INTERFACE | ENUM)) == 0)
   776                 abstractok = false;
   777             for (Scope.Entry e = c.members().lookup(name);
   778                  e.scope != null;
   779                  e = e.next()) {
   780                 //- System.out.println(" e " + e.sym);
   781                 if (e.sym.kind == MTH &&
   782                     (e.sym.flags_field & SYNTHETIC) == 0) {
   783                     bestSoFar = selectBest(env, site, argtypes, typeargtypes,
   784                                            e.sym, bestSoFar,
   785                                            allowBoxing,
   786                                            useVarargs,
   787                                            operator);
   788                 }
   789             }
   790             //- System.out.println(" - " + bestSoFar);
   791             if (abstractok) {
   792                 Symbol concrete = methodNotFound;
   793                 if ((bestSoFar.flags() & ABSTRACT) == 0)
   794                     concrete = bestSoFar;
   795                 for (List<Type> l = types.interfaces(c.type);
   796                      l.nonEmpty();
   797                      l = l.tail) {
   798                     bestSoFar = findMethod(env, site, name, argtypes,
   799                                            typeargtypes,
   800                                            l.head, abstractok, bestSoFar,
   801                                            allowBoxing, useVarargs, operator);
   802                 }
   803                 if (concrete != bestSoFar &&
   804                     concrete.kind < ERR  && bestSoFar.kind < ERR &&
   805                     types.isSubSignature(concrete.type, bestSoFar.type))
   806                     bestSoFar = concrete;
   807             }
   808         }
   809         return bestSoFar;
   810     }
   812     /** Find unqualified method matching given name, type and value arguments.
   813      *  @param env       The current environment.
   814      *  @param name      The method's name.
   815      *  @param argtypes  The method's value arguments.
   816      *  @param typeargtypes  The method's type arguments.
   817      *  @param allowBoxing Allow boxing conversions of arguments.
   818      *  @param useVarargs Box trailing arguments into an array for varargs.
   819      */
   820     Symbol findFun(Env<AttrContext> env, Name name,
   821                    List<Type> argtypes, List<Type> typeargtypes,
   822                    boolean allowBoxing, boolean useVarargs) {
   823         Symbol bestSoFar = methodNotFound;
   824         Symbol sym;
   825         Env<AttrContext> env1 = env;
   826         boolean staticOnly = false;
   827         while (env1.outer != null) {
   828             if (isStatic(env1)) staticOnly = true;
   829             sym = findMethod(
   830                 env1, env1.enclClass.sym.type, name, argtypes, typeargtypes,
   831                 allowBoxing, useVarargs, false);
   832             if (sym.exists()) {
   833                 if (staticOnly &&
   834                     sym.kind == MTH &&
   835                     sym.owner.kind == TYP &&
   836                     (sym.flags() & STATIC) == 0) return new StaticError(sym);
   837                 else return sym;
   838             } else if (sym.kind < bestSoFar.kind) {
   839                 bestSoFar = sym;
   840             }
   841             if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
   842             env1 = env1.outer;
   843         }
   845         sym = findMethod(env, syms.predefClass.type, name, argtypes,
   846                          typeargtypes, allowBoxing, useVarargs, false);
   847         if (sym.exists())
   848             return sym;
   850         Scope.Entry e = env.toplevel.namedImportScope.lookup(name);
   851         for (; e.scope != null; e = e.next()) {
   852             sym = e.sym;
   853             Type origin = e.getOrigin().owner.type;
   854             if (sym.kind == MTH) {
   855                 if (e.sym.owner.type != origin)
   856                     sym = sym.clone(e.getOrigin().owner);
   857                 if (!isAccessible(env, origin, sym))
   858                     sym = new AccessError(env, origin, sym);
   859                 bestSoFar = selectBest(env, origin,
   860                                        argtypes, typeargtypes,
   861                                        sym, bestSoFar,
   862                                        allowBoxing, useVarargs, false);
   863             }
   864         }
   865         if (bestSoFar.exists())
   866             return bestSoFar;
   868         e = env.toplevel.starImportScope.lookup(name);
   869         for (; e.scope != null; e = e.next()) {
   870             sym = e.sym;
   871             Type origin = e.getOrigin().owner.type;
   872             if (sym.kind == MTH) {
   873                 if (e.sym.owner.type != origin)
   874                     sym = sym.clone(e.getOrigin().owner);
   875                 if (!isAccessible(env, origin, sym))
   876                     sym = new AccessError(env, origin, sym);
   877                 bestSoFar = selectBest(env, origin,
   878                                        argtypes, typeargtypes,
   879                                        sym, bestSoFar,
   880                                        allowBoxing, useVarargs, false);
   881             }
   882         }
   883         return bestSoFar;
   884     }
   886     /** Find or create an implicit method of exactly the given type (after erasure).
   887      *  Searches in a side table, not the main scope of the site.
   888      *  This emulates the lookup process required by JSR 292 in JVM.
   889      *  @param env       The current environment.
   890      *  @param site      The original type from where the selection
   891      *                   takes place.
   892      *  @param name      The method's name.
   893      *  @param argtypes  The method's value arguments.
   894      *  @param typeargtypes The method's type arguments
   895      */
   896     Symbol findImplicitMethod(Env<AttrContext> env,
   897                               Type site,
   898                               Name name,
   899                               List<Type> argtypes,
   900                               List<Type> typeargtypes) {
   901         assert allowInvokedynamic;
   902         assert site == syms.invokeDynamicType || (site == syms.methodHandleType && name == names.invoke);
   903         ClassSymbol c = (ClassSymbol) site.tsym;
   904         Scope implicit = c.members().next;
   905         if (implicit == null) {
   906             c.members().next = implicit = new Scope(c);
   907         }
   908         Type restype;
   909         if (typeargtypes.isEmpty()) {
   910             restype = syms.objectType;
   911         } else {
   912             restype = typeargtypes.head;
   913             if (!typeargtypes.tail.isEmpty())
   914                 return methodNotFound;
   915         }
   916         List<Type> paramtypes = Type.map(argtypes, implicitArgType);
   917         MethodType mtype = new MethodType(paramtypes,
   918                                           restype,
   919                                           List.<Type>nil(),
   920                                           syms.methodClass);
   921         int flags = PUBLIC | ABSTRACT;
   922         if (site == syms.invokeDynamicType)  flags |= STATIC;
   923         Symbol m = null;
   924         for (Scope.Entry e = implicit.lookup(name);
   925              e.scope != null;
   926              e = e.next()) {
   927             Symbol sym = e.sym;
   928             assert sym.kind == MTH;
   929             if (types.isSameType(mtype, sym.type)
   930                 && (sym.flags() & STATIC) == (flags & STATIC)) {
   931                 m = sym;
   932                 break;
   933             }
   934         }
   935         if (m == null) {
   936             // create the desired method
   937             m = new MethodSymbol(flags, name, mtype, c);
   938             implicit.enter(m);
   939         }
   940         assert argumentsAcceptable(argtypes, types.memberType(site, m).getParameterTypes(),
   941                                    false, false, Warner.noWarnings);
   942         assert null != instantiate(env, site, m, argtypes, typeargtypes, false, false, Warner.noWarnings);
   943         return m;
   944     }
   945     //where
   946         Mapping implicitArgType = new Mapping ("implicitArgType") {
   947                 public Type apply(Type t) { return implicitArgType(t); }
   948             };
   949         Type implicitArgType(Type argType) {
   950             argType = types.erasure(argType);
   951             if (argType.tag == BOT)
   952                 // nulls type as the marker type Null (which has no instances)
   953                 // TO DO: figure out how to access java.lang.Null safely, else throw nice error
   954                 //argType = types.boxedClass(syms.botType).type;
   955                 argType = types.boxedClass(syms.voidType).type;  // REMOVE
   956             return argType;
   957         }
   959     /** Load toplevel or member class with given fully qualified name and
   960      *  verify that it is accessible.
   961      *  @param env       The current environment.
   962      *  @param name      The fully qualified name of the class to be loaded.
   963      */
   964     Symbol loadClass(Env<AttrContext> env, Name name) {
   965         try {
   966             ClassSymbol c = reader.loadClass(name);
   967             return isAccessible(env, c) ? c : new AccessError(c);
   968         } catch (ClassReader.BadClassFile err) {
   969             throw err;
   970         } catch (CompletionFailure ex) {
   971             return typeNotFound;
   972         }
   973     }
   975     /** Find qualified member type.
   976      *  @param env       The current environment.
   977      *  @param site      The original type from where the selection takes
   978      *                   place.
   979      *  @param name      The type's name.
   980      *  @param c         The class to search for the member type. This is
   981      *                   always a superclass or implemented interface of
   982      *                   site's class.
   983      */
   984     Symbol findMemberType(Env<AttrContext> env,
   985                           Type site,
   986                           Name name,
   987                           TypeSymbol c) {
   988         Symbol bestSoFar = typeNotFound;
   989         Symbol sym;
   990         Scope.Entry e = c.members().lookup(name);
   991         while (e.scope != null) {
   992             if (e.sym.kind == TYP) {
   993                 return isAccessible(env, site, e.sym)
   994                     ? e.sym
   995                     : new AccessError(env, site, e.sym);
   996             }
   997             e = e.next();
   998         }
   999         Type st = types.supertype(c.type);
  1000         if (st != null && st.tag == CLASS) {
  1001             sym = findMemberType(env, site, name, st.tsym);
  1002             if (sym.kind < bestSoFar.kind) bestSoFar = sym;
  1004         for (List<Type> l = types.interfaces(c.type);
  1005              bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
  1006              l = l.tail) {
  1007             sym = findMemberType(env, site, name, l.head.tsym);
  1008             if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS &&
  1009                 sym.owner != bestSoFar.owner)
  1010                 bestSoFar = new AmbiguityError(bestSoFar, sym);
  1011             else if (sym.kind < bestSoFar.kind)
  1012                 bestSoFar = sym;
  1014         return bestSoFar;
  1017     /** Find a global type in given scope and load corresponding class.
  1018      *  @param env       The current environment.
  1019      *  @param scope     The scope in which to look for the type.
  1020      *  @param name      The type's name.
  1021      */
  1022     Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) {
  1023         Symbol bestSoFar = typeNotFound;
  1024         for (Scope.Entry e = scope.lookup(name); e.scope != null; e = e.next()) {
  1025             Symbol sym = loadClass(env, e.sym.flatName());
  1026             if (bestSoFar.kind == TYP && sym.kind == TYP &&
  1027                 bestSoFar != sym)
  1028                 return new AmbiguityError(bestSoFar, sym);
  1029             else if (sym.kind < bestSoFar.kind)
  1030                 bestSoFar = sym;
  1032         return bestSoFar;
  1035     /** Find an unqualified type symbol.
  1036      *  @param env       The current environment.
  1037      *  @param name      The type's name.
  1038      */
  1039     Symbol findType(Env<AttrContext> env, Name name) {
  1040         Symbol bestSoFar = typeNotFound;
  1041         Symbol sym;
  1042         boolean staticOnly = false;
  1043         for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) {
  1044             if (isStatic(env1)) staticOnly = true;
  1045             for (Scope.Entry e = env1.info.scope.lookup(name);
  1046                  e.scope != null;
  1047                  e = e.next()) {
  1048                 if (e.sym.kind == TYP) {
  1049                     if (staticOnly &&
  1050                         e.sym.type.tag == TYPEVAR &&
  1051                         e.sym.owner.kind == TYP) return new StaticError(e.sym);
  1052                     return e.sym;
  1056             sym = findMemberType(env1, env1.enclClass.sym.type, name,
  1057                                  env1.enclClass.sym);
  1058             if (staticOnly && sym.kind == TYP &&
  1059                 sym.type.tag == CLASS &&
  1060                 sym.type.getEnclosingType().tag == CLASS &&
  1061                 env1.enclClass.sym.type.isParameterized() &&
  1062                 sym.type.getEnclosingType().isParameterized())
  1063                 return new StaticError(sym);
  1064             else if (sym.exists()) return sym;
  1065             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
  1067             JCClassDecl encl = env1.baseClause ? (JCClassDecl)env1.tree : env1.enclClass;
  1068             if ((encl.sym.flags() & STATIC) != 0)
  1069                 staticOnly = true;
  1072         if (env.tree.getTag() != JCTree.IMPORT) {
  1073             sym = findGlobalType(env, env.toplevel.namedImportScope, name);
  1074             if (sym.exists()) return sym;
  1075             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
  1077             sym = findGlobalType(env, env.toplevel.packge.members(), name);
  1078             if (sym.exists()) return sym;
  1079             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
  1081             sym = findGlobalType(env, env.toplevel.starImportScope, name);
  1082             if (sym.exists()) return sym;
  1083             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
  1086         return bestSoFar;
  1089     /** Find an unqualified identifier which matches a specified kind set.
  1090      *  @param env       The current environment.
  1091      *  @param name      The indentifier's name.
  1092      *  @param kind      Indicates the possible symbol kinds
  1093      *                   (a subset of VAL, TYP, PCK).
  1094      */
  1095     Symbol findIdent(Env<AttrContext> env, Name name, int kind) {
  1096         Symbol bestSoFar = typeNotFound;
  1097         Symbol sym;
  1099         if ((kind & VAR) != 0) {
  1100             sym = findVar(env, name);
  1101             if (sym.exists()) return sym;
  1102             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
  1105         if ((kind & TYP) != 0) {
  1106             sym = findType(env, name);
  1107             if (sym.exists()) return sym;
  1108             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
  1111         if ((kind & PCK) != 0) return reader.enterPackage(name);
  1112         else return bestSoFar;
  1115     /** Find an identifier in a package which matches a specified kind set.
  1116      *  @param env       The current environment.
  1117      *  @param name      The identifier's name.
  1118      *  @param kind      Indicates the possible symbol kinds
  1119      *                   (a nonempty subset of TYP, PCK).
  1120      */
  1121     Symbol findIdentInPackage(Env<AttrContext> env, TypeSymbol pck,
  1122                               Name name, int kind) {
  1123         Name fullname = TypeSymbol.formFullName(name, pck);
  1124         Symbol bestSoFar = typeNotFound;
  1125         PackageSymbol pack = null;
  1126         if ((kind & PCK) != 0) {
  1127             pack = reader.enterPackage(fullname);
  1128             if (pack.exists()) return pack;
  1130         if ((kind & TYP) != 0) {
  1131             Symbol sym = loadClass(env, fullname);
  1132             if (sym.exists()) {
  1133                 // don't allow programs to use flatnames
  1134                 if (name == sym.name) return sym;
  1136             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
  1138         return (pack != null) ? pack : bestSoFar;
  1141     /** Find an identifier among the members of a given type `site'.
  1142      *  @param env       The current environment.
  1143      *  @param site      The type containing the symbol to be found.
  1144      *  @param name      The identifier's name.
  1145      *  @param kind      Indicates the possible symbol kinds
  1146      *                   (a subset of VAL, TYP).
  1147      */
  1148     Symbol findIdentInType(Env<AttrContext> env, Type site,
  1149                            Name name, int kind) {
  1150         Symbol bestSoFar = typeNotFound;
  1151         Symbol sym;
  1152         if ((kind & VAR) != 0) {
  1153             sym = findField(env, site, name, site.tsym);
  1154             if (sym.exists()) return sym;
  1155             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
  1158         if ((kind & TYP) != 0) {
  1159             sym = findMemberType(env, site, name, site.tsym);
  1160             if (sym.exists()) return sym;
  1161             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
  1163         return bestSoFar;
  1166 /* ***************************************************************************
  1167  *  Access checking
  1168  *  The following methods convert ResolveErrors to ErrorSymbols, issuing
  1169  *  an error message in the process
  1170  ****************************************************************************/
  1172     /** If `sym' is a bad symbol: report error and return errSymbol
  1173      *  else pass through unchanged,
  1174      *  additional arguments duplicate what has been used in trying to find the
  1175      *  symbol (--> flyweight pattern). This improves performance since we
  1176      *  expect misses to happen frequently.
  1178      *  @param sym       The symbol that was found, or a ResolveError.
  1179      *  @param pos       The position to use for error reporting.
  1180      *  @param site      The original type from where the selection took place.
  1181      *  @param name      The symbol's name.
  1182      *  @param argtypes  The invocation's value arguments,
  1183      *                   if we looked for a method.
  1184      *  @param typeargtypes  The invocation's type arguments,
  1185      *                   if we looked for a method.
  1186      */
  1187     Symbol access(Symbol sym,
  1188                   DiagnosticPosition pos,
  1189                   Type site,
  1190                   Name name,
  1191                   boolean qualified,
  1192                   List<Type> argtypes,
  1193                   List<Type> typeargtypes) {
  1194         if (sym.kind >= AMBIGUOUS) {
  1195 //          printscopes(site.tsym.members());//DEBUG
  1196             if (!site.isErroneous() &&
  1197                 !Type.isErroneous(argtypes) &&
  1198                 (typeargtypes==null || !Type.isErroneous(typeargtypes)))
  1199                 ((ResolveError)sym).report(log, pos, site, name, argtypes, typeargtypes);
  1200             do {
  1201                 sym = ((ResolveError)sym).sym;
  1202             } while (sym.kind >= AMBIGUOUS);
  1203             if (sym == syms.errSymbol // preserve the symbol name through errors
  1204                 || ((sym.kind & ERRONEOUS) == 0 // make sure an error symbol is returned
  1205                     && (sym.kind & TYP) != 0))
  1206                 sym = types.createErrorType(name, qualified ? site.tsym : syms.noSymbol, sym.type).tsym;
  1208         return sym;
  1211     /** Same as above, but without type arguments and arguments.
  1212      */
  1213     Symbol access(Symbol sym,
  1214                   DiagnosticPosition pos,
  1215                   Type site,
  1216                   Name name,
  1217                   boolean qualified) {
  1218         if (sym.kind >= AMBIGUOUS)
  1219             return access(sym, pos, site, name, qualified, List.<Type>nil(), null);
  1220         else
  1221             return sym;
  1224     /** Check that sym is not an abstract method.
  1225      */
  1226     void checkNonAbstract(DiagnosticPosition pos, Symbol sym) {
  1227         if ((sym.flags() & ABSTRACT) != 0)
  1228             log.error(pos, "abstract.cant.be.accessed.directly",
  1229                       kindName(sym), sym, sym.location());
  1232 /* ***************************************************************************
  1233  *  Debugging
  1234  ****************************************************************************/
  1236     /** print all scopes starting with scope s and proceeding outwards.
  1237      *  used for debugging.
  1238      */
  1239     public void printscopes(Scope s) {
  1240         while (s != null) {
  1241             if (s.owner != null)
  1242                 System.err.print(s.owner + ": ");
  1243             for (Scope.Entry e = s.elems; e != null; e = e.sibling) {
  1244                 if ((e.sym.flags() & ABSTRACT) != 0)
  1245                     System.err.print("abstract ");
  1246                 System.err.print(e.sym + " ");
  1248             System.err.println();
  1249             s = s.next;
  1253     void printscopes(Env<AttrContext> env) {
  1254         while (env.outer != null) {
  1255             System.err.println("------------------------------");
  1256             printscopes(env.info.scope);
  1257             env = env.outer;
  1261     public void printscopes(Type t) {
  1262         while (t.tag == CLASS) {
  1263             printscopes(t.tsym.members());
  1264             t = types.supertype(t);
  1268 /* ***************************************************************************
  1269  *  Name resolution
  1270  *  Naming conventions are as for symbol lookup
  1271  *  Unlike the find... methods these methods will report access errors
  1272  ****************************************************************************/
  1274     /** Resolve an unqualified (non-method) identifier.
  1275      *  @param pos       The position to use for error reporting.
  1276      *  @param env       The environment current at the identifier use.
  1277      *  @param name      The identifier's name.
  1278      *  @param kind      The set of admissible symbol kinds for the identifier.
  1279      */
  1280     Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env,
  1281                         Name name, int kind) {
  1282         return access(
  1283             findIdent(env, name, kind),
  1284             pos, env.enclClass.sym.type, name, false);
  1287     /** Resolve an unqualified method identifier.
  1288      *  @param pos       The position to use for error reporting.
  1289      *  @param env       The environment current at the method invocation.
  1290      *  @param name      The identifier's name.
  1291      *  @param argtypes  The types of the invocation's value arguments.
  1292      *  @param typeargtypes  The types of the invocation's type arguments.
  1293      */
  1294     Symbol resolveMethod(DiagnosticPosition pos,
  1295                          Env<AttrContext> env,
  1296                          Name name,
  1297                          List<Type> argtypes,
  1298                          List<Type> typeargtypes) {
  1299         Symbol sym = methodNotFound;
  1300         List<MethodResolutionPhase> steps = methodResolutionSteps;
  1301         while (steps.nonEmpty() &&
  1302                steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
  1303                sym.kind >= ERRONEOUS) {
  1304             sym = findFun(env, name, argtypes, typeargtypes,
  1305                     steps.head.isBoxingRequired,
  1306                     env.info.varArgs = steps.head.isVarargsRequired);
  1307             methodResolutionCache.put(steps.head, sym);
  1308             steps = steps.tail;
  1310         if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
  1311             MethodResolutionPhase errPhase =
  1312                     firstErroneousResolutionPhase();
  1313             sym = access(methodResolutionCache.get(errPhase),
  1314                     pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes);
  1315             env.info.varArgs = errPhase.isVarargsRequired;
  1317         return sym;
  1320     /** Resolve a qualified method identifier
  1321      *  @param pos       The position to use for error reporting.
  1322      *  @param env       The environment current at the method invocation.
  1323      *  @param site      The type of the qualifying expression, in which
  1324      *                   identifier is searched.
  1325      *  @param name      The identifier's name.
  1326      *  @param argtypes  The types of the invocation's value arguments.
  1327      *  @param typeargtypes  The types of the invocation's type arguments.
  1328      */
  1329     Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
  1330                                   Type site, Name name, List<Type> argtypes,
  1331                                   List<Type> typeargtypes) {
  1332         Symbol sym = methodNotFound;
  1333         List<MethodResolutionPhase> steps = methodResolutionSteps;
  1334         while (steps.nonEmpty() &&
  1335                steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
  1336                sym.kind >= ERRONEOUS) {
  1337             sym = findMethod(env, site, name, argtypes, typeargtypes,
  1338                     steps.head.isBoxingRequired(),
  1339                     env.info.varArgs = steps.head.isVarargsRequired(), false);
  1340             methodResolutionCache.put(steps.head, sym);
  1341             steps = steps.tail;
  1343         if (sym.kind >= AMBIGUOUS &&
  1344             allowInvokedynamic &&
  1345             (site == syms.invokeDynamicType ||
  1346              site == syms.methodHandleType && name == names.invoke)) {
  1347             // lookup failed; supply an exactly-typed implicit method
  1348             sym = findImplicitMethod(env, site, name, argtypes, typeargtypes);
  1349             env.info.varArgs = false;
  1351         if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
  1352             MethodResolutionPhase errPhase =
  1353                     firstErroneousResolutionPhase();
  1354             sym = access(methodResolutionCache.get(errPhase),
  1355                     pos, site, name, true, argtypes, typeargtypes);
  1356             env.info.varArgs = errPhase.isVarargsRequired;
  1358         return sym;
  1361     /** Resolve a qualified method identifier, throw a fatal error if not
  1362      *  found.
  1363      *  @param pos       The position to use for error reporting.
  1364      *  @param env       The environment current at the method invocation.
  1365      *  @param site      The type of the qualifying expression, in which
  1366      *                   identifier is searched.
  1367      *  @param name      The identifier's name.
  1368      *  @param argtypes  The types of the invocation's value arguments.
  1369      *  @param typeargtypes  The types of the invocation's type arguments.
  1370      */
  1371     public MethodSymbol resolveInternalMethod(DiagnosticPosition pos, Env<AttrContext> env,
  1372                                         Type site, Name name,
  1373                                         List<Type> argtypes,
  1374                                         List<Type> typeargtypes) {
  1375         Symbol sym = resolveQualifiedMethod(
  1376             pos, env, site, name, argtypes, typeargtypes);
  1377         if (sym.kind == MTH) return (MethodSymbol)sym;
  1378         else throw new FatalError(
  1379                  diags.fragment("fatal.err.cant.locate.meth",
  1380                                 name));
  1383     /** Resolve constructor.
  1384      *  @param pos       The position to use for error reporting.
  1385      *  @param env       The environment current at the constructor invocation.
  1386      *  @param site      The type of class for which a constructor is searched.
  1387      *  @param argtypes  The types of the constructor invocation's value
  1388      *                   arguments.
  1389      *  @param typeargtypes  The types of the constructor invocation's type
  1390      *                   arguments.
  1391      */
  1392     Symbol resolveConstructor(DiagnosticPosition pos,
  1393                               Env<AttrContext> env,
  1394                               Type site,
  1395                               List<Type> argtypes,
  1396                               List<Type> typeargtypes) {
  1397         Symbol sym = methodNotFound;
  1398         List<MethodResolutionPhase> steps = methodResolutionSteps;
  1399         while (steps.nonEmpty() &&
  1400                steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
  1401                sym.kind >= ERRONEOUS) {
  1402             sym = resolveConstructor(pos, env, site, argtypes, typeargtypes,
  1403                     steps.head.isBoxingRequired(),
  1404                     env.info.varArgs = steps.head.isVarargsRequired());
  1405             methodResolutionCache.put(steps.head, sym);
  1406             steps = steps.tail;
  1408         if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
  1409             MethodResolutionPhase errPhase = firstErroneousResolutionPhase();
  1410             sym = access(methodResolutionCache.get(errPhase),
  1411                     pos, site, names.init, true, argtypes, typeargtypes);
  1412             env.info.varArgs = errPhase.isVarargsRequired();
  1414         return sym;
  1417     /** Resolve constructor.
  1418      *  @param pos       The position to use for error reporting.
  1419      *  @param env       The environment current at the constructor invocation.
  1420      *  @param site      The type of class for which a constructor is searched.
  1421      *  @param argtypes  The types of the constructor invocation's value
  1422      *                   arguments.
  1423      *  @param typeargtypes  The types of the constructor invocation's type
  1424      *                   arguments.
  1425      *  @param allowBoxing Allow boxing and varargs conversions.
  1426      *  @param useVarargs Box trailing arguments into an array for varargs.
  1427      */
  1428     Symbol resolveConstructor(DiagnosticPosition pos, Env<AttrContext> env,
  1429                               Type site, List<Type> argtypes,
  1430                               List<Type> typeargtypes,
  1431                               boolean allowBoxing,
  1432                               boolean useVarargs) {
  1433         Symbol sym = findMethod(env, site,
  1434                                 names.init, argtypes,
  1435                                 typeargtypes, allowBoxing,
  1436                                 useVarargs, false);
  1437         if ((sym.flags() & DEPRECATED) != 0 &&
  1438             (env.info.scope.owner.flags() & DEPRECATED) == 0 &&
  1439             env.info.scope.owner.outermostClass() != sym.outermostClass())
  1440             chk.warnDeprecated(pos, sym);
  1441         return sym;
  1444     /** Resolve a constructor, throw a fatal error if not found.
  1445      *  @param pos       The position to use for error reporting.
  1446      *  @param env       The environment current at the method invocation.
  1447      *  @param site      The type to be constructed.
  1448      *  @param argtypes  The types of the invocation's value arguments.
  1449      *  @param typeargtypes  The types of the invocation's type arguments.
  1450      */
  1451     public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env,
  1452                                         Type site,
  1453                                         List<Type> argtypes,
  1454                                         List<Type> typeargtypes) {
  1455         Symbol sym = resolveConstructor(
  1456             pos, env, site, argtypes, typeargtypes);
  1457         if (sym.kind == MTH) return (MethodSymbol)sym;
  1458         else throw new FatalError(
  1459                  diags.fragment("fatal.err.cant.locate.ctor", site));
  1462     /** Resolve operator.
  1463      *  @param pos       The position to use for error reporting.
  1464      *  @param optag     The tag of the operation tree.
  1465      *  @param env       The environment current at the operation.
  1466      *  @param argtypes  The types of the operands.
  1467      */
  1468     Symbol resolveOperator(DiagnosticPosition pos, int optag,
  1469                            Env<AttrContext> env, List<Type> argtypes) {
  1470         Name name = treeinfo.operatorName(optag);
  1471         Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
  1472                                 null, false, false, true);
  1473         if (boxingEnabled && sym.kind >= WRONG_MTHS)
  1474             sym = findMethod(env, syms.predefClass.type, name, argtypes,
  1475                              null, true, false, true);
  1476         return access(sym, pos, env.enclClass.sym.type, name,
  1477                       false, argtypes, null);
  1480     /** Resolve operator.
  1481      *  @param pos       The position to use for error reporting.
  1482      *  @param optag     The tag of the operation tree.
  1483      *  @param env       The environment current at the operation.
  1484      *  @param arg       The type of the operand.
  1485      */
  1486     Symbol resolveUnaryOperator(DiagnosticPosition pos, int optag, Env<AttrContext> env, Type arg) {
  1487         return resolveOperator(pos, optag, env, List.of(arg));
  1490     /** Resolve binary operator.
  1491      *  @param pos       The position to use for error reporting.
  1492      *  @param optag     The tag of the operation tree.
  1493      *  @param env       The environment current at the operation.
  1494      *  @param left      The types of the left operand.
  1495      *  @param right     The types of the right operand.
  1496      */
  1497     Symbol resolveBinaryOperator(DiagnosticPosition pos,
  1498                                  int optag,
  1499                                  Env<AttrContext> env,
  1500                                  Type left,
  1501                                  Type right) {
  1502         return resolveOperator(pos, optag, env, List.of(left, right));
  1505     /**
  1506      * Resolve `c.name' where name == this or name == super.
  1507      * @param pos           The position to use for error reporting.
  1508      * @param env           The environment current at the expression.
  1509      * @param c             The qualifier.
  1510      * @param name          The identifier's name.
  1511      */
  1512     Symbol resolveSelf(DiagnosticPosition pos,
  1513                        Env<AttrContext> env,
  1514                        TypeSymbol c,
  1515                        Name name) {
  1516         Env<AttrContext> env1 = env;
  1517         boolean staticOnly = false;
  1518         while (env1.outer != null) {
  1519             if (isStatic(env1)) staticOnly = true;
  1520             if (env1.enclClass.sym == c) {
  1521                 Symbol sym = env1.info.scope.lookup(name).sym;
  1522                 if (sym != null) {
  1523                     if (staticOnly) sym = new StaticError(sym);
  1524                     return access(sym, pos, env.enclClass.sym.type,
  1525                                   name, true);
  1528             if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
  1529             env1 = env1.outer;
  1531         log.error(pos, "not.encl.class", c);
  1532         return syms.errSymbol;
  1535     /**
  1536      * Resolve `c.this' for an enclosing class c that contains the
  1537      * named member.
  1538      * @param pos           The position to use for error reporting.
  1539      * @param env           The environment current at the expression.
  1540      * @param member        The member that must be contained in the result.
  1541      */
  1542     Symbol resolveSelfContaining(DiagnosticPosition pos,
  1543                                  Env<AttrContext> env,
  1544                                  Symbol member) {
  1545         Name name = names._this;
  1546         Env<AttrContext> env1 = env;
  1547         boolean staticOnly = false;
  1548         while (env1.outer != null) {
  1549             if (isStatic(env1)) staticOnly = true;
  1550             if (env1.enclClass.sym.isSubClass(member.owner, types) &&
  1551                 isAccessible(env, env1.enclClass.sym.type, member)) {
  1552                 Symbol sym = env1.info.scope.lookup(name).sym;
  1553                 if (sym != null) {
  1554                     if (staticOnly) sym = new StaticError(sym);
  1555                     return access(sym, pos, env.enclClass.sym.type,
  1556                                   name, true);
  1559             if ((env1.enclClass.sym.flags() & STATIC) != 0)
  1560                 staticOnly = true;
  1561             env1 = env1.outer;
  1563         log.error(pos, "encl.class.required", member);
  1564         return syms.errSymbol;
  1567     /**
  1568      * Resolve an appropriate implicit this instance for t's container.
  1569      * JLS2 8.8.5.1 and 15.9.2
  1570      */
  1571     Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t) {
  1572         Type thisType = (((t.tsym.owner.kind & (MTH|VAR)) != 0)
  1573                          ? resolveSelf(pos, env, t.getEnclosingType().tsym, names._this)
  1574                          : resolveSelfContaining(pos, env, t.tsym)).type;
  1575         if (env.info.isSelfCall && thisType.tsym == env.enclClass.sym)
  1576             log.error(pos, "cant.ref.before.ctor.called", "this");
  1577         return thisType;
  1580 /* ***************************************************************************
  1581  *  ResolveError classes, indicating error situations when accessing symbols
  1582  ****************************************************************************/
  1584     public void logAccessError(Env<AttrContext> env, JCTree tree, Type type) {
  1585         AccessError error = new AccessError(env, type.getEnclosingType(), type.tsym);
  1586         error.report(log, tree.pos(), type.getEnclosingType(), null, null, null);
  1589     private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
  1591     public Object methodArguments(List<Type> argtypes) {
  1592         return argtypes.isEmpty() ? noArgs : argtypes;
  1595     /** Root class for resolve errors.
  1596      *  Instances of this class indicate "Symbol not found".
  1597      *  Instances of subclass indicate other errors.
  1598      */
  1599     private class ResolveError extends Symbol {
  1601         ResolveError(int kind, Symbol sym, String debugName) {
  1602             super(kind, 0, null, null, null);
  1603             this.debugName = debugName;
  1604             this.sym = sym;
  1607         /** The name of the kind of error, for debugging only.
  1608          */
  1609         final String debugName;
  1611         /** The symbol that was determined by resolution, or errSymbol if none
  1612          *  was found.
  1613          */
  1614         final Symbol sym;
  1616         /** The symbol that was a close mismatch, or null if none was found.
  1617          *  wrongSym is currently set if a simgle method with the correct name, but
  1618          *  the wrong parameters was found.
  1619          */
  1620         Symbol wrongSym;
  1622         /** An auxiliary explanation set in case of instantiation errors.
  1623          */
  1624         JCDiagnostic explanation;
  1627         public <R, P> R accept(ElementVisitor<R, P> v, P p) {
  1628             throw new AssertionError();
  1631         /** Print the (debug only) name of the kind of error.
  1632          */
  1633         public String toString() {
  1634             return debugName + " wrongSym=" + wrongSym + " explanation=" + explanation;
  1637         /** Update wrongSym and explanation and return this.
  1638          */
  1639         ResolveError setWrongSym(Symbol sym, JCDiagnostic explanation) {
  1640             this.wrongSym = sym;
  1641             this.explanation = explanation;
  1642             return this;
  1645         /** Update wrongSym and return this.
  1646          */
  1647         ResolveError setWrongSym(Symbol sym) {
  1648             this.wrongSym = sym;
  1649             this.explanation = null;
  1650             return this;
  1653         public boolean exists() {
  1654             switch (kind) {
  1655             case HIDDEN:
  1656             case ABSENT_VAR:
  1657             case ABSENT_MTH:
  1658             case ABSENT_TYP:
  1659                 return false;
  1660             default:
  1661                 return true;
  1665         /** Report error.
  1666          *  @param log       The error log to be used for error reporting.
  1667          *  @param pos       The position to be used for error reporting.
  1668          *  @param site      The original type from where the selection took place.
  1669          *  @param name      The name of the symbol to be resolved.
  1670          *  @param argtypes  The invocation's value arguments,
  1671          *                   if we looked for a method.
  1672          *  @param typeargtypes  The invocation's type arguments,
  1673          *                   if we looked for a method.
  1674          */
  1675         void report(Log log, DiagnosticPosition pos, Type site, Name name,
  1676                     List<Type> argtypes, List<Type> typeargtypes) {
  1677             if (argtypes == null)
  1678                 argtypes = List.nil();
  1679             if (typeargtypes == null)
  1680                 typeargtypes = List.nil();
  1681             if (name != names.error) {
  1682                 KindName kindname = absentKind(kind);
  1683                 Name idname = name;
  1684                 if (kind >= WRONG_MTHS && kind <= ABSENT_MTH) {
  1685                     if (isOperator(name)) {
  1686                         log.error(pos, "operator.cant.be.applied",
  1687                                   name, argtypes);
  1688                         return;
  1690                     if (name == names.init) {
  1691                         kindname = KindName.CONSTRUCTOR;
  1692                         idname = site.tsym.name;
  1695                 if (kind == WRONG_MTH) {
  1696                     Symbol ws = wrongSym.asMemberOf(site, types);
  1697                     log.error(pos,
  1698                               "cant.apply.symbol" + (explanation != null ? ".1" : ""),
  1699                               kindname,
  1700                               ws.name == names.init ? ws.owner.name : ws.name,
  1701                               methodArguments(ws.type.getParameterTypes()),
  1702                               methodArguments(argtypes),
  1703                               kindName(ws.owner),
  1704                               ws.owner.type,
  1705                               explanation);
  1706                 } else if (!site.tsym.name.isEmpty()) {
  1707                     if (site.tsym.kind == PCK && !site.tsym.exists())
  1708                         log.error(pos, "doesnt.exist", site.tsym);
  1709                     else {
  1710                         String errKey = getErrorKey("cant.resolve.location",
  1711                                                     argtypes, typeargtypes,
  1712                                                     kindname);
  1713                         log.error(pos, errKey, kindname, idname, //symbol kindname, name
  1714                                   typeargtypes, argtypes, //type parameters and arguments (if any)
  1715                                   typeKindName(site), site); //location kindname, type
  1717                 } else {
  1718                     String errKey = getErrorKey("cant.resolve",
  1719                                                 argtypes, typeargtypes,
  1720                                                 kindname);
  1721                     log.error(pos, errKey, kindname, idname, //symbol kindname, name
  1722                               typeargtypes, argtypes); //type parameters and arguments (if any)
  1726         //where
  1727         String getErrorKey(String key, List<Type> argtypes, List<Type> typeargtypes, KindName kindname) {
  1728             String suffix = "";
  1729             switch (kindname) {
  1730                 case METHOD:
  1731                 case CONSTRUCTOR: {
  1732                     suffix += ".args";
  1733                     suffix += typeargtypes.nonEmpty() ? ".params" : "";
  1736             return key + suffix;
  1739         /** A name designates an operator if it consists
  1740          *  of a non-empty sequence of operator symbols +-~!/*%&|^<>=
  1741          */
  1742         boolean isOperator(Name name) {
  1743             int i = 0;
  1744             while (i < name.getByteLength() &&
  1745                    "+-~!*/%&|^<>=".indexOf(name.getByteAt(i)) >= 0) i++;
  1746             return i > 0 && i == name.getByteLength();
  1750     /** Resolve error class indicating that a symbol is not accessible.
  1751      */
  1752     class AccessError extends ResolveError {
  1754         AccessError(Symbol sym) {
  1755             this(null, null, sym);
  1758         AccessError(Env<AttrContext> env, Type site, Symbol sym) {
  1759             super(HIDDEN, sym, "access error");
  1760             this.env = env;
  1761             this.site = site;
  1762             if (debugResolve)
  1763                 log.error("proc.messager", sym + " @ " + site + " is inaccessible.");
  1766         private Env<AttrContext> env;
  1767         private Type site;
  1769         /** Report error.
  1770          *  @param log       The error log to be used for error reporting.
  1771          *  @param pos       The position to be used for error reporting.
  1772          *  @param site      The original type from where the selection took place.
  1773          *  @param name      The name of the symbol to be resolved.
  1774          *  @param argtypes  The invocation's value arguments,
  1775          *                   if we looked for a method.
  1776          *  @param typeargtypes  The invocation's type arguments,
  1777          *                   if we looked for a method.
  1778          */
  1779         void report(Log log, DiagnosticPosition pos, Type site, Name name,
  1780                     List<Type> argtypes, List<Type> typeargtypes) {
  1781             if (sym.owner.type.tag != ERROR) {
  1782                 if (sym.name == names.init && sym.owner != site.tsym)
  1783                     new ResolveError(ABSENT_MTH, sym.owner, "absent method " + sym).report(
  1784                         log, pos, site, name, argtypes, typeargtypes);
  1785                 if ((sym.flags() & PUBLIC) != 0
  1786                     || (env != null && this.site != null
  1787                         && !isAccessible(env, this.site)))
  1788                     log.error(pos, "not.def.access.class.intf.cant.access",
  1789                         sym, sym.location());
  1790                 else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0)
  1791                     log.error(pos, "report.access", sym,
  1792                               asFlagSet(sym.flags() & (PRIVATE | PROTECTED)),
  1793                               sym.location());
  1794                 else
  1795                     log.error(pos, "not.def.public.cant.access",
  1796                               sym, sym.location());
  1801     /** Resolve error class indicating that an instance member was accessed
  1802      *  from a static context.
  1803      */
  1804     class StaticError extends ResolveError {
  1805         StaticError(Symbol sym) {
  1806             super(STATICERR, sym, "static error");
  1809         /** Report error.
  1810          *  @param log       The error log to be used for error reporting.
  1811          *  @param pos       The position to be used for error reporting.
  1812          *  @param site      The original type from where the selection took place.
  1813          *  @param name      The name of the symbol to be resolved.
  1814          *  @param argtypes  The invocation's value arguments,
  1815          *                   if we looked for a method.
  1816          *  @param typeargtypes  The invocation's type arguments,
  1817          *                   if we looked for a method.
  1818          */
  1819         void report(Log log,
  1820                     DiagnosticPosition pos,
  1821                     Type site,
  1822                     Name name,
  1823                     List<Type> argtypes,
  1824                     List<Type> typeargtypes) {
  1825             Symbol errSym = ((sym.kind == TYP && sym.type.tag == CLASS)
  1826                 ? types.erasure(sym.type).tsym
  1827                 : sym);
  1828             log.error(pos, "non-static.cant.be.ref",
  1829                       kindName(sym), errSym);
  1833     /** Resolve error class indicating an ambiguous reference.
  1834      */
  1835     class AmbiguityError extends ResolveError {
  1836         Symbol sym1;
  1837         Symbol sym2;
  1839         AmbiguityError(Symbol sym1, Symbol sym2) {
  1840             super(AMBIGUOUS, sym1, "ambiguity error");
  1841             this.sym1 = sym1;
  1842             this.sym2 = sym2;
  1845         /** Report error.
  1846          *  @param log       The error log to be used for error reporting.
  1847          *  @param pos       The position to be used for error reporting.
  1848          *  @param site      The original type from where the selection took place.
  1849          *  @param name      The name of the symbol to be resolved.
  1850          *  @param argtypes  The invocation's value arguments,
  1851          *                   if we looked for a method.
  1852          *  @param typeargtypes  The invocation's type arguments,
  1853          *                   if we looked for a method.
  1854          */
  1855         void report(Log log, DiagnosticPosition pos, Type site, Name name,
  1856                     List<Type> argtypes, List<Type> typeargtypes) {
  1857             AmbiguityError pair = this;
  1858             while (true) {
  1859                 if (pair.sym1.kind == AMBIGUOUS)
  1860                     pair = (AmbiguityError)pair.sym1;
  1861                 else if (pair.sym2.kind == AMBIGUOUS)
  1862                     pair = (AmbiguityError)pair.sym2;
  1863                 else break;
  1865             Name sname = pair.sym1.name;
  1866             if (sname == names.init) sname = pair.sym1.owner.name;
  1867             log.error(pos, "ref.ambiguous", sname,
  1868                       kindName(pair.sym1),
  1869                       pair.sym1,
  1870                       pair.sym1.location(site, types),
  1871                       kindName(pair.sym2),
  1872                       pair.sym2,
  1873                       pair.sym2.location(site, types));
  1877     enum MethodResolutionPhase {
  1878         BASIC(false, false),
  1879         BOX(true, false),
  1880         VARARITY(true, true);
  1882         boolean isBoxingRequired;
  1883         boolean isVarargsRequired;
  1885         MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) {
  1886            this.isBoxingRequired = isBoxingRequired;
  1887            this.isVarargsRequired = isVarargsRequired;
  1890         public boolean isBoxingRequired() {
  1891             return isBoxingRequired;
  1894         public boolean isVarargsRequired() {
  1895             return isVarargsRequired;
  1898         public boolean isApplicable(boolean boxingEnabled, boolean varargsEnabled) {
  1899             return (varargsEnabled || !isVarargsRequired) &&
  1900                    (boxingEnabled || !isBoxingRequired);
  1904     private Map<MethodResolutionPhase, Symbol> methodResolutionCache =
  1905         new HashMap<MethodResolutionPhase, Symbol>(MethodResolutionPhase.values().length);
  1907     final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
  1909     private MethodResolutionPhase firstErroneousResolutionPhase() {
  1910         MethodResolutionPhase bestSoFar = BASIC;
  1911         Symbol sym = methodNotFound;
  1912         List<MethodResolutionPhase> steps = methodResolutionSteps;
  1913         while (steps.nonEmpty() &&
  1914                steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
  1915                sym.kind >= WRONG_MTHS) {
  1916             sym = methodResolutionCache.get(steps.head);
  1917             bestSoFar = steps.head;
  1918             steps = steps.tail;
  1920         return bestSoFar;

mercurial