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