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