Mon, 26 Mar 2012 15:28:22 +0100
7151492: Encapsulate check logic into Attr.ResultInfo
Summary: ResultInfo class should be used to make attribution code transparent w.r.t. check logic being used
Reviewed-by: jjg, dlsmith
1 /*
2 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.tools.javac.comp;
28 import com.sun.tools.javac.api.Formattable.LocalizedString;
29 import com.sun.tools.javac.code.*;
30 import com.sun.tools.javac.code.Type.*;
31 import com.sun.tools.javac.code.Symbol.*;
32 import com.sun.tools.javac.comp.Attr.ResultInfo;
33 import com.sun.tools.javac.comp.Check.CheckContext;
34 import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
35 import com.sun.tools.javac.jvm.*;
36 import com.sun.tools.javac.tree.*;
37 import com.sun.tools.javac.tree.JCTree.*;
38 import com.sun.tools.javac.util.*;
39 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
40 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
41 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
43 import java.util.Arrays;
44 import java.util.Collection;
45 import java.util.EnumMap;
46 import java.util.EnumSet;
47 import java.util.HashSet;
48 import java.util.Map;
49 import java.util.Set;
51 import javax.lang.model.element.ElementVisitor;
53 import static com.sun.tools.javac.code.Flags.*;
54 import static com.sun.tools.javac.code.Flags.BLOCK;
55 import static com.sun.tools.javac.code.Kinds.*;
56 import static com.sun.tools.javac.code.Kinds.ERRONEOUS;
57 import static com.sun.tools.javac.code.TypeTags.*;
58 import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
59 import static com.sun.tools.javac.tree.JCTree.Tag.*;
61 /** Helper class for name resolution, used mostly by the attribution phase.
62 *
63 * <p><b>This is NOT part of any supported API.
64 * If you write code that depends on this, you do so at your own risk.
65 * This code and its internal interfaces are subject to change or
66 * deletion without notice.</b>
67 */
68 public class Resolve {
69 protected static final Context.Key<Resolve> resolveKey =
70 new Context.Key<Resolve>();
72 Names names;
73 Log log;
74 Symtab syms;
75 Attr attr;
76 Check chk;
77 Infer infer;
78 ClassReader reader;
79 TreeInfo treeinfo;
80 Types types;
81 JCDiagnostic.Factory diags;
82 public final boolean boxingEnabled; // = source.allowBoxing();
83 public final boolean varargsEnabled; // = source.allowVarargs();
84 public final boolean allowMethodHandles;
85 private final boolean debugResolve;
86 final EnumSet<VerboseResolutionMode> verboseResolutionMode;
88 Scope polymorphicSignatureScope;
90 protected Resolve(Context context) {
91 context.put(resolveKey, this);
92 syms = Symtab.instance(context);
94 varNotFound = new
95 SymbolNotFoundError(ABSENT_VAR);
96 wrongMethod = new
97 InapplicableSymbolError();
98 wrongMethods = new
99 InapplicableSymbolsError();
100 methodNotFound = new
101 SymbolNotFoundError(ABSENT_MTH);
102 typeNotFound = new
103 SymbolNotFoundError(ABSENT_TYP);
105 names = Names.instance(context);
106 log = Log.instance(context);
107 attr = Attr.instance(context);
108 chk = Check.instance(context);
109 infer = Infer.instance(context);
110 reader = ClassReader.instance(context);
111 treeinfo = TreeInfo.instance(context);
112 types = Types.instance(context);
113 diags = JCDiagnostic.Factory.instance(context);
114 Source source = Source.instance(context);
115 boxingEnabled = source.allowBoxing();
116 varargsEnabled = source.allowVarargs();
117 Options options = Options.instance(context);
118 debugResolve = options.isSet("debugresolve");
119 verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
120 Target target = Target.instance(context);
121 allowMethodHandles = target.hasMethodHandles();
122 polymorphicSignatureScope = new Scope(syms.noSymbol);
124 inapplicableMethodException = new InapplicableMethodException(diags);
125 }
127 /** error symbols, which are returned when resolution fails
128 */
129 private final SymbolNotFoundError varNotFound;
130 private final InapplicableSymbolError wrongMethod;
131 private final InapplicableSymbolsError wrongMethods;
132 private final SymbolNotFoundError methodNotFound;
133 private final SymbolNotFoundError typeNotFound;
135 public static Resolve instance(Context context) {
136 Resolve instance = context.get(resolveKey);
137 if (instance == null)
138 instance = new Resolve(context);
139 return instance;
140 }
142 // <editor-fold defaultstate="collapsed" desc="Verbose resolution diagnostics support">
143 enum VerboseResolutionMode {
144 SUCCESS("success"),
145 FAILURE("failure"),
146 APPLICABLE("applicable"),
147 INAPPLICABLE("inapplicable"),
148 DEFERRED_INST("deferred-inference"),
149 PREDEF("predef"),
150 OBJECT_INIT("object-init"),
151 INTERNAL("internal");
153 String opt;
155 private VerboseResolutionMode(String opt) {
156 this.opt = opt;
157 }
159 static EnumSet<VerboseResolutionMode> getVerboseResolutionMode(Options opts) {
160 String s = opts.get("verboseResolution");
161 EnumSet<VerboseResolutionMode> res = EnumSet.noneOf(VerboseResolutionMode.class);
162 if (s == null) return res;
163 if (s.contains("all")) {
164 res = EnumSet.allOf(VerboseResolutionMode.class);
165 }
166 Collection<String> args = Arrays.asList(s.split(","));
167 for (VerboseResolutionMode mode : values()) {
168 if (args.contains(mode.opt)) {
169 res.add(mode);
170 } else if (args.contains("-" + mode.opt)) {
171 res.remove(mode);
172 }
173 }
174 return res;
175 }
176 }
178 void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site,
179 List<Type> argtypes, List<Type> typeargtypes, Symbol bestSoFar) {
180 boolean success = bestSoFar.kind < ERRONEOUS;
182 if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) {
183 return;
184 } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) {
185 return;
186 }
188 if (bestSoFar.name == names.init &&
189 bestSoFar.owner == syms.objectType.tsym &&
190 !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) {
191 return; //skip diags for Object constructor resolution
192 } else if (site == syms.predefClass.type &&
193 !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) {
194 return; //skip spurious diags for predef symbols (i.e. operators)
195 } else if (currentResolutionContext.internalResolution &&
196 !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) {
197 return;
198 }
200 int pos = 0;
201 int mostSpecificPos = -1;
202 ListBuffer<JCDiagnostic> subDiags = ListBuffer.lb();
203 for (Candidate c : currentResolutionContext.candidates) {
204 if (currentResolutionContext.step != c.step ||
205 (c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE)) ||
206 (!c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))) {
207 continue;
208 } else {
209 subDiags.append(c.isApplicable() ?
210 getVerboseApplicableCandidateDiag(pos, c.sym, c.mtype) :
211 getVerboseInapplicableCandidateDiag(pos, c.sym, c.details));
212 if (c.sym == bestSoFar)
213 mostSpecificPos = pos;
214 pos++;
215 }
216 }
217 String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1";
218 JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name,
219 site.tsym, mostSpecificPos, currentResolutionContext.step,
220 methodArguments(argtypes), methodArguments(typeargtypes));
221 JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList());
222 log.report(d);
223 }
225 JCDiagnostic getVerboseApplicableCandidateDiag(int pos, Symbol sym, Type inst) {
226 JCDiagnostic subDiag = null;
227 if (inst.getReturnType().tag == FORALL) {
228 Type diagType = types.createMethodTypeWithReturn(inst.asMethodType(),
229 ((ForAll)inst.getReturnType()).qtype);
230 subDiag = diags.fragment("partial.inst.sig", diagType);
231 } else if (sym.type.tag == FORALL) {
232 subDiag = diags.fragment("full.inst.sig", inst.asMethodType());
233 }
235 String key = subDiag == null ?
236 "applicable.method.found" :
237 "applicable.method.found.1";
239 return diags.fragment(key, pos, sym, subDiag);
240 }
242 JCDiagnostic getVerboseInapplicableCandidateDiag(int pos, Symbol sym, JCDiagnostic subDiag) {
243 return diags.fragment("not.applicable.method.found", pos, sym, subDiag);
244 }
245 // </editor-fold>
247 /* ************************************************************************
248 * Identifier resolution
249 *************************************************************************/
251 /** An environment is "static" if its static level is greater than
252 * the one of its outer environment
253 */
254 static boolean isStatic(Env<AttrContext> env) {
255 return env.info.staticLevel > env.outer.info.staticLevel;
256 }
258 /** An environment is an "initializer" if it is a constructor or
259 * an instance initializer.
260 */
261 static boolean isInitializer(Env<AttrContext> env) {
262 Symbol owner = env.info.scope.owner;
263 return owner.isConstructor() ||
264 owner.owner.kind == TYP &&
265 (owner.kind == VAR ||
266 owner.kind == MTH && (owner.flags() & BLOCK) != 0) &&
267 (owner.flags() & STATIC) == 0;
268 }
270 /** Is class accessible in given evironment?
271 * @param env The current environment.
272 * @param c The class whose accessibility is checked.
273 */
274 public boolean isAccessible(Env<AttrContext> env, TypeSymbol c) {
275 return isAccessible(env, c, false);
276 }
278 public boolean isAccessible(Env<AttrContext> env, TypeSymbol c, boolean checkInner) {
279 boolean isAccessible = false;
280 switch ((short)(c.flags() & AccessFlags)) {
281 case PRIVATE:
282 isAccessible =
283 env.enclClass.sym.outermostClass() ==
284 c.owner.outermostClass();
285 break;
286 case 0:
287 isAccessible =
288 env.toplevel.packge == c.owner // fast special case
289 ||
290 env.toplevel.packge == c.packge()
291 ||
292 // Hack: this case is added since synthesized default constructors
293 // of anonymous classes should be allowed to access
294 // classes which would be inaccessible otherwise.
295 env.enclMethod != null &&
296 (env.enclMethod.mods.flags & ANONCONSTR) != 0;
297 break;
298 default: // error recovery
299 case PUBLIC:
300 isAccessible = true;
301 break;
302 case PROTECTED:
303 isAccessible =
304 env.toplevel.packge == c.owner // fast special case
305 ||
306 env.toplevel.packge == c.packge()
307 ||
308 isInnerSubClass(env.enclClass.sym, c.owner);
309 break;
310 }
311 return (checkInner == false || c.type.getEnclosingType() == Type.noType) ?
312 isAccessible :
313 isAccessible && isAccessible(env, c.type.getEnclosingType(), checkInner);
314 }
315 //where
316 /** Is given class a subclass of given base class, or an inner class
317 * of a subclass?
318 * Return null if no such class exists.
319 * @param c The class which is the subclass or is contained in it.
320 * @param base The base class
321 */
322 private boolean isInnerSubClass(ClassSymbol c, Symbol base) {
323 while (c != null && !c.isSubClass(base, types)) {
324 c = c.owner.enclClass();
325 }
326 return c != null;
327 }
329 boolean isAccessible(Env<AttrContext> env, Type t) {
330 return isAccessible(env, t, false);
331 }
333 boolean isAccessible(Env<AttrContext> env, Type t, boolean checkInner) {
334 return (t.tag == ARRAY)
335 ? isAccessible(env, types.elemtype(t))
336 : isAccessible(env, t.tsym, checkInner);
337 }
339 /** Is symbol accessible as a member of given type in given evironment?
340 * @param env The current environment.
341 * @param site The type of which the tested symbol is regarded
342 * as a member.
343 * @param sym The symbol.
344 */
345 public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym) {
346 return isAccessible(env, site, sym, false);
347 }
348 public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym, boolean checkInner) {
349 if (sym.name == names.init && sym.owner != site.tsym) return false;
350 switch ((short)(sym.flags() & AccessFlags)) {
351 case PRIVATE:
352 return
353 (env.enclClass.sym == sym.owner // fast special case
354 ||
355 env.enclClass.sym.outermostClass() ==
356 sym.owner.outermostClass())
357 &&
358 sym.isInheritedIn(site.tsym, types);
359 case 0:
360 return
361 (env.toplevel.packge == sym.owner.owner // fast special case
362 ||
363 env.toplevel.packge == sym.packge())
364 &&
365 isAccessible(env, site, checkInner)
366 &&
367 sym.isInheritedIn(site.tsym, types)
368 &&
369 notOverriddenIn(site, sym);
370 case PROTECTED:
371 return
372 (env.toplevel.packge == sym.owner.owner // fast special case
373 ||
374 env.toplevel.packge == sym.packge()
375 ||
376 isProtectedAccessible(sym, env.enclClass.sym, site)
377 ||
378 // OK to select instance method or field from 'super' or type name
379 // (but type names should be disallowed elsewhere!)
380 env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP)
381 &&
382 isAccessible(env, site, checkInner)
383 &&
384 notOverriddenIn(site, sym);
385 default: // this case includes erroneous combinations as well
386 return isAccessible(env, site, checkInner) && notOverriddenIn(site, sym);
387 }
388 }
389 //where
390 /* `sym' is accessible only if not overridden by
391 * another symbol which is a member of `site'
392 * (because, if it is overridden, `sym' is not strictly
393 * speaking a member of `site'). A polymorphic signature method
394 * cannot be overridden (e.g. MH.invokeExact(Object[])).
395 */
396 private boolean notOverriddenIn(Type site, Symbol sym) {
397 if (sym.kind != MTH || sym.isConstructor() || sym.isStatic())
398 return true;
399 else {
400 Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true);
401 return (s2 == null || s2 == sym || sym.owner == s2.owner ||
402 s2.isPolymorphicSignatureGeneric() ||
403 !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym)));
404 }
405 }
406 //where
407 /** Is given protected symbol accessible if it is selected from given site
408 * and the selection takes place in given class?
409 * @param sym The symbol with protected access
410 * @param c The class where the access takes place
411 * @site The type of the qualifier
412 */
413 private
414 boolean isProtectedAccessible(Symbol sym, ClassSymbol c, Type site) {
415 while (c != null &&
416 !(c.isSubClass(sym.owner, types) &&
417 (c.flags() & INTERFACE) == 0 &&
418 // In JLS 2e 6.6.2.1, the subclass restriction applies
419 // only to instance fields and methods -- types are excluded
420 // regardless of whether they are declared 'static' or not.
421 ((sym.flags() & STATIC) != 0 || sym.kind == TYP || site.tsym.isSubClass(c, types))))
422 c = c.owner.enclClass();
423 return c != null;
424 }
426 /** Try to instantiate the type of a method so that it fits
427 * given type arguments and argument types. If succesful, return
428 * the method's instantiated type, else return null.
429 * The instantiation will take into account an additional leading
430 * formal parameter if the method is an instance method seen as a member
431 * of un underdetermined site In this case, we treat site as an additional
432 * parameter and the parameters of the class containing the method as
433 * additional type variables that get instantiated.
434 *
435 * @param env The current environment
436 * @param site The type of which the method is a member.
437 * @param m The method symbol.
438 * @param argtypes The invocation's given value arguments.
439 * @param typeargtypes The invocation's given type arguments.
440 * @param allowBoxing Allow boxing conversions of arguments.
441 * @param useVarargs Box trailing arguments into an array for varargs.
442 */
443 Type rawInstantiate(Env<AttrContext> env,
444 Type site,
445 Symbol m,
446 List<Type> argtypes,
447 List<Type> typeargtypes,
448 boolean allowBoxing,
449 boolean useVarargs,
450 Warner warn)
451 throws Infer.InferenceException {
452 boolean polymorphicSignature = m.isPolymorphicSignatureGeneric() && allowMethodHandles;
453 if (useVarargs && (m.flags() & VARARGS) == 0)
454 throw inapplicableMethodException.setMessage();
455 Type mt = types.memberType(site, m);
457 // tvars is the list of formal type variables for which type arguments
458 // need to inferred.
459 List<Type> tvars = null;
460 if (env.info.tvars != null) {
461 tvars = types.newInstances(env.info.tvars);
462 mt = types.subst(mt, env.info.tvars, tvars);
463 }
464 if (typeargtypes == null) typeargtypes = List.nil();
465 if (mt.tag != FORALL && typeargtypes.nonEmpty()) {
466 // This is not a polymorphic method, but typeargs are supplied
467 // which is fine, see JLS 15.12.2.1
468 } else if (mt.tag == FORALL && typeargtypes.nonEmpty()) {
469 ForAll pmt = (ForAll) mt;
470 if (typeargtypes.length() != pmt.tvars.length())
471 throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args
472 // Check type arguments are within bounds
473 List<Type> formals = pmt.tvars;
474 List<Type> actuals = typeargtypes;
475 while (formals.nonEmpty() && actuals.nonEmpty()) {
476 List<Type> bounds = types.subst(types.getBounds((TypeVar)formals.head),
477 pmt.tvars, typeargtypes);
478 for (; bounds.nonEmpty(); bounds = bounds.tail)
479 if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn))
480 throw inapplicableMethodException.setMessage("explicit.param.do.not.conform.to.bounds",actuals.head, bounds);
481 formals = formals.tail;
482 actuals = actuals.tail;
483 }
484 mt = types.subst(pmt.qtype, pmt.tvars, typeargtypes);
485 } else if (mt.tag == FORALL) {
486 ForAll pmt = (ForAll) mt;
487 List<Type> tvars1 = types.newInstances(pmt.tvars);
488 tvars = tvars.appendList(tvars1);
489 mt = types.subst(pmt.qtype, pmt.tvars, tvars1);
490 }
492 // find out whether we need to go the slow route via infer
493 boolean instNeeded = tvars.tail != null || /*inlined: tvars.nonEmpty()*/
494 polymorphicSignature;
495 for (List<Type> l = argtypes;
496 l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded;
497 l = l.tail) {
498 if (l.head.tag == FORALL) instNeeded = true;
499 }
501 if (instNeeded)
502 return polymorphicSignature ?
503 infer.instantiatePolymorphicSignatureInstance(env, site, m.name, (MethodSymbol)m, argtypes) :
504 infer.instantiateMethod(env,
505 tvars,
506 (MethodType)mt,
507 m,
508 argtypes,
509 allowBoxing,
510 useVarargs,
511 warn);
513 checkRawArgumentsAcceptable(env, argtypes, mt.getParameterTypes(),
514 allowBoxing, useVarargs, warn);
515 return mt;
516 }
518 /** Same but returns null instead throwing a NoInstanceException
519 */
520 Type instantiate(Env<AttrContext> env,
521 Type site,
522 Symbol m,
523 List<Type> argtypes,
524 List<Type> typeargtypes,
525 boolean allowBoxing,
526 boolean useVarargs,
527 Warner warn) {
528 try {
529 return rawInstantiate(env, site, m, argtypes, typeargtypes,
530 allowBoxing, useVarargs, warn);
531 } catch (InapplicableMethodException ex) {
532 return null;
533 }
534 }
536 /** Check if a parameter list accepts a list of args.
537 */
538 boolean argumentsAcceptable(Env<AttrContext> env,
539 List<Type> argtypes,
540 List<Type> formals,
541 boolean allowBoxing,
542 boolean useVarargs,
543 Warner warn) {
544 try {
545 checkRawArgumentsAcceptable(env, argtypes, formals, allowBoxing, useVarargs, warn);
546 return true;
547 } catch (InapplicableMethodException ex) {
548 return false;
549 }
550 }
551 /**
552 * A check handler is used by the main method applicability routine in order
553 * to handle specific method applicability failures. It is assumed that a class
554 * implementing this interface should throw exceptions that are a subtype of
555 * InapplicableMethodException (see below). Such exception will terminate the
556 * method applicability check and propagate important info outwards (for the
557 * purpose of generating better diagnostics).
558 */
559 interface MethodCheckHandler {
560 /* The number of actuals and formals differ */
561 InapplicableMethodException arityMismatch();
562 /* An actual argument type does not conform to the corresponding formal type */
563 InapplicableMethodException argumentMismatch(boolean varargs, Type found, Type expected);
564 /* The element type of a varargs is not accessible in the current context */
565 InapplicableMethodException inaccessibleVarargs(Symbol location, Type expected);
566 }
568 /**
569 * Basic method check handler used within Resolve - all methods end up
570 * throwing InapplicableMethodException; a diagnostic fragment that describes
571 * the cause as to why the method is not applicable is set on the exception
572 * before it is thrown.
573 */
574 MethodCheckHandler resolveHandler = new MethodCheckHandler() {
575 public InapplicableMethodException arityMismatch() {
576 return inapplicableMethodException.setMessage("arg.length.mismatch");
577 }
578 public InapplicableMethodException argumentMismatch(boolean varargs, Type found, Type expected) {
579 String key = varargs ?
580 "varargs.argument.mismatch" :
581 "no.conforming.assignment.exists";
582 return inapplicableMethodException.setMessage(key,
583 found, expected);
584 }
585 public InapplicableMethodException inaccessibleVarargs(Symbol location, Type expected) {
586 return inapplicableMethodException.setMessage("inaccessible.varargs.type",
587 expected, Kinds.kindName(location), location);
588 }
589 };
591 void checkRawArgumentsAcceptable(Env<AttrContext> env,
592 List<Type> argtypes,
593 List<Type> formals,
594 boolean allowBoxing,
595 boolean useVarargs,
596 Warner warn) {
597 checkRawArgumentsAcceptable(env, List.<Type>nil(), argtypes, formals,
598 allowBoxing, useVarargs, warn, resolveHandler);
599 }
601 /**
602 * Main method applicability routine. Given a list of actual types A,
603 * a list of formal types F, determines whether the types in A are
604 * compatible (by method invocation conversion) with the types in F.
605 *
606 * Since this routine is shared between overload resolution and method
607 * type-inference, it is crucial that actual types are converted to the
608 * corresponding 'undet' form (i.e. where inference variables are replaced
609 * with undetvars) so that constraints can be propagated and collected.
610 *
611 * Moreover, if one or more types in A is a poly type, this routine calls
612 * Infer.instantiateArg in order to complete the poly type (this might involve
613 * deferred attribution).
614 *
615 * A method check handler (see above) is used in order to report errors.
616 */
617 List<Type> checkRawArgumentsAcceptable(Env<AttrContext> env,
618 List<Type> undetvars,
619 List<Type> argtypes,
620 List<Type> formals,
621 boolean allowBoxing,
622 boolean useVarargs,
623 Warner warn,
624 MethodCheckHandler handler) {
625 Type varargsFormal = useVarargs ? formals.last() : null;
626 ListBuffer<Type> checkedArgs = ListBuffer.lb();
628 if (varargsFormal == null &&
629 argtypes.size() != formals.size()) {
630 throw handler.arityMismatch(); // not enough args
631 }
633 while (argtypes.nonEmpty() && formals.head != varargsFormal) {
634 ResultInfo resultInfo = methodCheckResult(formals.head, allowBoxing, false, undetvars, handler, warn);
635 checkedArgs.append(resultInfo.check(env.tree.pos(), argtypes.head));
636 argtypes = argtypes.tail;
637 formals = formals.tail;
638 }
640 if (formals.head != varargsFormal) {
641 throw handler.arityMismatch(); // not enough args
642 }
644 if (useVarargs) {
645 //note: if applicability check is triggered by most specific test,
646 //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
647 Type elt = types.elemtype(varargsFormal);
648 while (argtypes.nonEmpty()) {
649 ResultInfo resultInfo = methodCheckResult(elt, allowBoxing, true, undetvars, handler, warn);
650 checkedArgs.append(resultInfo.check(env.tree.pos(), argtypes.head));
651 argtypes = argtypes.tail;
652 }
653 //check varargs element type accessibility
654 if (undetvars.isEmpty() && !isAccessible(env, elt)) {
655 Symbol location = env.enclClass.sym;
656 throw handler.inaccessibleVarargs(location, elt);
657 }
658 }
659 return checkedArgs.toList();
660 }
662 /**
663 * Check context to be used during method applicability checks. A method check
664 * context might contain inference variables.
665 */
666 abstract class MethodCheckContext implements CheckContext {
668 MethodCheckHandler handler;
669 boolean useVarargs;
670 List<Type> undetvars;
671 Warner rsWarner;
673 public MethodCheckContext(MethodCheckHandler handler, boolean useVarargs, List<Type> undetvars, Warner rsWarner) {
674 this.handler = handler;
675 this.useVarargs = useVarargs;
676 this.undetvars = undetvars;
677 this.rsWarner = rsWarner;
678 }
680 public void report(DiagnosticPosition pos, Type found, Type req, JCDiagnostic details) {
681 throw handler.argumentMismatch(useVarargs, found, req);
682 }
684 public Type rawInstantiatePoly(ForAll found, Type req, Warner warn) {
685 throw new AssertionError("ForAll in argument position");
686 }
688 public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
689 return rsWarner;
690 }
691 }
693 /**
694 * Subclass of method check context class that implements strict method conversion.
695 * Strict method conversion checks compatibility between types using subtyping tests.
696 */
697 class StrictMethodContext extends MethodCheckContext {
699 public StrictMethodContext(MethodCheckHandler handler, boolean useVarargs, List<Type> undetvars, Warner rsWarner) {
700 super(handler, useVarargs, undetvars, rsWarner);
701 }
703 public boolean compatible(Type found, Type req, Warner warn) {
704 return types.isSubtypeUnchecked(found, infer.asUndetType(req, undetvars), warn);
705 }
706 }
708 /**
709 * Subclass of method check context class that implements loose method conversion.
710 * Loose method conversion checks compatibility between types using method conversion tests.
711 */
712 class LooseMethodContext extends MethodCheckContext {
714 public LooseMethodContext(MethodCheckHandler handler, boolean useVarargs, List<Type> undetvars, Warner rsWarner) {
715 super(handler, useVarargs, undetvars, rsWarner);
716 }
718 public boolean compatible(Type found, Type req, Warner warn) {
719 return types.isConvertible(found, infer.asUndetType(req, undetvars), warn);
720 }
721 }
723 /**
724 * Create a method check context to be used during method applicability check
725 */
726 ResultInfo methodCheckResult(Type to, boolean allowBoxing, boolean useVarargs,
727 List<Type> undetvars, MethodCheckHandler methodHandler, Warner rsWarner) {
728 MethodCheckContext checkContext = allowBoxing ?
729 new LooseMethodContext(methodHandler, useVarargs, undetvars, rsWarner) :
730 new StrictMethodContext(methodHandler, useVarargs, undetvars, rsWarner);
731 return attr.new ResultInfo(VAL, to, checkContext) {
732 @Override
733 protected Type check(DiagnosticPosition pos, Type found) {
734 return super.check(pos, chk.checkNonVoid(pos, types.capture(types.upperBound(found))));
735 }
736 };
737 }
739 public static class InapplicableMethodException extends RuntimeException {
740 private static final long serialVersionUID = 0;
742 JCDiagnostic diagnostic;
743 JCDiagnostic.Factory diags;
745 InapplicableMethodException(JCDiagnostic.Factory diags) {
746 this.diagnostic = null;
747 this.diags = diags;
748 }
749 InapplicableMethodException setMessage() {
750 this.diagnostic = null;
751 return this;
752 }
753 InapplicableMethodException setMessage(String key) {
754 this.diagnostic = key != null ? diags.fragment(key) : null;
755 return this;
756 }
757 InapplicableMethodException setMessage(String key, Object... args) {
758 this.diagnostic = key != null ? diags.fragment(key, args) : null;
759 return this;
760 }
761 InapplicableMethodException setMessage(JCDiagnostic diag) {
762 this.diagnostic = diag;
763 return this;
764 }
766 public JCDiagnostic getDiagnostic() {
767 return diagnostic;
768 }
769 }
770 private final InapplicableMethodException inapplicableMethodException;
772 /* ***************************************************************************
773 * Symbol lookup
774 * the following naming conventions for arguments are used
775 *
776 * env is the environment where the symbol was mentioned
777 * site is the type of which the symbol is a member
778 * name is the symbol's name
779 * if no arguments are given
780 * argtypes are the value arguments, if we search for a method
781 *
782 * If no symbol was found, a ResolveError detailing the problem is returned.
783 ****************************************************************************/
785 /** Find field. Synthetic fields are always skipped.
786 * @param env The current environment.
787 * @param site The original type from where the selection takes place.
788 * @param name The name of the field.
789 * @param c The class to search for the field. This is always
790 * a superclass or implemented interface of site's class.
791 */
792 Symbol findField(Env<AttrContext> env,
793 Type site,
794 Name name,
795 TypeSymbol c) {
796 while (c.type.tag == TYPEVAR)
797 c = c.type.getUpperBound().tsym;
798 Symbol bestSoFar = varNotFound;
799 Symbol sym;
800 Scope.Entry e = c.members().lookup(name);
801 while (e.scope != null) {
802 if (e.sym.kind == VAR && (e.sym.flags_field & SYNTHETIC) == 0) {
803 return isAccessible(env, site, e.sym)
804 ? e.sym : new AccessError(env, site, e.sym);
805 }
806 e = e.next();
807 }
808 Type st = types.supertype(c.type);
809 if (st != null && (st.tag == CLASS || st.tag == TYPEVAR)) {
810 sym = findField(env, site, name, st.tsym);
811 if (sym.kind < bestSoFar.kind) bestSoFar = sym;
812 }
813 for (List<Type> l = types.interfaces(c.type);
814 bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
815 l = l.tail) {
816 sym = findField(env, site, name, l.head.tsym);
817 if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS &&
818 sym.owner != bestSoFar.owner)
819 bestSoFar = new AmbiguityError(bestSoFar, sym);
820 else if (sym.kind < bestSoFar.kind)
821 bestSoFar = sym;
822 }
823 return bestSoFar;
824 }
826 /** Resolve a field identifier, throw a fatal error if not found.
827 * @param pos The position to use for error reporting.
828 * @param env The environment current at the method invocation.
829 * @param site The type of the qualifying expression, in which
830 * identifier is searched.
831 * @param name The identifier's name.
832 */
833 public VarSymbol resolveInternalField(DiagnosticPosition pos, Env<AttrContext> env,
834 Type site, Name name) {
835 Symbol sym = findField(env, site, name, site.tsym);
836 if (sym.kind == VAR) return (VarSymbol)sym;
837 else throw new FatalError(
838 diags.fragment("fatal.err.cant.locate.field",
839 name));
840 }
842 /** Find unqualified variable or field with given name.
843 * Synthetic fields always skipped.
844 * @param env The current environment.
845 * @param name The name of the variable or field.
846 */
847 Symbol findVar(Env<AttrContext> env, Name name) {
848 Symbol bestSoFar = varNotFound;
849 Symbol sym;
850 Env<AttrContext> env1 = env;
851 boolean staticOnly = false;
852 while (env1.outer != null) {
853 if (isStatic(env1)) staticOnly = true;
854 Scope.Entry e = env1.info.scope.lookup(name);
855 while (e.scope != null &&
856 (e.sym.kind != VAR ||
857 (e.sym.flags_field & SYNTHETIC) != 0))
858 e = e.next();
859 sym = (e.scope != null)
860 ? e.sym
861 : findField(
862 env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
863 if (sym.exists()) {
864 if (staticOnly &&
865 sym.kind == VAR &&
866 sym.owner.kind == TYP &&
867 (sym.flags() & STATIC) == 0)
868 return new StaticError(sym);
869 else
870 return sym;
871 } else if (sym.kind < bestSoFar.kind) {
872 bestSoFar = sym;
873 }
875 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
876 env1 = env1.outer;
877 }
879 sym = findField(env, syms.predefClass.type, name, syms.predefClass);
880 if (sym.exists())
881 return sym;
882 if (bestSoFar.exists())
883 return bestSoFar;
885 Scope.Entry e = env.toplevel.namedImportScope.lookup(name);
886 for (; e.scope != null; e = e.next()) {
887 sym = e.sym;
888 Type origin = e.getOrigin().owner.type;
889 if (sym.kind == VAR) {
890 if (e.sym.owner.type != origin)
891 sym = sym.clone(e.getOrigin().owner);
892 return isAccessible(env, origin, sym)
893 ? sym : new AccessError(env, origin, sym);
894 }
895 }
897 Symbol origin = null;
898 e = env.toplevel.starImportScope.lookup(name);
899 for (; e.scope != null; e = e.next()) {
900 sym = e.sym;
901 if (sym.kind != VAR)
902 continue;
903 // invariant: sym.kind == VAR
904 if (bestSoFar.kind < AMBIGUOUS && sym.owner != bestSoFar.owner)
905 return new AmbiguityError(bestSoFar, sym);
906 else if (bestSoFar.kind >= VAR) {
907 origin = e.getOrigin().owner;
908 bestSoFar = isAccessible(env, origin.type, sym)
909 ? sym : new AccessError(env, origin.type, sym);
910 }
911 }
912 if (bestSoFar.kind == VAR && bestSoFar.owner.type != origin.type)
913 return bestSoFar.clone(origin);
914 else
915 return bestSoFar;
916 }
918 Warner noteWarner = new Warner();
920 /** Select the best method for a call site among two choices.
921 * @param env The current environment.
922 * @param site The original type from where the
923 * selection takes place.
924 * @param argtypes The invocation's value arguments,
925 * @param typeargtypes The invocation's type arguments,
926 * @param sym Proposed new best match.
927 * @param bestSoFar Previously found best match.
928 * @param allowBoxing Allow boxing conversions of arguments.
929 * @param useVarargs Box trailing arguments into an array for varargs.
930 */
931 @SuppressWarnings("fallthrough")
932 Symbol selectBest(Env<AttrContext> env,
933 Type site,
934 List<Type> argtypes,
935 List<Type> typeargtypes,
936 Symbol sym,
937 Symbol bestSoFar,
938 boolean allowBoxing,
939 boolean useVarargs,
940 boolean operator) {
941 if (sym.kind == ERR) return bestSoFar;
942 if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar;
943 Assert.check(sym.kind < AMBIGUOUS);
944 try {
945 Type mt = rawInstantiate(env, site, sym, argtypes, typeargtypes,
946 allowBoxing, useVarargs, Warner.noWarnings);
947 if (!operator)
948 currentResolutionContext.addApplicableCandidate(sym, mt);
949 } catch (InapplicableMethodException ex) {
950 if (!operator)
951 currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic());
952 switch (bestSoFar.kind) {
953 case ABSENT_MTH:
954 return wrongMethod;
955 case WRONG_MTH:
956 if (operator) return bestSoFar;
957 case WRONG_MTHS:
958 return wrongMethods;
959 default:
960 return bestSoFar;
961 }
962 }
963 if (!isAccessible(env, site, sym)) {
964 return (bestSoFar.kind == ABSENT_MTH)
965 ? new AccessError(env, site, sym)
966 : bestSoFar;
967 }
968 return (bestSoFar.kind > AMBIGUOUS)
969 ? sym
970 : mostSpecific(sym, bestSoFar, env, site,
971 allowBoxing && operator, useVarargs);
972 }
974 /* Return the most specific of the two methods for a call,
975 * given that both are accessible and applicable.
976 * @param m1 A new candidate for most specific.
977 * @param m2 The previous most specific candidate.
978 * @param env The current environment.
979 * @param site The original type from where the selection
980 * takes place.
981 * @param allowBoxing Allow boxing conversions of arguments.
982 * @param useVarargs Box trailing arguments into an array for varargs.
983 */
984 Symbol mostSpecific(Symbol m1,
985 Symbol m2,
986 Env<AttrContext> env,
987 final Type site,
988 boolean allowBoxing,
989 boolean useVarargs) {
990 switch (m2.kind) {
991 case MTH:
992 if (m1 == m2) return m1;
993 boolean m1SignatureMoreSpecific = signatureMoreSpecific(env, site, m1, m2, allowBoxing, useVarargs);
994 boolean m2SignatureMoreSpecific = signatureMoreSpecific(env, site, m2, m1, allowBoxing, useVarargs);
995 if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) {
996 Type mt1 = types.memberType(site, m1);
997 Type mt2 = types.memberType(site, m2);
998 if (!types.overrideEquivalent(mt1, mt2))
999 return ambiguityError(m1, m2);
1001 // same signature; select (a) the non-bridge method, or
1002 // (b) the one that overrides the other, or (c) the concrete
1003 // one, or (d) merge both abstract signatures
1004 if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE))
1005 return ((m1.flags() & BRIDGE) != 0) ? m2 : m1;
1007 // if one overrides or hides the other, use it
1008 TypeSymbol m1Owner = (TypeSymbol)m1.owner;
1009 TypeSymbol m2Owner = (TypeSymbol)m2.owner;
1010 if (types.asSuper(m1Owner.type, m2Owner) != null &&
1011 ((m1.owner.flags_field & INTERFACE) == 0 ||
1012 (m2.owner.flags_field & INTERFACE) != 0) &&
1013 m1.overrides(m2, m1Owner, types, false))
1014 return m1;
1015 if (types.asSuper(m2Owner.type, m1Owner) != null &&
1016 ((m2.owner.flags_field & INTERFACE) == 0 ||
1017 (m1.owner.flags_field & INTERFACE) != 0) &&
1018 m2.overrides(m1, m2Owner, types, false))
1019 return m2;
1020 boolean m1Abstract = (m1.flags() & ABSTRACT) != 0;
1021 boolean m2Abstract = (m2.flags() & ABSTRACT) != 0;
1022 if (m1Abstract && !m2Abstract) return m2;
1023 if (m2Abstract && !m1Abstract) return m1;
1024 // both abstract or both concrete
1025 if (!m1Abstract && !m2Abstract)
1026 return ambiguityError(m1, m2);
1027 // check that both signatures have the same erasure
1028 if (!types.isSameTypes(m1.erasure(types).getParameterTypes(),
1029 m2.erasure(types).getParameterTypes()))
1030 return ambiguityError(m1, m2);
1031 // both abstract, neither overridden; merge throws clause and result type
1032 Type mst = mostSpecificReturnType(mt1, mt2);
1033 if (mst == null) {
1034 // Theoretically, this can't happen, but it is possible
1035 // due to error recovery or mixing incompatible class files
1036 return ambiguityError(m1, m2);
1037 }
1038 Symbol mostSpecific = mst == mt1 ? m1 : m2;
1039 List<Type> allThrown = chk.intersect(mt1.getThrownTypes(), mt2.getThrownTypes());
1040 Type newSig = types.createMethodTypeWithThrown(mostSpecific.type, allThrown);
1041 MethodSymbol result = new MethodSymbol(
1042 mostSpecific.flags(),
1043 mostSpecific.name,
1044 newSig,
1045 mostSpecific.owner) {
1046 @Override
1047 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
1048 if (origin == site.tsym)
1049 return this;
1050 else
1051 return super.implementation(origin, types, checkResult);
1052 }
1053 };
1054 return result;
1055 }
1056 if (m1SignatureMoreSpecific) return m1;
1057 if (m2SignatureMoreSpecific) return m2;
1058 return ambiguityError(m1, m2);
1059 case AMBIGUOUS:
1060 AmbiguityError e = (AmbiguityError)m2;
1061 Symbol err1 = mostSpecific(m1, e.sym, env, site, allowBoxing, useVarargs);
1062 Symbol err2 = mostSpecific(m1, e.sym2, env, site, allowBoxing, useVarargs);
1063 if (err1 == err2) return err1;
1064 if (err1 == e.sym && err2 == e.sym2) return m2;
1065 if (err1 instanceof AmbiguityError &&
1066 err2 instanceof AmbiguityError &&
1067 ((AmbiguityError)err1).sym == ((AmbiguityError)err2).sym)
1068 return ambiguityError(m1, m2);
1069 else
1070 return ambiguityError(err1, err2);
1071 default:
1072 throw new AssertionError();
1073 }
1074 }
1075 //where
1076 private boolean signatureMoreSpecific(Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean allowBoxing, boolean useVarargs) {
1077 noteWarner.clear();
1078 Type mtype1 = types.memberType(site, adjustVarargs(m1, m2, useVarargs));
1079 Type mtype2 = instantiate(env, site, adjustVarargs(m2, m1, useVarargs),
1080 types.lowerBoundArgtypes(mtype1), null,
1081 allowBoxing, false, noteWarner);
1082 return mtype2 != null &&
1083 !noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
1084 }
1085 //where
1086 private Symbol adjustVarargs(Symbol to, Symbol from, boolean useVarargs) {
1087 List<Type> fromArgs = from.type.getParameterTypes();
1088 List<Type> toArgs = to.type.getParameterTypes();
1089 if (useVarargs &&
1090 (from.flags() & VARARGS) != 0 &&
1091 (to.flags() & VARARGS) != 0) {
1092 Type varargsTypeFrom = fromArgs.last();
1093 Type varargsTypeTo = toArgs.last();
1094 ListBuffer<Type> args = ListBuffer.lb();
1095 if (toArgs.length() < fromArgs.length()) {
1096 //if we are checking a varargs method 'from' against another varargs
1097 //method 'to' (where arity of 'to' < arity of 'from') then expand signature
1098 //of 'to' to 'fit' arity of 'from' (this means adding fake formals to 'to'
1099 //until 'to' signature has the same arity as 'from')
1100 while (fromArgs.head != varargsTypeFrom) {
1101 args.append(toArgs.head == varargsTypeTo ? types.elemtype(varargsTypeTo) : toArgs.head);
1102 fromArgs = fromArgs.tail;
1103 toArgs = toArgs.head == varargsTypeTo ?
1104 toArgs :
1105 toArgs.tail;
1106 }
1107 } else {
1108 //formal argument list is same as original list where last
1109 //argument (array type) is removed
1110 args.appendList(toArgs.reverse().tail.reverse());
1111 }
1112 //append varargs element type as last synthetic formal
1113 args.append(types.elemtype(varargsTypeTo));
1114 Type mtype = types.createMethodTypeWithParameters(to.type, args.toList());
1115 return new MethodSymbol(to.flags_field & ~VARARGS, to.name, mtype, to.owner);
1116 } else {
1117 return to;
1118 }
1119 }
1120 //where
1121 Type mostSpecificReturnType(Type mt1, Type mt2) {
1122 Type rt1 = mt1.getReturnType();
1123 Type rt2 = mt2.getReturnType();
1125 if (mt1.tag == FORALL && mt2.tag == FORALL) {
1126 //if both are generic methods, adjust return type ahead of subtyping check
1127 rt1 = types.subst(rt1, mt1.getTypeArguments(), mt2.getTypeArguments());
1128 }
1129 //first use subtyping, then return type substitutability
1130 if (types.isSubtype(rt1, rt2)) {
1131 return mt1;
1132 } else if (types.isSubtype(rt2, rt1)) {
1133 return mt2;
1134 } else if (types.returnTypeSubstitutable(mt1, mt2)) {
1135 return mt1;
1136 } else if (types.returnTypeSubstitutable(mt2, mt1)) {
1137 return mt2;
1138 } else {
1139 return null;
1140 }
1141 }
1142 //where
1143 Symbol ambiguityError(Symbol m1, Symbol m2) {
1144 if (((m1.flags() | m2.flags()) & CLASH) != 0) {
1145 return (m1.flags() & CLASH) == 0 ? m1 : m2;
1146 } else {
1147 return new AmbiguityError(m1, m2);
1148 }
1149 }
1151 /** Find best qualified method matching given name, type and value
1152 * arguments.
1153 * @param env The current environment.
1154 * @param site The original type from where the selection
1155 * takes place.
1156 * @param name The method's name.
1157 * @param argtypes The method's value arguments.
1158 * @param typeargtypes The method's type arguments
1159 * @param allowBoxing Allow boxing conversions of arguments.
1160 * @param useVarargs Box trailing arguments into an array for varargs.
1161 */
1162 Symbol findMethod(Env<AttrContext> env,
1163 Type site,
1164 Name name,
1165 List<Type> argtypes,
1166 List<Type> typeargtypes,
1167 boolean allowBoxing,
1168 boolean useVarargs,
1169 boolean operator) {
1170 Symbol bestSoFar = methodNotFound;
1171 bestSoFar = findMethod(env,
1172 site,
1173 name,
1174 argtypes,
1175 typeargtypes,
1176 site.tsym.type,
1177 true,
1178 bestSoFar,
1179 allowBoxing,
1180 useVarargs,
1181 operator,
1182 new HashSet<TypeSymbol>());
1183 reportVerboseResolutionDiagnostic(env.tree.pos(), name, site, argtypes, typeargtypes, bestSoFar);
1184 return bestSoFar;
1185 }
1186 // where
1187 private Symbol findMethod(Env<AttrContext> env,
1188 Type site,
1189 Name name,
1190 List<Type> argtypes,
1191 List<Type> typeargtypes,
1192 Type intype,
1193 boolean abstractok,
1194 Symbol bestSoFar,
1195 boolean allowBoxing,
1196 boolean useVarargs,
1197 boolean operator,
1198 Set<TypeSymbol> seen) {
1199 for (Type ct = intype; ct.tag == CLASS || ct.tag == TYPEVAR; ct = types.supertype(ct)) {
1200 while (ct.tag == TYPEVAR)
1201 ct = ct.getUpperBound();
1202 ClassSymbol c = (ClassSymbol)ct.tsym;
1203 if (!seen.add(c)) return bestSoFar;
1204 if ((c.flags() & (ABSTRACT | INTERFACE | ENUM)) == 0)
1205 abstractok = false;
1206 for (Scope.Entry e = c.members().lookup(name);
1207 e.scope != null;
1208 e = e.next()) {
1209 //- System.out.println(" e " + e.sym);
1210 if (e.sym.kind == MTH &&
1211 (e.sym.flags_field & SYNTHETIC) == 0) {
1212 bestSoFar = selectBest(env, site, argtypes, typeargtypes,
1213 e.sym, bestSoFar,
1214 allowBoxing,
1215 useVarargs,
1216 operator);
1217 }
1218 }
1219 if (name == names.init)
1220 break;
1221 //- System.out.println(" - " + bestSoFar);
1222 if (abstractok) {
1223 Symbol concrete = methodNotFound;
1224 if ((bestSoFar.flags() & ABSTRACT) == 0)
1225 concrete = bestSoFar;
1226 for (List<Type> l = types.interfaces(c.type);
1227 l.nonEmpty();
1228 l = l.tail) {
1229 bestSoFar = findMethod(env, site, name, argtypes,
1230 typeargtypes,
1231 l.head, abstractok, bestSoFar,
1232 allowBoxing, useVarargs, operator, seen);
1233 }
1234 if (concrete != bestSoFar &&
1235 concrete.kind < ERR && bestSoFar.kind < ERR &&
1236 types.isSubSignature(concrete.type, bestSoFar.type))
1237 bestSoFar = concrete;
1238 }
1239 }
1240 return bestSoFar;
1241 }
1243 /** Find unqualified method matching given name, type and value arguments.
1244 * @param env The current environment.
1245 * @param name The method's name.
1246 * @param argtypes The method's value arguments.
1247 * @param typeargtypes The method's type arguments.
1248 * @param allowBoxing Allow boxing conversions of arguments.
1249 * @param useVarargs Box trailing arguments into an array for varargs.
1250 */
1251 Symbol findFun(Env<AttrContext> env, Name name,
1252 List<Type> argtypes, List<Type> typeargtypes,
1253 boolean allowBoxing, boolean useVarargs) {
1254 Symbol bestSoFar = methodNotFound;
1255 Symbol sym;
1256 Env<AttrContext> env1 = env;
1257 boolean staticOnly = false;
1258 while (env1.outer != null) {
1259 if (isStatic(env1)) staticOnly = true;
1260 sym = findMethod(
1261 env1, env1.enclClass.sym.type, name, argtypes, typeargtypes,
1262 allowBoxing, useVarargs, false);
1263 if (sym.exists()) {
1264 if (staticOnly &&
1265 sym.kind == MTH &&
1266 sym.owner.kind == TYP &&
1267 (sym.flags() & STATIC) == 0) return new StaticError(sym);
1268 else return sym;
1269 } else if (sym.kind < bestSoFar.kind) {
1270 bestSoFar = sym;
1271 }
1272 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
1273 env1 = env1.outer;
1274 }
1276 sym = findMethod(env, syms.predefClass.type, name, argtypes,
1277 typeargtypes, allowBoxing, useVarargs, false);
1278 if (sym.exists())
1279 return sym;
1281 Scope.Entry e = env.toplevel.namedImportScope.lookup(name);
1282 for (; e.scope != null; e = e.next()) {
1283 sym = e.sym;
1284 Type origin = e.getOrigin().owner.type;
1285 if (sym.kind == MTH) {
1286 if (e.sym.owner.type != origin)
1287 sym = sym.clone(e.getOrigin().owner);
1288 if (!isAccessible(env, origin, sym))
1289 sym = new AccessError(env, origin, sym);
1290 bestSoFar = selectBest(env, origin,
1291 argtypes, typeargtypes,
1292 sym, bestSoFar,
1293 allowBoxing, useVarargs, false);
1294 }
1295 }
1296 if (bestSoFar.exists())
1297 return bestSoFar;
1299 e = env.toplevel.starImportScope.lookup(name);
1300 for (; e.scope != null; e = e.next()) {
1301 sym = e.sym;
1302 Type origin = e.getOrigin().owner.type;
1303 if (sym.kind == MTH) {
1304 if (e.sym.owner.type != origin)
1305 sym = sym.clone(e.getOrigin().owner);
1306 if (!isAccessible(env, origin, sym))
1307 sym = new AccessError(env, origin, sym);
1308 bestSoFar = selectBest(env, origin,
1309 argtypes, typeargtypes,
1310 sym, bestSoFar,
1311 allowBoxing, useVarargs, false);
1312 }
1313 }
1314 return bestSoFar;
1315 }
1317 /** Load toplevel or member class with given fully qualified name and
1318 * verify that it is accessible.
1319 * @param env The current environment.
1320 * @param name The fully qualified name of the class to be loaded.
1321 */
1322 Symbol loadClass(Env<AttrContext> env, Name name) {
1323 try {
1324 ClassSymbol c = reader.loadClass(name);
1325 return isAccessible(env, c) ? c : new AccessError(c);
1326 } catch (ClassReader.BadClassFile err) {
1327 throw err;
1328 } catch (CompletionFailure ex) {
1329 return typeNotFound;
1330 }
1331 }
1333 /** Find qualified member type.
1334 * @param env The current environment.
1335 * @param site The original type from where the selection takes
1336 * place.
1337 * @param name The type's name.
1338 * @param c The class to search for the member type. This is
1339 * always a superclass or implemented interface of
1340 * site's class.
1341 */
1342 Symbol findMemberType(Env<AttrContext> env,
1343 Type site,
1344 Name name,
1345 TypeSymbol c) {
1346 Symbol bestSoFar = typeNotFound;
1347 Symbol sym;
1348 Scope.Entry e = c.members().lookup(name);
1349 while (e.scope != null) {
1350 if (e.sym.kind == TYP) {
1351 return isAccessible(env, site, e.sym)
1352 ? e.sym
1353 : new AccessError(env, site, e.sym);
1354 }
1355 e = e.next();
1356 }
1357 Type st = types.supertype(c.type);
1358 if (st != null && st.tag == CLASS) {
1359 sym = findMemberType(env, site, name, st.tsym);
1360 if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1361 }
1362 for (List<Type> l = types.interfaces(c.type);
1363 bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
1364 l = l.tail) {
1365 sym = findMemberType(env, site, name, l.head.tsym);
1366 if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS &&
1367 sym.owner != bestSoFar.owner)
1368 bestSoFar = new AmbiguityError(bestSoFar, sym);
1369 else if (sym.kind < bestSoFar.kind)
1370 bestSoFar = sym;
1371 }
1372 return bestSoFar;
1373 }
1375 /** Find a global type in given scope and load corresponding class.
1376 * @param env The current environment.
1377 * @param scope The scope in which to look for the type.
1378 * @param name The type's name.
1379 */
1380 Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) {
1381 Symbol bestSoFar = typeNotFound;
1382 for (Scope.Entry e = scope.lookup(name); e.scope != null; e = e.next()) {
1383 Symbol sym = loadClass(env, e.sym.flatName());
1384 if (bestSoFar.kind == TYP && sym.kind == TYP &&
1385 bestSoFar != sym)
1386 return new AmbiguityError(bestSoFar, sym);
1387 else if (sym.kind < bestSoFar.kind)
1388 bestSoFar = sym;
1389 }
1390 return bestSoFar;
1391 }
1393 /** Find an unqualified type symbol.
1394 * @param env The current environment.
1395 * @param name The type's name.
1396 */
1397 Symbol findType(Env<AttrContext> env, Name name) {
1398 Symbol bestSoFar = typeNotFound;
1399 Symbol sym;
1400 boolean staticOnly = false;
1401 for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) {
1402 if (isStatic(env1)) staticOnly = true;
1403 for (Scope.Entry e = env1.info.scope.lookup(name);
1404 e.scope != null;
1405 e = e.next()) {
1406 if (e.sym.kind == TYP) {
1407 if (staticOnly &&
1408 e.sym.type.tag == TYPEVAR &&
1409 e.sym.owner.kind == TYP) return new StaticError(e.sym);
1410 return e.sym;
1411 }
1412 }
1414 sym = findMemberType(env1, env1.enclClass.sym.type, name,
1415 env1.enclClass.sym);
1416 if (staticOnly && sym.kind == TYP &&
1417 sym.type.tag == CLASS &&
1418 sym.type.getEnclosingType().tag == CLASS &&
1419 env1.enclClass.sym.type.isParameterized() &&
1420 sym.type.getEnclosingType().isParameterized())
1421 return new StaticError(sym);
1422 else if (sym.exists()) return sym;
1423 else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1425 JCClassDecl encl = env1.baseClause ? (JCClassDecl)env1.tree : env1.enclClass;
1426 if ((encl.sym.flags() & STATIC) != 0)
1427 staticOnly = true;
1428 }
1430 if (!env.tree.hasTag(IMPORT)) {
1431 sym = findGlobalType(env, env.toplevel.namedImportScope, name);
1432 if (sym.exists()) return sym;
1433 else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1435 sym = findGlobalType(env, env.toplevel.packge.members(), name);
1436 if (sym.exists()) return sym;
1437 else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1439 sym = findGlobalType(env, env.toplevel.starImportScope, name);
1440 if (sym.exists()) return sym;
1441 else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1442 }
1444 return bestSoFar;
1445 }
1447 /** Find an unqualified identifier which matches a specified kind set.
1448 * @param env The current environment.
1449 * @param name The indentifier's name.
1450 * @param kind Indicates the possible symbol kinds
1451 * (a subset of VAL, TYP, PCK).
1452 */
1453 Symbol findIdent(Env<AttrContext> env, Name name, int kind) {
1454 Symbol bestSoFar = typeNotFound;
1455 Symbol sym;
1457 if ((kind & VAR) != 0) {
1458 sym = findVar(env, name);
1459 if (sym.exists()) return sym;
1460 else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1461 }
1463 if ((kind & TYP) != 0) {
1464 sym = findType(env, name);
1465 if (sym.exists()) return sym;
1466 else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1467 }
1469 if ((kind & PCK) != 0) return reader.enterPackage(name);
1470 else return bestSoFar;
1471 }
1473 /** Find an identifier in a package which matches a specified kind set.
1474 * @param env The current environment.
1475 * @param name The identifier's name.
1476 * @param kind Indicates the possible symbol kinds
1477 * (a nonempty subset of TYP, PCK).
1478 */
1479 Symbol findIdentInPackage(Env<AttrContext> env, TypeSymbol pck,
1480 Name name, int kind) {
1481 Name fullname = TypeSymbol.formFullName(name, pck);
1482 Symbol bestSoFar = typeNotFound;
1483 PackageSymbol pack = null;
1484 if ((kind & PCK) != 0) {
1485 pack = reader.enterPackage(fullname);
1486 if (pack.exists()) return pack;
1487 }
1488 if ((kind & TYP) != 0) {
1489 Symbol sym = loadClass(env, fullname);
1490 if (sym.exists()) {
1491 // don't allow programs to use flatnames
1492 if (name == sym.name) return sym;
1493 }
1494 else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1495 }
1496 return (pack != null) ? pack : bestSoFar;
1497 }
1499 /** Find an identifier among the members of a given type `site'.
1500 * @param env The current environment.
1501 * @param site The type containing the symbol to be found.
1502 * @param name The identifier's name.
1503 * @param kind Indicates the possible symbol kinds
1504 * (a subset of VAL, TYP).
1505 */
1506 Symbol findIdentInType(Env<AttrContext> env, Type site,
1507 Name name, int kind) {
1508 Symbol bestSoFar = typeNotFound;
1509 Symbol sym;
1510 if ((kind & VAR) != 0) {
1511 sym = findField(env, site, name, site.tsym);
1512 if (sym.exists()) return sym;
1513 else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1514 }
1516 if ((kind & TYP) != 0) {
1517 sym = findMemberType(env, site, name, site.tsym);
1518 if (sym.exists()) return sym;
1519 else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1520 }
1521 return bestSoFar;
1522 }
1524 /* ***************************************************************************
1525 * Access checking
1526 * The following methods convert ResolveErrors to ErrorSymbols, issuing
1527 * an error message in the process
1528 ****************************************************************************/
1530 /** If `sym' is a bad symbol: report error and return errSymbol
1531 * else pass through unchanged,
1532 * additional arguments duplicate what has been used in trying to find the
1533 * symbol (--> flyweight pattern). This improves performance since we
1534 * expect misses to happen frequently.
1535 *
1536 * @param sym The symbol that was found, or a ResolveError.
1537 * @param pos The position to use for error reporting.
1538 * @param site The original type from where the selection took place.
1539 * @param name The symbol's name.
1540 * @param argtypes The invocation's value arguments,
1541 * if we looked for a method.
1542 * @param typeargtypes The invocation's type arguments,
1543 * if we looked for a method.
1544 */
1545 Symbol access(Symbol sym,
1546 DiagnosticPosition pos,
1547 Symbol location,
1548 Type site,
1549 Name name,
1550 boolean qualified,
1551 List<Type> argtypes,
1552 List<Type> typeargtypes) {
1553 if (sym.kind >= AMBIGUOUS) {
1554 ResolveError errSym = (ResolveError)sym;
1555 if (!site.isErroneous() &&
1556 !Type.isErroneous(argtypes) &&
1557 (typeargtypes==null || !Type.isErroneous(typeargtypes)))
1558 logResolveError(errSym, pos, location, site, name, argtypes, typeargtypes);
1559 sym = errSym.access(name, qualified ? site.tsym : syms.noSymbol);
1560 }
1561 return sym;
1562 }
1564 /** Same as original access(), but without location.
1565 */
1566 Symbol access(Symbol sym,
1567 DiagnosticPosition pos,
1568 Type site,
1569 Name name,
1570 boolean qualified,
1571 List<Type> argtypes,
1572 List<Type> typeargtypes) {
1573 return access(sym, pos, site.tsym, site, name, qualified, argtypes, typeargtypes);
1574 }
1576 /** Same as original access(), but without type arguments and arguments.
1577 */
1578 Symbol access(Symbol sym,
1579 DiagnosticPosition pos,
1580 Symbol location,
1581 Type site,
1582 Name name,
1583 boolean qualified) {
1584 if (sym.kind >= AMBIGUOUS)
1585 return access(sym, pos, location, site, name, qualified, List.<Type>nil(), null);
1586 else
1587 return sym;
1588 }
1590 /** Same as original access(), but without location, type arguments and arguments.
1591 */
1592 Symbol access(Symbol sym,
1593 DiagnosticPosition pos,
1594 Type site,
1595 Name name,
1596 boolean qualified) {
1597 return access(sym, pos, site.tsym, site, name, qualified);
1598 }
1600 /** Check that sym is not an abstract method.
1601 */
1602 void checkNonAbstract(DiagnosticPosition pos, Symbol sym) {
1603 if ((sym.flags() & ABSTRACT) != 0)
1604 log.error(pos, "abstract.cant.be.accessed.directly",
1605 kindName(sym), sym, sym.location());
1606 }
1608 /* ***************************************************************************
1609 * Debugging
1610 ****************************************************************************/
1612 /** print all scopes starting with scope s and proceeding outwards.
1613 * used for debugging.
1614 */
1615 public void printscopes(Scope s) {
1616 while (s != null) {
1617 if (s.owner != null)
1618 System.err.print(s.owner + ": ");
1619 for (Scope.Entry e = s.elems; e != null; e = e.sibling) {
1620 if ((e.sym.flags() & ABSTRACT) != 0)
1621 System.err.print("abstract ");
1622 System.err.print(e.sym + " ");
1623 }
1624 System.err.println();
1625 s = s.next;
1626 }
1627 }
1629 void printscopes(Env<AttrContext> env) {
1630 while (env.outer != null) {
1631 System.err.println("------------------------------");
1632 printscopes(env.info.scope);
1633 env = env.outer;
1634 }
1635 }
1637 public void printscopes(Type t) {
1638 while (t.tag == CLASS) {
1639 printscopes(t.tsym.members());
1640 t = types.supertype(t);
1641 }
1642 }
1644 /* ***************************************************************************
1645 * Name resolution
1646 * Naming conventions are as for symbol lookup
1647 * Unlike the find... methods these methods will report access errors
1648 ****************************************************************************/
1650 /** Resolve an unqualified (non-method) identifier.
1651 * @param pos The position to use for error reporting.
1652 * @param env The environment current at the identifier use.
1653 * @param name The identifier's name.
1654 * @param kind The set of admissible symbol kinds for the identifier.
1655 */
1656 Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env,
1657 Name name, int kind) {
1658 return access(
1659 findIdent(env, name, kind),
1660 pos, env.enclClass.sym.type, name, false);
1661 }
1663 /** Resolve an unqualified method identifier.
1664 * @param pos The position to use for error reporting.
1665 * @param env The environment current at the method invocation.
1666 * @param name The identifier's name.
1667 * @param argtypes The types of the invocation's value arguments.
1668 * @param typeargtypes The types of the invocation's type arguments.
1669 */
1670 Symbol resolveMethod(DiagnosticPosition pos,
1671 Env<AttrContext> env,
1672 Name name,
1673 List<Type> argtypes,
1674 List<Type> typeargtypes) {
1675 MethodResolutionContext prevResolutionContext = currentResolutionContext;
1676 try {
1677 currentResolutionContext = new MethodResolutionContext();
1678 Symbol sym = methodNotFound;
1679 List<MethodResolutionPhase> steps = methodResolutionSteps;
1680 while (steps.nonEmpty() &&
1681 steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
1682 sym.kind >= ERRONEOUS) {
1683 currentResolutionContext.step = steps.head;
1684 sym = findFun(env, name, argtypes, typeargtypes,
1685 steps.head.isBoxingRequired,
1686 env.info.varArgs = steps.head.isVarargsRequired);
1687 currentResolutionContext.resolutionCache.put(steps.head, sym);
1688 steps = steps.tail;
1689 }
1690 if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
1691 MethodResolutionPhase errPhase =
1692 currentResolutionContext.firstErroneousResolutionPhase();
1693 sym = access(currentResolutionContext.resolutionCache.get(errPhase),
1694 pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes);
1695 env.info.varArgs = errPhase.isVarargsRequired;
1696 }
1697 return sym;
1698 }
1699 finally {
1700 currentResolutionContext = prevResolutionContext;
1701 }
1702 }
1704 /** Resolve a qualified method identifier
1705 * @param pos The position to use for error reporting.
1706 * @param env The environment current at the method invocation.
1707 * @param site The type of the qualifying expression, in which
1708 * identifier is searched.
1709 * @param name The identifier's name.
1710 * @param argtypes The types of the invocation's value arguments.
1711 * @param typeargtypes The types of the invocation's type arguments.
1712 */
1713 Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
1714 Type site, Name name, List<Type> argtypes,
1715 List<Type> typeargtypes) {
1716 return resolveQualifiedMethod(pos, env, site.tsym, site, name, argtypes, typeargtypes);
1717 }
1718 Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
1719 Symbol location, Type site, Name name, List<Type> argtypes,
1720 List<Type> typeargtypes) {
1721 return resolveQualifiedMethod(new MethodResolutionContext(), pos, env, location, site, name, argtypes, typeargtypes);
1722 }
1723 private Symbol resolveQualifiedMethod(MethodResolutionContext resolveContext,
1724 DiagnosticPosition pos, Env<AttrContext> env,
1725 Symbol location, Type site, Name name, List<Type> argtypes,
1726 List<Type> typeargtypes) {
1727 MethodResolutionContext prevResolutionContext = currentResolutionContext;
1728 try {
1729 currentResolutionContext = resolveContext;
1730 Symbol sym = methodNotFound;
1731 List<MethodResolutionPhase> steps = methodResolutionSteps;
1732 while (steps.nonEmpty() &&
1733 steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
1734 sym.kind >= ERRONEOUS) {
1735 currentResolutionContext.step = steps.head;
1736 sym = findMethod(env, site, name, argtypes, typeargtypes,
1737 steps.head.isBoxingRequired(),
1738 env.info.varArgs = steps.head.isVarargsRequired(), false);
1739 currentResolutionContext.resolutionCache.put(steps.head, sym);
1740 steps = steps.tail;
1741 }
1742 if (sym.kind >= AMBIGUOUS) {
1743 if (site.tsym.isPolymorphicSignatureGeneric()) {
1744 //polymorphic receiver - synthesize new method symbol
1745 env.info.varArgs = false;
1746 sym = findPolymorphicSignatureInstance(env,
1747 site, name, null, argtypes);
1748 }
1749 else {
1750 //if nothing is found return the 'first' error
1751 MethodResolutionPhase errPhase =
1752 currentResolutionContext.firstErroneousResolutionPhase();
1753 sym = access(currentResolutionContext.resolutionCache.get(errPhase),
1754 pos, location, site, name, true, argtypes, typeargtypes);
1755 env.info.varArgs = errPhase.isVarargsRequired;
1756 }
1757 } else if (allowMethodHandles && sym.isPolymorphicSignatureGeneric()) {
1758 //non-instantiated polymorphic signature - synthesize new method symbol
1759 env.info.varArgs = false;
1760 sym = findPolymorphicSignatureInstance(env,
1761 site, name, (MethodSymbol)sym, argtypes);
1762 }
1763 return sym;
1764 }
1765 finally {
1766 currentResolutionContext = prevResolutionContext;
1767 }
1768 }
1770 /** Find or create an implicit method of exactly the given type (after erasure).
1771 * Searches in a side table, not the main scope of the site.
1772 * This emulates the lookup process required by JSR 292 in JVM.
1773 * @param env Attribution environment
1774 * @param site The original type from where the selection takes place.
1775 * @param name The method's name.
1776 * @param spMethod A template for the implicit method, or null.
1777 * @param argtypes The required argument types.
1778 * @param typeargtypes The required type arguments.
1779 */
1780 Symbol findPolymorphicSignatureInstance(Env<AttrContext> env, Type site,
1781 Name name,
1782 MethodSymbol spMethod, // sig. poly. method or null if none
1783 List<Type> argtypes) {
1784 Type mtype = infer.instantiatePolymorphicSignatureInstance(env,
1785 site, name, spMethod, argtypes);
1786 long flags = ABSTRACT | HYPOTHETICAL | POLYMORPHIC_SIGNATURE |
1787 (spMethod != null ?
1788 spMethod.flags() & Flags.AccessFlags :
1789 Flags.PUBLIC | Flags.STATIC);
1790 Symbol m = null;
1791 for (Scope.Entry e = polymorphicSignatureScope.lookup(name);
1792 e.scope != null;
1793 e = e.next()) {
1794 Symbol sym = e.sym;
1795 if (types.isSameType(mtype, sym.type) &&
1796 (sym.flags() & Flags.STATIC) == (flags & Flags.STATIC) &&
1797 types.isSameType(sym.owner.type, site)) {
1798 m = sym;
1799 break;
1800 }
1801 }
1802 if (m == null) {
1803 // create the desired method
1804 m = new MethodSymbol(flags, name, mtype, site.tsym);
1805 polymorphicSignatureScope.enter(m);
1806 }
1807 return m;
1808 }
1810 /** Resolve a qualified method identifier, throw a fatal error if not
1811 * found.
1812 * @param pos The position to use for error reporting.
1813 * @param env The environment current at the method invocation.
1814 * @param site The type of the qualifying expression, in which
1815 * identifier is searched.
1816 * @param name The identifier's name.
1817 * @param argtypes The types of the invocation's value arguments.
1818 * @param typeargtypes The types of the invocation's type arguments.
1819 */
1820 public MethodSymbol resolveInternalMethod(DiagnosticPosition pos, Env<AttrContext> env,
1821 Type site, Name name,
1822 List<Type> argtypes,
1823 List<Type> typeargtypes) {
1824 MethodResolutionContext resolveContext = new MethodResolutionContext();
1825 resolveContext.internalResolution = true;
1826 Symbol sym = resolveQualifiedMethod(resolveContext, pos, env, site.tsym,
1827 site, name, argtypes, typeargtypes);
1828 if (sym.kind == MTH) return (MethodSymbol)sym;
1829 else throw new FatalError(
1830 diags.fragment("fatal.err.cant.locate.meth",
1831 name));
1832 }
1834 /** Resolve constructor.
1835 * @param pos The position to use for error reporting.
1836 * @param env The environment current at the constructor invocation.
1837 * @param site The type of class for which a constructor is searched.
1838 * @param argtypes The types of the constructor invocation's value
1839 * arguments.
1840 * @param typeargtypes The types of the constructor invocation's type
1841 * arguments.
1842 */
1843 Symbol resolveConstructor(DiagnosticPosition pos,
1844 Env<AttrContext> env,
1845 Type site,
1846 List<Type> argtypes,
1847 List<Type> typeargtypes) {
1848 return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes);
1849 }
1850 private Symbol resolveConstructor(MethodResolutionContext resolveContext,
1851 DiagnosticPosition pos,
1852 Env<AttrContext> env,
1853 Type site,
1854 List<Type> argtypes,
1855 List<Type> typeargtypes) {
1856 MethodResolutionContext prevResolutionContext = currentResolutionContext;
1857 try {
1858 currentResolutionContext = resolveContext;
1859 Symbol sym = methodNotFound;
1860 List<MethodResolutionPhase> steps = methodResolutionSteps;
1861 while (steps.nonEmpty() &&
1862 steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
1863 sym.kind >= ERRONEOUS) {
1864 currentResolutionContext.step = steps.head;
1865 sym = findConstructor(pos, env, site, argtypes, typeargtypes,
1866 steps.head.isBoxingRequired(),
1867 env.info.varArgs = steps.head.isVarargsRequired());
1868 currentResolutionContext.resolutionCache.put(steps.head, sym);
1869 steps = steps.tail;
1870 }
1871 if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
1872 MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase();
1873 sym = access(currentResolutionContext.resolutionCache.get(errPhase),
1874 pos, site, names.init, true, argtypes, typeargtypes);
1875 env.info.varArgs = errPhase.isVarargsRequired();
1876 }
1877 return sym;
1878 }
1879 finally {
1880 currentResolutionContext = prevResolutionContext;
1881 }
1882 }
1884 /** Resolve constructor using diamond inference.
1885 * @param pos The position to use for error reporting.
1886 * @param env The environment current at the constructor invocation.
1887 * @param site The type of class for which a constructor is searched.
1888 * The scope of this class has been touched in attribution.
1889 * @param argtypes The types of the constructor invocation's value
1890 * arguments.
1891 * @param typeargtypes The types of the constructor invocation's type
1892 * arguments.
1893 */
1894 Symbol resolveDiamond(DiagnosticPosition pos,
1895 Env<AttrContext> env,
1896 Type site,
1897 List<Type> argtypes,
1898 List<Type> typeargtypes) {
1899 MethodResolutionContext prevResolutionContext = currentResolutionContext;
1900 try {
1901 currentResolutionContext = new MethodResolutionContext();
1902 Symbol sym = methodNotFound;
1903 List<MethodResolutionPhase> steps = methodResolutionSteps;
1904 while (steps.nonEmpty() &&
1905 steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
1906 sym.kind >= ERRONEOUS) {
1907 currentResolutionContext.step = steps.head;
1908 sym = findDiamond(env, site, argtypes, typeargtypes,
1909 steps.head.isBoxingRequired(),
1910 env.info.varArgs = steps.head.isVarargsRequired());
1911 currentResolutionContext.resolutionCache.put(steps.head, sym);
1912 steps = steps.tail;
1913 }
1914 if (sym.kind >= AMBIGUOUS) {
1915 final JCDiagnostic details = sym.kind == WRONG_MTH ?
1916 currentResolutionContext.candidates.head.details :
1917 null;
1918 Symbol errSym = new ResolveError(WRONG_MTH, "diamond error") {
1919 @Override
1920 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
1921 Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
1922 String key = details == null ?
1923 "cant.apply.diamond" :
1924 "cant.apply.diamond.1";
1925 return diags.create(dkind, log.currentSource(), pos, key,
1926 diags.fragment("diamond", site.tsym), details);
1927 }
1928 };
1929 MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase();
1930 sym = access(errSym, pos, site, names.init, true, argtypes, typeargtypes);
1931 env.info.varArgs = errPhase.isVarargsRequired();
1932 }
1933 return sym;
1934 }
1935 finally {
1936 currentResolutionContext = prevResolutionContext;
1937 }
1938 }
1940 /** This method scans all the constructor symbol in a given class scope -
1941 * assuming that the original scope contains a constructor of the kind:
1942 * Foo(X x, Y y), where X,Y are class type-variables declared in Foo,
1943 * a method check is executed against the modified constructor type:
1944 * <X,Y>Foo<X,Y>(X x, Y y). This is crucial in order to enable diamond
1945 * inference. The inferred return type of the synthetic constructor IS
1946 * the inferred type for the diamond operator.
1947 */
1948 private Symbol findDiamond(Env<AttrContext> env,
1949 Type site,
1950 List<Type> argtypes,
1951 List<Type> typeargtypes,
1952 boolean allowBoxing,
1953 boolean useVarargs) {
1954 Symbol bestSoFar = methodNotFound;
1955 for (Scope.Entry e = site.tsym.members().lookup(names.init);
1956 e.scope != null;
1957 e = e.next()) {
1958 //- System.out.println(" e " + e.sym);
1959 if (e.sym.kind == MTH &&
1960 (e.sym.flags_field & SYNTHETIC) == 0) {
1961 List<Type> oldParams = e.sym.type.tag == FORALL ?
1962 ((ForAll)e.sym.type).tvars :
1963 List.<Type>nil();
1964 Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams),
1965 types.createMethodTypeWithReturn(e.sym.type.asMethodType(), site));
1966 bestSoFar = selectBest(env, site, argtypes, typeargtypes,
1967 new MethodSymbol(e.sym.flags(), names.init, constrType, site.tsym),
1968 bestSoFar,
1969 allowBoxing,
1970 useVarargs,
1971 false);
1972 }
1973 }
1974 return bestSoFar;
1975 }
1977 /** Resolve constructor.
1978 * @param pos The position to use for error reporting.
1979 * @param env The environment current at the constructor invocation.
1980 * @param site The type of class for which a constructor is searched.
1981 * @param argtypes The types of the constructor invocation's value
1982 * arguments.
1983 * @param typeargtypes The types of the constructor invocation's type
1984 * arguments.
1985 * @param allowBoxing Allow boxing and varargs conversions.
1986 * @param useVarargs Box trailing arguments into an array for varargs.
1987 */
1988 Symbol resolveConstructor(DiagnosticPosition pos, Env<AttrContext> env,
1989 Type site, List<Type> argtypes,
1990 List<Type> typeargtypes,
1991 boolean allowBoxing,
1992 boolean useVarargs) {
1993 MethodResolutionContext prevResolutionContext = currentResolutionContext;
1994 try {
1995 currentResolutionContext = new MethodResolutionContext();
1996 return findConstructor(pos, env, site, argtypes, typeargtypes, allowBoxing, useVarargs);
1997 }
1998 finally {
1999 currentResolutionContext = prevResolutionContext;
2000 }
2001 }
2003 Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2004 Type site, List<Type> argtypes,
2005 List<Type> typeargtypes,
2006 boolean allowBoxing,
2007 boolean useVarargs) {
2008 Symbol sym = findMethod(env, site,
2009 names.init, argtypes,
2010 typeargtypes, allowBoxing,
2011 useVarargs, false);
2012 chk.checkDeprecated(pos, env.info.scope.owner, sym);
2013 return sym;
2014 }
2016 /** Resolve a constructor, throw a fatal error if not found.
2017 * @param pos The position to use for error reporting.
2018 * @param env The environment current at the method invocation.
2019 * @param site The type to be constructed.
2020 * @param argtypes The types of the invocation's value arguments.
2021 * @param typeargtypes The types of the invocation's type arguments.
2022 */
2023 public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2024 Type site,
2025 List<Type> argtypes,
2026 List<Type> typeargtypes) {
2027 MethodResolutionContext resolveContext = new MethodResolutionContext();
2028 resolveContext.internalResolution = true;
2029 Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes);
2030 if (sym.kind == MTH) return (MethodSymbol)sym;
2031 else throw new FatalError(
2032 diags.fragment("fatal.err.cant.locate.ctor", site));
2033 }
2035 /** Resolve operator.
2036 * @param pos The position to use for error reporting.
2037 * @param optag The tag of the operation tree.
2038 * @param env The environment current at the operation.
2039 * @param argtypes The types of the operands.
2040 */
2041 Symbol resolveOperator(DiagnosticPosition pos, JCTree.Tag optag,
2042 Env<AttrContext> env, List<Type> argtypes) {
2043 MethodResolutionContext prevResolutionContext = currentResolutionContext;
2044 try {
2045 currentResolutionContext = new MethodResolutionContext();
2046 Name name = treeinfo.operatorName(optag);
2047 Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
2048 null, false, false, true);
2049 if (boxingEnabled && sym.kind >= WRONG_MTHS)
2050 sym = findMethod(env, syms.predefClass.type, name, argtypes,
2051 null, true, false, true);
2052 return access(sym, pos, env.enclClass.sym.type, name,
2053 false, argtypes, null);
2054 }
2055 finally {
2056 currentResolutionContext = prevResolutionContext;
2057 }
2058 }
2060 /** Resolve operator.
2061 * @param pos The position to use for error reporting.
2062 * @param optag The tag of the operation tree.
2063 * @param env The environment current at the operation.
2064 * @param arg The type of the operand.
2065 */
2066 Symbol resolveUnaryOperator(DiagnosticPosition pos, JCTree.Tag optag, Env<AttrContext> env, Type arg) {
2067 return resolveOperator(pos, optag, env, List.of(arg));
2068 }
2070 /** Resolve binary operator.
2071 * @param pos The position to use for error reporting.
2072 * @param optag The tag of the operation tree.
2073 * @param env The environment current at the operation.
2074 * @param left The types of the left operand.
2075 * @param right The types of the right operand.
2076 */
2077 Symbol resolveBinaryOperator(DiagnosticPosition pos,
2078 JCTree.Tag optag,
2079 Env<AttrContext> env,
2080 Type left,
2081 Type right) {
2082 return resolveOperator(pos, optag, env, List.of(left, right));
2083 }
2085 /**
2086 * Resolve `c.name' where name == this or name == super.
2087 * @param pos The position to use for error reporting.
2088 * @param env The environment current at the expression.
2089 * @param c The qualifier.
2090 * @param name The identifier's name.
2091 */
2092 Symbol resolveSelf(DiagnosticPosition pos,
2093 Env<AttrContext> env,
2094 TypeSymbol c,
2095 Name name) {
2096 Env<AttrContext> env1 = env;
2097 boolean staticOnly = false;
2098 while (env1.outer != null) {
2099 if (isStatic(env1)) staticOnly = true;
2100 if (env1.enclClass.sym == c) {
2101 Symbol sym = env1.info.scope.lookup(name).sym;
2102 if (sym != null) {
2103 if (staticOnly) sym = new StaticError(sym);
2104 return access(sym, pos, env.enclClass.sym.type,
2105 name, true);
2106 }
2107 }
2108 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
2109 env1 = env1.outer;
2110 }
2111 log.error(pos, "not.encl.class", c);
2112 return syms.errSymbol;
2113 }
2115 /**
2116 * Resolve `c.this' for an enclosing class c that contains the
2117 * named member.
2118 * @param pos The position to use for error reporting.
2119 * @param env The environment current at the expression.
2120 * @param member The member that must be contained in the result.
2121 */
2122 Symbol resolveSelfContaining(DiagnosticPosition pos,
2123 Env<AttrContext> env,
2124 Symbol member,
2125 boolean isSuperCall) {
2126 Name name = names._this;
2127 Env<AttrContext> env1 = isSuperCall ? env.outer : env;
2128 boolean staticOnly = false;
2129 if (env1 != null) {
2130 while (env1 != null && env1.outer != null) {
2131 if (isStatic(env1)) staticOnly = true;
2132 if (env1.enclClass.sym.isSubClass(member.owner, types)) {
2133 Symbol sym = env1.info.scope.lookup(name).sym;
2134 if (sym != null) {
2135 if (staticOnly) sym = new StaticError(sym);
2136 return access(sym, pos, env.enclClass.sym.type,
2137 name, true);
2138 }
2139 }
2140 if ((env1.enclClass.sym.flags() & STATIC) != 0)
2141 staticOnly = true;
2142 env1 = env1.outer;
2143 }
2144 }
2145 log.error(pos, "encl.class.required", member);
2146 return syms.errSymbol;
2147 }
2149 /**
2150 * Resolve an appropriate implicit this instance for t's container.
2151 * JLS 8.8.5.1 and 15.9.2
2152 */
2153 Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t) {
2154 return resolveImplicitThis(pos, env, t, false);
2155 }
2157 Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t, boolean isSuperCall) {
2158 Type thisType = (((t.tsym.owner.kind & (MTH|VAR)) != 0)
2159 ? resolveSelf(pos, env, t.getEnclosingType().tsym, names._this)
2160 : resolveSelfContaining(pos, env, t.tsym, isSuperCall)).type;
2161 if (env.info.isSelfCall && thisType.tsym == env.enclClass.sym)
2162 log.error(pos, "cant.ref.before.ctor.called", "this");
2163 return thisType;
2164 }
2166 /* ***************************************************************************
2167 * ResolveError classes, indicating error situations when accessing symbols
2168 ****************************************************************************/
2170 //used by TransTypes when checking target type of synthetic cast
2171 public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) {
2172 AccessError error = new AccessError(env, env.enclClass.type, type.tsym);
2173 logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null);
2174 }
2175 //where
2176 private void logResolveError(ResolveError error,
2177 DiagnosticPosition pos,
2178 Symbol location,
2179 Type site,
2180 Name name,
2181 List<Type> argtypes,
2182 List<Type> typeargtypes) {
2183 JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
2184 pos, location, site, name, argtypes, typeargtypes);
2185 if (d != null) {
2186 d.setFlag(DiagnosticFlag.RESOLVE_ERROR);
2187 log.report(d);
2188 }
2189 }
2191 private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
2193 public Object methodArguments(List<Type> argtypes) {
2194 return argtypes == null || argtypes.isEmpty() ? noArgs : argtypes;
2195 }
2197 /**
2198 * Root class for resolution errors. Subclass of ResolveError
2199 * represent a different kinds of resolution error - as such they must
2200 * specify how they map into concrete compiler diagnostics.
2201 */
2202 private abstract class ResolveError extends Symbol {
2204 /** The name of the kind of error, for debugging only. */
2205 final String debugName;
2207 ResolveError(int kind, String debugName) {
2208 super(kind, 0, null, null, null);
2209 this.debugName = debugName;
2210 }
2212 @Override
2213 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
2214 throw new AssertionError();
2215 }
2217 @Override
2218 public String toString() {
2219 return debugName;
2220 }
2222 @Override
2223 public boolean exists() {
2224 return false;
2225 }
2227 /**
2228 * Create an external representation for this erroneous symbol to be
2229 * used during attribution - by default this returns the symbol of a
2230 * brand new error type which stores the original type found
2231 * during resolution.
2232 *
2233 * @param name the name used during resolution
2234 * @param location the location from which the symbol is accessed
2235 */
2236 protected Symbol access(Name name, TypeSymbol location) {
2237 return types.createErrorType(name, location, syms.errSymbol.type).tsym;
2238 }
2240 /**
2241 * Create a diagnostic representing this resolution error.
2242 *
2243 * @param dkind The kind of the diagnostic to be created (e.g error).
2244 * @param pos The position to be used for error reporting.
2245 * @param site The original type from where the selection took place.
2246 * @param name The name of the symbol to be resolved.
2247 * @param argtypes The invocation's value arguments,
2248 * if we looked for a method.
2249 * @param typeargtypes The invocation's type arguments,
2250 * if we looked for a method.
2251 */
2252 abstract JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
2253 DiagnosticPosition pos,
2254 Symbol location,
2255 Type site,
2256 Name name,
2257 List<Type> argtypes,
2258 List<Type> typeargtypes);
2260 /**
2261 * A name designates an operator if it consists
2262 * of a non-empty sequence of operator symbols +-~!/*%&|^<>=
2263 */
2264 boolean isOperator(Name name) {
2265 int i = 0;
2266 while (i < name.getByteLength() &&
2267 "+-~!*/%&|^<>=".indexOf(name.getByteAt(i)) >= 0) i++;
2268 return i > 0 && i == name.getByteLength();
2269 }
2270 }
2272 /**
2273 * This class is the root class of all resolution errors caused by
2274 * an invalid symbol being found during resolution.
2275 */
2276 abstract class InvalidSymbolError extends ResolveError {
2278 /** The invalid symbol found during resolution */
2279 Symbol sym;
2281 InvalidSymbolError(int kind, Symbol sym, String debugName) {
2282 super(kind, debugName);
2283 this.sym = sym;
2284 }
2286 @Override
2287 public boolean exists() {
2288 return true;
2289 }
2291 @Override
2292 public String toString() {
2293 return super.toString() + " wrongSym=" + sym;
2294 }
2296 @Override
2297 public Symbol access(Name name, TypeSymbol location) {
2298 if (sym.kind >= AMBIGUOUS)
2299 return ((ResolveError)sym).access(name, location);
2300 else if ((sym.kind & ERRONEOUS) == 0 && (sym.kind & TYP) != 0)
2301 return types.createErrorType(name, location, sym.type).tsym;
2302 else
2303 return sym;
2304 }
2305 }
2307 /**
2308 * InvalidSymbolError error class indicating that a symbol matching a
2309 * given name does not exists in a given site.
2310 */
2311 class SymbolNotFoundError extends ResolveError {
2313 SymbolNotFoundError(int kind) {
2314 super(kind, "symbol not found error");
2315 }
2317 @Override
2318 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
2319 DiagnosticPosition pos,
2320 Symbol location,
2321 Type site,
2322 Name name,
2323 List<Type> argtypes,
2324 List<Type> typeargtypes) {
2325 argtypes = argtypes == null ? List.<Type>nil() : argtypes;
2326 typeargtypes = typeargtypes == null ? List.<Type>nil() : typeargtypes;
2327 if (name == names.error)
2328 return null;
2330 if (isOperator(name)) {
2331 boolean isUnaryOp = argtypes.size() == 1;
2332 String key = argtypes.size() == 1 ?
2333 "operator.cant.be.applied" :
2334 "operator.cant.be.applied.1";
2335 Type first = argtypes.head;
2336 Type second = !isUnaryOp ? argtypes.tail.head : null;
2337 return diags.create(dkind, log.currentSource(), pos,
2338 key, name, first, second);
2339 }
2340 boolean hasLocation = false;
2341 if (location == null) {
2342 location = site.tsym;
2343 }
2344 if (!location.name.isEmpty()) {
2345 if (location.kind == PCK && !site.tsym.exists()) {
2346 return diags.create(dkind, log.currentSource(), pos,
2347 "doesnt.exist", location);
2348 }
2349 hasLocation = !location.name.equals(names._this) &&
2350 !location.name.equals(names._super);
2351 }
2352 boolean isConstructor = kind == ABSENT_MTH &&
2353 name == names.table.names.init;
2354 KindName kindname = isConstructor ? KindName.CONSTRUCTOR : absentKind(kind);
2355 Name idname = isConstructor ? site.tsym.name : name;
2356 String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation);
2357 if (hasLocation) {
2358 return diags.create(dkind, log.currentSource(), pos,
2359 errKey, kindname, idname, //symbol kindname, name
2360 typeargtypes, argtypes, //type parameters and arguments (if any)
2361 getLocationDiag(location, site)); //location kindname, type
2362 }
2363 else {
2364 return diags.create(dkind, log.currentSource(), pos,
2365 errKey, kindname, idname, //symbol kindname, name
2366 typeargtypes, argtypes); //type parameters and arguments (if any)
2367 }
2368 }
2369 //where
2370 private String getErrorKey(KindName kindname, boolean hasTypeArgs, boolean hasLocation) {
2371 String key = "cant.resolve";
2372 String suffix = hasLocation ? ".location" : "";
2373 switch (kindname) {
2374 case METHOD:
2375 case CONSTRUCTOR: {
2376 suffix += ".args";
2377 suffix += hasTypeArgs ? ".params" : "";
2378 }
2379 }
2380 return key + suffix;
2381 }
2382 private JCDiagnostic getLocationDiag(Symbol location, Type site) {
2383 if (location.kind == VAR) {
2384 return diags.fragment("location.1",
2385 kindName(location),
2386 location,
2387 location.type);
2388 } else {
2389 return diags.fragment("location",
2390 typeKindName(site),
2391 site,
2392 null);
2393 }
2394 }
2395 }
2397 /**
2398 * InvalidSymbolError error class indicating that a given symbol
2399 * (either a method, a constructor or an operand) is not applicable
2400 * given an actual arguments/type argument list.
2401 */
2402 class InapplicableSymbolError extends ResolveError {
2404 InapplicableSymbolError() {
2405 super(WRONG_MTH, "inapplicable symbol error");
2406 }
2408 protected InapplicableSymbolError(int kind, String debugName) {
2409 super(kind, debugName);
2410 }
2412 @Override
2413 public String toString() {
2414 return super.toString();
2415 }
2417 @Override
2418 public boolean exists() {
2419 return true;
2420 }
2422 @Override
2423 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
2424 DiagnosticPosition pos,
2425 Symbol location,
2426 Type site,
2427 Name name,
2428 List<Type> argtypes,
2429 List<Type> typeargtypes) {
2430 if (name == names.error)
2431 return null;
2433 if (isOperator(name)) {
2434 boolean isUnaryOp = argtypes.size() == 1;
2435 String key = argtypes.size() == 1 ?
2436 "operator.cant.be.applied" :
2437 "operator.cant.be.applied.1";
2438 Type first = argtypes.head;
2439 Type second = !isUnaryOp ? argtypes.tail.head : null;
2440 return diags.create(dkind, log.currentSource(), pos,
2441 key, name, first, second);
2442 }
2443 else {
2444 Candidate c = errCandidate();
2445 Symbol ws = c.sym.asMemberOf(site, types);
2446 return diags.create(dkind, log.currentSource(), pos,
2447 "cant.apply.symbol" + (c.details != null ? ".1" : ""),
2448 kindName(ws),
2449 ws.name == names.init ? ws.owner.name : ws.name,
2450 methodArguments(ws.type.getParameterTypes()),
2451 methodArguments(argtypes),
2452 kindName(ws.owner),
2453 ws.owner.type,
2454 c.details);
2455 }
2456 }
2458 @Override
2459 public Symbol access(Name name, TypeSymbol location) {
2460 return types.createErrorType(name, location, syms.errSymbol.type).tsym;
2461 }
2463 protected boolean shouldReport(Candidate c) {
2464 return !c.isApplicable() &&
2465 (((c.sym.flags() & VARARGS) != 0 && c.step == VARARITY) ||
2466 (c.sym.flags() & VARARGS) == 0 && c.step == (boxingEnabled ? BOX : BASIC));
2467 }
2469 private Candidate errCandidate() {
2470 for (Candidate c : currentResolutionContext.candidates) {
2471 if (shouldReport(c)) {
2472 return c;
2473 }
2474 }
2475 Assert.error();
2476 return null;
2477 }
2478 }
2480 /**
2481 * ResolveError error class indicating that a set of symbols
2482 * (either methods, constructors or operands) is not applicable
2483 * given an actual arguments/type argument list.
2484 */
2485 class InapplicableSymbolsError extends InapplicableSymbolError {
2487 InapplicableSymbolsError() {
2488 super(WRONG_MTHS, "inapplicable symbols");
2489 }
2491 @Override
2492 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
2493 DiagnosticPosition pos,
2494 Symbol location,
2495 Type site,
2496 Name name,
2497 List<Type> argtypes,
2498 List<Type> typeargtypes) {
2499 if (currentResolutionContext.candidates.nonEmpty()) {
2500 JCDiagnostic err = diags.create(dkind,
2501 log.currentSource(),
2502 pos,
2503 "cant.apply.symbols",
2504 name == names.init ? KindName.CONSTRUCTOR : absentKind(kind),
2505 getName(),
2506 argtypes);
2507 return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(site));
2508 } else {
2509 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos,
2510 location, site, name, argtypes, typeargtypes);
2511 }
2512 }
2514 //where
2515 List<JCDiagnostic> candidateDetails(Type site) {
2516 List<JCDiagnostic> details = List.nil();
2517 for (Candidate c : currentResolutionContext.candidates) {
2518 if (!shouldReport(c)) continue;
2519 JCDiagnostic detailDiag = diags.fragment("inapplicable.method",
2520 Kinds.kindName(c.sym),
2521 c.sym.location(site, types),
2522 c.sym.asMemberOf(site, types),
2523 c.details);
2524 details = details.prepend(detailDiag);
2525 }
2526 return details.reverse();
2527 }
2529 private Name getName() {
2530 Symbol sym = currentResolutionContext.candidates.head.sym;
2531 return sym.name == names.init ?
2532 sym.owner.name :
2533 sym.name;
2534 }
2535 }
2537 /**
2538 * An InvalidSymbolError error class indicating that a symbol is not
2539 * accessible from a given site
2540 */
2541 class AccessError extends InvalidSymbolError {
2543 private Env<AttrContext> env;
2544 private Type site;
2546 AccessError(Symbol sym) {
2547 this(null, null, sym);
2548 }
2550 AccessError(Env<AttrContext> env, Type site, Symbol sym) {
2551 super(HIDDEN, sym, "access error");
2552 this.env = env;
2553 this.site = site;
2554 if (debugResolve)
2555 log.error("proc.messager", sym + " @ " + site + " is inaccessible.");
2556 }
2558 @Override
2559 public boolean exists() {
2560 return false;
2561 }
2563 @Override
2564 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
2565 DiagnosticPosition pos,
2566 Symbol location,
2567 Type site,
2568 Name name,
2569 List<Type> argtypes,
2570 List<Type> typeargtypes) {
2571 if (sym.owner.type.tag == ERROR)
2572 return null;
2574 if (sym.name == names.init && sym.owner != site.tsym) {
2575 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind,
2576 pos, location, site, name, argtypes, typeargtypes);
2577 }
2578 else if ((sym.flags() & PUBLIC) != 0
2579 || (env != null && this.site != null
2580 && !isAccessible(env, this.site))) {
2581 return diags.create(dkind, log.currentSource(),
2582 pos, "not.def.access.class.intf.cant.access",
2583 sym, sym.location());
2584 }
2585 else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) {
2586 return diags.create(dkind, log.currentSource(),
2587 pos, "report.access", sym,
2588 asFlagSet(sym.flags() & (PRIVATE | PROTECTED)),
2589 sym.location());
2590 }
2591 else {
2592 return diags.create(dkind, log.currentSource(),
2593 pos, "not.def.public.cant.access", sym, sym.location());
2594 }
2595 }
2596 }
2598 /**
2599 * InvalidSymbolError error class indicating that an instance member
2600 * has erroneously been accessed from a static context.
2601 */
2602 class StaticError extends InvalidSymbolError {
2604 StaticError(Symbol sym) {
2605 super(STATICERR, sym, "static error");
2606 }
2608 @Override
2609 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
2610 DiagnosticPosition pos,
2611 Symbol location,
2612 Type site,
2613 Name name,
2614 List<Type> argtypes,
2615 List<Type> typeargtypes) {
2616 Symbol errSym = ((sym.kind == TYP && sym.type.tag == CLASS)
2617 ? types.erasure(sym.type).tsym
2618 : sym);
2619 return diags.create(dkind, log.currentSource(), pos,
2620 "non-static.cant.be.ref", kindName(sym), errSym);
2621 }
2622 }
2624 /**
2625 * InvalidSymbolError error class indicating that a pair of symbols
2626 * (either methods, constructors or operands) are ambiguous
2627 * given an actual arguments/type argument list.
2628 */
2629 class AmbiguityError extends InvalidSymbolError {
2631 /** The other maximally specific symbol */
2632 Symbol sym2;
2634 AmbiguityError(Symbol sym1, Symbol sym2) {
2635 super(AMBIGUOUS, sym1, "ambiguity error");
2636 this.sym2 = sym2;
2637 }
2639 @Override
2640 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
2641 DiagnosticPosition pos,
2642 Symbol location,
2643 Type site,
2644 Name name,
2645 List<Type> argtypes,
2646 List<Type> typeargtypes) {
2647 AmbiguityError pair = this;
2648 while (true) {
2649 if (pair.sym.kind == AMBIGUOUS)
2650 pair = (AmbiguityError)pair.sym;
2651 else if (pair.sym2.kind == AMBIGUOUS)
2652 pair = (AmbiguityError)pair.sym2;
2653 else break;
2654 }
2655 Name sname = pair.sym.name;
2656 if (sname == names.init) sname = pair.sym.owner.name;
2657 return diags.create(dkind, log.currentSource(),
2658 pos, "ref.ambiguous", sname,
2659 kindName(pair.sym),
2660 pair.sym,
2661 pair.sym.location(site, types),
2662 kindName(pair.sym2),
2663 pair.sym2,
2664 pair.sym2.location(site, types));
2665 }
2666 }
2668 enum MethodResolutionPhase {
2669 BASIC(false, false),
2670 BOX(true, false),
2671 VARARITY(true, true);
2673 boolean isBoxingRequired;
2674 boolean isVarargsRequired;
2676 MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) {
2677 this.isBoxingRequired = isBoxingRequired;
2678 this.isVarargsRequired = isVarargsRequired;
2679 }
2681 public boolean isBoxingRequired() {
2682 return isBoxingRequired;
2683 }
2685 public boolean isVarargsRequired() {
2686 return isVarargsRequired;
2687 }
2689 public boolean isApplicable(boolean boxingEnabled, boolean varargsEnabled) {
2690 return (varargsEnabled || !isVarargsRequired) &&
2691 (boxingEnabled || !isBoxingRequired);
2692 }
2693 }
2695 final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
2697 /**
2698 * A resolution context is used to keep track of intermediate results of
2699 * overload resolution, such as list of method that are not applicable
2700 * (used to generate more precise diagnostics) and so on. Resolution contexts
2701 * can be nested - this means that when each overload resolution routine should
2702 * work within the resolution context it created.
2703 */
2704 class MethodResolutionContext {
2706 private List<Candidate> candidates = List.nil();
2708 private Map<MethodResolutionPhase, Symbol> resolutionCache =
2709 new EnumMap<MethodResolutionPhase, Symbol>(MethodResolutionPhase.class);
2711 private MethodResolutionPhase step = null;
2713 private boolean internalResolution = false;
2715 private MethodResolutionPhase firstErroneousResolutionPhase() {
2716 MethodResolutionPhase bestSoFar = BASIC;
2717 Symbol sym = methodNotFound;
2718 List<MethodResolutionPhase> steps = methodResolutionSteps;
2719 while (steps.nonEmpty() &&
2720 steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
2721 sym.kind >= WRONG_MTHS) {
2722 sym = resolutionCache.get(steps.head);
2723 bestSoFar = steps.head;
2724 steps = steps.tail;
2725 }
2726 return bestSoFar;
2727 }
2729 void addInapplicableCandidate(Symbol sym, JCDiagnostic details) {
2730 Candidate c = new Candidate(currentResolutionContext.step, sym, details, null);
2731 if (!candidates.contains(c))
2732 candidates = candidates.append(c);
2733 }
2735 void addApplicableCandidate(Symbol sym, Type mtype) {
2736 Candidate c = new Candidate(currentResolutionContext.step, sym, null, mtype);
2737 candidates = candidates.append(c);
2738 }
2740 /**
2741 * This class represents an overload resolution candidate. There are two
2742 * kinds of candidates: applicable methods and inapplicable methods;
2743 * applicable methods have a pointer to the instantiated method type,
2744 * while inapplicable candidates contain further details about the
2745 * reason why the method has been considered inapplicable.
2746 */
2747 class Candidate {
2749 final MethodResolutionPhase step;
2750 final Symbol sym;
2751 final JCDiagnostic details;
2752 final Type mtype;
2754 private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) {
2755 this.step = step;
2756 this.sym = sym;
2757 this.details = details;
2758 this.mtype = mtype;
2759 }
2761 @Override
2762 public boolean equals(Object o) {
2763 if (o instanceof Candidate) {
2764 Symbol s1 = this.sym;
2765 Symbol s2 = ((Candidate)o).sym;
2766 if ((s1 != s2 &&
2767 (s1.overrides(s2, s1.owner.type.tsym, types, false) ||
2768 (s2.overrides(s1, s2.owner.type.tsym, types, false)))) ||
2769 ((s1.isConstructor() || s2.isConstructor()) && s1.owner != s2.owner))
2770 return true;
2771 }
2772 return false;
2773 }
2775 boolean isApplicable() {
2776 return mtype != null;
2777 }
2778 }
2779 }
2781 MethodResolutionContext currentResolutionContext = null;
2782 }