1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,1809 @@ 1.4 +/* 1.5 + * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Sun designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Sun in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.26 + * have any questions. 1.27 + */ 1.28 + 1.29 +package com.sun.tools.javac.comp; 1.30 + 1.31 +import com.sun.tools.javac.util.*; 1.32 +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 1.33 +import com.sun.tools.javac.code.*; 1.34 +import com.sun.tools.javac.jvm.*; 1.35 +import com.sun.tools.javac.tree.*; 1.36 + 1.37 +import com.sun.tools.javac.code.Type.*; 1.38 +import com.sun.tools.javac.code.Symbol.*; 1.39 +import com.sun.tools.javac.tree.JCTree.*; 1.40 + 1.41 +import static com.sun.tools.javac.code.Flags.*; 1.42 +import static com.sun.tools.javac.code.Kinds.*; 1.43 +import static com.sun.tools.javac.code.TypeTags.*; 1.44 +import javax.lang.model.element.ElementVisitor; 1.45 + 1.46 +/** Helper class for name resolution, used mostly by the attribution phase. 1.47 + * 1.48 + * <p><b>This is NOT part of any API supported by Sun Microsystems. If 1.49 + * you write code that depends on this, you do so at your own risk. 1.50 + * This code and its internal interfaces are subject to change or 1.51 + * deletion without notice.</b> 1.52 + */ 1.53 +public class Resolve { 1.54 + protected static final Context.Key<Resolve> resolveKey = 1.55 + new Context.Key<Resolve>(); 1.56 + 1.57 + Name.Table names; 1.58 + Log log; 1.59 + Symtab syms; 1.60 + Check chk; 1.61 + Infer infer; 1.62 + ClassReader reader; 1.63 + TreeInfo treeinfo; 1.64 + Types types; 1.65 + public final boolean boxingEnabled; // = source.allowBoxing(); 1.66 + public final boolean varargsEnabled; // = source.allowVarargs(); 1.67 + private final boolean debugResolve; 1.68 + 1.69 + public static Resolve instance(Context context) { 1.70 + Resolve instance = context.get(resolveKey); 1.71 + if (instance == null) 1.72 + instance = new Resolve(context); 1.73 + return instance; 1.74 + } 1.75 + 1.76 + protected Resolve(Context context) { 1.77 + context.put(resolveKey, this); 1.78 + syms = Symtab.instance(context); 1.79 + 1.80 + varNotFound = new 1.81 + ResolveError(ABSENT_VAR, syms.errSymbol, "variable not found"); 1.82 + wrongMethod = new 1.83 + ResolveError(WRONG_MTH, syms.errSymbol, "method not found"); 1.84 + wrongMethods = new 1.85 + ResolveError(WRONG_MTHS, syms.errSymbol, "wrong methods"); 1.86 + methodNotFound = new 1.87 + ResolveError(ABSENT_MTH, syms.errSymbol, "method not found"); 1.88 + typeNotFound = new 1.89 + ResolveError(ABSENT_TYP, syms.errSymbol, "type not found"); 1.90 + 1.91 + names = Name.Table.instance(context); 1.92 + log = Log.instance(context); 1.93 + chk = Check.instance(context); 1.94 + infer = Infer.instance(context); 1.95 + reader = ClassReader.instance(context); 1.96 + treeinfo = TreeInfo.instance(context); 1.97 + types = Types.instance(context); 1.98 + Source source = Source.instance(context); 1.99 + boxingEnabled = source.allowBoxing(); 1.100 + varargsEnabled = source.allowVarargs(); 1.101 + Options options = Options.instance(context); 1.102 + debugResolve = options.get("debugresolve") != null; 1.103 + } 1.104 + 1.105 + /** error symbols, which are returned when resolution fails 1.106 + */ 1.107 + final ResolveError varNotFound; 1.108 + final ResolveError wrongMethod; 1.109 + final ResolveError wrongMethods; 1.110 + final ResolveError methodNotFound; 1.111 + final ResolveError typeNotFound; 1.112 + 1.113 +/* ************************************************************************ 1.114 + * Identifier resolution 1.115 + *************************************************************************/ 1.116 + 1.117 + /** An environment is "static" if its static level is greater than 1.118 + * the one of its outer environment 1.119 + */ 1.120 + static boolean isStatic(Env<AttrContext> env) { 1.121 + return env.info.staticLevel > env.outer.info.staticLevel; 1.122 + } 1.123 + 1.124 + /** An environment is an "initializer" if it is a constructor or 1.125 + * an instance initializer. 1.126 + */ 1.127 + static boolean isInitializer(Env<AttrContext> env) { 1.128 + Symbol owner = env.info.scope.owner; 1.129 + return owner.isConstructor() || 1.130 + owner.owner.kind == TYP && 1.131 + (owner.kind == VAR || 1.132 + owner.kind == MTH && (owner.flags() & BLOCK) != 0) && 1.133 + (owner.flags() & STATIC) == 0; 1.134 + } 1.135 + 1.136 + /** Is class accessible in given evironment? 1.137 + * @param env The current environment. 1.138 + * @param c The class whose accessibility is checked. 1.139 + */ 1.140 + public boolean isAccessible(Env<AttrContext> env, TypeSymbol c) { 1.141 + switch ((short)(c.flags() & AccessFlags)) { 1.142 + case PRIVATE: 1.143 + return 1.144 + env.enclClass.sym.outermostClass() == 1.145 + c.owner.outermostClass(); 1.146 + case 0: 1.147 + return 1.148 + env.toplevel.packge == c.owner // fast special case 1.149 + || 1.150 + env.toplevel.packge == c.packge() 1.151 + || 1.152 + // Hack: this case is added since synthesized default constructors 1.153 + // of anonymous classes should be allowed to access 1.154 + // classes which would be inaccessible otherwise. 1.155 + env.enclMethod != null && 1.156 + (env.enclMethod.mods.flags & ANONCONSTR) != 0; 1.157 + default: // error recovery 1.158 + case PUBLIC: 1.159 + return true; 1.160 + case PROTECTED: 1.161 + return 1.162 + env.toplevel.packge == c.owner // fast special case 1.163 + || 1.164 + env.toplevel.packge == c.packge() 1.165 + || 1.166 + isInnerSubClass(env.enclClass.sym, c.owner); 1.167 + } 1.168 + } 1.169 + //where 1.170 + /** Is given class a subclass of given base class, or an inner class 1.171 + * of a subclass? 1.172 + * Return null if no such class exists. 1.173 + * @param c The class which is the subclass or is contained in it. 1.174 + * @param base The base class 1.175 + */ 1.176 + private boolean isInnerSubClass(ClassSymbol c, Symbol base) { 1.177 + while (c != null && !c.isSubClass(base, types)) { 1.178 + c = c.owner.enclClass(); 1.179 + } 1.180 + return c != null; 1.181 + } 1.182 + 1.183 + boolean isAccessible(Env<AttrContext> env, Type t) { 1.184 + return (t.tag == ARRAY) 1.185 + ? isAccessible(env, types.elemtype(t)) 1.186 + : isAccessible(env, t.tsym); 1.187 + } 1.188 + 1.189 + /** Is symbol accessible as a member of given type in given evironment? 1.190 + * @param env The current environment. 1.191 + * @param site The type of which the tested symbol is regarded 1.192 + * as a member. 1.193 + * @param sym The symbol. 1.194 + */ 1.195 + public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym) { 1.196 + if (sym.name == names.init && sym.owner != site.tsym) return false; 1.197 + ClassSymbol sub; 1.198 + switch ((short)(sym.flags() & AccessFlags)) { 1.199 + case PRIVATE: 1.200 + return 1.201 + (env.enclClass.sym == sym.owner // fast special case 1.202 + || 1.203 + env.enclClass.sym.outermostClass() == 1.204 + sym.owner.outermostClass()) 1.205 + && 1.206 + sym.isInheritedIn(site.tsym, types); 1.207 + case 0: 1.208 + return 1.209 + (env.toplevel.packge == sym.owner.owner // fast special case 1.210 + || 1.211 + env.toplevel.packge == sym.packge()) 1.212 + && 1.213 + isAccessible(env, site) 1.214 + && 1.215 + sym.isInheritedIn(site.tsym, types); 1.216 + case PROTECTED: 1.217 + return 1.218 + (env.toplevel.packge == sym.owner.owner // fast special case 1.219 + || 1.220 + env.toplevel.packge == sym.packge() 1.221 + || 1.222 + isProtectedAccessible(sym, env.enclClass.sym, site) 1.223 + || 1.224 + // OK to select instance method or field from 'super' or type name 1.225 + // (but type names should be disallowed elsewhere!) 1.226 + env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP) 1.227 + && 1.228 + isAccessible(env, site) 1.229 + && 1.230 + // `sym' is accessible only if not overridden by 1.231 + // another symbol which is a member of `site' 1.232 + // (because, if it is overridden, `sym' is not strictly 1.233 + // speaking a member of `site'.) 1.234 + (sym.kind != MTH || sym.isConstructor() || 1.235 + ((MethodSymbol)sym).implementation(site.tsym, types, true) == sym); 1.236 + default: // this case includes erroneous combinations as well 1.237 + return isAccessible(env, site); 1.238 + } 1.239 + } 1.240 + //where 1.241 + /** Is given protected symbol accessible if it is selected from given site 1.242 + * and the selection takes place in given class? 1.243 + * @param sym The symbol with protected access 1.244 + * @param c The class where the access takes place 1.245 + * @site The type of the qualifier 1.246 + */ 1.247 + private 1.248 + boolean isProtectedAccessible(Symbol sym, ClassSymbol c, Type site) { 1.249 + while (c != null && 1.250 + !(c.isSubClass(sym.owner, types) && 1.251 + (c.flags() & INTERFACE) == 0 && 1.252 + // In JLS 2e 6.6.2.1, the subclass restriction applies 1.253 + // only to instance fields and methods -- types are excluded 1.254 + // regardless of whether they are declared 'static' or not. 1.255 + ((sym.flags() & STATIC) != 0 || sym.kind == TYP || site.tsym.isSubClass(c, types)))) 1.256 + c = c.owner.enclClass(); 1.257 + return c != null; 1.258 + } 1.259 + 1.260 + /** Try to instantiate the type of a method so that it fits 1.261 + * given type arguments and argument types. If succesful, return 1.262 + * the method's instantiated type, else return null. 1.263 + * The instantiation will take into account an additional leading 1.264 + * formal parameter if the method is an instance method seen as a member 1.265 + * of un underdetermined site In this case, we treat site as an additional 1.266 + * parameter and the parameters of the class containing the method as 1.267 + * additional type variables that get instantiated. 1.268 + * 1.269 + * @param env The current environment 1.270 + * @param site The type of which the method is a member. 1.271 + * @param m The method symbol. 1.272 + * @param argtypes The invocation's given value arguments. 1.273 + * @param typeargtypes The invocation's given type arguments. 1.274 + * @param allowBoxing Allow boxing conversions of arguments. 1.275 + * @param useVarargs Box trailing arguments into an array for varargs. 1.276 + */ 1.277 + Type rawInstantiate(Env<AttrContext> env, 1.278 + Type site, 1.279 + Symbol m, 1.280 + List<Type> argtypes, 1.281 + List<Type> typeargtypes, 1.282 + boolean allowBoxing, 1.283 + boolean useVarargs, 1.284 + Warner warn) 1.285 + throws Infer.NoInstanceException { 1.286 + if (useVarargs && (m.flags() & VARARGS) == 0) return null; 1.287 + Type mt = types.memberType(site, m); 1.288 + 1.289 + // tvars is the list of formal type variables for which type arguments 1.290 + // need to inferred. 1.291 + List<Type> tvars = env.info.tvars; 1.292 + if (typeargtypes == null) typeargtypes = List.nil(); 1.293 + if (mt.tag != FORALL && typeargtypes.nonEmpty()) { 1.294 + // This is not a polymorphic method, but typeargs are supplied 1.295 + // which is fine, see JLS3 15.12.2.1 1.296 + } else if (mt.tag == FORALL && typeargtypes.nonEmpty()) { 1.297 + ForAll pmt = (ForAll) mt; 1.298 + if (typeargtypes.length() != pmt.tvars.length()) 1.299 + return null; 1.300 + // Check type arguments are within bounds 1.301 + List<Type> formals = pmt.tvars; 1.302 + List<Type> actuals = typeargtypes; 1.303 + while (formals.nonEmpty() && actuals.nonEmpty()) { 1.304 + List<Type> bounds = types.subst(types.getBounds((TypeVar)formals.head), 1.305 + pmt.tvars, typeargtypes); 1.306 + for (; bounds.nonEmpty(); bounds = bounds.tail) 1.307 + if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn)) 1.308 + return null; 1.309 + formals = formals.tail; 1.310 + actuals = actuals.tail; 1.311 + } 1.312 + mt = types.subst(pmt.qtype, pmt.tvars, typeargtypes); 1.313 + } else if (mt.tag == FORALL) { 1.314 + ForAll pmt = (ForAll) mt; 1.315 + List<Type> tvars1 = types.newInstances(pmt.tvars); 1.316 + tvars = tvars.appendList(tvars1); 1.317 + mt = types.subst(pmt.qtype, pmt.tvars, tvars1); 1.318 + } 1.319 + 1.320 + // find out whether we need to go the slow route via infer 1.321 + boolean instNeeded = tvars.tail != null/*inlined: tvars.nonEmpty()*/; 1.322 + for (List<Type> l = argtypes; 1.323 + l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded; 1.324 + l = l.tail) { 1.325 + if (l.head.tag == FORALL) instNeeded = true; 1.326 + } 1.327 + 1.328 + if (instNeeded) 1.329 + return 1.330 + infer.instantiateMethod(tvars, 1.331 + (MethodType)mt, 1.332 + argtypes, 1.333 + allowBoxing, 1.334 + useVarargs, 1.335 + warn); 1.336 + return 1.337 + argumentsAcceptable(argtypes, mt.getParameterTypes(), 1.338 + allowBoxing, useVarargs, warn) 1.339 + ? mt 1.340 + : null; 1.341 + } 1.342 + 1.343 + /** Same but returns null instead throwing a NoInstanceException 1.344 + */ 1.345 + Type instantiate(Env<AttrContext> env, 1.346 + Type site, 1.347 + Symbol m, 1.348 + List<Type> argtypes, 1.349 + List<Type> typeargtypes, 1.350 + boolean allowBoxing, 1.351 + boolean useVarargs, 1.352 + Warner warn) { 1.353 + try { 1.354 + return rawInstantiate(env, site, m, argtypes, typeargtypes, 1.355 + allowBoxing, useVarargs, warn); 1.356 + } catch (Infer.NoInstanceException ex) { 1.357 + return null; 1.358 + } 1.359 + } 1.360 + 1.361 + /** Check if a parameter list accepts a list of args. 1.362 + */ 1.363 + boolean argumentsAcceptable(List<Type> argtypes, 1.364 + List<Type> formals, 1.365 + boolean allowBoxing, 1.366 + boolean useVarargs, 1.367 + Warner warn) { 1.368 + Type varargsFormal = useVarargs ? formals.last() : null; 1.369 + while (argtypes.nonEmpty() && formals.head != varargsFormal) { 1.370 + boolean works = allowBoxing 1.371 + ? types.isConvertible(argtypes.head, formals.head, warn) 1.372 + : types.isSubtypeUnchecked(argtypes.head, formals.head, warn); 1.373 + if (!works) return false; 1.374 + argtypes = argtypes.tail; 1.375 + formals = formals.tail; 1.376 + } 1.377 + if (formals.head != varargsFormal) return false; // not enough args 1.378 + if (!useVarargs) 1.379 + return argtypes.isEmpty(); 1.380 + Type elt = types.elemtype(varargsFormal); 1.381 + while (argtypes.nonEmpty()) { 1.382 + if (!types.isConvertible(argtypes.head, elt, warn)) 1.383 + return false; 1.384 + argtypes = argtypes.tail; 1.385 + } 1.386 + return true; 1.387 + } 1.388 + 1.389 +/* *************************************************************************** 1.390 + * Symbol lookup 1.391 + * the following naming conventions for arguments are used 1.392 + * 1.393 + * env is the environment where the symbol was mentioned 1.394 + * site is the type of which the symbol is a member 1.395 + * name is the symbol's name 1.396 + * if no arguments are given 1.397 + * argtypes are the value arguments, if we search for a method 1.398 + * 1.399 + * If no symbol was found, a ResolveError detailing the problem is returned. 1.400 + ****************************************************************************/ 1.401 + 1.402 + /** Find field. Synthetic fields are always skipped. 1.403 + * @param env The current environment. 1.404 + * @param site The original type from where the selection takes place. 1.405 + * @param name The name of the field. 1.406 + * @param c The class to search for the field. This is always 1.407 + * a superclass or implemented interface of site's class. 1.408 + */ 1.409 + Symbol findField(Env<AttrContext> env, 1.410 + Type site, 1.411 + Name name, 1.412 + TypeSymbol c) { 1.413 + Symbol bestSoFar = varNotFound; 1.414 + Symbol sym; 1.415 + Scope.Entry e = c.members().lookup(name); 1.416 + while (e.scope != null) { 1.417 + if (e.sym.kind == VAR && (e.sym.flags_field & SYNTHETIC) == 0) { 1.418 + return isAccessible(env, site, e.sym) 1.419 + ? e.sym : new AccessError(env, site, e.sym); 1.420 + } 1.421 + e = e.next(); 1.422 + } 1.423 + Type st = types.supertype(c.type); 1.424 + if (st != null && st.tag == CLASS) { 1.425 + sym = findField(env, site, name, st.tsym); 1.426 + if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1.427 + } 1.428 + for (List<Type> l = types.interfaces(c.type); 1.429 + bestSoFar.kind != AMBIGUOUS && l.nonEmpty(); 1.430 + l = l.tail) { 1.431 + sym = findField(env, site, name, l.head.tsym); 1.432 + if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS && 1.433 + sym.owner != bestSoFar.owner) 1.434 + bestSoFar = new AmbiguityError(bestSoFar, sym); 1.435 + else if (sym.kind < bestSoFar.kind) 1.436 + bestSoFar = sym; 1.437 + } 1.438 + return bestSoFar; 1.439 + } 1.440 + 1.441 + /** Resolve a field identifier, throw a fatal error if not found. 1.442 + * @param pos The position to use for error reporting. 1.443 + * @param env The environment current at the method invocation. 1.444 + * @param site The type of the qualifying expression, in which 1.445 + * identifier is searched. 1.446 + * @param name The identifier's name. 1.447 + */ 1.448 + public VarSymbol resolveInternalField(DiagnosticPosition pos, Env<AttrContext> env, 1.449 + Type site, Name name) { 1.450 + Symbol sym = findField(env, site, name, site.tsym); 1.451 + if (sym.kind == VAR) return (VarSymbol)sym; 1.452 + else throw new FatalError( 1.453 + JCDiagnostic.fragment("fatal.err.cant.locate.field", 1.454 + name)); 1.455 + } 1.456 + 1.457 + /** Find unqualified variable or field with given name. 1.458 + * Synthetic fields always skipped. 1.459 + * @param env The current environment. 1.460 + * @param name The name of the variable or field. 1.461 + */ 1.462 + Symbol findVar(Env<AttrContext> env, Name name) { 1.463 + Symbol bestSoFar = varNotFound; 1.464 + Symbol sym; 1.465 + Env<AttrContext> env1 = env; 1.466 + boolean staticOnly = false; 1.467 + while (env1.outer != null) { 1.468 + if (isStatic(env1)) staticOnly = true; 1.469 + Scope.Entry e = env1.info.scope.lookup(name); 1.470 + while (e.scope != null && 1.471 + (e.sym.kind != VAR || 1.472 + (e.sym.flags_field & SYNTHETIC) != 0)) 1.473 + e = e.next(); 1.474 + sym = (e.scope != null) 1.475 + ? e.sym 1.476 + : findField( 1.477 + env1, env1.enclClass.sym.type, name, env1.enclClass.sym); 1.478 + if (sym.exists()) { 1.479 + if (staticOnly && 1.480 + sym.kind == VAR && 1.481 + sym.owner.kind == TYP && 1.482 + (sym.flags() & STATIC) == 0) 1.483 + return new StaticError(sym); 1.484 + else 1.485 + return sym; 1.486 + } else if (sym.kind < bestSoFar.kind) { 1.487 + bestSoFar = sym; 1.488 + } 1.489 + 1.490 + if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; 1.491 + env1 = env1.outer; 1.492 + } 1.493 + 1.494 + sym = findField(env, syms.predefClass.type, name, syms.predefClass); 1.495 + if (sym.exists()) 1.496 + return sym; 1.497 + if (bestSoFar.exists()) 1.498 + return bestSoFar; 1.499 + 1.500 + Scope.Entry e = env.toplevel.namedImportScope.lookup(name); 1.501 + for (; e.scope != null; e = e.next()) { 1.502 + sym = e.sym; 1.503 + Type origin = e.getOrigin().owner.type; 1.504 + if (sym.kind == VAR) { 1.505 + if (e.sym.owner.type != origin) 1.506 + sym = sym.clone(e.getOrigin().owner); 1.507 + return isAccessible(env, origin, sym) 1.508 + ? sym : new AccessError(env, origin, sym); 1.509 + } 1.510 + } 1.511 + 1.512 + Symbol origin = null; 1.513 + e = env.toplevel.starImportScope.lookup(name); 1.514 + for (; e.scope != null; e = e.next()) { 1.515 + sym = e.sym; 1.516 + if (sym.kind != VAR) 1.517 + continue; 1.518 + // invariant: sym.kind == VAR 1.519 + if (bestSoFar.kind < AMBIGUOUS && sym.owner != bestSoFar.owner) 1.520 + return new AmbiguityError(bestSoFar, sym); 1.521 + else if (bestSoFar.kind >= VAR) { 1.522 + origin = e.getOrigin().owner; 1.523 + bestSoFar = isAccessible(env, origin.type, sym) 1.524 + ? sym : new AccessError(env, origin.type, sym); 1.525 + } 1.526 + } 1.527 + if (bestSoFar.kind == VAR && bestSoFar.owner.type != origin.type) 1.528 + return bestSoFar.clone(origin); 1.529 + else 1.530 + return bestSoFar; 1.531 + } 1.532 + 1.533 + Warner noteWarner = new Warner(); 1.534 + 1.535 + /** Select the best method for a call site among two choices. 1.536 + * @param env The current environment. 1.537 + * @param site The original type from where the 1.538 + * selection takes place. 1.539 + * @param argtypes The invocation's value arguments, 1.540 + * @param typeargtypes The invocation's type arguments, 1.541 + * @param sym Proposed new best match. 1.542 + * @param bestSoFar Previously found best match. 1.543 + * @param allowBoxing Allow boxing conversions of arguments. 1.544 + * @param useVarargs Box trailing arguments into an array for varargs. 1.545 + */ 1.546 + Symbol selectBest(Env<AttrContext> env, 1.547 + Type site, 1.548 + List<Type> argtypes, 1.549 + List<Type> typeargtypes, 1.550 + Symbol sym, 1.551 + Symbol bestSoFar, 1.552 + boolean allowBoxing, 1.553 + boolean useVarargs, 1.554 + boolean operator) { 1.555 + if (sym.kind == ERR) return bestSoFar; 1.556 + if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar; 1.557 + assert sym.kind < AMBIGUOUS; 1.558 + try { 1.559 + if (rawInstantiate(env, site, sym, argtypes, typeargtypes, 1.560 + allowBoxing, useVarargs, Warner.noWarnings) == null) { 1.561 + // inapplicable 1.562 + switch (bestSoFar.kind) { 1.563 + case ABSENT_MTH: return wrongMethod.setWrongSym(sym); 1.564 + case WRONG_MTH: return wrongMethods; 1.565 + default: return bestSoFar; 1.566 + } 1.567 + } 1.568 + } catch (Infer.NoInstanceException ex) { 1.569 + switch (bestSoFar.kind) { 1.570 + case ABSENT_MTH: 1.571 + return wrongMethod.setWrongSym(sym, ex.getDiagnostic()); 1.572 + case WRONG_MTH: 1.573 + return wrongMethods; 1.574 + default: 1.575 + return bestSoFar; 1.576 + } 1.577 + } 1.578 + if (!isAccessible(env, site, sym)) { 1.579 + return (bestSoFar.kind == ABSENT_MTH) 1.580 + ? new AccessError(env, site, sym) 1.581 + : bestSoFar; 1.582 + } 1.583 + return (bestSoFar.kind > AMBIGUOUS) 1.584 + ? sym 1.585 + : mostSpecific(sym, bestSoFar, env, site, 1.586 + allowBoxing && operator, useVarargs); 1.587 + } 1.588 + 1.589 + /* Return the most specific of the two methods for a call, 1.590 + * given that both are accessible and applicable. 1.591 + * @param m1 A new candidate for most specific. 1.592 + * @param m2 The previous most specific candidate. 1.593 + * @param env The current environment. 1.594 + * @param site The original type from where the selection 1.595 + * takes place. 1.596 + * @param allowBoxing Allow boxing conversions of arguments. 1.597 + * @param useVarargs Box trailing arguments into an array for varargs. 1.598 + */ 1.599 + Symbol mostSpecific(Symbol m1, 1.600 + Symbol m2, 1.601 + Env<AttrContext> env, 1.602 + Type site, 1.603 + boolean allowBoxing, 1.604 + boolean useVarargs) { 1.605 + switch (m2.kind) { 1.606 + case MTH: 1.607 + if (m1 == m2) return m1; 1.608 + Type mt1 = types.memberType(site, m1); 1.609 + noteWarner.unchecked = false; 1.610 + boolean m1SignatureMoreSpecific = 1.611 + (instantiate(env, site, m2, types.lowerBoundArgtypes(mt1), null, 1.612 + allowBoxing, false, noteWarner) != null || 1.613 + useVarargs && instantiate(env, site, m2, types.lowerBoundArgtypes(mt1), null, 1.614 + allowBoxing, true, noteWarner) != null) && 1.615 + !noteWarner.unchecked; 1.616 + Type mt2 = types.memberType(site, m2); 1.617 + noteWarner.unchecked = false; 1.618 + boolean m2SignatureMoreSpecific = 1.619 + (instantiate(env, site, m1, types.lowerBoundArgtypes(mt2), null, 1.620 + allowBoxing, false, noteWarner) != null || 1.621 + useVarargs && instantiate(env, site, m1, types.lowerBoundArgtypes(mt2), null, 1.622 + allowBoxing, true, noteWarner) != null) && 1.623 + !noteWarner.unchecked; 1.624 + if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) { 1.625 + if (!types.overrideEquivalent(mt1, mt2)) 1.626 + return new AmbiguityError(m1, m2); 1.627 + // same signature; select (a) the non-bridge method, or 1.628 + // (b) the one that overrides the other, or (c) the concrete 1.629 + // one, or (d) merge both abstract signatures 1.630 + if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE)) { 1.631 + return ((m1.flags() & BRIDGE) != 0) ? m2 : m1; 1.632 + } 1.633 + // if one overrides or hides the other, use it 1.634 + TypeSymbol m1Owner = (TypeSymbol)m1.owner; 1.635 + TypeSymbol m2Owner = (TypeSymbol)m2.owner; 1.636 + if (types.asSuper(m1Owner.type, m2Owner) != null && 1.637 + ((m1.owner.flags_field & INTERFACE) == 0 || 1.638 + (m2.owner.flags_field & INTERFACE) != 0) && 1.639 + m1.overrides(m2, m1Owner, types, false)) 1.640 + return m1; 1.641 + if (types.asSuper(m2Owner.type, m1Owner) != null && 1.642 + ((m2.owner.flags_field & INTERFACE) == 0 || 1.643 + (m1.owner.flags_field & INTERFACE) != 0) && 1.644 + m2.overrides(m1, m2Owner, types, false)) 1.645 + return m2; 1.646 + boolean m1Abstract = (m1.flags() & ABSTRACT) != 0; 1.647 + boolean m2Abstract = (m2.flags() & ABSTRACT) != 0; 1.648 + if (m1Abstract && !m2Abstract) return m2; 1.649 + if (m2Abstract && !m1Abstract) return m1; 1.650 + // both abstract or both concrete 1.651 + if (!m1Abstract && !m2Abstract) 1.652 + return new AmbiguityError(m1, m2); 1.653 + // check for same erasure 1.654 + if (!types.isSameType(m1.erasure(types), m2.erasure(types))) 1.655 + return new AmbiguityError(m1, m2); 1.656 + // both abstract, neither overridden; merge throws clause and result type 1.657 + Symbol result; 1.658 + Type result2 = mt2.getReturnType();; 1.659 + if (mt2.tag == FORALL) 1.660 + result2 = types.subst(result2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars); 1.661 + if (types.isSubtype(mt1.getReturnType(), result2)) { 1.662 + result = m1; 1.663 + } else if (types.isSubtype(result2, mt1.getReturnType())) { 1.664 + result = m2; 1.665 + } else { 1.666 + // Theoretically, this can't happen, but it is possible 1.667 + // due to error recovery or mixing incompatible class files 1.668 + return new AmbiguityError(m1, m2); 1.669 + } 1.670 + result = result.clone(result.owner); 1.671 + result.type = (Type)result.type.clone(); 1.672 + result.type.setThrown(chk.intersect(mt1.getThrownTypes(), 1.673 + mt2.getThrownTypes())); 1.674 + return result; 1.675 + } 1.676 + if (m1SignatureMoreSpecific) return m1; 1.677 + if (m2SignatureMoreSpecific) return m2; 1.678 + return new AmbiguityError(m1, m2); 1.679 + case AMBIGUOUS: 1.680 + AmbiguityError e = (AmbiguityError)m2; 1.681 + Symbol err1 = mostSpecific(m1, e.sym1, env, site, allowBoxing, useVarargs); 1.682 + Symbol err2 = mostSpecific(m1, e.sym2, env, site, allowBoxing, useVarargs); 1.683 + if (err1 == err2) return err1; 1.684 + if (err1 == e.sym1 && err2 == e.sym2) return m2; 1.685 + if (err1 instanceof AmbiguityError && 1.686 + err2 instanceof AmbiguityError && 1.687 + ((AmbiguityError)err1).sym1 == ((AmbiguityError)err2).sym1) 1.688 + return new AmbiguityError(m1, m2); 1.689 + else 1.690 + return new AmbiguityError(err1, err2); 1.691 + default: 1.692 + throw new AssertionError(); 1.693 + } 1.694 + } 1.695 + 1.696 + /** Find best qualified method matching given name, type and value 1.697 + * arguments. 1.698 + * @param env The current environment. 1.699 + * @param site The original type from where the selection 1.700 + * takes place. 1.701 + * @param name The method's name. 1.702 + * @param argtypes The method's value arguments. 1.703 + * @param typeargtypes The method's type arguments 1.704 + * @param allowBoxing Allow boxing conversions of arguments. 1.705 + * @param useVarargs Box trailing arguments into an array for varargs. 1.706 + */ 1.707 + Symbol findMethod(Env<AttrContext> env, 1.708 + Type site, 1.709 + Name name, 1.710 + List<Type> argtypes, 1.711 + List<Type> typeargtypes, 1.712 + boolean allowBoxing, 1.713 + boolean useVarargs, 1.714 + boolean operator) { 1.715 + return findMethod(env, 1.716 + site, 1.717 + name, 1.718 + argtypes, 1.719 + typeargtypes, 1.720 + site.tsym.type, 1.721 + true, 1.722 + methodNotFound, 1.723 + allowBoxing, 1.724 + useVarargs, 1.725 + operator); 1.726 + } 1.727 + // where 1.728 + private Symbol findMethod(Env<AttrContext> env, 1.729 + Type site, 1.730 + Name name, 1.731 + List<Type> argtypes, 1.732 + List<Type> typeargtypes, 1.733 + Type intype, 1.734 + boolean abstractok, 1.735 + Symbol bestSoFar, 1.736 + boolean allowBoxing, 1.737 + boolean useVarargs, 1.738 + boolean operator) { 1.739 + for (Type ct = intype; ct.tag == CLASS; ct = types.supertype(ct)) { 1.740 + ClassSymbol c = (ClassSymbol)ct.tsym; 1.741 + if ((c.flags() & (ABSTRACT | INTERFACE)) == 0) 1.742 + abstractok = false; 1.743 + for (Scope.Entry e = c.members().lookup(name); 1.744 + e.scope != null; 1.745 + e = e.next()) { 1.746 + //- System.out.println(" e " + e.sym); 1.747 + if (e.sym.kind == MTH && 1.748 + (e.sym.flags_field & SYNTHETIC) == 0) { 1.749 + bestSoFar = selectBest(env, site, argtypes, typeargtypes, 1.750 + e.sym, bestSoFar, 1.751 + allowBoxing, 1.752 + useVarargs, 1.753 + operator); 1.754 + } 1.755 + } 1.756 + //- System.out.println(" - " + bestSoFar); 1.757 + if (abstractok) { 1.758 + Symbol concrete = methodNotFound; 1.759 + if ((bestSoFar.flags() & ABSTRACT) == 0) 1.760 + concrete = bestSoFar; 1.761 + for (List<Type> l = types.interfaces(c.type); 1.762 + l.nonEmpty(); 1.763 + l = l.tail) { 1.764 + bestSoFar = findMethod(env, site, name, argtypes, 1.765 + typeargtypes, 1.766 + l.head, abstractok, bestSoFar, 1.767 + allowBoxing, useVarargs, operator); 1.768 + } 1.769 + if (concrete != bestSoFar && 1.770 + concrete.kind < ERR && bestSoFar.kind < ERR && 1.771 + types.isSubSignature(concrete.type, bestSoFar.type)) 1.772 + bestSoFar = concrete; 1.773 + } 1.774 + } 1.775 + return bestSoFar; 1.776 + } 1.777 + 1.778 + /** Find unqualified method matching given name, type and value arguments. 1.779 + * @param env The current environment. 1.780 + * @param name The method's name. 1.781 + * @param argtypes The method's value arguments. 1.782 + * @param typeargtypes The method's type arguments. 1.783 + * @param allowBoxing Allow boxing conversions of arguments. 1.784 + * @param useVarargs Box trailing arguments into an array for varargs. 1.785 + */ 1.786 + Symbol findFun(Env<AttrContext> env, Name name, 1.787 + List<Type> argtypes, List<Type> typeargtypes, 1.788 + boolean allowBoxing, boolean useVarargs) { 1.789 + Symbol bestSoFar = methodNotFound; 1.790 + Symbol sym; 1.791 + Env<AttrContext> env1 = env; 1.792 + boolean staticOnly = false; 1.793 + while (env1.outer != null) { 1.794 + if (isStatic(env1)) staticOnly = true; 1.795 + sym = findMethod( 1.796 + env1, env1.enclClass.sym.type, name, argtypes, typeargtypes, 1.797 + allowBoxing, useVarargs, false); 1.798 + if (sym.exists()) { 1.799 + if (staticOnly && 1.800 + sym.kind == MTH && 1.801 + sym.owner.kind == TYP && 1.802 + (sym.flags() & STATIC) == 0) return new StaticError(sym); 1.803 + else return sym; 1.804 + } else if (sym.kind < bestSoFar.kind) { 1.805 + bestSoFar = sym; 1.806 + } 1.807 + if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; 1.808 + env1 = env1.outer; 1.809 + } 1.810 + 1.811 + sym = findMethod(env, syms.predefClass.type, name, argtypes, 1.812 + typeargtypes, allowBoxing, useVarargs, false); 1.813 + if (sym.exists()) 1.814 + return sym; 1.815 + 1.816 + Scope.Entry e = env.toplevel.namedImportScope.lookup(name); 1.817 + for (; e.scope != null; e = e.next()) { 1.818 + sym = e.sym; 1.819 + Type origin = e.getOrigin().owner.type; 1.820 + if (sym.kind == MTH) { 1.821 + if (e.sym.owner.type != origin) 1.822 + sym = sym.clone(e.getOrigin().owner); 1.823 + if (!isAccessible(env, origin, sym)) 1.824 + sym = new AccessError(env, origin, sym); 1.825 + bestSoFar = selectBest(env, origin, 1.826 + argtypes, typeargtypes, 1.827 + sym, bestSoFar, 1.828 + allowBoxing, useVarargs, false); 1.829 + } 1.830 + } 1.831 + if (bestSoFar.exists()) 1.832 + return bestSoFar; 1.833 + 1.834 + e = env.toplevel.starImportScope.lookup(name); 1.835 + for (; e.scope != null; e = e.next()) { 1.836 + sym = e.sym; 1.837 + Type origin = e.getOrigin().owner.type; 1.838 + if (sym.kind == MTH) { 1.839 + if (e.sym.owner.type != origin) 1.840 + sym = sym.clone(e.getOrigin().owner); 1.841 + if (!isAccessible(env, origin, sym)) 1.842 + sym = new AccessError(env, origin, sym); 1.843 + bestSoFar = selectBest(env, origin, 1.844 + argtypes, typeargtypes, 1.845 + sym, bestSoFar, 1.846 + allowBoxing, useVarargs, false); 1.847 + } 1.848 + } 1.849 + return bestSoFar; 1.850 + } 1.851 + 1.852 + /** Load toplevel or member class with given fully qualified name and 1.853 + * verify that it is accessible. 1.854 + * @param env The current environment. 1.855 + * @param name The fully qualified name of the class to be loaded. 1.856 + */ 1.857 + Symbol loadClass(Env<AttrContext> env, Name name) { 1.858 + try { 1.859 + ClassSymbol c = reader.loadClass(name); 1.860 + return isAccessible(env, c) ? c : new AccessError(c); 1.861 + } catch (ClassReader.BadClassFile err) { 1.862 + throw err; 1.863 + } catch (CompletionFailure ex) { 1.864 + return typeNotFound; 1.865 + } 1.866 + } 1.867 + 1.868 + /** Find qualified member type. 1.869 + * @param env The current environment. 1.870 + * @param site The original type from where the selection takes 1.871 + * place. 1.872 + * @param name The type's name. 1.873 + * @param c The class to search for the member type. This is 1.874 + * always a superclass or implemented interface of 1.875 + * site's class. 1.876 + */ 1.877 + Symbol findMemberType(Env<AttrContext> env, 1.878 + Type site, 1.879 + Name name, 1.880 + TypeSymbol c) { 1.881 + Symbol bestSoFar = typeNotFound; 1.882 + Symbol sym; 1.883 + Scope.Entry e = c.members().lookup(name); 1.884 + while (e.scope != null) { 1.885 + if (e.sym.kind == TYP) { 1.886 + return isAccessible(env, site, e.sym) 1.887 + ? e.sym 1.888 + : new AccessError(env, site, e.sym); 1.889 + } 1.890 + e = e.next(); 1.891 + } 1.892 + Type st = types.supertype(c.type); 1.893 + if (st != null && st.tag == CLASS) { 1.894 + sym = findMemberType(env, site, name, st.tsym); 1.895 + if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1.896 + } 1.897 + for (List<Type> l = types.interfaces(c.type); 1.898 + bestSoFar.kind != AMBIGUOUS && l.nonEmpty(); 1.899 + l = l.tail) { 1.900 + sym = findMemberType(env, site, name, l.head.tsym); 1.901 + if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS && 1.902 + sym.owner != bestSoFar.owner) 1.903 + bestSoFar = new AmbiguityError(bestSoFar, sym); 1.904 + else if (sym.kind < bestSoFar.kind) 1.905 + bestSoFar = sym; 1.906 + } 1.907 + return bestSoFar; 1.908 + } 1.909 + 1.910 + /** Find a global type in given scope and load corresponding class. 1.911 + * @param env The current environment. 1.912 + * @param scope The scope in which to look for the type. 1.913 + * @param name The type's name. 1.914 + */ 1.915 + Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) { 1.916 + Symbol bestSoFar = typeNotFound; 1.917 + for (Scope.Entry e = scope.lookup(name); e.scope != null; e = e.next()) { 1.918 + Symbol sym = loadClass(env, e.sym.flatName()); 1.919 + if (bestSoFar.kind == TYP && sym.kind == TYP && 1.920 + bestSoFar != sym) 1.921 + return new AmbiguityError(bestSoFar, sym); 1.922 + else if (sym.kind < bestSoFar.kind) 1.923 + bestSoFar = sym; 1.924 + } 1.925 + return bestSoFar; 1.926 + } 1.927 + 1.928 + /** Find an unqualified type symbol. 1.929 + * @param env The current environment. 1.930 + * @param name The type's name. 1.931 + */ 1.932 + Symbol findType(Env<AttrContext> env, Name name) { 1.933 + Symbol bestSoFar = typeNotFound; 1.934 + Symbol sym; 1.935 + boolean staticOnly = false; 1.936 + for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) { 1.937 + if (isStatic(env1)) staticOnly = true; 1.938 + for (Scope.Entry e = env1.info.scope.lookup(name); 1.939 + e.scope != null; 1.940 + e = e.next()) { 1.941 + if (e.sym.kind == TYP) { 1.942 + if (staticOnly && 1.943 + e.sym.type.tag == TYPEVAR && 1.944 + e.sym.owner.kind == TYP) return new StaticError(e.sym); 1.945 + return e.sym; 1.946 + } 1.947 + } 1.948 + 1.949 + sym = findMemberType(env1, env1.enclClass.sym.type, name, 1.950 + env1.enclClass.sym); 1.951 + if (staticOnly && sym.kind == TYP && 1.952 + sym.type.tag == CLASS && 1.953 + sym.type.getEnclosingType().tag == CLASS && 1.954 + env1.enclClass.sym.type.isParameterized() && 1.955 + sym.type.getEnclosingType().isParameterized()) 1.956 + return new StaticError(sym); 1.957 + else if (sym.exists()) return sym; 1.958 + else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1.959 + 1.960 + JCClassDecl encl = env1.baseClause ? (JCClassDecl)env1.tree : env1.enclClass; 1.961 + if ((encl.sym.flags() & STATIC) != 0) 1.962 + staticOnly = true; 1.963 + } 1.964 + 1.965 + if (env.tree.getTag() != JCTree.IMPORT) { 1.966 + sym = findGlobalType(env, env.toplevel.namedImportScope, name); 1.967 + if (sym.exists()) return sym; 1.968 + else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1.969 + 1.970 + sym = findGlobalType(env, env.toplevel.packge.members(), name); 1.971 + if (sym.exists()) return sym; 1.972 + else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1.973 + 1.974 + sym = findGlobalType(env, env.toplevel.starImportScope, name); 1.975 + if (sym.exists()) return sym; 1.976 + else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1.977 + } 1.978 + 1.979 + return bestSoFar; 1.980 + } 1.981 + 1.982 + /** Find an unqualified identifier which matches a specified kind set. 1.983 + * @param env The current environment. 1.984 + * @param name The indentifier's name. 1.985 + * @param kind Indicates the possible symbol kinds 1.986 + * (a subset of VAL, TYP, PCK). 1.987 + */ 1.988 + Symbol findIdent(Env<AttrContext> env, Name name, int kind) { 1.989 + Symbol bestSoFar = typeNotFound; 1.990 + Symbol sym; 1.991 + 1.992 + if ((kind & VAR) != 0) { 1.993 + sym = findVar(env, name); 1.994 + if (sym.exists()) return sym; 1.995 + else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1.996 + } 1.997 + 1.998 + if ((kind & TYP) != 0) { 1.999 + sym = findType(env, name); 1.1000 + if (sym.exists()) return sym; 1.1001 + else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1.1002 + } 1.1003 + 1.1004 + if ((kind & PCK) != 0) return reader.enterPackage(name); 1.1005 + else return bestSoFar; 1.1006 + } 1.1007 + 1.1008 + /** Find an identifier in a package which matches a specified kind set. 1.1009 + * @param env The current environment. 1.1010 + * @param name The identifier's name. 1.1011 + * @param kind Indicates the possible symbol kinds 1.1012 + * (a nonempty subset of TYP, PCK). 1.1013 + */ 1.1014 + Symbol findIdentInPackage(Env<AttrContext> env, TypeSymbol pck, 1.1015 + Name name, int kind) { 1.1016 + Name fullname = TypeSymbol.formFullName(name, pck); 1.1017 + Symbol bestSoFar = typeNotFound; 1.1018 + PackageSymbol pack = null; 1.1019 + if ((kind & PCK) != 0) { 1.1020 + pack = reader.enterPackage(fullname); 1.1021 + if (pack.exists()) return pack; 1.1022 + } 1.1023 + if ((kind & TYP) != 0) { 1.1024 + Symbol sym = loadClass(env, fullname); 1.1025 + if (sym.exists()) { 1.1026 + // don't allow programs to use flatnames 1.1027 + if (name == sym.name) return sym; 1.1028 + } 1.1029 + else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1.1030 + } 1.1031 + return (pack != null) ? pack : bestSoFar; 1.1032 + } 1.1033 + 1.1034 + /** Find an identifier among the members of a given type `site'. 1.1035 + * @param env The current environment. 1.1036 + * @param site The type containing the symbol to be found. 1.1037 + * @param name The identifier's name. 1.1038 + * @param kind Indicates the possible symbol kinds 1.1039 + * (a subset of VAL, TYP). 1.1040 + */ 1.1041 + Symbol findIdentInType(Env<AttrContext> env, Type site, 1.1042 + Name name, int kind) { 1.1043 + Symbol bestSoFar = typeNotFound; 1.1044 + Symbol sym; 1.1045 + if ((kind & VAR) != 0) { 1.1046 + sym = findField(env, site, name, site.tsym); 1.1047 + if (sym.exists()) return sym; 1.1048 + else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1.1049 + } 1.1050 + 1.1051 + if ((kind & TYP) != 0) { 1.1052 + sym = findMemberType(env, site, name, site.tsym); 1.1053 + if (sym.exists()) return sym; 1.1054 + else if (sym.kind < bestSoFar.kind) bestSoFar = sym; 1.1055 + } 1.1056 + return bestSoFar; 1.1057 + } 1.1058 + 1.1059 +/* *************************************************************************** 1.1060 + * Access checking 1.1061 + * The following methods convert ResolveErrors to ErrorSymbols, issuing 1.1062 + * an error message in the process 1.1063 + ****************************************************************************/ 1.1064 + 1.1065 + /** If `sym' is a bad symbol: report error and return errSymbol 1.1066 + * else pass through unchanged, 1.1067 + * additional arguments duplicate what has been used in trying to find the 1.1068 + * symbol (--> flyweight pattern). This improves performance since we 1.1069 + * expect misses to happen frequently. 1.1070 + * 1.1071 + * @param sym The symbol that was found, or a ResolveError. 1.1072 + * @param pos The position to use for error reporting. 1.1073 + * @param site The original type from where the selection took place. 1.1074 + * @param name The symbol's name. 1.1075 + * @param argtypes The invocation's value arguments, 1.1076 + * if we looked for a method. 1.1077 + * @param typeargtypes The invocation's type arguments, 1.1078 + * if we looked for a method. 1.1079 + */ 1.1080 + Symbol access(Symbol sym, 1.1081 + DiagnosticPosition pos, 1.1082 + Type site, 1.1083 + Name name, 1.1084 + boolean qualified, 1.1085 + List<Type> argtypes, 1.1086 + List<Type> typeargtypes) { 1.1087 + if (sym.kind >= AMBIGUOUS) { 1.1088 +// printscopes(site.tsym.members());//DEBUG 1.1089 + if (!site.isErroneous() && 1.1090 + !Type.isErroneous(argtypes) && 1.1091 + (typeargtypes==null || !Type.isErroneous(typeargtypes))) 1.1092 + ((ResolveError)sym).report(log, pos, site, name, argtypes, typeargtypes); 1.1093 + do { 1.1094 + sym = ((ResolveError)sym).sym; 1.1095 + } while (sym.kind >= AMBIGUOUS); 1.1096 + if (sym == syms.errSymbol // preserve the symbol name through errors 1.1097 + || ((sym.kind & ERRONEOUS) == 0 // make sure an error symbol is returned 1.1098 + && (sym.kind & TYP) != 0)) 1.1099 + sym = new ErrorType(name, qualified?site.tsym:syms.noSymbol).tsym; 1.1100 + } 1.1101 + return sym; 1.1102 + } 1.1103 + 1.1104 + /** Same as above, but without type arguments and arguments. 1.1105 + */ 1.1106 + Symbol access(Symbol sym, 1.1107 + DiagnosticPosition pos, 1.1108 + Type site, 1.1109 + Name name, 1.1110 + boolean qualified) { 1.1111 + if (sym.kind >= AMBIGUOUS) 1.1112 + return access(sym, pos, site, name, qualified, List.<Type>nil(), null); 1.1113 + else 1.1114 + return sym; 1.1115 + } 1.1116 + 1.1117 + /** Check that sym is not an abstract method. 1.1118 + */ 1.1119 + void checkNonAbstract(DiagnosticPosition pos, Symbol sym) { 1.1120 + if ((sym.flags() & ABSTRACT) != 0) 1.1121 + log.error(pos, "abstract.cant.be.accessed.directly", 1.1122 + kindName(sym), sym, sym.location()); 1.1123 + } 1.1124 + 1.1125 +/* *************************************************************************** 1.1126 + * Debugging 1.1127 + ****************************************************************************/ 1.1128 + 1.1129 + /** print all scopes starting with scope s and proceeding outwards. 1.1130 + * used for debugging. 1.1131 + */ 1.1132 + public void printscopes(Scope s) { 1.1133 + while (s != null) { 1.1134 + if (s.owner != null) 1.1135 + System.err.print(s.owner + ": "); 1.1136 + for (Scope.Entry e = s.elems; e != null; e = e.sibling) { 1.1137 + if ((e.sym.flags() & ABSTRACT) != 0) 1.1138 + System.err.print("abstract "); 1.1139 + System.err.print(e.sym + " "); 1.1140 + } 1.1141 + System.err.println(); 1.1142 + s = s.next; 1.1143 + } 1.1144 + } 1.1145 + 1.1146 + void printscopes(Env<AttrContext> env) { 1.1147 + while (env.outer != null) { 1.1148 + System.err.println("------------------------------"); 1.1149 + printscopes(env.info.scope); 1.1150 + env = env.outer; 1.1151 + } 1.1152 + } 1.1153 + 1.1154 + public void printscopes(Type t) { 1.1155 + while (t.tag == CLASS) { 1.1156 + printscopes(t.tsym.members()); 1.1157 + t = types.supertype(t); 1.1158 + } 1.1159 + } 1.1160 + 1.1161 +/* *************************************************************************** 1.1162 + * Name resolution 1.1163 + * Naming conventions are as for symbol lookup 1.1164 + * Unlike the find... methods these methods will report access errors 1.1165 + ****************************************************************************/ 1.1166 + 1.1167 + /** Resolve an unqualified (non-method) identifier. 1.1168 + * @param pos The position to use for error reporting. 1.1169 + * @param env The environment current at the identifier use. 1.1170 + * @param name The identifier's name. 1.1171 + * @param kind The set of admissible symbol kinds for the identifier. 1.1172 + */ 1.1173 + Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env, 1.1174 + Name name, int kind) { 1.1175 + return access( 1.1176 + findIdent(env, name, kind), 1.1177 + pos, env.enclClass.sym.type, name, false); 1.1178 + } 1.1179 + 1.1180 + /** Resolve an unqualified method identifier. 1.1181 + * @param pos The position to use for error reporting. 1.1182 + * @param env The environment current at the method invocation. 1.1183 + * @param name The identifier's name. 1.1184 + * @param argtypes The types of the invocation's value arguments. 1.1185 + * @param typeargtypes The types of the invocation's type arguments. 1.1186 + */ 1.1187 + Symbol resolveMethod(DiagnosticPosition pos, 1.1188 + Env<AttrContext> env, 1.1189 + Name name, 1.1190 + List<Type> argtypes, 1.1191 + List<Type> typeargtypes) { 1.1192 + Symbol sym = findFun(env, name, argtypes, typeargtypes, false, env.info.varArgs=false); 1.1193 + if (varargsEnabled && sym.kind >= WRONG_MTHS) { 1.1194 + sym = findFun(env, name, argtypes, typeargtypes, true, false); 1.1195 + if (sym.kind >= WRONG_MTHS) 1.1196 + sym = findFun(env, name, argtypes, typeargtypes, true, env.info.varArgs=true); 1.1197 + } 1.1198 + if (sym.kind >= AMBIGUOUS) { 1.1199 + sym = access( 1.1200 + sym, pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes); 1.1201 + } 1.1202 + return sym; 1.1203 + } 1.1204 + 1.1205 + /** Resolve a qualified method identifier 1.1206 + * @param pos The position to use for error reporting. 1.1207 + * @param env The environment current at the method invocation. 1.1208 + * @param site The type of the qualifying expression, in which 1.1209 + * identifier is searched. 1.1210 + * @param name The identifier's name. 1.1211 + * @param argtypes The types of the invocation's value arguments. 1.1212 + * @param typeargtypes The types of the invocation's type arguments. 1.1213 + */ 1.1214 + Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env, 1.1215 + Type site, Name name, List<Type> argtypes, 1.1216 + List<Type> typeargtypes) { 1.1217 + Symbol sym = findMethod(env, site, name, argtypes, typeargtypes, false, 1.1218 + env.info.varArgs=false, false); 1.1219 + if (varargsEnabled && sym.kind >= WRONG_MTHS) { 1.1220 + sym = findMethod(env, site, name, argtypes, typeargtypes, true, 1.1221 + false, false); 1.1222 + if (sym.kind >= WRONG_MTHS) 1.1223 + sym = findMethod(env, site, name, argtypes, typeargtypes, true, 1.1224 + env.info.varArgs=true, false); 1.1225 + } 1.1226 + if (sym.kind >= AMBIGUOUS) { 1.1227 + sym = access(sym, pos, site, name, true, argtypes, typeargtypes); 1.1228 + } 1.1229 + return sym; 1.1230 + } 1.1231 + 1.1232 + /** Resolve a qualified method identifier, throw a fatal error if not 1.1233 + * found. 1.1234 + * @param pos The position to use for error reporting. 1.1235 + * @param env The environment current at the method invocation. 1.1236 + * @param site The type of the qualifying expression, in which 1.1237 + * identifier is searched. 1.1238 + * @param name The identifier's name. 1.1239 + * @param argtypes The types of the invocation's value arguments. 1.1240 + * @param typeargtypes The types of the invocation's type arguments. 1.1241 + */ 1.1242 + public MethodSymbol resolveInternalMethod(DiagnosticPosition pos, Env<AttrContext> env, 1.1243 + Type site, Name name, 1.1244 + List<Type> argtypes, 1.1245 + List<Type> typeargtypes) { 1.1246 + Symbol sym = resolveQualifiedMethod( 1.1247 + pos, env, site, name, argtypes, typeargtypes); 1.1248 + if (sym.kind == MTH) return (MethodSymbol)sym; 1.1249 + else throw new FatalError( 1.1250 + JCDiagnostic.fragment("fatal.err.cant.locate.meth", 1.1251 + name)); 1.1252 + } 1.1253 + 1.1254 + /** Resolve constructor. 1.1255 + * @param pos The position to use for error reporting. 1.1256 + * @param env The environment current at the constructor invocation. 1.1257 + * @param site The type of class for which a constructor is searched. 1.1258 + * @param argtypes The types of the constructor invocation's value 1.1259 + * arguments. 1.1260 + * @param typeargtypes The types of the constructor invocation's type 1.1261 + * arguments. 1.1262 + */ 1.1263 + Symbol resolveConstructor(DiagnosticPosition pos, 1.1264 + Env<AttrContext> env, 1.1265 + Type site, 1.1266 + List<Type> argtypes, 1.1267 + List<Type> typeargtypes) { 1.1268 + Symbol sym = resolveConstructor(pos, env, site, argtypes, typeargtypes, false, env.info.varArgs=false); 1.1269 + if (varargsEnabled && sym.kind >= WRONG_MTHS) { 1.1270 + sym = resolveConstructor(pos, env, site, argtypes, typeargtypes, true, false); 1.1271 + if (sym.kind >= WRONG_MTHS) 1.1272 + sym = resolveConstructor(pos, env, site, argtypes, typeargtypes, true, env.info.varArgs=true); 1.1273 + } 1.1274 + if (sym.kind >= AMBIGUOUS) { 1.1275 + sym = access(sym, pos, site, names.init, true, argtypes, typeargtypes); 1.1276 + } 1.1277 + return sym; 1.1278 + } 1.1279 + 1.1280 + /** Resolve constructor. 1.1281 + * @param pos The position to use for error reporting. 1.1282 + * @param env The environment current at the constructor invocation. 1.1283 + * @param site The type of class for which a constructor is searched. 1.1284 + * @param argtypes The types of the constructor invocation's value 1.1285 + * arguments. 1.1286 + * @param typeargtypes The types of the constructor invocation's type 1.1287 + * arguments. 1.1288 + * @param allowBoxing Allow boxing and varargs conversions. 1.1289 + * @param useVarargs Box trailing arguments into an array for varargs. 1.1290 + */ 1.1291 + Symbol resolveConstructor(DiagnosticPosition pos, Env<AttrContext> env, 1.1292 + Type site, List<Type> argtypes, 1.1293 + List<Type> typeargtypes, 1.1294 + boolean allowBoxing, 1.1295 + boolean useVarargs) { 1.1296 + Symbol sym = findMethod(env, site, 1.1297 + names.init, argtypes, 1.1298 + typeargtypes, allowBoxing, 1.1299 + useVarargs, false); 1.1300 + if ((sym.flags() & DEPRECATED) != 0 && 1.1301 + (env.info.scope.owner.flags() & DEPRECATED) == 0 && 1.1302 + env.info.scope.owner.outermostClass() != sym.outermostClass()) 1.1303 + chk.warnDeprecated(pos, sym); 1.1304 + return sym; 1.1305 + } 1.1306 + 1.1307 + /** Resolve a constructor, throw a fatal error if not found. 1.1308 + * @param pos The position to use for error reporting. 1.1309 + * @param env The environment current at the method invocation. 1.1310 + * @param site The type to be constructed. 1.1311 + * @param argtypes The types of the invocation's value arguments. 1.1312 + * @param typeargtypes The types of the invocation's type arguments. 1.1313 + */ 1.1314 + public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env, 1.1315 + Type site, 1.1316 + List<Type> argtypes, 1.1317 + List<Type> typeargtypes) { 1.1318 + Symbol sym = resolveConstructor( 1.1319 + pos, env, site, argtypes, typeargtypes); 1.1320 + if (sym.kind == MTH) return (MethodSymbol)sym; 1.1321 + else throw new FatalError( 1.1322 + JCDiagnostic.fragment("fatal.err.cant.locate.ctor", site)); 1.1323 + } 1.1324 + 1.1325 + /** Resolve operator. 1.1326 + * @param pos The position to use for error reporting. 1.1327 + * @param optag The tag of the operation tree. 1.1328 + * @param env The environment current at the operation. 1.1329 + * @param argtypes The types of the operands. 1.1330 + */ 1.1331 + Symbol resolveOperator(DiagnosticPosition pos, int optag, 1.1332 + Env<AttrContext> env, List<Type> argtypes) { 1.1333 + Name name = treeinfo.operatorName(optag); 1.1334 + Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes, 1.1335 + null, false, false, true); 1.1336 + if (boxingEnabled && sym.kind >= WRONG_MTHS) 1.1337 + sym = findMethod(env, syms.predefClass.type, name, argtypes, 1.1338 + null, true, false, true); 1.1339 + return access(sym, pos, env.enclClass.sym.type, name, 1.1340 + false, argtypes, null); 1.1341 + } 1.1342 + 1.1343 + /** Resolve operator. 1.1344 + * @param pos The position to use for error reporting. 1.1345 + * @param optag The tag of the operation tree. 1.1346 + * @param env The environment current at the operation. 1.1347 + * @param arg The type of the operand. 1.1348 + */ 1.1349 + Symbol resolveUnaryOperator(DiagnosticPosition pos, int optag, Env<AttrContext> env, Type arg) { 1.1350 + return resolveOperator(pos, optag, env, List.of(arg)); 1.1351 + } 1.1352 + 1.1353 + /** Resolve binary operator. 1.1354 + * @param pos The position to use for error reporting. 1.1355 + * @param optag The tag of the operation tree. 1.1356 + * @param env The environment current at the operation. 1.1357 + * @param left The types of the left operand. 1.1358 + * @param right The types of the right operand. 1.1359 + */ 1.1360 + Symbol resolveBinaryOperator(DiagnosticPosition pos, 1.1361 + int optag, 1.1362 + Env<AttrContext> env, 1.1363 + Type left, 1.1364 + Type right) { 1.1365 + return resolveOperator(pos, optag, env, List.of(left, right)); 1.1366 + } 1.1367 + 1.1368 + /** 1.1369 + * Resolve `c.name' where name == this or name == super. 1.1370 + * @param pos The position to use for error reporting. 1.1371 + * @param env The environment current at the expression. 1.1372 + * @param c The qualifier. 1.1373 + * @param name The identifier's name. 1.1374 + */ 1.1375 + Symbol resolveSelf(DiagnosticPosition pos, 1.1376 + Env<AttrContext> env, 1.1377 + TypeSymbol c, 1.1378 + Name name) { 1.1379 + Env<AttrContext> env1 = env; 1.1380 + boolean staticOnly = false; 1.1381 + while (env1.outer != null) { 1.1382 + if (isStatic(env1)) staticOnly = true; 1.1383 + if (env1.enclClass.sym == c) { 1.1384 + Symbol sym = env1.info.scope.lookup(name).sym; 1.1385 + if (sym != null) { 1.1386 + if (staticOnly) sym = new StaticError(sym); 1.1387 + return access(sym, pos, env.enclClass.sym.type, 1.1388 + name, true); 1.1389 + } 1.1390 + } 1.1391 + if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; 1.1392 + env1 = env1.outer; 1.1393 + } 1.1394 + log.error(pos, "not.encl.class", c); 1.1395 + return syms.errSymbol; 1.1396 + } 1.1397 + 1.1398 + /** 1.1399 + * Resolve `c.this' for an enclosing class c that contains the 1.1400 + * named member. 1.1401 + * @param pos The position to use for error reporting. 1.1402 + * @param env The environment current at the expression. 1.1403 + * @param member The member that must be contained in the result. 1.1404 + */ 1.1405 + Symbol resolveSelfContaining(DiagnosticPosition pos, 1.1406 + Env<AttrContext> env, 1.1407 + Symbol member) { 1.1408 + Name name = names._this; 1.1409 + Env<AttrContext> env1 = env; 1.1410 + boolean staticOnly = false; 1.1411 + while (env1.outer != null) { 1.1412 + if (isStatic(env1)) staticOnly = true; 1.1413 + if (env1.enclClass.sym.isSubClass(member.owner, types) && 1.1414 + isAccessible(env, env1.enclClass.sym.type, member)) { 1.1415 + Symbol sym = env1.info.scope.lookup(name).sym; 1.1416 + if (sym != null) { 1.1417 + if (staticOnly) sym = new StaticError(sym); 1.1418 + return access(sym, pos, env.enclClass.sym.type, 1.1419 + name, true); 1.1420 + } 1.1421 + } 1.1422 + if ((env1.enclClass.sym.flags() & STATIC) != 0) 1.1423 + staticOnly = true; 1.1424 + env1 = env1.outer; 1.1425 + } 1.1426 + log.error(pos, "encl.class.required", member); 1.1427 + return syms.errSymbol; 1.1428 + } 1.1429 + 1.1430 + /** 1.1431 + * Resolve an appropriate implicit this instance for t's container. 1.1432 + * JLS2 8.8.5.1 and 15.9.2 1.1433 + */ 1.1434 + Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t) { 1.1435 + Type thisType = (((t.tsym.owner.kind & (MTH|VAR)) != 0) 1.1436 + ? resolveSelf(pos, env, t.getEnclosingType().tsym, names._this) 1.1437 + : resolveSelfContaining(pos, env, t.tsym)).type; 1.1438 + if (env.info.isSelfCall && thisType.tsym == env.enclClass.sym) 1.1439 + log.error(pos, "cant.ref.before.ctor.called", "this"); 1.1440 + return thisType; 1.1441 + } 1.1442 + 1.1443 +/* *************************************************************************** 1.1444 + * Methods related to kinds 1.1445 + ****************************************************************************/ 1.1446 + 1.1447 + /** A localized string describing a given kind. 1.1448 + */ 1.1449 + static JCDiagnostic kindName(int kind) { 1.1450 + switch (kind) { 1.1451 + case PCK: return JCDiagnostic.fragment("kindname.package"); 1.1452 + case TYP: return JCDiagnostic.fragment("kindname.class"); 1.1453 + case VAR: return JCDiagnostic.fragment("kindname.variable"); 1.1454 + case VAL: return JCDiagnostic.fragment("kindname.value"); 1.1455 + case MTH: return JCDiagnostic.fragment("kindname.method"); 1.1456 + default : return JCDiagnostic.fragment("kindname", 1.1457 + Integer.toString(kind)); //debug 1.1458 + } 1.1459 + } 1.1460 + 1.1461 + static JCDiagnostic kindName(Symbol sym) { 1.1462 + switch (sym.getKind()) { 1.1463 + case PACKAGE: 1.1464 + return JCDiagnostic.fragment("kindname.package"); 1.1465 + 1.1466 + case ENUM: 1.1467 + case ANNOTATION_TYPE: 1.1468 + case INTERFACE: 1.1469 + case CLASS: 1.1470 + return JCDiagnostic.fragment("kindname.class"); 1.1471 + 1.1472 + case TYPE_PARAMETER: 1.1473 + return JCDiagnostic.fragment("kindname.type.variable"); 1.1474 + 1.1475 + case ENUM_CONSTANT: 1.1476 + case FIELD: 1.1477 + case PARAMETER: 1.1478 + case LOCAL_VARIABLE: 1.1479 + case EXCEPTION_PARAMETER: 1.1480 + return JCDiagnostic.fragment("kindname.variable"); 1.1481 + 1.1482 + case METHOD: 1.1483 + case CONSTRUCTOR: 1.1484 + case STATIC_INIT: 1.1485 + case INSTANCE_INIT: 1.1486 + return JCDiagnostic.fragment("kindname.method"); 1.1487 + 1.1488 + default: 1.1489 + if (sym.kind == VAL) 1.1490 + // I don't think this can happen but it can't harm 1.1491 + // playing it safe --ahe 1.1492 + return JCDiagnostic.fragment("kindname.value"); 1.1493 + else 1.1494 + return JCDiagnostic.fragment("kindname", sym.getKind()); // debug 1.1495 + } 1.1496 + } 1.1497 + 1.1498 + /** A localized string describing a given set of kinds. 1.1499 + */ 1.1500 + static JCDiagnostic kindNames(int kind) { 1.1501 + StringBuffer key = new StringBuffer(); 1.1502 + key.append("kindname"); 1.1503 + if ((kind & VAL) != 0) 1.1504 + key.append(((kind & VAL) == VAR) ? ".variable" : ".value"); 1.1505 + if ((kind & MTH) != 0) key.append(".method"); 1.1506 + if ((kind & TYP) != 0) key.append(".class"); 1.1507 + if ((kind & PCK) != 0) key.append(".package"); 1.1508 + return JCDiagnostic.fragment(key.toString(), kind); 1.1509 + } 1.1510 + 1.1511 + /** A localized string describing the kind -- either class or interface -- 1.1512 + * of a given type. 1.1513 + */ 1.1514 + static JCDiagnostic typeKindName(Type t) { 1.1515 + if (t.tag == TYPEVAR || 1.1516 + t.tag == CLASS && (t.tsym.flags() & COMPOUND) != 0) 1.1517 + return JCDiagnostic.fragment("kindname.type.variable.bound"); 1.1518 + else if (t.tag == PACKAGE) 1.1519 + return JCDiagnostic.fragment("kindname.package"); 1.1520 + else if ((t.tsym.flags_field & ANNOTATION) != 0) 1.1521 + return JCDiagnostic.fragment("kindname.annotation"); 1.1522 + else if ((t.tsym.flags_field & INTERFACE) != 0) 1.1523 + return JCDiagnostic.fragment("kindname.interface"); 1.1524 + else 1.1525 + return JCDiagnostic.fragment("kindname.class"); 1.1526 + } 1.1527 + 1.1528 + /** A localized string describing the kind of a missing symbol, given an 1.1529 + * error kind. 1.1530 + */ 1.1531 + static JCDiagnostic absentKindName(int kind) { 1.1532 + switch (kind) { 1.1533 + case ABSENT_VAR: 1.1534 + return JCDiagnostic.fragment("kindname.variable"); 1.1535 + case WRONG_MTHS: case WRONG_MTH: case ABSENT_MTH: 1.1536 + return JCDiagnostic.fragment("kindname.method"); 1.1537 + case ABSENT_TYP: 1.1538 + return JCDiagnostic.fragment("kindname.class"); 1.1539 + default: 1.1540 + return JCDiagnostic.fragment("kindname", kind); 1.1541 + } 1.1542 + } 1.1543 + 1.1544 +/* *************************************************************************** 1.1545 + * ResolveError classes, indicating error situations when accessing symbols 1.1546 + ****************************************************************************/ 1.1547 + 1.1548 + public void logAccessError(Env<AttrContext> env, JCTree tree, Type type) { 1.1549 + AccessError error = new AccessError(env, type.getEnclosingType(), type.tsym); 1.1550 + error.report(log, tree.pos(), type.getEnclosingType(), null, null, null); 1.1551 + } 1.1552 + 1.1553 + /** Root class for resolve errors. 1.1554 + * Instances of this class indicate "Symbol not found". 1.1555 + * Instances of subclass indicate other errors. 1.1556 + */ 1.1557 + private class ResolveError extends Symbol { 1.1558 + 1.1559 + ResolveError(int kind, Symbol sym, String debugName) { 1.1560 + super(kind, 0, null, null, null); 1.1561 + this.debugName = debugName; 1.1562 + this.sym = sym; 1.1563 + } 1.1564 + 1.1565 + /** The name of the kind of error, for debugging only. 1.1566 + */ 1.1567 + final String debugName; 1.1568 + 1.1569 + /** The symbol that was determined by resolution, or errSymbol if none 1.1570 + * was found. 1.1571 + */ 1.1572 + final Symbol sym; 1.1573 + 1.1574 + /** The symbol that was a close mismatch, or null if none was found. 1.1575 + * wrongSym is currently set if a simgle method with the correct name, but 1.1576 + * the wrong parameters was found. 1.1577 + */ 1.1578 + Symbol wrongSym; 1.1579 + 1.1580 + /** An auxiliary explanation set in case of instantiation errors. 1.1581 + */ 1.1582 + JCDiagnostic explanation; 1.1583 + 1.1584 + 1.1585 + public <R, P> R accept(ElementVisitor<R, P> v, P p) { 1.1586 + throw new AssertionError(); 1.1587 + } 1.1588 + 1.1589 + /** Print the (debug only) name of the kind of error. 1.1590 + */ 1.1591 + public String toString() { 1.1592 + return debugName + " wrongSym=" + wrongSym + " explanation=" + explanation; 1.1593 + } 1.1594 + 1.1595 + /** Update wrongSym and explanation and return this. 1.1596 + */ 1.1597 + ResolveError setWrongSym(Symbol sym, JCDiagnostic explanation) { 1.1598 + this.wrongSym = sym; 1.1599 + this.explanation = explanation; 1.1600 + return this; 1.1601 + } 1.1602 + 1.1603 + /** Update wrongSym and return this. 1.1604 + */ 1.1605 + ResolveError setWrongSym(Symbol sym) { 1.1606 + this.wrongSym = sym; 1.1607 + this.explanation = null; 1.1608 + return this; 1.1609 + } 1.1610 + 1.1611 + public boolean exists() { 1.1612 + switch (kind) { 1.1613 + case HIDDEN: 1.1614 + case ABSENT_VAR: 1.1615 + case ABSENT_MTH: 1.1616 + case ABSENT_TYP: 1.1617 + return false; 1.1618 + default: 1.1619 + return true; 1.1620 + } 1.1621 + } 1.1622 + 1.1623 + /** Report error. 1.1624 + * @param log The error log to be used for error reporting. 1.1625 + * @param pos The position to be used for error reporting. 1.1626 + * @param site The original type from where the selection took place. 1.1627 + * @param name The name of the symbol to be resolved. 1.1628 + * @param argtypes The invocation's value arguments, 1.1629 + * if we looked for a method. 1.1630 + * @param typeargtypes The invocation's type arguments, 1.1631 + * if we looked for a method. 1.1632 + */ 1.1633 + void report(Log log, DiagnosticPosition pos, Type site, Name name, 1.1634 + List<Type> argtypes, List<Type> typeargtypes) { 1.1635 + if (name != name.table.error) { 1.1636 + JCDiagnostic kindname = absentKindName(kind); 1.1637 + String idname = name.toString(); 1.1638 + String args = ""; 1.1639 + String typeargs = ""; 1.1640 + if (kind >= WRONG_MTHS && kind <= ABSENT_MTH) { 1.1641 + if (isOperator(name)) { 1.1642 + log.error(pos, "operator.cant.be.applied", 1.1643 + name, Type.toString(argtypes)); 1.1644 + return; 1.1645 + } 1.1646 + if (name == name.table.init) { 1.1647 + kindname = JCDiagnostic.fragment("kindname.constructor"); 1.1648 + idname = site.tsym.name.toString(); 1.1649 + } 1.1650 + args = "(" + Type.toString(argtypes) + ")"; 1.1651 + if (typeargtypes != null && typeargtypes.nonEmpty()) 1.1652 + typeargs = "<" + Type.toString(typeargtypes) + ">"; 1.1653 + } 1.1654 + if (kind == WRONG_MTH) { 1.1655 + log.error(pos, 1.1656 + "cant.apply.symbol" + (explanation != null ? ".1" : ""), 1.1657 + wrongSym.asMemberOf(site, types), 1.1658 + wrongSym.location(site, types), 1.1659 + typeargs, 1.1660 + Type.toString(argtypes), 1.1661 + explanation); 1.1662 + } else if (site.tsym.name.len != 0) { 1.1663 + if (site.tsym.kind == PCK && !site.tsym.exists()) 1.1664 + log.error(pos, "doesnt.exist", site.tsym); 1.1665 + else 1.1666 + log.error(pos, "cant.resolve.location", 1.1667 + kindname, idname, args, typeargs, 1.1668 + typeKindName(site), site); 1.1669 + } else { 1.1670 + log.error(pos, "cant.resolve", kindname, idname, args, typeargs); 1.1671 + } 1.1672 + } 1.1673 + } 1.1674 +//where 1.1675 + /** A name designates an operator if it consists 1.1676 + * of a non-empty sequence of operator symbols +-~!/*%&|^<>= 1.1677 + */ 1.1678 + boolean isOperator(Name name) { 1.1679 + int i = 0; 1.1680 + while (i < name.len && 1.1681 + "+-~!*/%&|^<>=".indexOf(name.byteAt(i)) >= 0) i++; 1.1682 + return i > 0 && i == name.len; 1.1683 + } 1.1684 + } 1.1685 + 1.1686 + /** Resolve error class indicating that a symbol is not accessible. 1.1687 + */ 1.1688 + class AccessError extends ResolveError { 1.1689 + 1.1690 + AccessError(Symbol sym) { 1.1691 + this(null, null, sym); 1.1692 + } 1.1693 + 1.1694 + AccessError(Env<AttrContext> env, Type site, Symbol sym) { 1.1695 + super(HIDDEN, sym, "access error"); 1.1696 + this.env = env; 1.1697 + this.site = site; 1.1698 + if (debugResolve) 1.1699 + log.error("proc.messager", sym + " @ " + site + " is inaccessible."); 1.1700 + } 1.1701 + 1.1702 + private Env<AttrContext> env; 1.1703 + private Type site; 1.1704 + 1.1705 + /** Report error. 1.1706 + * @param log The error log to be used for error reporting. 1.1707 + * @param pos The position to be used for error reporting. 1.1708 + * @param site The original type from where the selection took place. 1.1709 + * @param name The name of the symbol to be resolved. 1.1710 + * @param argtypes The invocation's value arguments, 1.1711 + * if we looked for a method. 1.1712 + * @param typeargtypes The invocation's type arguments, 1.1713 + * if we looked for a method. 1.1714 + */ 1.1715 + void report(Log log, DiagnosticPosition pos, Type site, Name name, 1.1716 + List<Type> argtypes, List<Type> typeargtypes) { 1.1717 + if (sym.owner.type.tag != ERROR) { 1.1718 + if (sym.name == sym.name.table.init && sym.owner != site.tsym) 1.1719 + new ResolveError(ABSENT_MTH, sym.owner, "absent method " + sym).report( 1.1720 + log, pos, site, name, argtypes, typeargtypes); 1.1721 + if ((sym.flags() & PUBLIC) != 0 1.1722 + || (env != null && this.site != null 1.1723 + && !isAccessible(env, this.site))) 1.1724 + log.error(pos, "not.def.access.class.intf.cant.access", 1.1725 + sym, sym.location()); 1.1726 + else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) 1.1727 + log.error(pos, "report.access", sym, 1.1728 + TreeInfo.flagNames(sym.flags() & (PRIVATE | PROTECTED)), 1.1729 + sym.location()); 1.1730 + else 1.1731 + log.error(pos, "not.def.public.cant.access", 1.1732 + sym, sym.location()); 1.1733 + } 1.1734 + } 1.1735 + } 1.1736 + 1.1737 + /** Resolve error class indicating that an instance member was accessed 1.1738 + * from a static context. 1.1739 + */ 1.1740 + class StaticError extends ResolveError { 1.1741 + StaticError(Symbol sym) { 1.1742 + super(STATICERR, sym, "static error"); 1.1743 + } 1.1744 + 1.1745 + /** Report error. 1.1746 + * @param log The error log to be used for error reporting. 1.1747 + * @param pos The position to be used for error reporting. 1.1748 + * @param site The original type from where the selection took place. 1.1749 + * @param name The name of the symbol to be resolved. 1.1750 + * @param argtypes The invocation's value arguments, 1.1751 + * if we looked for a method. 1.1752 + * @param typeargtypes The invocation's type arguments, 1.1753 + * if we looked for a method. 1.1754 + */ 1.1755 + void report(Log log, 1.1756 + DiagnosticPosition pos, 1.1757 + Type site, 1.1758 + Name name, 1.1759 + List<Type> argtypes, 1.1760 + List<Type> typeargtypes) { 1.1761 + String symstr = ((sym.kind == TYP && sym.type.tag == CLASS) 1.1762 + ? types.erasure(sym.type) 1.1763 + : sym).toString(); 1.1764 + log.error(pos, "non-static.cant.be.ref", 1.1765 + kindName(sym), symstr); 1.1766 + } 1.1767 + } 1.1768 + 1.1769 + /** Resolve error class indicating an ambiguous reference. 1.1770 + */ 1.1771 + class AmbiguityError extends ResolveError { 1.1772 + Symbol sym1; 1.1773 + Symbol sym2; 1.1774 + 1.1775 + AmbiguityError(Symbol sym1, Symbol sym2) { 1.1776 + super(AMBIGUOUS, sym1, "ambiguity error"); 1.1777 + this.sym1 = sym1; 1.1778 + this.sym2 = sym2; 1.1779 + } 1.1780 + 1.1781 + /** Report error. 1.1782 + * @param log The error log to be used for error reporting. 1.1783 + * @param pos The position to be used for error reporting. 1.1784 + * @param site The original type from where the selection took place. 1.1785 + * @param name The name of the symbol to be resolved. 1.1786 + * @param argtypes The invocation's value arguments, 1.1787 + * if we looked for a method. 1.1788 + * @param typeargtypes The invocation's type arguments, 1.1789 + * if we looked for a method. 1.1790 + */ 1.1791 + void report(Log log, DiagnosticPosition pos, Type site, Name name, 1.1792 + List<Type> argtypes, List<Type> typeargtypes) { 1.1793 + AmbiguityError pair = this; 1.1794 + while (true) { 1.1795 + if (pair.sym1.kind == AMBIGUOUS) 1.1796 + pair = (AmbiguityError)pair.sym1; 1.1797 + else if (pair.sym2.kind == AMBIGUOUS) 1.1798 + pair = (AmbiguityError)pair.sym2; 1.1799 + else break; 1.1800 + } 1.1801 + Name sname = pair.sym1.name; 1.1802 + if (sname == sname.table.init) sname = pair.sym1.owner.name; 1.1803 + log.error(pos, "ref.ambiguous", sname, 1.1804 + kindName(pair.sym1), 1.1805 + pair.sym1, 1.1806 + pair.sym1.location(site, types), 1.1807 + kindName(pair.sym2), 1.1808 + pair.sym2, 1.1809 + pair.sym2.location(site, types)); 1.1810 + } 1.1811 + } 1.1812 +}