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