0001: /*
0002: * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
0003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004: *
0005: * This code is free software; you can redistribute it and/or modify it
0006: * under the terms of the GNU General Public License version 2 only, as
0007: * published by the Free Software Foundation. Sun designates this
0008: * particular file as subject to the "Classpath" exception as provided
0009: * by Sun in the LICENSE file that accompanied this code.
0010: *
0011: * This code is distributed in the hope that it will be useful, but WITHOUT
0012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014: * version 2 for more details (a copy is included in the LICENSE file that
0015: * accompanied this code).
0016: *
0017: * You should have received a copy of the GNU General Public License version
0018: * 2 along with this work; if not, write to the Free Software Foundation,
0019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020: *
0021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022: * CA 95054 USA or visit www.sun.com if you need additional information or
0023: * have any questions.
0024: */
0025:
0026: package com.sun.tools.javac.comp;
0027:
0028: import com.sun.tools.javac.util.*;
0029: import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
0030: import com.sun.tools.javac.code.*;
0031: import com.sun.tools.javac.jvm.*;
0032: import com.sun.tools.javac.tree.*;
0033:
0034: import com.sun.tools.javac.code.Type.*;
0035: import com.sun.tools.javac.code.Symbol.*;
0036: import com.sun.tools.javac.tree.JCTree.*;
0037:
0038: import static com.sun.tools.javac.code.Flags.*;
0039: import static com.sun.tools.javac.code.Kinds.*;
0040: import static com.sun.tools.javac.code.TypeTags.*;
0041: import javax.lang.model.element.ElementVisitor;
0042:
0043: /** Helper class for name resolution, used mostly by the attribution phase.
0044: *
0045: * <p><b>This is NOT part of any API supported by Sun Microsystems. If
0046: * you write code that depends on this, you do so at your own risk.
0047: * This code and its internal interfaces are subject to change or
0048: * deletion without notice.</b>
0049: */
0050: @Version("@(#)Resolve.java 1.141 07/06/14")
0051: public class Resolve {
0052: protected static final Context.Key<Resolve> resolveKey = new Context.Key<Resolve>();
0053:
0054: Name.Table names;
0055: Log log;
0056: Symtab syms;
0057: Check chk;
0058: Infer infer;
0059: ClassReader reader;
0060: TreeInfo treeinfo;
0061: Types types;
0062: public final boolean boxingEnabled; // = source.allowBoxing();
0063: public final boolean varargsEnabled; // = source.allowVarargs();
0064: private final boolean debugResolve;
0065:
0066: public static Resolve instance(Context context) {
0067: Resolve instance = context.get(resolveKey);
0068: if (instance == null)
0069: instance = new Resolve(context);
0070: return instance;
0071: }
0072:
0073: protected Resolve(Context context) {
0074: context.put(resolveKey, this );
0075: syms = Symtab.instance(context);
0076:
0077: varNotFound = new ResolveError(ABSENT_VAR, syms.errSymbol,
0078: "variable not found");
0079: wrongMethod = new ResolveError(WRONG_MTH, syms.errSymbol,
0080: "method not found");
0081: wrongMethods = new ResolveError(WRONG_MTHS, syms.errSymbol,
0082: "wrong methods");
0083: methodNotFound = new ResolveError(ABSENT_MTH, syms.errSymbol,
0084: "method not found");
0085: typeNotFound = new ResolveError(ABSENT_TYP, syms.errSymbol,
0086: "type not found");
0087:
0088: names = Name.Table.instance(context);
0089: log = Log.instance(context);
0090: chk = Check.instance(context);
0091: infer = Infer.instance(context);
0092: reader = ClassReader.instance(context);
0093: treeinfo = TreeInfo.instance(context);
0094: types = Types.instance(context);
0095: Source source = Source.instance(context);
0096: boxingEnabled = source.allowBoxing();
0097: varargsEnabled = source.allowVarargs();
0098: Options options = Options.instance(context);
0099: debugResolve = options.get("debugresolve") != null;
0100: }
0101:
0102: /** error symbols, which are returned when resolution fails
0103: */
0104: final ResolveError varNotFound;
0105: final ResolveError wrongMethod;
0106: final ResolveError wrongMethods;
0107: final ResolveError methodNotFound;
0108: final ResolveError typeNotFound;
0109:
0110: /* ************************************************************************
0111: * Identifier resolution
0112: *************************************************************************/
0113:
0114: /** An environment is "static" if its static level is greater than
0115: * the one of its outer environment
0116: */
0117: static boolean isStatic(Env<AttrContext> env) {
0118: return env.info.staticLevel > env.outer.info.staticLevel;
0119: }
0120:
0121: /** An environment is an "initializer" if it is a constructor or
0122: * an instance initializer.
0123: */
0124: static boolean isInitializer(Env<AttrContext> env) {
0125: Symbol owner = env.info.scope.owner;
0126: return owner.isConstructor()
0127: || owner.owner.kind == TYP
0128: && (owner.kind == VAR || owner.kind == MTH
0129: && (owner.flags() & BLOCK) != 0)
0130: && (owner.flags() & STATIC) == 0;
0131: }
0132:
0133: /** Is class accessible in given evironment?
0134: * @param env The current environment.
0135: * @param c The class whose accessibility is checked.
0136: */
0137: public boolean isAccessible(Env<AttrContext> env, TypeSymbol c) {
0138: switch ((short) (c.flags() & AccessFlags)) {
0139: case PRIVATE:
0140: return env.enclClass.sym.outermostClass() == c.owner
0141: .outermostClass();
0142: case 0:
0143: return env.toplevel.packge == c.owner // fast special case
0144: || env.toplevel.packge == c.packge()
0145: ||
0146: // Hack: this case is added since synthesized default constructors
0147: // of anonymous classes should be allowed to access
0148: // classes which would be inaccessible otherwise.
0149: env.enclMethod != null
0150: && (env.enclMethod.mods.flags & ANONCONSTR) != 0;
0151: default: // error recovery
0152: case PUBLIC:
0153: return true;
0154: case PROTECTED:
0155: return env.toplevel.packge == c.owner // fast special case
0156: || env.toplevel.packge == c.packge()
0157: || isInnerSubClass(env.enclClass.sym, c.owner);
0158: }
0159: }
0160:
0161: //where
0162: /** Is given class a subclass of given base class, or an inner class
0163: * of a subclass?
0164: * Return null if no such class exists.
0165: * @param c The class which is the subclass or is contained in it.
0166: * @param base The base class
0167: */
0168: private boolean isInnerSubClass(ClassSymbol c, Symbol base) {
0169: while (c != null && !c.isSubClass(base, types)) {
0170: c = c.owner.enclClass();
0171: }
0172: return c != null;
0173: }
0174:
0175: boolean isAccessible(Env<AttrContext> env, Type t) {
0176: return (t.tag == ARRAY) ? isAccessible(env, types.elemtype(t))
0177: : isAccessible(env, t.tsym);
0178: }
0179:
0180: /** Is symbol accessible as a member of given type in given evironment?
0181: * @param env The current environment.
0182: * @param site The type of which the tested symbol is regarded
0183: * as a member.
0184: * @param sym The symbol.
0185: */
0186: public boolean isAccessible(Env<AttrContext> env, Type site,
0187: Symbol sym) {
0188: if (sym.name == names.init && sym.owner != site.tsym)
0189: return false;
0190: ClassSymbol sub;
0191: switch ((short) (sym.flags() & AccessFlags)) {
0192: case PRIVATE:
0193: return (env.enclClass.sym == sym.owner // fast special case
0194: || env.enclClass.sym.outermostClass() == sym.owner
0195: .outermostClass())
0196: && sym.isInheritedIn(site.tsym, types);
0197: case 0:
0198: return (env.toplevel.packge == sym.owner.owner // fast special case
0199: || env.toplevel.packge == sym.packge())
0200: && isAccessible(env, site)
0201: && sym.isInheritedIn(site.tsym, types);
0202: case PROTECTED:
0203: return (env.toplevel.packge == sym.owner.owner // fast special case
0204: || env.toplevel.packge == sym.packge()
0205: || isProtectedAccessible(sym, env.enclClass.sym,
0206: site) ||
0207: // OK to select instance method or field from 'super' or type name
0208: // (but type names should be disallowed elsewhere!)
0209: env.info.selectSuper && (sym.flags() & STATIC) == 0
0210: && sym.kind != TYP)
0211: && isAccessible(env, site) &&
0212: // `sym' is accessible only if not overridden by
0213: // another symbol which is a member of `site'
0214: // (because, if it is overridden, `sym' is not strictly
0215: // speaking a member of `site'.)
0216: (sym.kind != MTH || sym.isConstructor() || ((MethodSymbol) sym)
0217: .implementation(site.tsym, types, true) == sym);
0218: default: // this case includes erroneous combinations as well
0219: return isAccessible(env, site);
0220: }
0221: }
0222:
0223: //where
0224: /** Is given protected symbol accessible if it is selected from given site
0225: * and the selection takes place in given class?
0226: * @param sym The symbol with protected access
0227: * @param c The class where the access takes place
0228: * @site The type of the qualifier
0229: */
0230: private boolean isProtectedAccessible(Symbol sym, ClassSymbol c,
0231: Type site) {
0232: while (c != null
0233: && !(c.isSubClass(sym.owner, types)
0234: && (c.flags() & INTERFACE) == 0 &&
0235: // In JLS 2e 6.6.2.1, the subclass restriction applies
0236: // only to instance fields and methods -- types are excluded
0237: // regardless of whether they are declared 'static' or not.
0238: ((sym.flags() & STATIC) != 0 || sym.kind == TYP || site.tsym
0239: .isSubClass(c, types))))
0240: c = c.owner.enclClass();
0241: return c != null;
0242: }
0243:
0244: /** Try to instantiate the type of a method so that it fits
0245: * given type arguments and argument types. If succesful, return
0246: * the method's instantiated type, else return null.
0247: * The instantiation will take into account an additional leading
0248: * formal parameter if the method is an instance method seen as a member
0249: * of un underdetermined site In this case, we treat site as an additional
0250: * parameter and the parameters of the class containing the method as
0251: * additional type variables that get instantiated.
0252: *
0253: * @param env The current environment
0254: * @param site The type of which the method is a member.
0255: * @param m The method symbol.
0256: * @param argtypes The invocation's given value arguments.
0257: * @param typeargtypes The invocation's given type arguments.
0258: * @param allowBoxing Allow boxing conversions of arguments.
0259: * @param useVarargs Box trailing arguments into an array for varargs.
0260: */
0261: Type rawInstantiate(Env<AttrContext> env, Type site, Symbol m,
0262: List<Type> argtypes, List<Type> typeargtypes,
0263: boolean allowBoxing, boolean useVarargs, Warner warn)
0264: throws Infer.NoInstanceException {
0265: if (useVarargs && (m.flags() & VARARGS) == 0)
0266: return null;
0267: Type mt = types.memberType(site, m);
0268:
0269: // tvars is the list of formal type variables for which type arguments
0270: // need to inferred.
0271: List<Type> tvars = env.info.tvars;
0272: if (typeargtypes == null)
0273: typeargtypes = List.nil();
0274: if (mt.tag != FORALL && typeargtypes.nonEmpty()) {
0275: // This is not a polymorphic method, but typeargs are supplied
0276: // which is fine, see JLS3 15.12.2.1
0277: } else if (mt.tag == FORALL && typeargtypes.nonEmpty()) {
0278: ForAll pmt = (ForAll) mt;
0279: if (typeargtypes.length() != pmt.tvars.length())
0280: return null;
0281: // Check type arguments are within bounds
0282: List<Type> formals = pmt.tvars;
0283: List<Type> actuals = typeargtypes;
0284: while (formals.nonEmpty() && actuals.nonEmpty()) {
0285: List<Type> bounds = types.subst(types
0286: .getBounds((TypeVar) formals.head), pmt.tvars,
0287: typeargtypes);
0288: for (; bounds.nonEmpty(); bounds = bounds.tail)
0289: if (!types.isSubtypeUnchecked(actuals.head,
0290: bounds.head, warn))
0291: return null;
0292: formals = formals.tail;
0293: actuals = actuals.tail;
0294: }
0295: mt = types.subst(pmt.qtype, pmt.tvars, typeargtypes);
0296: } else if (mt.tag == FORALL) {
0297: ForAll pmt = (ForAll) mt;
0298: List<Type> tvars1 = types.newInstances(pmt.tvars);
0299: tvars = tvars.appendList(tvars1);
0300: mt = types.subst(pmt.qtype, pmt.tvars, tvars1);
0301: }
0302:
0303: // find out whether we need to go the slow route via infer
0304: boolean instNeeded = tvars.tail != null/*inlined: tvars.nonEmpty()*/;
0305: for (List<Type> l = argtypes; l.tail != null/*inlined: l.nonEmpty()*/
0306: && !instNeeded; l = l.tail) {
0307: if (l.head.tag == FORALL)
0308: instNeeded = true;
0309: }
0310:
0311: if (instNeeded)
0312: return infer.instantiateMethod(tvars, (MethodType) mt,
0313: argtypes, allowBoxing, useVarargs, warn);
0314: return argumentsAcceptable(argtypes, mt.getParameterTypes(),
0315: allowBoxing, useVarargs, warn) ? mt : null;
0316: }
0317:
0318: /** Same but returns null instead throwing a NoInstanceException
0319: */
0320: Type instantiate(Env<AttrContext> env, Type site, Symbol m,
0321: List<Type> argtypes, List<Type> typeargtypes,
0322: boolean allowBoxing, boolean useVarargs, Warner warn) {
0323: try {
0324: return rawInstantiate(env, site, m, argtypes, typeargtypes,
0325: allowBoxing, useVarargs, warn);
0326: } catch (Infer.NoInstanceException ex) {
0327: return null;
0328: }
0329: }
0330:
0331: /** Check if a parameter list accepts a list of args.
0332: */
0333: boolean argumentsAcceptable(List<Type> argtypes,
0334: List<Type> formals, boolean allowBoxing,
0335: boolean useVarargs, Warner warn) {
0336: Type varargsFormal = useVarargs ? formals.last() : null;
0337: while (argtypes.nonEmpty() && formals.head != varargsFormal) {
0338: boolean works = allowBoxing ? types.isConvertible(
0339: argtypes.head, formals.head, warn) : types
0340: .isSubtypeUnchecked(argtypes.head, formals.head,
0341: warn);
0342: if (!works)
0343: return false;
0344: argtypes = argtypes.tail;
0345: formals = formals.tail;
0346: }
0347: if (formals.head != varargsFormal)
0348: return false; // not enough args
0349: if (!useVarargs)
0350: return argtypes.isEmpty();
0351: Type elt = types.elemtype(varargsFormal);
0352: while (argtypes.nonEmpty()) {
0353: if (!types.isConvertible(argtypes.head, elt, warn))
0354: return false;
0355: argtypes = argtypes.tail;
0356: }
0357: return true;
0358: }
0359:
0360: /* ***************************************************************************
0361: * Symbol lookup
0362: * the following naming conventions for arguments are used
0363: *
0364: * env is the environment where the symbol was mentioned
0365: * site is the type of which the symbol is a member
0366: * name is the symbol's name
0367: * if no arguments are given
0368: * argtypes are the value arguments, if we search for a method
0369: *
0370: * If no symbol was found, a ResolveError detailing the problem is returned.
0371: ****************************************************************************/
0372:
0373: /** Find field. Synthetic fields are always skipped.
0374: * @param env The current environment.
0375: * @param site The original type from where the selection takes place.
0376: * @param name The name of the field.
0377: * @param c The class to search for the field. This is always
0378: * a superclass or implemented interface of site's class.
0379: */
0380: Symbol findField(Env<AttrContext> env, Type site, Name name,
0381: TypeSymbol c) {
0382: Symbol bestSoFar = varNotFound;
0383: Symbol sym;
0384: Scope.Entry e = c.members().lookup(name);
0385: while (e.scope != null) {
0386: if (e.sym.kind == VAR
0387: && (e.sym.flags_field & SYNTHETIC) == 0) {
0388: return isAccessible(env, site, e.sym) ? e.sym
0389: : new AccessError(env, site, e.sym);
0390: }
0391: e = e.next();
0392: }
0393: Type st = types.super type(c.type);
0394: if (st != null && st.tag == CLASS) {
0395: sym = findField(env, site, name, st.tsym);
0396: if (sym.kind < bestSoFar.kind)
0397: bestSoFar = sym;
0398: }
0399: for (List<Type> l = types.interfaces(c.type); bestSoFar.kind != AMBIGUOUS
0400: && l.nonEmpty(); l = l.tail) {
0401: sym = findField(env, site, name, l.head.tsym);
0402: if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS
0403: && sym.owner != bestSoFar.owner)
0404: bestSoFar = new AmbiguityError(bestSoFar, sym);
0405: else if (sym.kind < bestSoFar.kind)
0406: bestSoFar = sym;
0407: }
0408: return bestSoFar;
0409: }
0410:
0411: /** Resolve a field identifier, throw a fatal error if not found.
0412: * @param pos The position to use for error reporting.
0413: * @param env The environment current at the method invocation.
0414: * @param site The type of the qualifying expression, in which
0415: * identifier is searched.
0416: * @param name The identifier's name.
0417: */
0418: public VarSymbol resolveInternalField(DiagnosticPosition pos,
0419: Env<AttrContext> env, Type site, Name name) {
0420: Symbol sym = findField(env, site, name, site.tsym);
0421: if (sym.kind == VAR)
0422: return (VarSymbol) sym;
0423: else
0424: throw new FatalError(JCDiagnostic.fragment(
0425: "fatal.err.cant.locate.field", name));
0426: }
0427:
0428: /** Find unqualified variable or field with given name.
0429: * Synthetic fields always skipped.
0430: * @param env The current environment.
0431: * @param name The name of the variable or field.
0432: */
0433: Symbol findVar(Env<AttrContext> env, Name name) {
0434: Symbol bestSoFar = varNotFound;
0435: Symbol sym;
0436: Env<AttrContext> env1 = env;
0437: boolean staticOnly = false;
0438: while (env1.outer != null) {
0439: if (isStatic(env1))
0440: staticOnly = true;
0441: Scope.Entry e = env1.info.scope.lookup(name);
0442: while (e.scope != null
0443: && (e.sym.kind != VAR || (e.sym.flags_field & SYNTHETIC) != 0))
0444: e = e.next();
0445: sym = (e.scope != null) ? e.sym : findField(env1,
0446: env1.enclClass.sym.type, name, env1.enclClass.sym);
0447: if (sym.exists()) {
0448: if (staticOnly && sym.kind == VAR
0449: && sym.owner.kind == TYP
0450: && (sym.flags() & STATIC) == 0)
0451: return new StaticError(sym);
0452: else
0453: return sym;
0454: } else if (sym.kind < bestSoFar.kind) {
0455: bestSoFar = sym;
0456: }
0457:
0458: if ((env1.enclClass.sym.flags() & STATIC) != 0)
0459: staticOnly = true;
0460: env1 = env1.outer;
0461: }
0462:
0463: sym = findField(env, syms.predefClass.type, name,
0464: syms.predefClass);
0465: if (sym.exists())
0466: return sym;
0467: if (bestSoFar.exists())
0468: return bestSoFar;
0469:
0470: Scope.Entry e = env.toplevel.namedImportScope.lookup(name);
0471: for (; e.scope != null; e = e.next()) {
0472: sym = e.sym;
0473: Type origin = e.getOrigin().owner.type;
0474: if (sym.kind == VAR) {
0475: if (e.sym.owner.type != origin)
0476: sym = sym.clone(e.getOrigin().owner);
0477: return isAccessible(env, origin, sym) ? sym
0478: : new AccessError(env, origin, sym);
0479: }
0480: }
0481:
0482: Symbol origin = null;
0483: e = env.toplevel.starImportScope.lookup(name);
0484: for (; e.scope != null; e = e.next()) {
0485: sym = e.sym;
0486: if (sym.kind != VAR)
0487: continue;
0488: // invariant: sym.kind == VAR
0489: if (bestSoFar.kind < AMBIGUOUS
0490: && sym.owner != bestSoFar.owner)
0491: return new AmbiguityError(bestSoFar, sym);
0492: else if (bestSoFar.kind >= VAR) {
0493: origin = e.getOrigin().owner;
0494: bestSoFar = isAccessible(env, origin.type, sym) ? sym
0495: : new AccessError(env, origin.type, sym);
0496: }
0497: }
0498: if (bestSoFar.kind == VAR
0499: && bestSoFar.owner.type != origin.type)
0500: return bestSoFar.clone(origin);
0501: else
0502: return bestSoFar;
0503: }
0504:
0505: Warner noteWarner = new Warner();
0506:
0507: /** Select the best method for a call site among two choices.
0508: * @param env The current environment.
0509: * @param site The original type from where the
0510: * selection takes place.
0511: * @param argtypes The invocation's value arguments,
0512: * @param typeargtypes The invocation's type arguments,
0513: * @param sym Proposed new best match.
0514: * @param bestSoFar Previously found best match.
0515: * @param allowBoxing Allow boxing conversions of arguments.
0516: * @param useVarargs Box trailing arguments into an array for varargs.
0517: */
0518: Symbol selectBest(Env<AttrContext> env, Type site,
0519: List<Type> argtypes, List<Type> typeargtypes, Symbol sym,
0520: Symbol bestSoFar, boolean allowBoxing, boolean useVarargs,
0521: boolean operator) {
0522: if (sym.kind == ERR)
0523: return bestSoFar;
0524: if (!sym.isInheritedIn(site.tsym, types))
0525: return bestSoFar;
0526: assert sym.kind < AMBIGUOUS;
0527: try {
0528: if (rawInstantiate(env, site, sym, argtypes, typeargtypes,
0529: allowBoxing, useVarargs, Warner.noWarnings) == null) {
0530: // inapplicable
0531: switch (bestSoFar.kind) {
0532: case ABSENT_MTH:
0533: return wrongMethod.setWrongSym(sym);
0534: case WRONG_MTH:
0535: return wrongMethods;
0536: default:
0537: return bestSoFar;
0538: }
0539: }
0540: } catch (Infer.NoInstanceException ex) {
0541: switch (bestSoFar.kind) {
0542: case ABSENT_MTH:
0543: return wrongMethod.setWrongSym(sym, ex.getDiagnostic());
0544: case WRONG_MTH:
0545: return wrongMethods;
0546: default:
0547: return bestSoFar;
0548: }
0549: }
0550: if (!isAccessible(env, site, sym)) {
0551: return (bestSoFar.kind == ABSENT_MTH) ? new AccessError(
0552: env, site, sym) : bestSoFar;
0553: }
0554: return (bestSoFar.kind > AMBIGUOUS) ? sym : mostSpecific(sym,
0555: bestSoFar, env, site, allowBoxing && operator,
0556: useVarargs);
0557: }
0558:
0559: /* Return the most specific of the two methods for a call,
0560: * given that both are accessible and applicable.
0561: * @param m1 A new candidate for most specific.
0562: * @param m2 The previous most specific candidate.
0563: * @param env The current environment.
0564: * @param site The original type from where the selection
0565: * takes place.
0566: * @param allowBoxing Allow boxing conversions of arguments.
0567: * @param useVarargs Box trailing arguments into an array for varargs.
0568: */
0569: Symbol mostSpecific(Symbol m1, Symbol m2, Env<AttrContext> env,
0570: Type site, boolean allowBoxing, boolean useVarargs) {
0571: switch (m2.kind) {
0572: case MTH:
0573: if (m1 == m2)
0574: return m1;
0575: Type mt1 = types.memberType(site, m1);
0576: noteWarner.unchecked = false;
0577: boolean m1SignatureMoreSpecific = (instantiate(env, site,
0578: m2, types.lowerBoundArgtypes(mt1), null,
0579: allowBoxing, false, noteWarner) != null || useVarargs
0580: && instantiate(env, site, m2, types
0581: .lowerBoundArgtypes(mt1), null,
0582: allowBoxing, true, noteWarner) != null)
0583: && !noteWarner.unchecked;
0584: Type mt2 = types.memberType(site, m2);
0585: noteWarner.unchecked = false;
0586: boolean m2SignatureMoreSpecific = (instantiate(env, site,
0587: m1, types.lowerBoundArgtypes(mt2), null,
0588: allowBoxing, false, noteWarner) != null || useVarargs
0589: && instantiate(env, site, m1, types
0590: .lowerBoundArgtypes(mt2), null,
0591: allowBoxing, true, noteWarner) != null)
0592: && !noteWarner.unchecked;
0593: if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) {
0594: if (!types.overrideEquivalent(mt1, mt2))
0595: return new AmbiguityError(m1, m2);
0596: // same signature; select (a) the non-bridge method, or
0597: // (b) the one that overrides the other, or (c) the concrete
0598: // one, or (d) merge both abstract signatures
0599: if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE)) {
0600: return ((m1.flags() & BRIDGE) != 0) ? m2 : m1;
0601: }
0602: // if one overrides or hides the other, use it
0603: TypeSymbol m1Owner = (TypeSymbol) m1.owner;
0604: TypeSymbol m2Owner = (TypeSymbol) m2.owner;
0605: if (types.asSuper(m1Owner.type, m2Owner) != null
0606: && ((m1.owner.flags_field & INTERFACE) == 0 || (m2.owner.flags_field & INTERFACE) != 0)
0607: && m1.overrides(m2, m1Owner, types, false))
0608: return m1;
0609: if (types.asSuper(m2Owner.type, m1Owner) != null
0610: && ((m2.owner.flags_field & INTERFACE) == 0 || (m1.owner.flags_field & INTERFACE) != 0)
0611: && m2.overrides(m1, m2Owner, types, false))
0612: return m2;
0613: boolean m1Abstract = (m1.flags() & ABSTRACT) != 0;
0614: boolean m2Abstract = (m2.flags() & ABSTRACT) != 0;
0615: if (m1Abstract && !m2Abstract)
0616: return m2;
0617: if (m2Abstract && !m1Abstract)
0618: return m1;
0619: // both abstract or both concrete
0620: if (!m1Abstract && !m2Abstract)
0621: return new AmbiguityError(m1, m2);
0622: // check for same erasure
0623: if (!types.isSameType(m1.erasure(types), m2
0624: .erasure(types)))
0625: return new AmbiguityError(m1, m2);
0626: // both abstract, neither overridden; merge throws clause and result type
0627: Symbol result;
0628: Type result2 = mt2.getReturnType();
0629: ;
0630: if (mt2.tag == FORALL)
0631: result2 = types.subst(result2,
0632: ((ForAll) mt2).tvars, ((ForAll) mt1).tvars);
0633: if (types.isSubtype(mt1.getReturnType(), result2)) {
0634: result = m1;
0635: } else if (types
0636: .isSubtype(result2, mt1.getReturnType())) {
0637: result = m2;
0638: } else {
0639: // Theoretically, this can't happen, but it is possible
0640: // due to error recovery or mixing incompatible class files
0641: return new AmbiguityError(m1, m2);
0642: }
0643: result = result.clone(result.owner);
0644: result.type = (Type) result.type.clone();
0645: result.type.setThrown(chk.intersect(mt1
0646: .getThrownTypes(), mt2.getThrownTypes()));
0647: return result;
0648: }
0649: if (m1SignatureMoreSpecific)
0650: return m1;
0651: if (m2SignatureMoreSpecific)
0652: return m2;
0653: return new AmbiguityError(m1, m2);
0654: case AMBIGUOUS:
0655: AmbiguityError e = (AmbiguityError) m2;
0656: Symbol err1 = mostSpecific(m1, e.sym1, env, site,
0657: allowBoxing, useVarargs);
0658: Symbol err2 = mostSpecific(m1, e.sym2, env, site,
0659: allowBoxing, useVarargs);
0660: if (err1 == err2)
0661: return err1;
0662: if (err1 == e.sym1 && err2 == e.sym2)
0663: return m2;
0664: if (err1 instanceof AmbiguityError
0665: && err2 instanceof AmbiguityError
0666: && ((AmbiguityError) err1).sym1 == ((AmbiguityError) err2).sym1)
0667: return new AmbiguityError(m1, m2);
0668: else
0669: return new AmbiguityError(err1, err2);
0670: default:
0671: throw new AssertionError();
0672: }
0673: }
0674:
0675: /** Find best qualified method matching given name, type and value
0676: * arguments.
0677: * @param env The current environment.
0678: * @param site The original type from where the selection
0679: * takes place.
0680: * @param name The method's name.
0681: * @param argtypes The method's value arguments.
0682: * @param typeargtypes The method's type arguments
0683: * @param allowBoxing Allow boxing conversions of arguments.
0684: * @param useVarargs Box trailing arguments into an array for varargs.
0685: */
0686: Symbol findMethod(Env<AttrContext> env, Type site, Name name,
0687: List<Type> argtypes, List<Type> typeargtypes,
0688: boolean allowBoxing, boolean useVarargs, boolean operator) {
0689: return findMethod(env, site, name, argtypes, typeargtypes,
0690: site.tsym.type, true, methodNotFound, allowBoxing,
0691: useVarargs, operator);
0692: }
0693:
0694: // where
0695: private Symbol findMethod(Env<AttrContext> env, Type site,
0696: Name name, List<Type> argtypes, List<Type> typeargtypes,
0697: Type intype, boolean abstractok, Symbol bestSoFar,
0698: boolean allowBoxing, boolean useVarargs, boolean operator) {
0699: for (Type ct = intype; ct.tag == CLASS; ct = types
0700: .super type(ct)) {
0701: ClassSymbol c = (ClassSymbol) ct.tsym;
0702: if ((c.flags() & (ABSTRACT | INTERFACE)) == 0)
0703: abstractok = false;
0704: for (Scope.Entry e = c.members().lookup(name); e.scope != null; e = e
0705: .next()) {
0706: //- System.out.println(" e " + e.sym);
0707: if (e.sym.kind == MTH
0708: && (e.sym.flags_field & SYNTHETIC) == 0) {
0709: bestSoFar = selectBest(env, site, argtypes,
0710: typeargtypes, e.sym, bestSoFar,
0711: allowBoxing, useVarargs, operator);
0712: }
0713: }
0714: //- System.out.println(" - " + bestSoFar);
0715: if (abstractok) {
0716: Symbol concrete = methodNotFound;
0717: if ((bestSoFar.flags() & ABSTRACT) == 0)
0718: concrete = bestSoFar;
0719: for (List<Type> l = types.interfaces(c.type); l
0720: .nonEmpty(); l = l.tail) {
0721: bestSoFar = findMethod(env, site, name, argtypes,
0722: typeargtypes, l.head, abstractok,
0723: bestSoFar, allowBoxing, useVarargs,
0724: operator);
0725: }
0726: if (concrete != bestSoFar
0727: && concrete.kind < ERR
0728: && bestSoFar.kind < ERR
0729: && types.isSubSignature(concrete.type,
0730: bestSoFar.type))
0731: bestSoFar = concrete;
0732: }
0733: }
0734: return bestSoFar;
0735: }
0736:
0737: /** Find unqualified method matching given name, type and value arguments.
0738: * @param env The current environment.
0739: * @param name The method's name.
0740: * @param argtypes The method's value arguments.
0741: * @param typeargtypes The method's type arguments.
0742: * @param allowBoxing Allow boxing conversions of arguments.
0743: * @param useVarargs Box trailing arguments into an array for varargs.
0744: */
0745: Symbol findFun(Env<AttrContext> env, Name name,
0746: List<Type> argtypes, List<Type> typeargtypes,
0747: boolean allowBoxing, boolean useVarargs) {
0748: Symbol bestSoFar = methodNotFound;
0749: Symbol sym;
0750: Env<AttrContext> env1 = env;
0751: boolean staticOnly = false;
0752: while (env1.outer != null) {
0753: if (isStatic(env1))
0754: staticOnly = true;
0755: sym = findMethod(env1, env1.enclClass.sym.type, name,
0756: argtypes, typeargtypes, allowBoxing, useVarargs,
0757: false);
0758: if (sym.exists()) {
0759: if (staticOnly && sym.kind == MTH
0760: && sym.owner.kind == TYP
0761: && (sym.flags() & STATIC) == 0)
0762: return new StaticError(sym);
0763: else
0764: return sym;
0765: } else if (sym.kind < bestSoFar.kind) {
0766: bestSoFar = sym;
0767: }
0768: if ((env1.enclClass.sym.flags() & STATIC) != 0)
0769: staticOnly = true;
0770: env1 = env1.outer;
0771: }
0772:
0773: sym = findMethod(env, syms.predefClass.type, name, argtypes,
0774: typeargtypes, allowBoxing, useVarargs, false);
0775: if (sym.exists())
0776: return sym;
0777:
0778: Scope.Entry e = env.toplevel.namedImportScope.lookup(name);
0779: for (; e.scope != null; e = e.next()) {
0780: sym = e.sym;
0781: Type origin = e.getOrigin().owner.type;
0782: if (sym.kind == MTH) {
0783: if (e.sym.owner.type != origin)
0784: sym = sym.clone(e.getOrigin().owner);
0785: if (!isAccessible(env, origin, sym))
0786: sym = new AccessError(env, origin, sym);
0787: bestSoFar = selectBest(env, origin, argtypes,
0788: typeargtypes, sym, bestSoFar, allowBoxing,
0789: useVarargs, false);
0790: }
0791: }
0792: if (bestSoFar.exists())
0793: return bestSoFar;
0794:
0795: e = env.toplevel.starImportScope.lookup(name);
0796: for (; e.scope != null; e = e.next()) {
0797: sym = e.sym;
0798: Type origin = e.getOrigin().owner.type;
0799: if (sym.kind == MTH) {
0800: if (e.sym.owner.type != origin)
0801: sym = sym.clone(e.getOrigin().owner);
0802: if (!isAccessible(env, origin, sym))
0803: sym = new AccessError(env, origin, sym);
0804: bestSoFar = selectBest(env, origin, argtypes,
0805: typeargtypes, sym, bestSoFar, allowBoxing,
0806: useVarargs, false);
0807: }
0808: }
0809: return bestSoFar;
0810: }
0811:
0812: /** Load toplevel or member class with given fully qualified name and
0813: * verify that it is accessible.
0814: * @param env The current environment.
0815: * @param name The fully qualified name of the class to be loaded.
0816: */
0817: Symbol loadClass(Env<AttrContext> env, Name name) {
0818: try {
0819: ClassSymbol c = reader.loadClass(name);
0820: return isAccessible(env, c) ? c : new AccessError(c);
0821: } catch (ClassReader.BadClassFile err) {
0822: throw err;
0823: } catch (CompletionFailure ex) {
0824: return typeNotFound;
0825: }
0826: }
0827:
0828: /** Find qualified member type.
0829: * @param env The current environment.
0830: * @param site The original type from where the selection takes
0831: * place.
0832: * @param name The type's name.
0833: * @param c The class to search for the member type. This is
0834: * always a superclass or implemented interface of
0835: * site's class.
0836: */
0837: Symbol findMemberType(Env<AttrContext> env, Type site, Name name,
0838: TypeSymbol c) {
0839: Symbol bestSoFar = typeNotFound;
0840: Symbol sym;
0841: Scope.Entry e = c.members().lookup(name);
0842: while (e.scope != null) {
0843: if (e.sym.kind == TYP) {
0844: return isAccessible(env, site, e.sym) ? e.sym
0845: : new AccessError(env, site, e.sym);
0846: }
0847: e = e.next();
0848: }
0849: Type st = types.super type(c.type);
0850: if (st != null && st.tag == CLASS) {
0851: sym = findMemberType(env, site, name, st.tsym);
0852: if (sym.kind < bestSoFar.kind)
0853: bestSoFar = sym;
0854: }
0855: for (List<Type> l = types.interfaces(c.type); bestSoFar.kind != AMBIGUOUS
0856: && l.nonEmpty(); l = l.tail) {
0857: sym = findMemberType(env, site, name, l.head.tsym);
0858: if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS
0859: && sym.owner != bestSoFar.owner)
0860: bestSoFar = new AmbiguityError(bestSoFar, sym);
0861: else if (sym.kind < bestSoFar.kind)
0862: bestSoFar = sym;
0863: }
0864: return bestSoFar;
0865: }
0866:
0867: /** Find a global type in given scope and load corresponding class.
0868: * @param env The current environment.
0869: * @param scope The scope in which to look for the type.
0870: * @param name The type's name.
0871: */
0872: Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) {
0873: Symbol bestSoFar = typeNotFound;
0874: for (Scope.Entry e = scope.lookup(name); e.scope != null; e = e
0875: .next()) {
0876: Symbol sym = loadClass(env, e.sym.flatName());
0877: if (bestSoFar.kind == TYP && sym.kind == TYP
0878: && bestSoFar != sym)
0879: return new AmbiguityError(bestSoFar, sym);
0880: else if (sym.kind < bestSoFar.kind)
0881: bestSoFar = sym;
0882: }
0883: return bestSoFar;
0884: }
0885:
0886: /** Find an unqualified type symbol.
0887: * @param env The current environment.
0888: * @param name The type's name.
0889: */
0890: Symbol findType(Env<AttrContext> env, Name name) {
0891: Symbol bestSoFar = typeNotFound;
0892: Symbol sym;
0893: boolean staticOnly = false;
0894: for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) {
0895: if (isStatic(env1))
0896: staticOnly = true;
0897: for (Scope.Entry e = env1.info.scope.lookup(name); e.scope != null; e = e
0898: .next()) {
0899: if (e.sym.kind == TYP) {
0900: if (staticOnly && e.sym.type.tag == TYPEVAR
0901: && e.sym.owner.kind == TYP)
0902: return new StaticError(e.sym);
0903: return e.sym;
0904: }
0905: }
0906:
0907: sym = findMemberType(env1, env1.enclClass.sym.type, name,
0908: env1.enclClass.sym);
0909: if (staticOnly && sym.kind == TYP && sym.type.tag == CLASS
0910: && sym.type.getEnclosingType().tag == CLASS
0911: && env1.enclClass.sym.type.isParameterized()
0912: && sym.type.getEnclosingType().isParameterized())
0913: return new StaticError(sym);
0914: else if (sym.exists())
0915: return sym;
0916: else if (sym.kind < bestSoFar.kind)
0917: bestSoFar = sym;
0918:
0919: JCClassDecl encl = env1.baseClause ? (JCClassDecl) env1.tree
0920: : env1.enclClass;
0921: if ((encl.sym.flags() & STATIC) != 0)
0922: staticOnly = true;
0923: }
0924:
0925: if (env.tree.getTag() != JCTree.IMPORT) {
0926: sym = findGlobalType(env, env.toplevel.namedImportScope,
0927: name);
0928: if (sym.exists())
0929: return sym;
0930: else if (sym.kind < bestSoFar.kind)
0931: bestSoFar = sym;
0932:
0933: sym = findGlobalType(env, env.toplevel.packge.members(),
0934: name);
0935: if (sym.exists())
0936: return sym;
0937: else if (sym.kind < bestSoFar.kind)
0938: bestSoFar = sym;
0939:
0940: sym = findGlobalType(env, env.toplevel.starImportScope,
0941: name);
0942: if (sym.exists())
0943: return sym;
0944: else if (sym.kind < bestSoFar.kind)
0945: bestSoFar = sym;
0946: }
0947:
0948: return bestSoFar;
0949: }
0950:
0951: /** Find an unqualified identifier which matches a specified kind set.
0952: * @param env The current environment.
0953: * @param name The indentifier's name.
0954: * @param kind Indicates the possible symbol kinds
0955: * (a subset of VAL, TYP, PCK).
0956: */
0957: Symbol findIdent(Env<AttrContext> env, Name name, int kind) {
0958: Symbol bestSoFar = typeNotFound;
0959: Symbol sym;
0960:
0961: if ((kind & VAR) != 0) {
0962: sym = findVar(env, name);
0963: if (sym.exists())
0964: return sym;
0965: else if (sym.kind < bestSoFar.kind)
0966: bestSoFar = sym;
0967: }
0968:
0969: if ((kind & TYP) != 0) {
0970: sym = findType(env, name);
0971: if (sym.exists())
0972: return sym;
0973: else if (sym.kind < bestSoFar.kind)
0974: bestSoFar = sym;
0975: }
0976:
0977: if ((kind & PCK) != 0)
0978: return reader.enterPackage(name);
0979: else
0980: return bestSoFar;
0981: }
0982:
0983: /** Find an identifier in a package which matches a specified kind set.
0984: * @param env The current environment.
0985: * @param name The identifier's name.
0986: * @param kind Indicates the possible symbol kinds
0987: * (a nonempty subset of TYP, PCK).
0988: */
0989: Symbol findIdentInPackage(Env<AttrContext> env, TypeSymbol pck,
0990: Name name, int kind) {
0991: Name fullname = TypeSymbol.formFullName(name, pck);
0992: Symbol bestSoFar = typeNotFound;
0993: PackageSymbol pack = null;
0994: if ((kind & PCK) != 0) {
0995: pack = reader.enterPackage(fullname);
0996: if (pack.exists())
0997: return pack;
0998: }
0999: if ((kind & TYP) != 0) {
1000: Symbol sym = loadClass(env, fullname);
1001: if (sym.exists()) {
1002: // don't allow programs to use flatnames
1003: if (name == sym.name)
1004: return sym;
1005: } else if (sym.kind < bestSoFar.kind)
1006: bestSoFar = sym;
1007: }
1008: return (pack != null) ? pack : bestSoFar;
1009: }
1010:
1011: /** Find an identifier among the members of a given type `site'.
1012: * @param env The current environment.
1013: * @param site The type containing the symbol to be found.
1014: * @param name The identifier's name.
1015: * @param kind Indicates the possible symbol kinds
1016: * (a subset of VAL, TYP).
1017: */
1018: Symbol findIdentInType(Env<AttrContext> env, Type site, Name name,
1019: int kind) {
1020: Symbol bestSoFar = typeNotFound;
1021: Symbol sym;
1022: if ((kind & VAR) != 0) {
1023: sym = findField(env, site, name, site.tsym);
1024: if (sym.exists())
1025: return sym;
1026: else if (sym.kind < bestSoFar.kind)
1027: bestSoFar = sym;
1028: }
1029:
1030: if ((kind & TYP) != 0) {
1031: sym = findMemberType(env, site, name, site.tsym);
1032: if (sym.exists())
1033: return sym;
1034: else if (sym.kind < bestSoFar.kind)
1035: bestSoFar = sym;
1036: }
1037: return bestSoFar;
1038: }
1039:
1040: /* ***************************************************************************
1041: * Access checking
1042: * The following methods convert ResolveErrors to ErrorSymbols, issuing
1043: * an error message in the process
1044: ****************************************************************************/
1045:
1046: /** If `sym' is a bad symbol: report error and return errSymbol
1047: * else pass through unchanged,
1048: * additional arguments duplicate what has been used in trying to find the
1049: * symbol (--> flyweight pattern). This improves performance since we
1050: * expect misses to happen frequently.
1051: *
1052: * @param sym The symbol that was found, or a ResolveError.
1053: * @param pos The position to use for error reporting.
1054: * @param site The original type from where the selection took place.
1055: * @param name The symbol's name.
1056: * @param argtypes The invocation's value arguments,
1057: * if we looked for a method.
1058: * @param typeargtypes The invocation's type arguments,
1059: * if we looked for a method.
1060: */
1061: Symbol access(Symbol sym, DiagnosticPosition pos, Type site,
1062: Name name, boolean qualified, List<Type> argtypes,
1063: List<Type> typeargtypes) {
1064: if (sym.kind >= AMBIGUOUS) {
1065: // printscopes(site.tsym.members());//DEBUG
1066: if (!site.isErroneous()
1067: && !Type.isErroneous(argtypes)
1068: && (typeargtypes == null || !Type
1069: .isErroneous(typeargtypes)))
1070: ((ResolveError) sym).report(log, pos, site, name,
1071: argtypes, typeargtypes);
1072: do {
1073: sym = ((ResolveError) sym).sym;
1074: } while (sym.kind >= AMBIGUOUS);
1075: if (sym == syms.errSymbol // preserve the symbol name through errors
1076: || ((sym.kind & ERRONEOUS) == 0 // make sure an error symbol is returned
1077: && (sym.kind & TYP) != 0))
1078: sym = new ErrorType(name, qualified ? site.tsym
1079: : syms.noSymbol).tsym;
1080: }
1081: return sym;
1082: }
1083:
1084: /** Same as above, but without type arguments and arguments.
1085: */
1086: Symbol access(Symbol sym, DiagnosticPosition pos, Type site,
1087: Name name, boolean qualified) {
1088: if (sym.kind >= AMBIGUOUS)
1089: return access(sym, pos, site, name, qualified, List
1090: .<Type> nil(), null);
1091: else
1092: return sym;
1093: }
1094:
1095: /** Check that sym is not an abstract method.
1096: */
1097: void checkNonAbstract(DiagnosticPosition pos, Symbol sym) {
1098: if ((sym.flags() & ABSTRACT) != 0)
1099: log.error(pos, "abstract.cant.be.accessed.directly",
1100: kindName(sym), sym, sym.location());
1101: }
1102:
1103: /* ***************************************************************************
1104: * Debugging
1105: ****************************************************************************/
1106:
1107: /** print all scopes starting with scope s and proceeding outwards.
1108: * used for debugging.
1109: */
1110: public void printscopes(Scope s) {
1111: while (s != null) {
1112: if (s.owner != null)
1113: System.err.print(s.owner + ": ");
1114: for (Scope.Entry e = s.elems; e != null; e = e.sibling) {
1115: if ((e.sym.flags() & ABSTRACT) != 0)
1116: System.err.print("abstract ");
1117: System.err.print(e.sym + " ");
1118: }
1119: System.err.println();
1120: s = s.next;
1121: }
1122: }
1123:
1124: void printscopes(Env<AttrContext> env) {
1125: while (env.outer != null) {
1126: System.err.println("------------------------------");
1127: printscopes(env.info.scope);
1128: env = env.outer;
1129: }
1130: }
1131:
1132: public void printscopes(Type t) {
1133: while (t.tag == CLASS) {
1134: printscopes(t.tsym.members());
1135: t = types.super type(t);
1136: }
1137: }
1138:
1139: /* ***************************************************************************
1140: * Name resolution
1141: * Naming conventions are as for symbol lookup
1142: * Unlike the find... methods these methods will report access errors
1143: ****************************************************************************/
1144:
1145: /** Resolve an unqualified (non-method) identifier.
1146: * @param pos The position to use for error reporting.
1147: * @param env The environment current at the identifier use.
1148: * @param name The identifier's name.
1149: * @param kind The set of admissible symbol kinds for the identifier.
1150: */
1151: Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env,
1152: Name name, int kind) {
1153: return access(findIdent(env, name, kind), pos,
1154: env.enclClass.sym.type, name, false);
1155: }
1156:
1157: /** Resolve an unqualified method identifier.
1158: * @param pos The position to use for error reporting.
1159: * @param env The environment current at the method invocation.
1160: * @param name The identifier's name.
1161: * @param argtypes The types of the invocation's value arguments.
1162: * @param typeargtypes The types of the invocation's type arguments.
1163: */
1164: Symbol resolveMethod(DiagnosticPosition pos, Env<AttrContext> env,
1165: Name name, List<Type> argtypes, List<Type> typeargtypes) {
1166: Symbol sym = findFun(env, name, argtypes, typeargtypes, false,
1167: env.info.varArgs = false);
1168: if (varargsEnabled && sym.kind >= WRONG_MTHS) {
1169: sym = findFun(env, name, argtypes, typeargtypes, true,
1170: false);
1171: if (sym.kind >= WRONG_MTHS)
1172: sym = findFun(env, name, argtypes, typeargtypes, true,
1173: env.info.varArgs = true);
1174: }
1175: if (sym.kind >= AMBIGUOUS) {
1176: sym = access(sym, pos, env.enclClass.sym.type, name, false,
1177: argtypes, typeargtypes);
1178: }
1179: return sym;
1180: }
1181:
1182: /** Resolve a qualified method identifier
1183: * @param pos The position to use for error reporting.
1184: * @param env The environment current at the method invocation.
1185: * @param site The type of the qualifying expression, in which
1186: * identifier is searched.
1187: * @param name The identifier's name.
1188: * @param argtypes The types of the invocation's value arguments.
1189: * @param typeargtypes The types of the invocation's type arguments.
1190: */
1191: Symbol resolveQualifiedMethod(DiagnosticPosition pos,
1192: Env<AttrContext> env, Type site, Name name,
1193: List<Type> argtypes, List<Type> typeargtypes) {
1194: Symbol sym = findMethod(env, site, name, argtypes,
1195: typeargtypes, false, env.info.varArgs = false, false);
1196: if (varargsEnabled && sym.kind >= WRONG_MTHS) {
1197: sym = findMethod(env, site, name, argtypes, typeargtypes,
1198: true, false, false);
1199: if (sym.kind >= WRONG_MTHS)
1200: sym = findMethod(env, site, name, argtypes,
1201: typeargtypes, true, env.info.varArgs = true,
1202: false);
1203: }
1204: if (sym.kind >= AMBIGUOUS) {
1205: sym = access(sym, pos, site, name, true, argtypes,
1206: typeargtypes);
1207: }
1208: return sym;
1209: }
1210:
1211: /** Resolve a qualified method identifier, throw a fatal error if not
1212: * found.
1213: * @param pos The position to use for error reporting.
1214: * @param env The environment current at the method invocation.
1215: * @param site The type of the qualifying expression, in which
1216: * identifier is searched.
1217: * @param name The identifier's name.
1218: * @param argtypes The types of the invocation's value arguments.
1219: * @param typeargtypes The types of the invocation's type arguments.
1220: */
1221: public MethodSymbol resolveInternalMethod(DiagnosticPosition pos,
1222: Env<AttrContext> env, Type site, Name name,
1223: List<Type> argtypes, List<Type> typeargtypes) {
1224: Symbol sym = resolveQualifiedMethod(pos, env, site, name,
1225: argtypes, typeargtypes);
1226: if (sym.kind == MTH)
1227: return (MethodSymbol) sym;
1228: else
1229: throw new FatalError(JCDiagnostic.fragment(
1230: "fatal.err.cant.locate.meth", name));
1231: }
1232:
1233: /** Resolve constructor.
1234: * @param pos The position to use for error reporting.
1235: * @param env The environment current at the constructor invocation.
1236: * @param site The type of class for which a constructor is searched.
1237: * @param argtypes The types of the constructor invocation's value
1238: * arguments.
1239: * @param typeargtypes The types of the constructor invocation's type
1240: * arguments.
1241: */
1242: Symbol resolveConstructor(DiagnosticPosition pos,
1243: Env<AttrContext> env, Type site, List<Type> argtypes,
1244: List<Type> typeargtypes) {
1245: Symbol sym = resolveConstructor(pos, env, site, argtypes,
1246: typeargtypes, false, env.info.varArgs = false);
1247: if (varargsEnabled && sym.kind >= WRONG_MTHS) {
1248: sym = resolveConstructor(pos, env, site, argtypes,
1249: typeargtypes, true, false);
1250: if (sym.kind >= WRONG_MTHS)
1251: sym = resolveConstructor(pos, env, site, argtypes,
1252: typeargtypes, true, env.info.varArgs = true);
1253: }
1254: if (sym.kind >= AMBIGUOUS) {
1255: sym = access(sym, pos, site, names.init, true, argtypes,
1256: typeargtypes);
1257: }
1258: return sym;
1259: }
1260:
1261: /** Resolve constructor.
1262: * @param pos The position to use for error reporting.
1263: * @param env The environment current at the constructor invocation.
1264: * @param site The type of class for which a constructor is searched.
1265: * @param argtypes The types of the constructor invocation's value
1266: * arguments.
1267: * @param typeargtypes The types of the constructor invocation's type
1268: * arguments.
1269: * @param allowBoxing Allow boxing and varargs conversions.
1270: * @param useVarargs Box trailing arguments into an array for varargs.
1271: */
1272: Symbol resolveConstructor(DiagnosticPosition pos,
1273: Env<AttrContext> env, Type site, List<Type> argtypes,
1274: List<Type> typeargtypes, boolean allowBoxing,
1275: boolean useVarargs) {
1276: Symbol sym = findMethod(env, site, names.init, argtypes,
1277: typeargtypes, allowBoxing, useVarargs, false);
1278: if ((sym.flags() & DEPRECATED) != 0
1279: && (env.info.scope.owner.flags() & DEPRECATED) == 0
1280: && env.info.scope.owner.outermostClass() != sym
1281: .outermostClass())
1282: chk.warnDeprecated(pos, sym);
1283: return sym;
1284: }
1285:
1286: /** Resolve a constructor, throw a fatal error if not found.
1287: * @param pos The position to use for error reporting.
1288: * @param env The environment current at the method invocation.
1289: * @param site The type to be constructed.
1290: * @param argtypes The types of the invocation's value arguments.
1291: * @param typeargtypes The types of the invocation's type arguments.
1292: */
1293: public MethodSymbol resolveInternalConstructor(
1294: DiagnosticPosition pos, Env<AttrContext> env, Type site,
1295: List<Type> argtypes, List<Type> typeargtypes) {
1296: Symbol sym = resolveConstructor(pos, env, site, argtypes,
1297: typeargtypes);
1298: if (sym.kind == MTH)
1299: return (MethodSymbol) sym;
1300: else
1301: throw new FatalError(JCDiagnostic.fragment(
1302: "fatal.err.cant.locate.ctor", site));
1303: }
1304:
1305: /** Resolve operator.
1306: * @param pos The position to use for error reporting.
1307: * @param optag The tag of the operation tree.
1308: * @param env The environment current at the operation.
1309: * @param argtypes The types of the operands.
1310: */
1311: Symbol resolveOperator(DiagnosticPosition pos, int optag,
1312: Env<AttrContext> env, List<Type> argtypes) {
1313: Name name = treeinfo.operatorName(optag);
1314: Symbol sym = findMethod(env, syms.predefClass.type, name,
1315: argtypes, null, false, false, true);
1316: if (boxingEnabled && sym.kind >= WRONG_MTHS)
1317: sym = findMethod(env, syms.predefClass.type, name,
1318: argtypes, null, true, false, true);
1319: return access(sym, pos, env.enclClass.sym.type, name, false,
1320: argtypes, null);
1321: }
1322:
1323: /** Resolve operator.
1324: * @param pos The position to use for error reporting.
1325: * @param optag The tag of the operation tree.
1326: * @param env The environment current at the operation.
1327: * @param arg The type of the operand.
1328: */
1329: Symbol resolveUnaryOperator(DiagnosticPosition pos, int optag,
1330: Env<AttrContext> env, Type arg) {
1331: return resolveOperator(pos, optag, env, List.of(arg));
1332: }
1333:
1334: /** Resolve binary operator.
1335: * @param pos The position to use for error reporting.
1336: * @param optag The tag of the operation tree.
1337: * @param env The environment current at the operation.
1338: * @param left The types of the left operand.
1339: * @param right The types of the right operand.
1340: */
1341: Symbol resolveBinaryOperator(DiagnosticPosition pos, int optag,
1342: Env<AttrContext> env, Type left, Type right) {
1343: return resolveOperator(pos, optag, env, List.of(left, right));
1344: }
1345:
1346: /**
1347: * Resolve `c.name' where name == this or name == super.
1348: * @param pos The position to use for error reporting.
1349: * @param env The environment current at the expression.
1350: * @param c The qualifier.
1351: * @param name The identifier's name.
1352: */
1353: Symbol resolveSelf(DiagnosticPosition pos, Env<AttrContext> env,
1354: TypeSymbol c, Name name) {
1355: Env<AttrContext> env1 = env;
1356: boolean staticOnly = false;
1357: while (env1.outer != null) {
1358: if (isStatic(env1))
1359: staticOnly = true;
1360: if (env1.enclClass.sym == c) {
1361: Symbol sym = env1.info.scope.lookup(name).sym;
1362: if (sym != null) {
1363: if (staticOnly)
1364: sym = new StaticError(sym);
1365: return access(sym, pos, env.enclClass.sym.type,
1366: name, true);
1367: }
1368: }
1369: if ((env1.enclClass.sym.flags() & STATIC) != 0)
1370: staticOnly = true;
1371: env1 = env1.outer;
1372: }
1373: log.error(pos, "not.encl.class", c);
1374: return syms.errSymbol;
1375: }
1376:
1377: /**
1378: * Resolve `c.this' for an enclosing class c that contains the
1379: * named member.
1380: * @param pos The position to use for error reporting.
1381: * @param env The environment current at the expression.
1382: * @param member The member that must be contained in the result.
1383: */
1384: Symbol resolveSelfContaining(DiagnosticPosition pos,
1385: Env<AttrContext> env, Symbol member) {
1386: Name name = names._this ;
1387: Env<AttrContext> env1 = env;
1388: boolean staticOnly = false;
1389: while (env1.outer != null) {
1390: if (isStatic(env1))
1391: staticOnly = true;
1392: if (env1.enclClass.sym.isSubClass(member.owner, types)
1393: && isAccessible(env, env1.enclClass.sym.type,
1394: member)) {
1395: Symbol sym = env1.info.scope.lookup(name).sym;
1396: if (sym != null) {
1397: if (staticOnly)
1398: sym = new StaticError(sym);
1399: return access(sym, pos, env.enclClass.sym.type,
1400: name, true);
1401: }
1402: }
1403: if ((env1.enclClass.sym.flags() & STATIC) != 0)
1404: staticOnly = true;
1405: env1 = env1.outer;
1406: }
1407: log.error(pos, "encl.class.required", member);
1408: return syms.errSymbol;
1409: }
1410:
1411: /**
1412: * Resolve an appropriate implicit this instance for t's container.
1413: * JLS2 8.8.5.1 and 15.9.2
1414: */
1415: Type resolveImplicitThis(DiagnosticPosition pos,
1416: Env<AttrContext> env, Type t) {
1417: Type this Type = (((t.tsym.owner.kind & (MTH | VAR)) != 0) ? resolveSelf(
1418: pos, env, t.getEnclosingType().tsym, names._this )
1419: : resolveSelfContaining(pos, env, t.tsym)).type;
1420: if (env.info.isSelfCall && this Type.tsym == env.enclClass.sym)
1421: log.error(pos, "cant.ref.before.ctor.called", "this");
1422: return this Type;
1423: }
1424:
1425: /* ***************************************************************************
1426: * Methods related to kinds
1427: ****************************************************************************/
1428:
1429: /** A localized string describing a given kind.
1430: */
1431: static JCDiagnostic kindName(int kind) {
1432: switch (kind) {
1433: case PCK:
1434: return JCDiagnostic.fragment("kindname.package");
1435: case TYP:
1436: return JCDiagnostic.fragment("kindname.class");
1437: case VAR:
1438: return JCDiagnostic.fragment("kindname.variable");
1439: case VAL:
1440: return JCDiagnostic.fragment("kindname.value");
1441: case MTH:
1442: return JCDiagnostic.fragment("kindname.method");
1443: default:
1444: return JCDiagnostic.fragment("kindname", Integer
1445: .toString(kind)); //debug
1446: }
1447: }
1448:
1449: static JCDiagnostic kindName(Symbol sym) {
1450: switch (sym.getKind()) {
1451: case PACKAGE:
1452: return JCDiagnostic.fragment("kindname.package");
1453:
1454: case ENUM:
1455: case ANNOTATION_TYPE:
1456: case INTERFACE:
1457: case CLASS:
1458: return JCDiagnostic.fragment("kindname.class");
1459:
1460: case TYPE_PARAMETER:
1461: return JCDiagnostic.fragment("kindname.type.variable");
1462:
1463: case ENUM_CONSTANT:
1464: case FIELD:
1465: case PARAMETER:
1466: case LOCAL_VARIABLE:
1467: case EXCEPTION_PARAMETER:
1468: return JCDiagnostic.fragment("kindname.variable");
1469:
1470: case METHOD:
1471: case CONSTRUCTOR:
1472: case STATIC_INIT:
1473: case INSTANCE_INIT:
1474: return JCDiagnostic.fragment("kindname.method");
1475:
1476: default:
1477: if (sym.kind == VAL)
1478: // I don't think this can happen but it can't harm
1479: // playing it safe --ahe
1480: return JCDiagnostic.fragment("kindname.value");
1481: else
1482: return JCDiagnostic.fragment("kindname", sym.getKind()); // debug
1483: }
1484: }
1485:
1486: /** A localized string describing a given set of kinds.
1487: */
1488: static JCDiagnostic kindNames(int kind) {
1489: StringBuffer key = new StringBuffer();
1490: key.append("kindname");
1491: if ((kind & VAL) != 0)
1492: key.append(((kind & VAL) == VAR) ? ".variable" : ".value");
1493: if ((kind & MTH) != 0)
1494: key.append(".method");
1495: if ((kind & TYP) != 0)
1496: key.append(".class");
1497: if ((kind & PCK) != 0)
1498: key.append(".package");
1499: return JCDiagnostic.fragment(key.toString(), kind);
1500: }
1501:
1502: /** A localized string describing the kind -- either class or interface --
1503: * of a given type.
1504: */
1505: static JCDiagnostic typeKindName(Type t) {
1506: if (t.tag == TYPEVAR || t.tag == CLASS
1507: && (t.tsym.flags() & COMPOUND) != 0)
1508: return JCDiagnostic
1509: .fragment("kindname.type.variable.bound");
1510: else if (t.tag == PACKAGE)
1511: return JCDiagnostic.fragment("kindname.package");
1512: else if ((t.tsym.flags_field & ANNOTATION) != 0)
1513: return JCDiagnostic.fragment("kindname.annotation");
1514: else if ((t.tsym.flags_field & INTERFACE) != 0)
1515: return JCDiagnostic.fragment("kindname.interface");
1516: else
1517: return JCDiagnostic.fragment("kindname.class");
1518: }
1519:
1520: /** A localized string describing the kind of a missing symbol, given an
1521: * error kind.
1522: */
1523: static JCDiagnostic absentKindName(int kind) {
1524: switch (kind) {
1525: case ABSENT_VAR:
1526: return JCDiagnostic.fragment("kindname.variable");
1527: case WRONG_MTHS:
1528: case WRONG_MTH:
1529: case ABSENT_MTH:
1530: return JCDiagnostic.fragment("kindname.method");
1531: case ABSENT_TYP:
1532: return JCDiagnostic.fragment("kindname.class");
1533: default:
1534: return JCDiagnostic.fragment("kindname", kind);
1535: }
1536: }
1537:
1538: /* ***************************************************************************
1539: * ResolveError classes, indicating error situations when accessing symbols
1540: ****************************************************************************/
1541:
1542: public void logAccessError(Env<AttrContext> env, JCTree tree,
1543: Type type) {
1544: AccessError error = new AccessError(env, type
1545: .getEnclosingType(), type.tsym);
1546: error.report(log, tree.pos(), type.getEnclosingType(), null,
1547: null, null);
1548: }
1549:
1550: /** Root class for resolve errors.
1551: * Instances of this class indicate "Symbol not found".
1552: * Instances of subclass indicate other errors.
1553: */
1554: private class ResolveError extends Symbol {
1555:
1556: ResolveError(int kind, Symbol sym, String debugName) {
1557: super (kind, 0, null, null, null);
1558: this .debugName = debugName;
1559: this .sym = sym;
1560: }
1561:
1562: /** The name of the kind of error, for debugging only.
1563: */
1564: final String debugName;
1565:
1566: /** The symbol that was determined by resolution, or errSymbol if none
1567: * was found.
1568: */
1569: final Symbol sym;
1570:
1571: /** The symbol that was a close mismatch, or null if none was found.
1572: * wrongSym is currently set if a simgle method with the correct name, but
1573: * the wrong parameters was found.
1574: */
1575: Symbol wrongSym;
1576:
1577: /** An auxiliary explanation set in case of instantiation errors.
1578: */
1579: JCDiagnostic explanation;
1580:
1581: public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1582: throw new AssertionError();
1583: }
1584:
1585: /** Print the (debug only) name of the kind of error.
1586: */
1587: public String toString() {
1588: return debugName + " wrongSym=" + wrongSym
1589: + " explanation=" + explanation;
1590: }
1591:
1592: /** Update wrongSym and explanation and return this.
1593: */
1594: ResolveError setWrongSym(Symbol sym, JCDiagnostic explanation) {
1595: this .wrongSym = sym;
1596: this .explanation = explanation;
1597: return this ;
1598: }
1599:
1600: /** Update wrongSym and return this.
1601: */
1602: ResolveError setWrongSym(Symbol sym) {
1603: this .wrongSym = sym;
1604: this .explanation = null;
1605: return this ;
1606: }
1607:
1608: public boolean exists() {
1609: switch (kind) {
1610: case HIDDEN:
1611: case ABSENT_VAR:
1612: case ABSENT_MTH:
1613: case ABSENT_TYP:
1614: return false;
1615: default:
1616: return true;
1617: }
1618: }
1619:
1620: /** Report error.
1621: * @param log The error log to be used for error reporting.
1622: * @param pos The position to be used for error reporting.
1623: * @param site The original type from where the selection took place.
1624: * @param name The name of the symbol to be resolved.
1625: * @param argtypes The invocation's value arguments,
1626: * if we looked for a method.
1627: * @param typeargtypes The invocation's type arguments,
1628: * if we looked for a method.
1629: */
1630: void report(Log log, DiagnosticPosition pos, Type site,
1631: Name name, List<Type> argtypes, List<Type> typeargtypes) {
1632: if (name != name.table.error) {
1633: JCDiagnostic kindname = absentKindName(kind);
1634: String idname = name.toString();
1635: String args = "";
1636: String typeargs = "";
1637: if (kind >= WRONG_MTHS && kind <= ABSENT_MTH) {
1638: if (isOperator(name)) {
1639: log.error(pos, "operator.cant.be.applied",
1640: name, Type.toString(argtypes));
1641: return;
1642: }
1643: if (name == name.table.init) {
1644: kindname = JCDiagnostic
1645: .fragment("kindname.constructor");
1646: idname = site.tsym.name.toString();
1647: }
1648: args = "(" + Type.toString(argtypes) + ")";
1649: if (typeargtypes != null && typeargtypes.nonEmpty())
1650: typeargs = "<" + Type.toString(typeargtypes)
1651: + ">";
1652: }
1653: if (kind == WRONG_MTH) {
1654: log.error(pos, "cant.apply.symbol"
1655: + (explanation != null ? ".1" : ""),
1656: wrongSym.asMemberOf(site, types), wrongSym
1657: .location(site, types), typeargs,
1658: Type.toString(argtypes), explanation);
1659: } else if (site.tsym.name.len != 0) {
1660: if (site.tsym.kind == PCK && !site.tsym.exists())
1661: log.error(pos, "doesnt.exist", site.tsym);
1662: else
1663: log.error(pos, "cant.resolve.location",
1664: kindname, idname, args, typeargs,
1665: typeKindName(site), site);
1666: } else {
1667: log.error(pos, "cant.resolve", kindname, idname,
1668: args, typeargs);
1669: }
1670: }
1671: }
1672:
1673: //where
1674: /** A name designates an operator if it consists
1675: * of a non-empty sequence of operator symbols +-~!/*%&|^<>=
1676: */
1677: boolean isOperator(Name name) {
1678: int i = 0;
1679: while (i < name.len
1680: && "+-~!*/%&|^<>=".indexOf(name.byteAt(i)) >= 0)
1681: i++;
1682: return i > 0 && i == name.len;
1683: }
1684: }
1685:
1686: /** Resolve error class indicating that a symbol is not accessible.
1687: */
1688: class AccessError extends ResolveError {
1689:
1690: AccessError(Symbol sym) {
1691: this (null, null, sym);
1692: }
1693:
1694: AccessError(Env<AttrContext> env, Type site, Symbol sym) {
1695: super (HIDDEN, sym, "access error");
1696: this .env = env;
1697: this .site = site;
1698: if (debugResolve)
1699: log.error("proc.messager", sym + " @ " + site
1700: + " is inaccessible.");
1701: }
1702:
1703: private Env<AttrContext> env;
1704: private Type site;
1705:
1706: /** Report error.
1707: * @param log The error log to be used for error reporting.
1708: * @param pos The position to be used for error reporting.
1709: * @param site The original type from where the selection took place.
1710: * @param name The name of the symbol to be resolved.
1711: * @param argtypes The invocation's value arguments,
1712: * if we looked for a method.
1713: * @param typeargtypes The invocation's type arguments,
1714: * if we looked for a method.
1715: */
1716: void report(Log log, DiagnosticPosition pos, Type site,
1717: Name name, List<Type> argtypes, List<Type> typeargtypes) {
1718: if (sym.owner.type.tag != ERROR) {
1719: if (sym.name == sym.name.table.init
1720: && sym.owner != site.tsym)
1721: new ResolveError(ABSENT_MTH, sym.owner,
1722: "absent method " + sym).report(log, pos,
1723: site, name, argtypes, typeargtypes);
1724: if ((sym.flags() & PUBLIC) != 0
1725: || (env != null && this .site != null && !isAccessible(
1726: env, this .site)))
1727: log.error(pos,
1728: "not.def.access.class.intf.cant.access",
1729: sym, sym.location());
1730: else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0)
1731: log.error(pos, "report.access", sym, TreeInfo
1732: .flagNames(sym.flags()
1733: & (PRIVATE | PROTECTED)), sym
1734: .location());
1735: else
1736: log.error(pos, "not.def.public.cant.access", sym,
1737: sym.location());
1738: }
1739: }
1740: }
1741:
1742: /** Resolve error class indicating that an instance member was accessed
1743: * from a static context.
1744: */
1745: class StaticError extends ResolveError {
1746: StaticError(Symbol sym) {
1747: super (STATICERR, sym, "static error");
1748: }
1749:
1750: /** Report error.
1751: * @param log The error log to be used for error reporting.
1752: * @param pos The position to be used for error reporting.
1753: * @param site The original type from where the selection took place.
1754: * @param name The name of the symbol to be resolved.
1755: * @param argtypes The invocation's value arguments,
1756: * if we looked for a method.
1757: * @param typeargtypes The invocation's type arguments,
1758: * if we looked for a method.
1759: */
1760: void report(Log log, DiagnosticPosition pos, Type site,
1761: Name name, List<Type> argtypes, List<Type> typeargtypes) {
1762: String symstr = ((sym.kind == TYP && sym.type.tag == CLASS) ? types
1763: .erasure(sym.type)
1764: : sym).toString();
1765: log.error(pos, "non-static.cant.be.ref", kindName(sym),
1766: symstr);
1767: }
1768: }
1769:
1770: /** Resolve error class indicating an ambiguous reference.
1771: */
1772: class AmbiguityError extends ResolveError {
1773: Symbol sym1;
1774: Symbol sym2;
1775:
1776: AmbiguityError(Symbol sym1, Symbol sym2) {
1777: super (AMBIGUOUS, sym1, "ambiguity error");
1778: this .sym1 = sym1;
1779: this .sym2 = sym2;
1780: }
1781:
1782: /** Report error.
1783: * @param log The error log to be used for error reporting.
1784: * @param pos The position to be used for error reporting.
1785: * @param site The original type from where the selection took place.
1786: * @param name The name of the symbol to be resolved.
1787: * @param argtypes The invocation's value arguments,
1788: * if we looked for a method.
1789: * @param typeargtypes The invocation's type arguments,
1790: * if we looked for a method.
1791: */
1792: void report(Log log, DiagnosticPosition pos, Type site,
1793: Name name, List<Type> argtypes, List<Type> typeargtypes) {
1794: AmbiguityError pair = this ;
1795: while (true) {
1796: if (pair.sym1.kind == AMBIGUOUS)
1797: pair = (AmbiguityError) pair.sym1;
1798: else if (pair.sym2.kind == AMBIGUOUS)
1799: pair = (AmbiguityError) pair.sym2;
1800: else
1801: break;
1802: }
1803: Name sname = pair.sym1.name;
1804: if (sname == sname.table.init)
1805: sname = pair.sym1.owner.name;
1806: log.error(pos, "ref.ambiguous", sname, kindName(pair.sym1),
1807: pair.sym1, pair.sym1.location(site, types),
1808: kindName(pair.sym2), pair.sym2, pair.sym2.location(
1809: site, types));
1810: }
1811: }
1812: }
|