1 /*
2 * Copyright (c) 1999, 2025, 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 */
25
26 package com.sun.tools.javac.comp;
27
28 import com.sun.tools.javac.api.Formattable.LocalizedString;
29 import com.sun.tools.javac.code.*;
30 import com.sun.tools.javac.code.Scope.WriteableScope;
31 import com.sun.tools.javac.code.Source.Feature;
32 import com.sun.tools.javac.code.Symbol.*;
33 import com.sun.tools.javac.code.Type.*;
34 import com.sun.tools.javac.comp.Attr.ResultInfo;
35 import com.sun.tools.javac.comp.Check.CheckContext;
36 import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
37 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
38 import com.sun.tools.javac.comp.DeferredAttr.DeferredType;
39 import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
40 import com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.Template;
41 import com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind;
42 import com.sun.tools.javac.jvm.*;
43 import com.sun.tools.javac.main.Option;
44 import com.sun.tools.javac.resources.CompilerProperties.Errors;
45 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
46 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
47 import com.sun.tools.javac.tree.*;
48 import com.sun.tools.javac.tree.JCTree.*;
49 import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
50 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
51 import com.sun.tools.javac.util.*;
52 import com.sun.tools.javac.util.DefinedBy.Api;
53 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
54 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
55 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
56
57 import java.util.Arrays;
58 import java.util.Collection;
59 import java.util.EnumSet;
60 import java.util.HashSet;
61 import java.util.Iterator;
62 import java.util.LinkedHashMap;
63 import java.util.Map;
64 import java.util.Set;
65 import java.util.function.BiFunction;
66 import java.util.function.BiPredicate;
67 import java.util.function.Function;
68 import java.util.function.Predicate;
69 import java.util.function.UnaryOperator;
70 import java.util.stream.Stream;
71 import java.util.stream.StreamSupport;
72
73 import javax.lang.model.element.ElementVisitor;
74
75 import static com.sun.tools.javac.code.Flags.*;
76 import static com.sun.tools.javac.code.Flags.BLOCK;
77 import static com.sun.tools.javac.code.Flags.STATIC;
78 import static com.sun.tools.javac.code.Kinds.*;
79 import static com.sun.tools.javac.code.Kinds.Kind.*;
80 import static com.sun.tools.javac.code.TypeTag.*;
81 import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
82 import static com.sun.tools.javac.main.Option.DOE;
83 import static com.sun.tools.javac.tree.JCTree.Tag.*;
84 import static com.sun.tools.javac.util.Iterators.createCompoundIterator;
85
86 /** Helper class for name resolution, used mostly by the attribution phase.
87 *
88 * <p><b>This is NOT part of any supported API.
89 * If you write code that depends on this, you do so at your own risk.
90 * This code and its internal interfaces are subject to change or
91 * deletion without notice.</b>
92 */
93 public class Resolve {
94 protected static final Context.Key<Resolve> resolveKey = new Context.Key<>();
95
96 Names names;
97 Log log;
98 Symtab syms;
99 Attr attr;
100 AttrRecover attrRecover;
101 DeferredAttr deferredAttr;
102 Check chk;
103 Infer infer;
104 Preview preview;
105 ClassFinder finder;
106 ModuleFinder moduleFinder;
107 Types types;
108 JCDiagnostic.Factory diags;
109 public final boolean allowModules;
110 public final boolean allowRecords;
111 private final boolean compactMethodDiags;
112 private final boolean allowLocalVariableTypeInference;
113 private final boolean allowYieldStatement;
114 private final boolean allowPrivateMembersInPermitsClause;
115 final EnumSet<VerboseResolutionMode> verboseResolutionMode;
116 final boolean dumpMethodReferenceSearchResults;
117 final boolean dumpStacktraceOnError;
118
119 WriteableScope polymorphicSignatureScope;
120
121 @SuppressWarnings("this-escape")
122 protected Resolve(Context context) {
123 context.put(resolveKey, this);
124 syms = Symtab.instance(context);
125
126 varNotFound = new SymbolNotFoundError(ABSENT_VAR);
127 methodNotFound = new SymbolNotFoundError(ABSENT_MTH);
128 typeNotFound = new SymbolNotFoundError(ABSENT_TYP);
129 referenceNotFound = ReferenceLookupResult.error(methodNotFound);
130
131 names = Names.instance(context);
132 log = Log.instance(context);
133 attr = Attr.instance(context);
134 attrRecover = AttrRecover.instance(context);
135 deferredAttr = DeferredAttr.instance(context);
136 chk = Check.instance(context);
137 infer = Infer.instance(context);
138 finder = ClassFinder.instance(context);
139 moduleFinder = ModuleFinder.instance(context);
140 types = Types.instance(context);
141 diags = JCDiagnostic.Factory.instance(context);
142 preview = Preview.instance(context);
143 Source source = Source.instance(context);
144 Options options = Options.instance(context);
145 compactMethodDiags = options.isSet(Option.XDIAGS, "compact") ||
146 options.isUnset(Option.XDIAGS) && options.isUnset("rawDiagnostics");
147 verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
148 Target target = Target.instance(context);
149 allowLocalVariableTypeInference = Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source);
150 allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source);
151 allowPrivateMembersInPermitsClause = Feature.PRIVATE_MEMBERS_IN_PERMITS_CLAUSE.allowedInSource(source);
152 polymorphicSignatureScope = WriteableScope.create(syms.noSymbol);
153 allowModules = Feature.MODULES.allowedInSource(source);
154 allowRecords = Feature.RECORDS.allowedInSource(source);
155 dumpMethodReferenceSearchResults = options.isSet("debug.dumpMethodReferenceSearchResults");
156 dumpStacktraceOnError = options.isSet("dev") || options.isSet(DOE);
157 }
158
159 /** error symbols, which are returned when resolution fails
160 */
161 private final SymbolNotFoundError varNotFound;
162 private final SymbolNotFoundError methodNotFound;
163 private final SymbolNotFoundError typeNotFound;
164
165 /** empty reference lookup result */
166 private final ReferenceLookupResult referenceNotFound;
167
168 public static Resolve instance(Context context) {
169 Resolve instance = context.get(resolveKey);
170 if (instance == null)
171 instance = new Resolve(context);
172 return instance;
173 }
174
175 private static Symbol bestOf(Symbol s1,
176 Symbol s2) {
177 return s1.kind.betterThan(s2.kind) ? s1 : s2;
178 }
179
180 // <editor-fold defaultstate="collapsed" desc="Verbose resolution diagnostics support">
181 enum VerboseResolutionMode {
182 SUCCESS("success"),
183 FAILURE("failure"),
184 APPLICABLE("applicable"),
185 INAPPLICABLE("inapplicable"),
186 DEFERRED_INST("deferred-inference"),
187 PREDEF("predef"),
188 OBJECT_INIT("object-init"),
189 INTERNAL("internal");
190
191 final String opt;
192
193 private VerboseResolutionMode(String opt) {
194 this.opt = opt;
195 }
196
197 static EnumSet<VerboseResolutionMode> getVerboseResolutionMode(Options opts) {
198 String s = opts.get("debug.verboseResolution");
199 EnumSet<VerboseResolutionMode> res = EnumSet.noneOf(VerboseResolutionMode.class);
200 if (s == null) return res;
201 if (s.contains("all")) {
202 res = EnumSet.allOf(VerboseResolutionMode.class);
203 }
204 Collection<String> args = Arrays.asList(s.split(","));
205 for (VerboseResolutionMode mode : values()) {
206 if (args.contains(mode.opt)) {
207 res.add(mode);
208 } else if (args.contains("-" + mode.opt)) {
209 res.remove(mode);
210 }
211 }
212 return res;
213 }
214 }
215
216 void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site,
217 List<Type> argtypes, List<Type> typeargtypes, Symbol bestSoFar) {
218 boolean success = !bestSoFar.kind.isResolutionError();
219
220 if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) {
221 return;
222 } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) {
223 return;
224 }
225
226 if (bestSoFar.name == names.init &&
227 bestSoFar.owner == syms.objectType.tsym &&
228 !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) {
229 return; //skip diags for Object constructor resolution
230 } else if (site == syms.predefClass.type &&
231 !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) {
232 return; //skip spurious diags for predef symbols (i.e. operators)
233 } else if (currentResolutionContext.internalResolution &&
234 !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) {
235 return;
236 }
237
238 int pos = 0;
239 int mostSpecificPos = -1;
240 ListBuffer<JCDiagnostic> subDiags = new ListBuffer<>();
241 for (Candidate c : currentResolutionContext.candidates) {
242 if (currentResolutionContext.step != c.step ||
243 (c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE)) ||
244 (!c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))) {
245 continue;
246 } else {
247 subDiags.append(c.isApplicable() ?
248 getVerboseApplicableCandidateDiag(pos, c.sym, c.mtype) :
249 getVerboseInapplicableCandidateDiag(pos, c.sym, c.details));
250 if (c.sym == bestSoFar)
251 mostSpecificPos = pos;
252 pos++;
253 }
254 }
255 String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1";
256 List<Type> argtypes2 = argtypes.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, bestSoFar, currentResolutionContext.step));
257 JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name,
258 site.tsym, mostSpecificPos, currentResolutionContext.step,
259 methodArguments(argtypes2),
260 methodArguments(typeargtypes));
261 JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList());
262 log.report(d);
263 }
264
265 JCDiagnostic getVerboseApplicableCandidateDiag(int pos, Symbol sym, Type inst) {
266 JCDiagnostic subDiag = null;
267 if (sym.type.hasTag(FORALL)) {
268 subDiag = diags.fragment(Fragments.PartialInstSig(inst));
269 }
270
271 String key = subDiag == null ?
272 "applicable.method.found" :
273 "applicable.method.found.1";
274
275 return diags.fragment(key, pos, sym, subDiag);
276 }
277
278 JCDiagnostic getVerboseInapplicableCandidateDiag(int pos, Symbol sym, JCDiagnostic subDiag) {
279 return diags.fragment(Fragments.NotApplicableMethodFound(pos, sym, subDiag));
280 }
281 // </editor-fold>
282
283 /* ************************************************************************
284 * Identifier resolution
285 *************************************************************************/
286
287 /** An environment is "static" if its static level is greater than
288 * the one of its outer environment
289 */
290 protected static boolean isStatic(Env<AttrContext> env) {
291 return env.outer != null && env.info.staticLevel > env.outer.info.staticLevel;
292 }
293
294 /** An environment is an "initializer" if it is a constructor or
295 * an instance initializer.
296 */
297 static boolean isInitializer(Env<AttrContext> env) {
298 Symbol owner = env.info.scope.owner;
299 return owner.isConstructor() ||
300 owner.owner.kind == TYP &&
301 (owner.kind == VAR ||
302 owner.kind == MTH && (owner.flags() & BLOCK) != 0) &&
303 (owner.flags() & STATIC) == 0;
304 }
305
306 /** Is class accessible in given environment?
307 * @param env The current environment.
308 * @param c The class whose accessibility is checked.
309 */
310 public boolean isAccessible(Env<AttrContext> env, TypeSymbol c) {
311 return isAccessible(env, c, false);
312 }
313
314 public boolean isAccessible(Env<AttrContext> env, TypeSymbol c, boolean checkInner) {
315
316 /* 15.9.5.1: Note that it is possible for the signature of the anonymous constructor
317 to refer to an inaccessible type
318 */
319 if (env.enclMethod != null && (env.enclMethod.mods.flags & ANONCONSTR) != 0)
320 return true;
321
322 if (env.info.visitingServiceImplementation &&
323 env.toplevel.modle == c.packge().modle) {
324 return true;
325 }
326
327 boolean isAccessible = false;
328 switch ((short)(c.flags() & AccessFlags)) {
329 case PRIVATE:
330 isAccessible =
331 env.enclClass.sym.outermostClass() ==
332 c.owner.outermostClass();
333 break;
334 case 0:
335 isAccessible =
336 env.toplevel.packge == c.owner // fast special case
337 ||
338 env.toplevel.packge == c.packge();
339 break;
340 default: // error recovery
341 isAccessible = true;
342 break;
343 case PUBLIC:
344 if (allowModules) {
345 ModuleSymbol currModule = env.toplevel.modle;
346 currModule.complete();
347 PackageSymbol p = c.packge();
348 isAccessible =
349 currModule == p.modle ||
350 currModule.visiblePackages.get(p.fullname) == p ||
351 p == syms.rootPackage ||
352 (p.modle == syms.unnamedModule && currModule.readModules.contains(p.modle));
353 } else {
354 isAccessible = true;
355 }
356 break;
357 case PROTECTED:
358 isAccessible =
359 env.toplevel.packge == c.owner // fast special case
360 ||
361 env.toplevel.packge == c.packge()
362 ||
363 isInnerSubClass(env.enclClass.sym, c.owner)
364 ||
365 env.info.allowProtectedAccess;
366 break;
367 }
368 return (checkInner == false || c.type.getEnclosingType() == Type.noType) ?
369 isAccessible :
370 isAccessible && isAccessible(env, c.type.getEnclosingType(), checkInner);
371 }
372 //where
373 /** Is given class a subclass of given base class, or an inner class
374 * of a subclass?
375 * Return null if no such class exists.
376 * @param c The class which is the subclass or is contained in it.
377 * @param base The base class
378 */
379 private boolean isInnerSubClass(ClassSymbol c, Symbol base) {
380 while (c != null && !c.isSubClass(base, types)) {
381 c = c.owner.enclClass();
382 }
383 return c != null;
384 }
385
386 boolean isAccessible(Env<AttrContext> env, Type t) {
387 return isAccessible(env, t, false);
388 }
389
390 boolean isAccessible(Env<AttrContext> env, Type t, boolean checkInner) {
391 if (t.hasTag(ARRAY)) {
392 return isAccessible(env, types.cvarUpperBound(types.elemtype(t)));
393 } else if (t.isUnion()) {
394 return StreamSupport.stream(((UnionClassType) t).getAlternativeTypes().spliterator(), false)
395 .allMatch(alternative -> isAccessible(env, alternative.tsym, checkInner));
396 } else {
397 return isAccessible(env, t.tsym, checkInner);
398 }
399 }
400
401 /** Is symbol accessible as a member of given type in given environment?
402 * @param env The current environment.
403 * @param site The type of which the tested symbol is regarded
404 * as a member.
405 * @param sym The symbol.
406 */
407 public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym) {
408 return isAccessible(env, site, sym, false);
409 }
410 public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym, boolean checkInner) {
411 if (sym.name == names.init && sym.owner != site.tsym) return false;
412
413 /* 15.9.5.1: Note that it is possible for the signature of the anonymous constructor
414 to refer to an inaccessible type
415 */
416 if (env.enclMethod != null && (env.enclMethod.mods.flags & ANONCONSTR) != 0)
417 return true;
418
419 if (env.info.visitingServiceImplementation &&
420 env.toplevel.modle == sym.packge().modle) {
421 return true;
422 }
423
424 switch ((short)(sym.flags() & AccessFlags)) {
425 case PRIVATE:
426 return
427 (env.enclClass.sym == sym.owner // fast special case
428 ||
429 env.enclClass.sym.outermostClass() ==
430 sym.owner.outermostClass()
431 ||
432 privateMemberInPermitsClauseIfAllowed(env, sym))
433 &&
434 sym.isInheritedIn(site.tsym, types);
435 case 0:
436 return
437 (env.toplevel.packge == sym.owner.owner // fast special case
438 ||
439 env.toplevel.packge == sym.packge())
440 &&
441 isAccessible(env, site, checkInner)
442 &&
443 sym.isInheritedIn(site.tsym, types)
444 &&
445 notOverriddenIn(site, sym);
446 case PROTECTED:
447 return
448 (env.toplevel.packge == sym.owner.owner // fast special case
449 ||
450 env.toplevel.packge == sym.packge()
451 ||
452 isProtectedAccessible(sym, env.enclClass.sym, site)
453 ||
454 // OK to select instance method or field from 'super' or type name
455 // (but type names should be disallowed elsewhere!)
456 env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP)
457 &&
458 isAccessible(env, site, checkInner)
459 &&
460 notOverriddenIn(site, sym);
461 default: // this case includes erroneous combinations as well
462 return isAccessible(env, site, checkInner) && notOverriddenIn(site, sym);
463 }
464 }
465
466 private boolean privateMemberInPermitsClauseIfAllowed(Env<AttrContext> env, Symbol sym) {
467 return allowPrivateMembersInPermitsClause &&
468 env.info.isPermitsClause &&
469 ((JCClassDecl) env.tree).sym.outermostClass() == sym.owner.outermostClass();
470 }
471
472 //where
473 /* `sym' is accessible only if not overridden by
474 * another symbol which is a member of `site'
475 * (because, if it is overridden, `sym' is not strictly
476 * speaking a member of `site'). A polymorphic signature method
477 * cannot be overridden (e.g. MH.invokeExact(Object[])).
478 */
479 private boolean notOverriddenIn(Type site, Symbol sym) {
480 if (sym.kind != MTH || sym.isConstructor() || sym.isStatic())
481 return true;
482 else {
483 Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true);
484 return (s2 == null || s2 == sym || sym.owner == s2.owner || (sym.owner.isInterface() && s2.owner == syms.objectType.tsym) ||
485 !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym)));
486 }
487 }
488 //where
489 /** Is given protected symbol accessible if it is selected from given site
490 * and the selection takes place in given class?
491 * @param sym The symbol with protected access
492 * @param c The class where the access takes place
493 * @param site The type of the qualifier
494 */
495 private
496 boolean isProtectedAccessible(Symbol sym, ClassSymbol c, Type site) {
497 Type newSite = site.hasTag(TYPEVAR) ? site.getUpperBound() : site;
498 while (c != null &&
499 !(c.isSubClass(sym.owner, types) &&
500 (c.flags() & INTERFACE) == 0 &&
501 // In JLS 2e 6.6.2.1, the subclass restriction applies
502 // only to instance fields and methods -- types are excluded
503 // regardless of whether they are declared 'static' or not.
504 ((sym.flags() & STATIC) != 0 || sym.kind == TYP || newSite.tsym.isSubClass(c, types))))
505 c = c.owner.enclClass();
506 return c != null;
507 }
508
509 /**
510 * Performs a recursive scan of a type looking for accessibility problems
511 * from current attribution environment
512 */
513 void checkAccessibleType(Env<AttrContext> env, Type t) {
514 accessibilityChecker.visit(t, env);
515 }
516
517 /**
518 * Accessibility type-visitor
519 */
520 Types.SimpleVisitor<Void, Env<AttrContext>> accessibilityChecker =
521 new Types.SimpleVisitor<Void, Env<AttrContext>>() {
522
523 void visit(List<Type> ts, Env<AttrContext> env) {
524 for (Type t : ts) {
525 visit(t, env);
526 }
527 }
528
529 public Void visitType(Type t, Env<AttrContext> env) {
530 return null;
531 }
532
533 @Override
534 public Void visitArrayType(ArrayType t, Env<AttrContext> env) {
535 visit(t.elemtype, env);
536 return null;
537 }
538
539 @Override
540 public Void visitClassType(ClassType t, Env<AttrContext> env) {
541 visit(t.getTypeArguments(), env);
542 if (!isAccessible(env, t, true)) {
543 accessBase(new AccessError(env, null, t.tsym), env.tree.pos(), env.enclClass.sym, t, t.tsym.name, true);
544 }
545 return null;
546 }
547
548 @Override
549 public Void visitWildcardType(WildcardType t, Env<AttrContext> env) {
550 visit(t.type, env);
551 return null;
552 }
553
554 @Override
555 public Void visitMethodType(MethodType t, Env<AttrContext> env) {
556 visit(t.getParameterTypes(), env);
557 visit(t.getReturnType(), env);
558 visit(t.getThrownTypes(), env);
559 return null;
560 }
561 };
562
563 /** Try to instantiate the type of a method so that it fits
564 * given type arguments and argument types. If successful, return
565 * the method's instantiated type, else return null.
566 * The instantiation will take into account an additional leading
567 * formal parameter if the method is an instance method seen as a member
568 * of an under determined site. In this case, we treat site as an additional
569 * parameter and the parameters of the class containing the method as
570 * additional type variables that get instantiated.
571 *
572 * @param env The current environment
573 * @param site The type of which the method is a member.
574 * @param m The method symbol.
575 * @param argtypes The invocation's given value arguments.
576 * @param typeargtypes The invocation's given type arguments.
577 * @param allowBoxing Allow boxing conversions of arguments.
578 * @param useVarargs Box trailing arguments into an array for varargs.
579 */
580 Type rawInstantiate(Env<AttrContext> env,
581 Type site,
582 Symbol m,
583 ResultInfo resultInfo,
584 List<Type> argtypes,
585 List<Type> typeargtypes,
586 boolean allowBoxing,
587 boolean useVarargs,
588 Warner warn) throws Infer.InferenceException {
589 Type mt = types.memberType(site, m);
590 // tvars is the list of formal type variables for which type arguments
591 // need to inferred.
592 List<Type> tvars = List.nil();
593 if (typeargtypes == null) typeargtypes = List.nil();
594 if (!mt.hasTag(FORALL) && typeargtypes.nonEmpty()) {
595 // This is not a polymorphic method, but typeargs are supplied
596 // which is fine, see JLS 15.12.2.1
597 } else if (mt.hasTag(FORALL) && typeargtypes.nonEmpty()) {
598 ForAll pmt = (ForAll) mt;
599 if (typeargtypes.length() != pmt.tvars.length())
600 // not enough args
601 throw new InapplicableMethodException(diags.fragment(Fragments.WrongNumberTypeArgs(Integer.toString(pmt.tvars.length()))), dumpStacktraceOnError);
602 // Check type arguments are within bounds
603 List<Type> formals = pmt.tvars;
604 List<Type> actuals = typeargtypes;
605 while (formals.nonEmpty() && actuals.nonEmpty()) {
606 List<Type> bounds = types.subst(types.getBounds((TypeVar)formals.head),
607 pmt.tvars, typeargtypes);
608 for (; bounds.nonEmpty(); bounds = bounds.tail) {
609 if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn)) {
610 throw new InapplicableMethodException(diags.fragment(Fragments.ExplicitParamDoNotConformToBounds(actuals.head, bounds)), dumpStacktraceOnError);
611 }
612 }
613 formals = formals.tail;
614 actuals = actuals.tail;
615 }
616 mt = types.subst(pmt.qtype, pmt.tvars, typeargtypes);
617 } else if (mt.hasTag(FORALL)) {
618 ForAll pmt = (ForAll) mt;
619 List<Type> tvars1 = types.newInstances(pmt.tvars);
620 tvars = tvars.appendList(tvars1);
621 mt = types.subst(pmt.qtype, pmt.tvars, tvars1);
622 }
623
624 // find out whether we need to go the slow route via infer
625 boolean instNeeded = tvars.tail != null; /*inlined: tvars.nonEmpty()*/
626 for (List<Type> l = argtypes;
627 l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded;
628 l = l.tail) {
629 if (l.head.hasTag(FORALL)) instNeeded = true;
630 }
631
632 if (instNeeded) {
633 return infer.instantiateMethod(env,
634 tvars,
635 (MethodType)mt,
636 resultInfo,
637 (MethodSymbol)m,
638 argtypes,
639 allowBoxing,
640 useVarargs,
641 currentResolutionContext,
642 warn);
643 }
644
645 DeferredAttr.DeferredAttrContext dc = currentResolutionContext.deferredAttrContext(m, infer.emptyContext, resultInfo, warn);
646 currentResolutionContext.methodCheck.argumentsAcceptable(env, dc,
647 argtypes, mt.getParameterTypes(), warn);
648 dc.complete();
649 return mt;
650 }
651
652 Type checkMethod(Env<AttrContext> env,
653 Type site,
654 Symbol m,
655 ResultInfo resultInfo,
656 List<Type> argtypes,
657 List<Type> typeargtypes,
658 Warner warn) {
659 MethodResolutionContext prevContext = currentResolutionContext;
660 try {
661 currentResolutionContext = new MethodResolutionContext();
662 currentResolutionContext.attrMode = (resultInfo.pt == Infer.anyPoly) ?
663 AttrMode.SPECULATIVE : DeferredAttr.AttrMode.CHECK;
664 if (env.tree.hasTag(JCTree.Tag.REFERENCE)) {
665 //method/constructor references need special check class
666 //to handle inference variables in 'argtypes' (might happen
667 //during an unsticking round)
668 currentResolutionContext.methodCheck =
669 new MethodReferenceCheck(resultInfo.checkContext.inferenceContext());
670 }
671 MethodResolutionPhase step = currentResolutionContext.step = env.info.pendingResolutionPhase;
672 return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes,
673 step.isBoxingRequired(), step.isVarargsRequired(), warn);
674 }
675 finally {
676 currentResolutionContext = prevContext;
677 }
678 }
679
680 /** Same but returns null instead throwing a NoInstanceException
681 */
682 Type instantiate(Env<AttrContext> env,
683 Type site,
684 Symbol m,
685 ResultInfo resultInfo,
686 List<Type> argtypes,
687 List<Type> typeargtypes,
688 boolean allowBoxing,
689 boolean useVarargs,
690 Warner warn) {
691 try {
692 return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes,
693 allowBoxing, useVarargs, warn);
694 } catch (InapplicableMethodException ex) {
695 return null;
696 }
697 }
698
699 /**
700 * This interface defines an entry point that should be used to perform a
701 * method check. A method check usually consist in determining as to whether
702 * a set of types (actuals) is compatible with another set of types (formals).
703 * Since the notion of compatibility can vary depending on the circumstances,
704 * this interfaces allows to easily add new pluggable method check routines.
705 */
706 interface MethodCheck {
707 /**
708 * Main method check routine. A method check usually consist in determining
709 * as to whether a set of types (actuals) is compatible with another set of
710 * types (formals). If an incompatibility is found, an unchecked exception
711 * is assumed to be thrown.
712 */
713 void argumentsAcceptable(Env<AttrContext> env,
714 DeferredAttrContext deferredAttrContext,
715 List<Type> argtypes,
716 List<Type> formals,
717 Warner warn);
718
719 /**
720 * Retrieve the method check object that will be used during a
721 * most specific check.
722 */
723 MethodCheck mostSpecificCheck(List<Type> actuals);
724 }
725
726 /**
727 * Helper enum defining all method check diagnostics (used by resolveMethodCheck).
728 */
729 enum MethodCheckDiag {
730 /**
731 * Actuals and formals differs in length.
732 */
733 ARITY_MISMATCH("arg.length.mismatch", "infer.arg.length.mismatch"),
734 /**
735 * An actual is incompatible with a formal.
736 */
737 ARG_MISMATCH("no.conforming.assignment.exists", "infer.no.conforming.assignment.exists"),
738 /**
739 * An actual is incompatible with the varargs element type.
740 */
741 VARARG_MISMATCH("varargs.argument.mismatch", "infer.varargs.argument.mismatch"),
742 /**
743 * The varargs element type is inaccessible.
744 */
745 INACCESSIBLE_VARARGS("inaccessible.varargs.type", "inaccessible.varargs.type");
746
747 final String basicKey;
748 final String inferKey;
749
750 MethodCheckDiag(String basicKey, String inferKey) {
751 this.basicKey = basicKey;
752 this.inferKey = inferKey;
753 }
754
755 String regex() {
756 return String.format("([a-z]*\\.)*(%s|%s)", basicKey, inferKey);
757 }
758 }
759
760 /**
761 * Dummy method check object. All methods are deemed applicable, regardless
762 * of their formal parameter types.
763 */
764 MethodCheck nilMethodCheck = new MethodCheck() {
765 public void argumentsAcceptable(Env<AttrContext> env, DeferredAttrContext deferredAttrContext, List<Type> argtypes, List<Type> formals, Warner warn) {
766 //do nothing - method always applicable regardless of actuals
767 }
768
769 public MethodCheck mostSpecificCheck(List<Type> actuals) {
770 return this;
771 }
772 };
773
774 /**
775 * Base class for 'real' method checks. The class defines the logic for
776 * iterating through formals and actuals and provides and entry point
777 * that can be used by subclasses in order to define the actual check logic.
778 */
779 abstract class AbstractMethodCheck implements MethodCheck {
780 @Override
781 public void argumentsAcceptable(final Env<AttrContext> env,
782 DeferredAttrContext deferredAttrContext,
783 List<Type> argtypes,
784 List<Type> formals,
785 Warner warn) {
786 //should we expand formals?
787 boolean useVarargs = deferredAttrContext.phase.isVarargsRequired();
788 JCTree callTree = treeForDiagnostics(env);
789 List<JCExpression> trees = TreeInfo.args(callTree);
790
791 //inference context used during this method check
792 InferenceContext inferenceContext = deferredAttrContext.inferenceContext;
793
794 Type varargsFormal = useVarargs ? formals.last() : null;
795
796 if (varargsFormal == null &&
797 argtypes.size() != formals.size()) {
798 reportMC(callTree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
799 }
800
801 while (argtypes.nonEmpty() && formals.head != varargsFormal) {
802 DiagnosticPosition pos = trees != null ? trees.head : null;
803 checkArg(pos, false, argtypes.head, formals.head, deferredAttrContext, warn);
804 argtypes = argtypes.tail;
805 formals = formals.tail;
806 trees = trees != null ? trees.tail : trees;
807 }
808
809 if (formals.head != varargsFormal) {
810 reportMC(callTree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
811 }
812
813 if (useVarargs) {
814 //note: if applicability check is triggered by most specific test,
815 //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
816 final Type elt = types.elemtype(varargsFormal);
817 while (argtypes.nonEmpty()) {
818 DiagnosticPosition pos = trees != null ? trees.head : null;
819 checkArg(pos, true, argtypes.head, elt, deferredAttrContext, warn);
820 argtypes = argtypes.tail;
821 trees = trees != null ? trees.tail : trees;
822 }
823 }
824 }
825
826 // where
827 private JCTree treeForDiagnostics(Env<AttrContext> env) {
828 return env.info.preferredTreeForDiagnostics != null ? env.info.preferredTreeForDiagnostics : env.tree;
829 }
830
831 /**
832 * Does the actual argument conforms to the corresponding formal?
833 */
834 abstract void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn);
835
836 protected void reportMC(DiagnosticPosition pos, MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) {
837 boolean inferDiag = inferenceContext != infer.emptyContext;
838 if (inferDiag && (!diag.inferKey.equals(diag.basicKey))) {
839 Object[] args2 = new Object[args.length + 1];
840 System.arraycopy(args, 0, args2, 1, args.length);
841 args2[0] = inferenceContext.inferenceVars();
842 args = args2;
843 }
844 String key = inferDiag ? diag.inferKey : diag.basicKey;
845 throw inferDiag ?
846 infer.error(diags.create(DiagnosticType.FRAGMENT, log.currentSource(), pos, key, args)) :
847 getMethodCheckFailure().setMessage(diags.create(DiagnosticType.FRAGMENT, log.currentSource(), pos, key, args));
848 }
849
850 /**
851 * To eliminate the overhead associated with allocating an exception object in such an
852 * hot execution path, we use flyweight pattern - and share the same exception instance
853 * across multiple method check failures.
854 */
855 class SharedInapplicableMethodException extends InapplicableMethodException {
856 private static final long serialVersionUID = 0;
857
858 SharedInapplicableMethodException() {
859 super(null, Resolve.this.dumpStacktraceOnError);
860 }
861
862 SharedInapplicableMethodException setMessage(JCDiagnostic details) {
863 this.diagnostic = details;
864 return this;
865 }
866 }
867
868 private SharedInapplicableMethodException methodCheckFailure;
869
870 public MethodCheck mostSpecificCheck(List<Type> actuals) {
871 return nilMethodCheck;
872 }
873
874 private SharedInapplicableMethodException getMethodCheckFailure() {
875 return methodCheckFailure == null ? methodCheckFailure = new SharedInapplicableMethodException() : methodCheckFailure;
876 }
877 }
878
879 /**
880 * Arity-based method check. A method is applicable if the number of actuals
881 * supplied conforms to the method signature.
882 */
883 MethodCheck arityMethodCheck = new AbstractMethodCheck() {
884 @Override
885 void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
886 //do nothing - actual always compatible to formals
887 }
888
889 @Override
890 public String toString() {
891 return "arityMethodCheck";
892 }
893 };
894
895 /**
896 * Main method applicability routine. Given a list of actual types A,
897 * a list of formal types F, determines whether the types in A are
898 * compatible (by method invocation conversion) with the types in F.
899 *
900 * Since this routine is shared between overload resolution and method
901 * type-inference, a (possibly empty) inference context is used to convert
902 * formal types to the corresponding 'undet' form ahead of a compatibility
903 * check so that constraints can be propagated and collected.
904 *
905 * Moreover, if one or more types in A is a deferred type, this routine uses
906 * DeferredAttr in order to perform deferred attribution. If one or more actual
907 * deferred types are stuck, they are placed in a queue and revisited later
908 * after the remainder of the arguments have been seen. If this is not sufficient
909 * to 'unstuck' the argument, a cyclic inference error is called out.
910 *
911 * A method check handler (see above) is used in order to report errors.
912 */
913 MethodCheck resolveMethodCheck = new AbstractMethodCheck() {
914
915 @Override
916 void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
917 ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn);
918 mresult.check(pos, actual);
919 }
920
921 @Override
922 public void argumentsAcceptable(final Env<AttrContext> env,
923 DeferredAttrContext deferredAttrContext,
924 List<Type> argtypes,
925 List<Type> formals,
926 Warner warn) {
927 super.argumentsAcceptable(env, deferredAttrContext, argtypes, formals, warn);
928 // should we check varargs element type accessibility?
929 if (deferredAttrContext.phase.isVarargsRequired()) {
930 if (deferredAttrContext.mode == AttrMode.CHECK) {
931 varargsAccessible(env, types.elemtype(formals.last()), deferredAttrContext.inferenceContext);
932 }
933 }
934 }
935
936 /**
937 * Test that the runtime array element type corresponding to 't' is accessible. 't' should be the
938 * varargs element type of either the method invocation type signature (after inference completes)
939 * or the method declaration signature (before inference completes).
940 */
941 private void varargsAccessible(final Env<AttrContext> env, final Type t, final InferenceContext inferenceContext) {
942 if (inferenceContext.free(t)) {
943 inferenceContext.addFreeTypeListener(List.of(t),
944 solvedContext -> varargsAccessible(env, solvedContext.asInstType(t), solvedContext));
945 } else {
946 if (!isAccessible(env, types.erasure(t))) {
947 Symbol location = env.enclClass.sym;
948 reportMC(env.tree, MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location);
949 }
950 }
951 }
952
953 private ResultInfo methodCheckResult(final boolean varargsCheck, Type to,
954 final DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner) {
955 CheckContext checkContext = new MethodCheckContext(!deferredAttrContext.phase.isBoxingRequired(), deferredAttrContext, rsWarner) {
956 MethodCheckDiag methodDiag = varargsCheck ?
957 MethodCheckDiag.VARARG_MISMATCH : MethodCheckDiag.ARG_MISMATCH;
958
959 @Override
960 public void report(DiagnosticPosition pos, JCDiagnostic details) {
961 reportMC(pos, methodDiag, deferredAttrContext.inferenceContext, details);
962 }
963 };
964 return new MethodResultInfo(to, checkContext);
965 }
966
967 @Override
968 public MethodCheck mostSpecificCheck(List<Type> actuals) {
969 return new MostSpecificCheck(actuals);
970 }
971
972 @Override
973 public String toString() {
974 return "resolveMethodCheck";
975 }
976 };
977
978 /**
979 * This class handles method reference applicability checks; since during
980 * these checks it's sometime possible to have inference variables on
981 * the actual argument types list, the method applicability check must be
982 * extended so that inference variables are 'opened' as needed.
983 */
984 class MethodReferenceCheck extends AbstractMethodCheck {
985
986 InferenceContext pendingInferenceContext;
987
988 MethodReferenceCheck(InferenceContext pendingInferenceContext) {
989 this.pendingInferenceContext = pendingInferenceContext;
990 }
991
992 @Override
993 void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
994 ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn);
995 mresult.check(pos, actual);
996 }
997
998 private ResultInfo methodCheckResult(final boolean varargsCheck, Type to,
999 final DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner) {
1000 CheckContext checkContext = new MethodCheckContext(!deferredAttrContext.phase.isBoxingRequired(), deferredAttrContext, rsWarner) {
1001 MethodCheckDiag methodDiag = varargsCheck ?
1002 MethodCheckDiag.VARARG_MISMATCH : MethodCheckDiag.ARG_MISMATCH;
1003
1004 @Override
1005 public boolean compatible(Type found, Type req, Warner warn) {
1006 found = pendingInferenceContext.asUndetVar(found);
1007 if (found.hasTag(UNDETVAR) && req.isPrimitive()) {
1008 req = types.boxedClass(req).type;
1009 }
1010 return super.compatible(found, req, warn);
1011 }
1012
1013 @Override
1014 public void report(DiagnosticPosition pos, JCDiagnostic details) {
1015 reportMC(pos, methodDiag, deferredAttrContext.inferenceContext, details);
1016 }
1017 };
1018 return new MethodResultInfo(to, checkContext);
1019 }
1020
1021 @Override
1022 public MethodCheck mostSpecificCheck(List<Type> actuals) {
1023 return new MostSpecificCheck(actuals);
1024 }
1025
1026 @Override
1027 public String toString() {
1028 return "MethodReferenceCheck";
1029 }
1030 }
1031
1032 /**
1033 * Check context to be used during method applicability checks. A method check
1034 * context might contain inference variables.
1035 */
1036 abstract class MethodCheckContext implements CheckContext {
1037
1038 boolean strict;
1039 DeferredAttrContext deferredAttrContext;
1040 Warner rsWarner;
1041
1042 public MethodCheckContext(boolean strict, DeferredAttrContext deferredAttrContext, Warner rsWarner) {
1043 this.strict = strict;
1044 this.deferredAttrContext = deferredAttrContext;
1045 this.rsWarner = rsWarner;
1046 }
1047
1048 public boolean compatible(Type found, Type req, Warner warn) {
1049 InferenceContext inferenceContext = deferredAttrContext.inferenceContext;
1050 return strict ?
1051 types.isSubtypeUnchecked(inferenceContext.asUndetVar(found), inferenceContext.asUndetVar(req), warn) :
1052 types.isConvertible(inferenceContext.asUndetVar(found), inferenceContext.asUndetVar(req), warn);
1053 }
1054
1055 public void report(DiagnosticPosition pos, JCDiagnostic details) {
1056 throw new InapplicableMethodException(details, Resolve.this.dumpStacktraceOnError);
1057 }
1058
1059 public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
1060 return rsWarner;
1061 }
1062
1063 public InferenceContext inferenceContext() {
1064 return deferredAttrContext.inferenceContext;
1065 }
1066
1067 public DeferredAttrContext deferredAttrContext() {
1068 return deferredAttrContext;
1069 }
1070
1071 @Override
1072 public String toString() {
1073 return "MethodCheckContext";
1074 }
1075 }
1076
1077 /**
1078 * ResultInfo class to be used during method applicability checks. Check
1079 * for deferred types goes through special path.
1080 */
1081 class MethodResultInfo extends ResultInfo {
1082
1083 public MethodResultInfo(Type pt, CheckContext checkContext) {
1084 attr.super(KindSelector.VAL, pt, checkContext);
1085 }
1086
1087 @Override
1088 protected Type check(DiagnosticPosition pos, Type found) {
1089 if (found.hasTag(DEFERRED)) {
1090 DeferredType dt = (DeferredType)found;
1091 return dt.check(this);
1092 } else {
1093 Type uResult = U(found);
1094 Type capturedType = pos == null || pos.getTree() == null ?
1095 types.capture(uResult) :
1096 checkContext.inferenceContext()
1097 .cachedCapture(pos.getTree(), uResult, true);
1098 return super.check(pos, chk.checkNonVoid(pos, capturedType));
1099 }
1100 }
1101
1102 /**
1103 * javac has a long-standing 'simplification' (see 6391995):
1104 * given an actual argument type, the method check is performed
1105 * on its upper bound. This leads to inconsistencies when an
1106 * argument type is checked against itself. For example, given
1107 * a type-variable T, it is not true that {@code U(T) <: T},
1108 * so we need to guard against that.
1109 */
1110 private Type U(Type found) {
1111 return found == pt ?
1112 found : types.cvarUpperBound(found);
1113 }
1114
1115 @Override
1116 protected MethodResultInfo dup(Type newPt) {
1117 return new MethodResultInfo(newPt, checkContext);
1118 }
1119
1120 @Override
1121 protected ResultInfo dup(CheckContext newContext) {
1122 return new MethodResultInfo(pt, newContext);
1123 }
1124
1125 @Override
1126 protected ResultInfo dup(Type newPt, CheckContext newContext) {
1127 return new MethodResultInfo(newPt, newContext);
1128 }
1129 }
1130
1131 /**
1132 * Most specific method applicability routine. Given a list of actual types A,
1133 * a list of formal types F1, and a list of formal types F2, the routine determines
1134 * as to whether the types in F1 can be considered more specific than those in F2 w.r.t.
1135 * argument types A.
1136 */
1137 class MostSpecificCheck implements MethodCheck {
1138
1139 List<Type> actuals;
1140
1141 MostSpecificCheck(List<Type> actuals) {
1142 this.actuals = actuals;
1143 }
1144
1145 @Override
1146 public void argumentsAcceptable(final Env<AttrContext> env,
1147 DeferredAttrContext deferredAttrContext,
1148 List<Type> formals1,
1149 List<Type> formals2,
1150 Warner warn) {
1151 formals2 = adjustArgs(formals2, deferredAttrContext.msym, formals1.length(), deferredAttrContext.phase.isVarargsRequired());
1152 while (formals2.nonEmpty()) {
1153 ResultInfo mresult = methodCheckResult(formals2.head, deferredAttrContext, warn, actuals.head);
1154 mresult.check(null, formals1.head);
1155 formals1 = formals1.tail;
1156 formals2 = formals2.tail;
1157 actuals = actuals.isEmpty() ? actuals : actuals.tail;
1158 }
1159 }
1160
1161 /**
1162 * Create a method check context to be used during the most specific applicability check
1163 */
1164 ResultInfo methodCheckResult(Type to, DeferredAttr.DeferredAttrContext deferredAttrContext,
1165 Warner rsWarner, Type actual) {
1166 return attr.new ResultInfo(KindSelector.VAL, to,
1167 new MostSpecificCheckContext(deferredAttrContext, rsWarner, actual));
1168 }
1169
1170 /**
1171 * Subclass of method check context class that implements most specific
1172 * method conversion. If the actual type under analysis is a deferred type
1173 * a full blown structural analysis is carried out.
1174 */
1175 class MostSpecificCheckContext extends MethodCheckContext {
1176
1177 Type actual;
1178
1179 public MostSpecificCheckContext(DeferredAttrContext deferredAttrContext, Warner rsWarner, Type actual) {
1180 super(true, deferredAttrContext, rsWarner);
1181 this.actual = actual;
1182 }
1183
1184 public boolean compatible(Type found, Type req, Warner warn) {
1185 if (unrelatedFunctionalInterfaces(found, req) &&
1186 (actual != null && actual.getTag() == DEFERRED)) {
1187 DeferredType dt = (DeferredType) actual;
1188 JCTree speculativeTree = dt.speculativeTree(deferredAttrContext);
1189 if (speculativeTree != deferredAttr.stuckTree) {
1190 return functionalInterfaceMostSpecific(found, req, speculativeTree);
1191 }
1192 }
1193 return compatibleBySubtyping(found, req);
1194 }
1195
1196 private boolean compatibleBySubtyping(Type found, Type req) {
1197 if (!strict && found.isPrimitive() != req.isPrimitive()) {
1198 found = found.isPrimitive() ? types.boxedClass(found).type : types.unboxedType(found);
1199 }
1200 return types.isSubtypeNoCapture(found, deferredAttrContext.inferenceContext.asUndetVar(req));
1201 }
1202
1203 /** Whether {@code t} and {@code s} are unrelated functional interface types. */
1204 private boolean unrelatedFunctionalInterfaces(Type t, Type s) {
1205 return types.isFunctionalInterface(t.tsym) &&
1206 types.isFunctionalInterface(s.tsym) &&
1207 unrelatedInterfaces(t, s);
1208 }
1209
1210 /** Whether {@code t} and {@code s} are unrelated interface types; recurs on intersections. **/
1211 private boolean unrelatedInterfaces(Type t, Type s) {
1212 if (t.isCompound()) {
1213 for (Type ti : types.interfaces(t)) {
1214 if (!unrelatedInterfaces(ti, s)) {
1215 return false;
1216 }
1217 }
1218 return true;
1219 } else if (s.isCompound()) {
1220 for (Type si : types.interfaces(s)) {
1221 if (!unrelatedInterfaces(t, si)) {
1222 return false;
1223 }
1224 }
1225 return true;
1226 } else {
1227 return types.asSuper(t, s.tsym) == null && types.asSuper(s, t.tsym) == null;
1228 }
1229 }
1230
1231 /** Parameters {@code t} and {@code s} are unrelated functional interface types. */
1232 private boolean functionalInterfaceMostSpecific(Type t, Type s, JCTree tree) {
1233 Type tDesc;
1234 Type tDescNoCapture;
1235 Type sDesc;
1236 try {
1237 tDesc = types.findDescriptorType(types.capture(t));
1238 tDescNoCapture = types.findDescriptorType(t);
1239 sDesc = types.findDescriptorType(s);
1240 } catch (Types.FunctionDescriptorLookupError ex) {
1241 // don't report, a more meaningful error should be reported upstream
1242 return false;
1243 }
1244 final List<Type> tTypeParams = tDesc.getTypeArguments();
1245 final List<Type> tTypeParamsNoCapture = tDescNoCapture.getTypeArguments();
1246 final List<Type> sTypeParams = sDesc.getTypeArguments();
1247
1248 // compare type parameters
1249 if (tDesc.hasTag(FORALL) && !types.hasSameBounds((ForAll) tDesc, (ForAll) tDescNoCapture)) {
1250 return false;
1251 }
1252 // can't use Types.hasSameBounds on sDesc because bounds may have ivars
1253 List<Type> tIter = tTypeParams;
1254 List<Type> sIter = sTypeParams;
1255 while (tIter.nonEmpty() && sIter.nonEmpty()) {
1256 Type tBound = tIter.head.getUpperBound();
1257 Type sBound = types.subst(sIter.head.getUpperBound(), sTypeParams, tTypeParams);
1258 if (tBound.containsAny(tTypeParams) && inferenceContext().free(sBound)) {
1259 return false;
1260 }
1261 if (!types.isSameType(tBound, inferenceContext().asUndetVar(sBound))) {
1262 return false;
1263 }
1264 tIter = tIter.tail;
1265 sIter = sIter.tail;
1266 }
1267 if (!tIter.isEmpty() || !sIter.isEmpty()) {
1268 return false;
1269 }
1270
1271 // compare parameters
1272 List<Type> tParams = tDesc.getParameterTypes();
1273 List<Type> tParamsNoCapture = tDescNoCapture.getParameterTypes();
1274 List<Type> sParams = sDesc.getParameterTypes();
1275 while (tParams.nonEmpty() && tParamsNoCapture.nonEmpty() && sParams.nonEmpty()) {
1276 Type tParam = tParams.head;
1277 Type tParamNoCapture = types.subst(tParamsNoCapture.head, tTypeParamsNoCapture, tTypeParams);
1278 Type sParam = types.subst(sParams.head, sTypeParams, tTypeParams);
1279 if (tParam.containsAny(tTypeParams) && inferenceContext().free(sParam)) {
1280 return false;
1281 }
1282 if (!types.isSubtype(inferenceContext().asUndetVar(sParam), tParam)) {
1283 return false;
1284 }
1285 if (!types.isSameType(tParamNoCapture, inferenceContext().asUndetVar(sParam))) {
1286 return false;
1287 }
1288 tParams = tParams.tail;
1289 tParamsNoCapture = tParamsNoCapture.tail;
1290 sParams = sParams.tail;
1291 }
1292 if (!tParams.isEmpty() || !tParamsNoCapture.isEmpty() || !sParams.isEmpty()) {
1293 return false;
1294 }
1295
1296 // compare returns
1297 Type tRet = tDesc.getReturnType();
1298 Type sRet = types.subst(sDesc.getReturnType(), sTypeParams, tTypeParams);
1299 if (tRet.containsAny(tTypeParams) && inferenceContext().free(sRet)) {
1300 return false;
1301 }
1302 MostSpecificFunctionReturnChecker msc = new MostSpecificFunctionReturnChecker(tRet, sRet);
1303 msc.scan(tree);
1304 return msc.result;
1305 }
1306
1307 /**
1308 * Tests whether one functional interface type can be considered more specific
1309 * than another unrelated functional interface type for the scanned expression.
1310 */
1311 class MostSpecificFunctionReturnChecker extends DeferredAttr.PolyScanner {
1312
1313 final Type tRet;
1314 final Type sRet;
1315 boolean result;
1316
1317 /** Parameters {@code t} and {@code s} are unrelated functional interface types. */
1318 MostSpecificFunctionReturnChecker(Type tRet, Type sRet) {
1319 this.tRet = tRet;
1320 this.sRet = sRet;
1321 result = true;
1322 }
1323
1324 @Override
1325 void skip(JCTree tree) {
1326 result = false;
1327 }
1328
1329 @Override
1330 public void visitConditional(JCConditional tree) {
1331 scan(asExpr(tree.truepart));
1332 scan(asExpr(tree.falsepart));
1333 }
1334
1335 @Override
1336 public void visitReference(JCMemberReference tree) {
1337 if (sRet.hasTag(VOID)) {
1338 // do nothing
1339 } else if (tRet.hasTag(VOID)) {
1340 result = false;
1341 } else if (tRet.isPrimitive() != sRet.isPrimitive()) {
1342 boolean retValIsPrimitive =
1343 tree.refPolyKind == PolyKind.STANDALONE &&
1344 tree.sym.type.getReturnType().isPrimitive();
1345 result &= (retValIsPrimitive == tRet.isPrimitive()) &&
1346 (retValIsPrimitive != sRet.isPrimitive());
1347 } else {
1348 result &= compatibleBySubtyping(tRet, sRet);
1349 }
1350 }
1351
1352 @Override
1353 public void visitParens(JCParens tree) {
1354 scan(asExpr(tree.expr));
1355 }
1356
1357 @Override
1358 public void visitLambda(JCLambda tree) {
1359 if (sRet.hasTag(VOID)) {
1360 // do nothing
1361 } else if (tRet.hasTag(VOID)) {
1362 result = false;
1363 } else {
1364 List<JCExpression> lambdaResults = lambdaResults(tree);
1365 if (!lambdaResults.isEmpty() && unrelatedFunctionalInterfaces(tRet, sRet)) {
1366 for (JCExpression expr : lambdaResults) {
1367 result &= functionalInterfaceMostSpecific(tRet, sRet, expr);
1368 }
1369 } else if (!lambdaResults.isEmpty() && tRet.isPrimitive() != sRet.isPrimitive()) {
1370 for (JCExpression expr : lambdaResults) {
1371 boolean retValIsPrimitive = expr.isStandalone() && expr.type.isPrimitive();
1372 result &= (retValIsPrimitive == tRet.isPrimitive()) &&
1373 (retValIsPrimitive != sRet.isPrimitive());
1374 }
1375 } else {
1376 result &= compatibleBySubtyping(tRet, sRet);
1377 }
1378 }
1379 }
1380 //where
1381
1382 private List<JCExpression> lambdaResults(JCLambda lambda) {
1383 if (lambda.getBodyKind() == JCTree.JCLambda.BodyKind.EXPRESSION) {
1384 return List.of(asExpr((JCExpression) lambda.body));
1385 } else {
1386 final ListBuffer<JCExpression> buffer = new ListBuffer<>();
1387 DeferredAttr.LambdaReturnScanner lambdaScanner =
1388 new DeferredAttr.LambdaReturnScanner() {
1389 @Override
1390 public void visitReturn(JCReturn tree) {
1391 if (tree.expr != null) {
1392 buffer.append(asExpr(tree.expr));
1393 }
1394 }
1395 };
1396 lambdaScanner.scan(lambda.body);
1397 return buffer.toList();
1398 }
1399 }
1400
1401 private JCExpression asExpr(JCExpression expr) {
1402 if (expr.type.hasTag(DEFERRED)) {
1403 JCTree speculativeTree = ((DeferredType)expr.type).speculativeTree(deferredAttrContext);
1404 if (speculativeTree != deferredAttr.stuckTree) {
1405 expr = (JCExpression)speculativeTree;
1406 }
1407 }
1408 return expr;
1409 }
1410 }
1411
1412 }
1413
1414 public MethodCheck mostSpecificCheck(List<Type> actuals) {
1415 Assert.error("Cannot get here!");
1416 return null;
1417 }
1418 }
1419
1420 public static class InapplicableMethodException extends CompilerInternalException {
1421 private static final long serialVersionUID = 0;
1422
1423 transient JCDiagnostic diagnostic;
1424
1425 InapplicableMethodException(JCDiagnostic diag, boolean dumpStackTraceOnError) {
1426 super(dumpStackTraceOnError);
1427 this.diagnostic = diag;
1428 }
1429
1430 public JCDiagnostic getDiagnostic() {
1431 return diagnostic;
1432 }
1433 }
1434
1435 /* ***************************************************************************
1436 * Symbol lookup
1437 * the following naming conventions for arguments are used
1438 *
1439 * env is the environment where the symbol was mentioned
1440 * site is the type of which the symbol is a member
1441 * name is the symbol's name
1442 * if no arguments are given
1443 * argtypes are the value arguments, if we search for a method
1444 *
1445 * If no symbol was found, a ResolveError detailing the problem is returned.
1446 ****************************************************************************/
1447
1448 /** Find field. Synthetic fields are always skipped.
1449 * @param env The current environment.
1450 * @param site The original type from where the selection takes place.
1451 * @param name The name of the field.
1452 * @param c The class to search for the field. This is always
1453 * a superclass or implemented interface of site's class.
1454 */
1455 Symbol findField(Env<AttrContext> env,
1456 Type site,
1457 Name name,
1458 TypeSymbol c) {
1459 while (c.type.hasTag(TYPEVAR))
1460 c = c.type.getUpperBound().tsym;
1461 Symbol bestSoFar = varNotFound;
1462 Symbol sym;
1463 for (Symbol s : c.members().getSymbolsByName(name)) {
1464 if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) {
1465 return isAccessible(env, site, s)
1466 ? s : new AccessError(env, site, s);
1467 }
1468 }
1469 Type st = types.supertype(c.type);
1470 if (st != null && (st.hasTag(CLASS) || st.hasTag(TYPEVAR))) {
1471 sym = findField(env, site, name, st.tsym);
1472 bestSoFar = bestOf(bestSoFar, sym);
1473 }
1474 for (List<Type> l = types.interfaces(c.type);
1475 bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
1476 l = l.tail) {
1477 sym = findField(env, site, name, l.head.tsym);
1478 if (bestSoFar.exists() && sym.exists() &&
1479 sym.owner != bestSoFar.owner)
1480 bestSoFar = new AmbiguityError(bestSoFar, sym);
1481 else
1482 bestSoFar = bestOf(bestSoFar, sym);
1483 }
1484 return bestSoFar;
1485 }
1486
1487 /** Resolve a field identifier, throw a fatal error if not found.
1488 * @param pos The position to use for error reporting.
1489 * @param env The environment current at the method invocation.
1490 * @param site The type of the qualifying expression, in which
1491 * identifier is searched.
1492 * @param name The identifier's name.
1493 */
1494 public VarSymbol resolveInternalField(DiagnosticPosition pos, Env<AttrContext> env,
1495 Type site, Name name) {
1496 Symbol sym = findField(env, site, name, site.tsym);
1497 if (sym.kind == VAR) return (VarSymbol)sym;
1498 else throw new FatalError(
1499 diags.fragment(Fragments.FatalErrCantLocateField(name)));
1500 }
1501
1502 /** Find unqualified variable or field with given name.
1503 * Synthetic fields always skipped.
1504 * @param pos The position to use for error reporting.
1505 * @param env The current environment.
1506 * @param name The name of the variable or field.
1507 */
1508 Symbol findVar(DiagnosticPosition pos, Env<AttrContext> env, Name name) {
1509 Symbol bestSoFar = varNotFound;
1510 Env<AttrContext> env1 = env;
1511 boolean staticOnly = false;
1512 while (env1.outer != null) {
1513 Symbol sym = null;
1514 for (Symbol s : env1.info.scope.getSymbolsByName(name)) {
1515 if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) {
1516 sym = s;
1517 if (staticOnly) {
1518 return new StaticError(sym);
1519 }
1520 break;
1521 }
1522 }
1523 if (isStatic(env1)) staticOnly = true;
1524 if (sym == null) {
1525 sym = findField(env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
1526 }
1527 if (sym.exists()) {
1528 if (sym.kind == VAR &&
1529 sym.owner.kind == TYP &&
1530 (sym.flags() & STATIC) == 0) {
1531 if (staticOnly)
1532 return new StaticError(sym);
1533 if (env1.info.ctorPrologue && !isAllowedEarlyReference(pos, env1, (VarSymbol)sym))
1534 return new RefBeforeCtorCalledError(sym);
1535 }
1536 return sym;
1537 } else {
1538 bestSoFar = bestOf(bestSoFar, sym);
1539 }
1540
1541 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
1542 env1 = env1.outer;
1543 }
1544
1545 Symbol sym = findField(env, syms.predefClass.type, name, syms.predefClass);
1546 if (sym.exists())
1547 return sym;
1548 if (bestSoFar.exists())
1549 return bestSoFar;
1550
1551 Symbol origin = null;
1552 for (Scope sc : new Scope[] { env.toplevel.namedImportScope, env.toplevel.starImportScope }) {
1553 for (Symbol currentSymbol : sc.getSymbolsByName(name)) {
1554 if (currentSymbol.kind != VAR)
1555 continue;
1556 // invariant: sym.kind == Symbol.Kind.VAR
1557 if (!bestSoFar.kind.isResolutionError() &&
1558 currentSymbol.owner != bestSoFar.owner)
1559 return new AmbiguityError(bestSoFar, currentSymbol);
1560 else if (!bestSoFar.kind.betterThan(VAR)) {
1561 origin = sc.getOrigin(currentSymbol).owner;
1562 bestSoFar = isAccessible(env, origin.type, currentSymbol)
1563 ? currentSymbol : new AccessError(env, origin.type, currentSymbol);
1564 }
1565 }
1566 if (bestSoFar.exists()) break;
1567 }
1568 if (bestSoFar.kind == VAR && bestSoFar.owner.type != origin.type)
1569 return bestSoFar.clone(origin);
1570 else
1571 return bestSoFar;
1572 }
1573
1574 Warner noteWarner = new Warner();
1575
1576 /** Select the best method for a call site among two choices.
1577 * @param env The current environment.
1578 * @param site The original type from where the
1579 * selection takes place.
1580 * @param argtypes The invocation's value arguments,
1581 * @param typeargtypes The invocation's type arguments,
1582 * @param sym Proposed new best match.
1583 * @param bestSoFar Previously found best match.
1584 * @param allowBoxing Allow boxing conversions of arguments.
1585 * @param useVarargs Box trailing arguments into an array for varargs.
1586 */
1587 @SuppressWarnings("fallthrough")
1588 Symbol selectBest(Env<AttrContext> env,
1589 Type site,
1590 List<Type> argtypes,
1591 List<Type> typeargtypes,
1592 Symbol sym,
1593 Symbol bestSoFar,
1594 boolean allowBoxing,
1595 boolean useVarargs) {
1596 if (sym.kind == ERR ||
1597 (site.tsym != sym.owner && !sym.isInheritedIn(site.tsym, types)) ||
1598 !notOverriddenIn(site, sym)) {
1599 return bestSoFar;
1600 } else if (useVarargs && (sym.flags() & VARARGS) == 0) {
1601 return bestSoFar.kind.isResolutionError() ?
1602 new BadVarargsMethod((ResolveError)bestSoFar.baseSymbol()) :
1603 bestSoFar;
1604 }
1605 Assert.check(!sym.kind.isResolutionError());
1606 try {
1607 types.noWarnings.clear();
1608 Type mt = rawInstantiate(env, site, sym, null, argtypes, typeargtypes,
1609 allowBoxing, useVarargs, types.noWarnings);
1610 currentResolutionContext.addApplicableCandidate(sym, mt);
1611 } catch (InapplicableMethodException ex) {
1612 currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic());
1613 // Currently, an InapplicableMethodException occurs.
1614 // If bestSoFar.kind was ABSENT_MTH, return an InapplicableSymbolError(kind is WRONG_MTH).
1615 // If bestSoFar.kind was HIDDEN(AccessError)/WRONG_MTH/WRONG_MTHS, return an InapplicableSymbolsError(kind is WRONG_MTHS).
1616 // See JDK-8255968 for more information.
1617 switch (bestSoFar.kind) {
1618 case ABSENT_MTH:
1619 return new InapplicableSymbolError(currentResolutionContext);
1620 case HIDDEN:
1621 if (bestSoFar instanceof AccessError accessError) {
1622 // Add the JCDiagnostic of previous AccessError to the currentResolutionContext
1623 // and construct InapplicableSymbolsError.
1624 // Intentionally fallthrough.
1625 currentResolutionContext.addInapplicableCandidate(accessError.sym,
1626 accessError.getDiagnostic(JCDiagnostic.DiagnosticType.FRAGMENT, null, null, site, null, argtypes, typeargtypes));
1627 } else {
1628 return bestSoFar;
1629 }
1630 case WRONG_MTH:
1631 bestSoFar = new InapplicableSymbolsError(currentResolutionContext);
1632 default:
1633 return bestSoFar;
1634 }
1635 }
1636 if (!isAccessible(env, site, sym)) {
1637 AccessError curAccessError = new AccessError(env, site, sym);
1638 JCDiagnostic curDiagnostic = curAccessError.getDiagnostic(JCDiagnostic.DiagnosticType.FRAGMENT, null, null, site, null, argtypes, typeargtypes);
1639 // Currently, an AccessError occurs.
1640 // If bestSoFar.kind was ABSENT_MTH, return an AccessError(kind is HIDDEN).
1641 // If bestSoFar.kind was HIDDEN(AccessError), WRONG_MTH, WRONG_MTHS, return an InapplicableSymbolsError(kind is WRONG_MTHS).
1642 // See JDK-8255968 for more information.
1643 if (bestSoFar.kind == ABSENT_MTH) {
1644 bestSoFar = curAccessError;
1645 } else if (bestSoFar.kind == WRONG_MTH) {
1646 // Add the JCDiagnostic of current AccessError to the currentResolutionContext
1647 // and construct InapplicableSymbolsError.
1648 currentResolutionContext.addInapplicableCandidate(sym, curDiagnostic);
1649 bestSoFar = new InapplicableSymbolsError(currentResolutionContext);
1650 } else if (bestSoFar.kind == WRONG_MTHS) {
1651 // Add the JCDiagnostic of current AccessError to the currentResolutionContext
1652 currentResolutionContext.addInapplicableCandidate(sym, curDiagnostic);
1653 } else if (bestSoFar.kind == HIDDEN && bestSoFar instanceof AccessError accessError) {
1654 // Add the JCDiagnostics of previous and current AccessError to the currentResolutionContext
1655 // and construct InapplicableSymbolsError.
1656 currentResolutionContext.addInapplicableCandidate(accessError.sym,
1657 accessError.getDiagnostic(JCDiagnostic.DiagnosticType.FRAGMENT, null, null, site, null, argtypes, typeargtypes));
1658 currentResolutionContext.addInapplicableCandidate(sym, curDiagnostic);
1659 bestSoFar = new InapplicableSymbolsError(currentResolutionContext);
1660 }
1661 return bestSoFar;
1662 }
1663 return (bestSoFar.kind.isResolutionError() && bestSoFar.kind != AMBIGUOUS)
1664 ? sym
1665 : mostSpecific(argtypes, sym, bestSoFar, env, site, useVarargs);
1666 }
1667
1668 /* Return the most specific of the two methods for a call,
1669 * given that both are accessible and applicable.
1670 * @param m1 A new candidate for most specific.
1671 * @param m2 The previous most specific candidate.
1672 * @param env The current environment.
1673 * @param site The original type from where the selection
1674 * takes place.
1675 * @param allowBoxing Allow boxing conversions of arguments.
1676 * @param useVarargs Box trailing arguments into an array for varargs.
1677 */
1678 Symbol mostSpecific(List<Type> argtypes, Symbol m1,
1679 Symbol m2,
1680 Env<AttrContext> env,
1681 final Type site,
1682 boolean useVarargs) {
1683 switch (m2.kind) {
1684 case MTH:
1685 if (m1 == m2) return m1;
1686 boolean m1SignatureMoreSpecific =
1687 signatureMoreSpecific(argtypes, env, site, m1, m2, useVarargs);
1688 boolean m2SignatureMoreSpecific =
1689 signatureMoreSpecific(argtypes, env, site, m2, m1, useVarargs);
1690 if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) {
1691 Type mt1 = types.memberType(site, m1);
1692 Type mt2 = types.memberType(site, m2);
1693 if (!types.overrideEquivalent(mt1, mt2))
1694 return ambiguityError(m1, m2);
1695
1696 // same signature; select (a) the non-bridge method, or
1697 // (b) the one that overrides the other, or (c) the concrete
1698 // one, or (d) merge both abstract signatures
1699 if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE))
1700 return ((m1.flags() & BRIDGE) != 0) ? m2 : m1;
1701
1702 if (m1.baseSymbol() == m2.baseSymbol()) {
1703 // this is the same imported symbol which has been cloned twice.
1704 // Return the first one (either will do).
1705 return m1;
1706 }
1707
1708 // if one overrides or hides the other, use it
1709 TypeSymbol m1Owner = (TypeSymbol)m1.owner;
1710 TypeSymbol m2Owner = (TypeSymbol)m2.owner;
1711 // the two owners can never be the same if the target methods are compiled from source,
1712 // but we need to protect against cases where the methods are defined in some classfile
1713 // and make sure we issue an ambiguity error accordingly (by skipping the logic below).
1714 if (m1Owner != m2Owner) {
1715 if (types.asSuper(m1Owner.type, m2Owner) != null &&
1716 ((m1.owner.flags_field & INTERFACE) == 0 ||
1717 (m2.owner.flags_field & INTERFACE) != 0) &&
1718 m1.overrides(m2, m1Owner, types, false))
1719 return m1;
1720 if (types.asSuper(m2Owner.type, m1Owner) != null &&
1721 ((m2.owner.flags_field & INTERFACE) == 0 ||
1722 (m1.owner.flags_field & INTERFACE) != 0) &&
1723 m2.overrides(m1, m2Owner, types, false))
1724 return m2;
1725 }
1726 boolean m1Abstract = (m1.flags() & ABSTRACT) != 0;
1727 boolean m2Abstract = (m2.flags() & ABSTRACT) != 0;
1728 if (m1Abstract && !m2Abstract) return m2;
1729 if (m2Abstract && !m1Abstract) return m1;
1730 // both abstract or both concrete
1731 return ambiguityError(m1, m2);
1732 }
1733 if (m1SignatureMoreSpecific) return m1;
1734 if (m2SignatureMoreSpecific) return m2;
1735 return ambiguityError(m1, m2);
1736 case AMBIGUOUS:
1737 //compare m1 to ambiguous methods in m2
1738 AmbiguityError e = (AmbiguityError)m2.baseSymbol();
1739 boolean m1MoreSpecificThanAnyAmbiguous = true;
1740 boolean allAmbiguousMoreSpecificThanM1 = true;
1741 for (Symbol s : e.ambiguousSyms) {
1742 Symbol moreSpecific = mostSpecific(argtypes, m1, s, env, site, useVarargs);
1743 m1MoreSpecificThanAnyAmbiguous &= moreSpecific == m1;
1744 allAmbiguousMoreSpecificThanM1 &= moreSpecific == s;
1745 }
1746 if (m1MoreSpecificThanAnyAmbiguous)
1747 return m1;
1748 //if m1 is more specific than some ambiguous methods, but other ambiguous methods are
1749 //more specific than m1, add it as a new ambiguous method:
1750 if (!allAmbiguousMoreSpecificThanM1)
1751 e.addAmbiguousSymbol(m1);
1752 return e;
1753 default:
1754 throw new AssertionError();
1755 }
1756 }
1757 //where
1758 private boolean signatureMoreSpecific(List<Type> actuals, Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean useVarargs) {
1759 noteWarner.clear();
1760 int maxLength = Math.max(
1761 Math.max(m1.type.getParameterTypes().length(), actuals.length()),
1762 m2.type.getParameterTypes().length());
1763 MethodResolutionContext prevResolutionContext = currentResolutionContext;
1764 try {
1765 currentResolutionContext = new MethodResolutionContext();
1766 currentResolutionContext.step = prevResolutionContext.step;
1767 currentResolutionContext.methodCheck =
1768 prevResolutionContext.methodCheck.mostSpecificCheck(actuals);
1769 Type mst = instantiate(env, site, m2, null,
1770 adjustArgs(types.cvarLowerBounds(types.memberType(site, m1).getParameterTypes()), m1, maxLength, useVarargs), null,
1771 false, useVarargs, noteWarner);
1772 return mst != null &&
1773 !noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
1774 } finally {
1775 currentResolutionContext = prevResolutionContext;
1776 }
1777 }
1778
1779 List<Type> adjustArgs(List<Type> args, Symbol msym, int length, boolean allowVarargs) {
1780 if ((msym.flags() & VARARGS) != 0 && allowVarargs) {
1781 Type varargsElem = types.elemtype(args.last());
1782 if (varargsElem == null) {
1783 Assert.error("Bad varargs = " + args.last() + " " + msym);
1784 }
1785 List<Type> newArgs = args.reverse().tail.prepend(varargsElem).reverse();
1786 while (newArgs.length() < length) {
1787 newArgs = newArgs.append(newArgs.last());
1788 }
1789 return newArgs;
1790 } else {
1791 return args;
1792 }
1793 }
1794 //where
1795 Symbol ambiguityError(Symbol m1, Symbol m2) {
1796 if (((m1.flags() | m2.flags()) & CLASH) != 0) {
1797 return (m1.flags() & CLASH) == 0 ? m1 : m2;
1798 } else {
1799 return new AmbiguityError(m1, m2);
1800 }
1801 }
1802
1803 Symbol findMethodInScope(Env<AttrContext> env,
1804 Type site,
1805 Name name,
1806 List<Type> argtypes,
1807 List<Type> typeargtypes,
1808 Scope sc,
1809 Symbol bestSoFar,
1810 boolean allowBoxing,
1811 boolean useVarargs,
1812 boolean abstractok) {
1813 for (Symbol s : sc.getSymbolsByName(name, new LookupFilter(abstractok))) {
1814 bestSoFar = selectBest(env, site, argtypes, typeargtypes, s,
1815 bestSoFar, allowBoxing, useVarargs);
1816 }
1817 return bestSoFar;
1818 }
1819 //where
1820 class LookupFilter implements Predicate<Symbol> {
1821
1822 boolean abstractOk;
1823
1824 LookupFilter(boolean abstractOk) {
1825 this.abstractOk = abstractOk;
1826 }
1827
1828 @Override
1829 public boolean test(Symbol s) {
1830 long flags = s.flags();
1831 return s.kind == MTH &&
1832 (flags & SYNTHETIC) == 0 &&
1833 (abstractOk ||
1834 (flags & DEFAULT) != 0 ||
1835 (flags & ABSTRACT) == 0);
1836 }
1837 }
1838
1839 /** Find best qualified method matching given name, type and value
1840 * arguments.
1841 * @param env The current environment.
1842 * @param site The original type from where the selection
1843 * takes place.
1844 * @param name The method's name.
1845 * @param argtypes The method's value arguments.
1846 * @param typeargtypes The method's type arguments
1847 * @param allowBoxing Allow boxing conversions of arguments.
1848 * @param useVarargs Box trailing arguments into an array for varargs.
1849 */
1850 Symbol findMethod(Env<AttrContext> env,
1851 Type site,
1852 Name name,
1853 List<Type> argtypes,
1854 List<Type> typeargtypes,
1855 boolean allowBoxing,
1856 boolean useVarargs) {
1857 Symbol bestSoFar = methodNotFound;
1858 bestSoFar = findMethod(env,
1859 site,
1860 name,
1861 argtypes,
1862 typeargtypes,
1863 site.tsym.type,
1864 bestSoFar,
1865 allowBoxing,
1866 useVarargs);
1867 if (bestSoFar.kind == AMBIGUOUS) {
1868 AmbiguityError a_err = (AmbiguityError)bestSoFar.baseSymbol();
1869 bestSoFar = a_err.mergeAbstracts(site);
1870 }
1871 return bestSoFar;
1872 }
1873 // where
1874 private Symbol findMethod(Env<AttrContext> env,
1875 Type site,
1876 Name name,
1877 List<Type> argtypes,
1878 List<Type> typeargtypes,
1879 Type intype,
1880 Symbol bestSoFar,
1881 boolean allowBoxing,
1882 boolean useVarargs) {
1883 @SuppressWarnings({"unchecked","rawtypes"})
1884 List<Type>[] itypes = (List<Type>[])new List[] { List.<Type>nil(), List.<Type>nil() };
1885
1886 InterfaceLookupPhase iphase = InterfaceLookupPhase.ABSTRACT_OK;
1887 boolean isInterface = site.tsym.isInterface();
1888 for (TypeSymbol s : isInterface ? List.of(intype.tsym) : superclasses(intype)) {
1889 bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
1890 s.members(), bestSoFar, allowBoxing, useVarargs, true);
1891 if (name == names.init) return bestSoFar;
1892 iphase = (iphase == null) ? null : iphase.update(s, this);
1893 if (iphase != null) {
1894 for (Type itype : types.interfaces(s.type)) {
1895 itypes[iphase.ordinal()] = types.union(types.closure(itype), itypes[iphase.ordinal()]);
1896 }
1897 }
1898 }
1899
1900 Symbol concrete = bestSoFar.kind.isValid() &&
1901 (bestSoFar.flags() & ABSTRACT) == 0 ?
1902 bestSoFar : methodNotFound;
1903
1904 for (InterfaceLookupPhase iphase2 : InterfaceLookupPhase.values()) {
1905 //keep searching for abstract methods
1906 for (Type itype : itypes[iphase2.ordinal()]) {
1907 if (!itype.isInterface()) continue; //skip j.l.Object (included by Types.closure())
1908 if (iphase2 == InterfaceLookupPhase.DEFAULT_OK &&
1909 (itype.tsym.flags() & DEFAULT) == 0) continue;
1910 bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
1911 itype.tsym.members(), bestSoFar, allowBoxing, useVarargs, true);
1912 if (concrete != bestSoFar &&
1913 concrete.kind.isValid() &&
1914 bestSoFar.kind.isValid() &&
1915 types.isSubSignature(concrete.type, bestSoFar.type)) {
1916 //this is an hack - as javac does not do full membership checks
1917 //most specific ends up comparing abstract methods that might have
1918 //been implemented by some concrete method in a subclass and,
1919 //because of raw override, it is possible for an abstract method
1920 //to be more specific than the concrete method - so we need
1921 //to explicitly call that out (see CR 6178365)
1922 bestSoFar = concrete;
1923 }
1924 }
1925 }
1926 if (isInterface && bestSoFar.kind.isResolutionError()) {
1927 bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
1928 syms.objectType.tsym.members(), bestSoFar, allowBoxing, useVarargs, true);
1929 if (bestSoFar.kind.isValid()) {
1930 Symbol baseSymbol = bestSoFar;
1931 bestSoFar = new MethodSymbol(bestSoFar.flags_field, bestSoFar.name, bestSoFar.type, intype.tsym) {
1932 @Override
1933 public Symbol baseSymbol() {
1934 return baseSymbol;
1935 }
1936 };
1937 }
1938 }
1939 return bestSoFar;
1940 }
1941
1942 enum InterfaceLookupPhase {
1943 ABSTRACT_OK() {
1944 @Override
1945 InterfaceLookupPhase update(Symbol s, Resolve rs) {
1946 //We should not look for abstract methods if receiver is a concrete class
1947 //(as concrete classes are expected to implement all abstracts coming
1948 //from superinterfaces)
1949 if ((s.flags() & (ABSTRACT | INTERFACE | ENUM)) != 0) {
1950 return this;
1951 } else {
1952 return DEFAULT_OK;
1953 }
1954 }
1955 },
1956 DEFAULT_OK() {
1957 @Override
1958 InterfaceLookupPhase update(Symbol s, Resolve rs) {
1959 return this;
1960 }
1961 };
1962
1963 abstract InterfaceLookupPhase update(Symbol s, Resolve rs);
1964 }
1965
1966 /**
1967 * Return an Iterable object to scan the superclasses of a given type.
1968 * It's crucial that the scan is done lazily, as we don't want to accidentally
1969 * access more supertypes than strictly needed (as this could trigger completion
1970 * errors if some of the not-needed supertypes are missing/ill-formed).
1971 */
1972 Iterable<TypeSymbol> superclasses(final Type intype) {
1973 return () -> new Iterator<TypeSymbol>() {
1974
1975 List<TypeSymbol> seen = List.nil();
1976 TypeSymbol currentSym = symbolFor(intype);
1977 TypeSymbol prevSym = null;
1978
1979 public boolean hasNext() {
1980 if (currentSym == syms.noSymbol) {
1981 currentSym = symbolFor(types.supertype(prevSym.type));
1982 }
1983 return currentSym != null;
1984 }
1985
1986 public TypeSymbol next() {
1987 prevSym = currentSym;
1988 currentSym = syms.noSymbol;
1989 Assert.check(prevSym != null || prevSym != syms.noSymbol);
1990 return prevSym;
1991 }
1992
1993 public void remove() {
1994 throw new UnsupportedOperationException();
1995 }
1996
1997 TypeSymbol symbolFor(Type t) {
1998 if (!t.hasTag(CLASS) &&
1999 !t.hasTag(TYPEVAR)) {
2000 return null;
2001 }
2002 t = types.skipTypeVars(t, false);
2003 if (seen.contains(t.tsym)) {
2004 //degenerate case in which we have a circular
2005 //class hierarchy - because of ill-formed classfiles
2006 return null;
2007 }
2008 seen = seen.prepend(t.tsym);
2009 return t.tsym;
2010 }
2011 };
2012 }
2013
2014 /** Find unqualified method matching given name, type and value arguments.
2015 * @param env The current environment.
2016 * @param name The method's name.
2017 * @param argtypes The method's value arguments.
2018 * @param typeargtypes The method's type arguments.
2019 * @param allowBoxing Allow boxing conversions of arguments.
2020 * @param useVarargs Box trailing arguments into an array for varargs.
2021 */
2022 Symbol findFun(Env<AttrContext> env, Name name,
2023 List<Type> argtypes, List<Type> typeargtypes,
2024 boolean allowBoxing, boolean useVarargs) {
2025 Symbol bestSoFar = methodNotFound;
2026 Env<AttrContext> env1 = env;
2027 boolean staticOnly = false;
2028 while (env1.outer != null) {
2029 if (isStatic(env1)) staticOnly = true;
2030 Assert.check(env1.info.preferredTreeForDiagnostics == null);
2031 env1.info.preferredTreeForDiagnostics = env.tree;
2032 try {
2033 Symbol sym = findMethod(
2034 env1, env1.enclClass.sym.type, name, argtypes, typeargtypes,
2035 allowBoxing, useVarargs);
2036 if (sym.exists()) {
2037 if (sym.kind == MTH &&
2038 sym.owner.kind == TYP &&
2039 (sym.flags() & STATIC) == 0) {
2040 if (staticOnly)
2041 return new StaticError(sym);
2042 if (env1.info.ctorPrologue && env1 == env)
2043 return new RefBeforeCtorCalledError(sym);
2044 }
2045 return sym;
2046 } else {
2047 bestSoFar = bestOf(bestSoFar, sym);
2048 }
2049 } finally {
2050 env1.info.preferredTreeForDiagnostics = null;
2051 }
2052 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
2053 env1 = env1.outer;
2054 }
2055
2056 Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
2057 typeargtypes, allowBoxing, useVarargs);
2058 if (sym.exists())
2059 return sym;
2060
2061 for (Symbol currentSym : env.toplevel.namedImportScope.getSymbolsByName(name)) {
2062 Symbol origin = env.toplevel.namedImportScope.getOrigin(currentSym).owner;
2063 if (currentSym.kind == MTH) {
2064 if (currentSym.owner.type != origin.type)
2065 currentSym = currentSym.clone(origin);
2066 if (!isAccessible(env, origin.type, currentSym))
2067 currentSym = new AccessError(env, origin.type, currentSym);
2068 bestSoFar = selectBest(env, origin.type,
2069 argtypes, typeargtypes,
2070 currentSym, bestSoFar,
2071 allowBoxing, useVarargs);
2072 }
2073 }
2074 if (bestSoFar.exists())
2075 return bestSoFar;
2076
2077 for (Symbol currentSym : env.toplevel.starImportScope.getSymbolsByName(name)) {
2078 Symbol origin = env.toplevel.starImportScope.getOrigin(currentSym).owner;
2079 if (currentSym.kind == MTH) {
2080 if (currentSym.owner.type != origin.type)
2081 currentSym = currentSym.clone(origin);
2082 if (!isAccessible(env, origin.type, currentSym))
2083 currentSym = new AccessError(env, origin.type, currentSym);
2084 bestSoFar = selectBest(env, origin.type,
2085 argtypes, typeargtypes,
2086 currentSym, bestSoFar,
2087 allowBoxing, useVarargs);
2088 }
2089 }
2090 return bestSoFar;
2091 }
2092
2093 /** Load toplevel or member class with given fully qualified name and
2094 * verify that it is accessible.
2095 * @param env The current environment.
2096 * @param name The fully qualified name of the class to be loaded.
2097 */
2098 Symbol loadClass(Env<AttrContext> env, Name name, RecoveryLoadClass recoveryLoadClass) {
2099 try {
2100 ClassSymbol c = finder.loadClass(env.toplevel.modle, name);
2101 return isAccessible(env, c) ? c : new AccessError(env, null, c);
2102 } catch (ClassFinder.BadClassFile err) {
2103 return new BadClassFileError(err);
2104 } catch (CompletionFailure ex) {
2105 Symbol candidate = recoveryLoadClass.loadClass(env, name);
2106
2107 if (candidate != null) {
2108 return candidate;
2109 }
2110
2111 return typeNotFound;
2112 }
2113 }
2114
2115 public interface RecoveryLoadClass {
2116 Symbol loadClass(Env<AttrContext> env, Name name);
2117 }
2118
2119 private final RecoveryLoadClass noRecovery = (env, name) -> null;
2120
2121 private final RecoveryLoadClass doRecoveryLoadClass = new RecoveryLoadClass() {
2122 @Override public Symbol loadClass(Env<AttrContext> env, Name name) {
2123 List<Name> candidates = Convert.classCandidates(name);
2124 return lookupInvisibleSymbol(env, name,
2125 n -> () -> createCompoundIterator(candidates,
2126 c -> syms.getClassesForName(c)
2127 .iterator()),
2128 (ms, n) -> {
2129 for (Name candidate : candidates) {
2130 try {
2131 return finder.loadClass(ms, candidate);
2132 } catch (CompletionFailure cf) {
2133 //ignore
2134 }
2135 }
2136 return null;
2137 }, sym -> sym.kind == Kind.TYP, typeNotFound);
2138 }
2139 };
2140
2141 private final RecoveryLoadClass namedImportScopeRecovery = (env, name) -> {
2142 Scope importScope = env.toplevel.namedImportScope;
2143 Symbol existing = importScope.findFirst(Convert.shortName(name),
2144 sym -> sym.kind == TYP && sym.flatName() == name);
2145
2146 if (existing != null) {
2147 return new InvisibleSymbolError(env, true, existing);
2148 }
2149 return null;
2150 };
2151
2152 private final RecoveryLoadClass starImportScopeRecovery =
2153 onDemandImportScopeRecovery(false);
2154
2155 private final RecoveryLoadClass moduleImportScopeRecovery =
2156 onDemandImportScopeRecovery(true);
2157
2158 private RecoveryLoadClass onDemandImportScopeRecovery(boolean moduleImportScope) {
2159 return (env, name) -> {
2160 Scope importScope = moduleImportScope ? env.toplevel.moduleImportScope
2161 : env.toplevel.starImportScope;
2162 Symbol existing = importScope.findFirst(Convert.shortName(name),
2163 sym -> sym.kind == TYP && sym.flatName() == name);
2164
2165 if (existing != null) {
2166 try {
2167 existing = finder.loadClass(existing.packge().modle, name);
2168
2169 return new InvisibleSymbolError(env, true, existing);
2170 } catch (CompletionFailure cf) {
2171 //ignore
2172 }
2173 }
2174
2175 return null;
2176 };
2177 }
2178
2179 Symbol lookupPackage(Env<AttrContext> env, Name name) {
2180 PackageSymbol pack = syms.lookupPackage(env.toplevel.modle, name);
2181
2182 if (allowModules && isImportOnDemand(env, name)) {
2183 if (pack.members().isEmpty()) {
2184 return lookupInvisibleSymbol(env, name, syms::getPackagesForName, syms::enterPackage, sym -> {
2185 sym.complete();
2186 return !sym.members().isEmpty();
2187 }, pack);
2188 }
2189 }
2190
2191 return pack;
2192 }
2193
2194 private boolean isImportOnDemand(Env<AttrContext> env, Name name) {
2195 if (!env.tree.hasTag(IMPORT))
2196 return false;
2197
2198 JCTree qualid = ((JCImport) env.tree).qualid;
2199
2200 if (!qualid.hasTag(SELECT))
2201 return false;
2202
2203 if (TreeInfo.name(qualid) != names.asterisk)
2204 return false;
2205
2206 return TreeInfo.fullName(((JCFieldAccess) qualid).selected) == name;
2207 }
2208
2209 private <S extends Symbol> Symbol lookupInvisibleSymbol(Env<AttrContext> env,
2210 Name name,
2211 Function<Name, Iterable<S>> get,
2212 BiFunction<ModuleSymbol, Name, S> load,
2213 Predicate<S> validate,
2214 Symbol defaultResult) {
2215 //even if a class/package cannot be found in the current module and among packages in modules
2216 //it depends on that are exported for any or this module, the class/package may exist internally
2217 //in some of these modules, or may exist in a module on which this module does not depend.
2218 //Provide better diagnostic in such cases by looking for the class in any module:
2219 Iterable<? extends S> candidates = get.apply(name);
2220
2221 for (S sym : candidates) {
2222 if (validate.test(sym))
2223 return createInvisibleSymbolError(env, sym);
2224 }
2225
2226 Set<ModuleSymbol> recoverableModules = new HashSet<>(syms.getAllModules());
2227
2228 recoverableModules.add(syms.unnamedModule);
2229 recoverableModules.remove(env.toplevel.modle);
2230
2231 for (ModuleSymbol ms : recoverableModules) {
2232 //avoid overly eager completing classes from source-based modules, as those
2233 //may not be completable with the current compiler settings:
2234 if (ms.sourceLocation == null) {
2235 if (ms.classLocation == null) {
2236 ms = moduleFinder.findModule(ms);
2237 }
2238
2239 if (ms.kind != ERR) {
2240 S sym = load.apply(ms, name);
2241
2242 if (sym != null && validate.test(sym)) {
2243 return createInvisibleSymbolError(env, sym);
2244 }
2245 }
2246 }
2247 }
2248
2249 return defaultResult;
2250 }
2251
2252 private Symbol createInvisibleSymbolError(Env<AttrContext> env, Symbol sym) {
2253 if (symbolPackageVisible(env, sym)) {
2254 return new AccessError(env, null, sym);
2255 } else {
2256 return new InvisibleSymbolError(env, false, sym);
2257 }
2258 }
2259
2260 private boolean symbolPackageVisible(Env<AttrContext> env, Symbol sym) {
2261 ModuleSymbol envMod = env.toplevel.modle;
2262 PackageSymbol symPack = sym.packge();
2263 return envMod == symPack.modle ||
2264 envMod.visiblePackages.containsKey(symPack.fullname);
2265 }
2266
2267 /**
2268 * Find a type declared in a scope (not inherited). Return null
2269 * if none is found.
2270 * @param env The current environment.
2271 * @param site The original type from where the selection takes
2272 * place.
2273 * @param name The type's name.
2274 * @param c The class to search for the member type. This is
2275 * always a superclass or implemented interface of
2276 * site's class.
2277 */
2278 Symbol findImmediateMemberType(Env<AttrContext> env,
2279 Type site,
2280 Name name,
2281 TypeSymbol c) {
2282 for (Symbol sym : c.members().getSymbolsByName(name)) {
2283 if (sym.kind == TYP) {
2284 return isAccessible(env, site, sym)
2285 ? sym
2286 : new AccessError(env, site, sym);
2287 }
2288 }
2289 return typeNotFound;
2290 }
2291
2292 /** Find a member type inherited from a superclass or interface.
2293 * @param env The current environment.
2294 * @param site The original type from where the selection takes
2295 * place.
2296 * @param name The type's name.
2297 * @param c The class to search for the member type. This is
2298 * always a superclass or implemented interface of
2299 * site's class.
2300 */
2301 Symbol findInheritedMemberType(Env<AttrContext> env,
2302 Type site,
2303 Name name,
2304 TypeSymbol c) {
2305 Symbol bestSoFar = typeNotFound;
2306 Symbol sym;
2307 Type st = types.supertype(c.type);
2308 if (st != null && st.hasTag(CLASS)) {
2309 sym = findMemberType(env, site, name, st.tsym);
2310 bestSoFar = bestOf(bestSoFar, sym);
2311 }
2312 for (List<Type> l = types.interfaces(c.type);
2313 bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
2314 l = l.tail) {
2315 sym = findMemberType(env, site, name, l.head.tsym);
2316 if (!bestSoFar.kind.isResolutionError() &&
2317 !sym.kind.isResolutionError() &&
2318 sym.owner != bestSoFar.owner)
2319 bestSoFar = new AmbiguityError(bestSoFar, sym);
2320 else
2321 bestSoFar = bestOf(bestSoFar, sym);
2322 }
2323 return bestSoFar;
2324 }
2325
2326 /** Find qualified member type.
2327 * @param env The current environment.
2328 * @param site The original type from where the selection takes
2329 * place.
2330 * @param name The type's name.
2331 * @param c The class to search for the member type. This is
2332 * always a superclass or implemented interface of
2333 * site's class.
2334 */
2335 Symbol findMemberType(Env<AttrContext> env,
2336 Type site,
2337 Name name,
2338 TypeSymbol c) {
2339 Symbol sym = findImmediateMemberType(env, site, name, c);
2340
2341 if (sym != typeNotFound)
2342 return sym;
2343
2344 return findInheritedMemberType(env, site, name, c);
2345
2346 }
2347
2348 /** Find a global type in given scope and load corresponding class.
2349 * @param env The current environment.
2350 * @param scope The scope in which to look for the type.
2351 * @param name The type's name.
2352 */
2353 Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name, RecoveryLoadClass recoveryLoadClass) {
2354 Symbol bestSoFar = typeNotFound;
2355 for (Symbol s : scope.getSymbolsByName(name)) {
2356 Symbol sym = loadClass(env, s.flatName(), recoveryLoadClass);
2357 if (bestSoFar.kind == TYP && sym.kind == TYP &&
2358 bestSoFar != sym)
2359 return new AmbiguityError(bestSoFar, sym);
2360 else
2361 bestSoFar = bestOf(bestSoFar, sym);
2362 }
2363 return bestSoFar;
2364 }
2365
2366 Symbol findTypeVar(Env<AttrContext> env, Name name, boolean staticOnly) {
2367 for (Symbol sym : env.info.scope.getSymbolsByName(name)) {
2368 if (sym.kind == TYP) {
2369 if (sym.type.hasTag(TYPEVAR) &&
2370 (staticOnly || (isStatic(env) && sym.owner.kind == TYP)))
2371 // if staticOnly is set, it means that we have recursed through a static declaration,
2372 // so type variable symbols should not be accessible. If staticOnly is unset, but
2373 // we are in a static declaration (field or method), we should not allow type-variables
2374 // defined in the enclosing class to "leak" into this context.
2375 return new StaticError(sym);
2376 return sym;
2377 }
2378 }
2379 return typeNotFound;
2380 }
2381
2382 /** Find an unqualified type symbol.
2383 * @param env The current environment.
2384 * @param name The type's name.
2385 */
2386 Symbol findType(Env<AttrContext> env, Name name) {
2387 if (name == names.empty)
2388 return typeNotFound; // do not allow inadvertent "lookup" of anonymous types
2389 Symbol bestSoFar = typeNotFound;
2390 Symbol sym;
2391 boolean staticOnly = false;
2392 for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) {
2393 // First, look for a type variable and the first member type
2394 final Symbol tyvar = findTypeVar(env1, name, staticOnly);
2395 if (isStatic(env1)) staticOnly = true;
2396 sym = findImmediateMemberType(env1, env1.enclClass.sym.type,
2397 name, env1.enclClass.sym);
2398
2399 // Return the type variable if we have it, and have no
2400 // immediate member, OR the type variable is for a method.
2401 if (tyvar != typeNotFound) {
2402 if (env.baseClause || sym == typeNotFound ||
2403 (tyvar.kind == TYP && tyvar.exists() &&
2404 tyvar.owner.kind == MTH)) {
2405 return tyvar;
2406 }
2407 }
2408
2409 // If the environment is a class def, finish up,
2410 // otherwise, do the entire findMemberType
2411 if (sym == typeNotFound)
2412 sym = findInheritedMemberType(env1, env1.enclClass.sym.type,
2413 name, env1.enclClass.sym);
2414
2415 if (staticOnly && sym.kind == TYP &&
2416 sym.type.hasTag(CLASS) &&
2417 sym.type.getEnclosingType().hasTag(CLASS) &&
2418 env1.enclClass.sym.type.isParameterized() &&
2419 sym.type.getEnclosingType().isParameterized())
2420 return new StaticError(sym);
2421 else if (sym.exists()) return sym;
2422 else bestSoFar = bestOf(bestSoFar, sym);
2423
2424 JCClassDecl encl = env1.baseClause ? (JCClassDecl)env1.tree : env1.enclClass;
2425 if ((encl.sym.flags() & STATIC) != 0)
2426 staticOnly = true;
2427 }
2428
2429 if (!env.tree.hasTag(IMPORT)) {
2430 sym = findGlobalType(env, env.toplevel.namedImportScope, name, namedImportScopeRecovery);
2431 if (sym.exists()) return sym;
2432 else bestSoFar = bestOf(bestSoFar, sym);
2433
2434 sym = findGlobalType(env, env.toplevel.toplevelScope, name, noRecovery);
2435 if (sym.exists()) return sym;
2436 else bestSoFar = bestOf(bestSoFar, sym);
2437
2438 sym = findGlobalType(env, env.toplevel.packge.members(), name, noRecovery);
2439 if (sym.exists()) return sym;
2440 else bestSoFar = bestOf(bestSoFar, sym);
2441
2442 sym = findGlobalType(env, env.toplevel.starImportScope, name, starImportScopeRecovery);
2443 if (sym.exists()) return sym;
2444 else bestSoFar = bestOf(bestSoFar, sym);
2445
2446 sym = findGlobalType(env, env.toplevel.moduleImportScope, name, moduleImportScopeRecovery);
2447 if (sym.exists()) return sym;
2448
2449 else bestSoFar = bestOf(bestSoFar, sym);
2450 }
2451
2452 return bestSoFar;
2453 }
2454
2455 /** Find an unqualified identifier which matches a specified kind set.
2456 * @param pos position on which report warnings, if any;
2457 * null warnings should not be reported
2458 * @param env The current environment.
2459 * @param name The identifier's name.
2460 * @param kind Indicates the possible symbol kinds
2461 * (a subset of VAL, TYP, PCK).
2462 */
2463 Symbol findIdent(DiagnosticPosition pos, Env<AttrContext> env, Name name, KindSelector kind) {
2464 try {
2465 return checkNonExistentType(checkRestrictedType(pos, findIdentInternal(pos, env, name, kind), name));
2466 } catch (ClassFinder.BadClassFile err) {
2467 return new BadClassFileError(err);
2468 } catch (CompletionFailure cf) {
2469 chk.completionError(pos, cf);
2470 return typeNotFound;
2471 }
2472 }
2473
2474 Symbol findIdentInternal(DiagnosticPosition pos, Env<AttrContext> env, Name name, KindSelector kind) {
2475 Symbol bestSoFar = typeNotFound;
2476 Symbol sym;
2477
2478 if (kind.contains(KindSelector.VAL)) {
2479 sym = findVar(pos, env, name);
2480 if (sym.exists()) return sym;
2481 else bestSoFar = bestOf(bestSoFar, sym);
2482 }
2483
2484 if (kind.contains(KindSelector.TYP)) {
2485 sym = findType(env, name);
2486 if (sym.exists()) return sym;
2487 else bestSoFar = bestOf(bestSoFar, sym);
2488 }
2489
2490 if (kind.contains(KindSelector.PCK))
2491 return lookupPackage(env, name);
2492 else return bestSoFar;
2493 }
2494
2495 /** Find an identifier in a package which matches a specified kind set.
2496 * @param pos position on which report warnings, if any;
2497 * null warnings should not be reported
2498 * @param env The current environment.
2499 * @param name The identifier's name.
2500 * @param kind Indicates the possible symbol kinds
2501 * (a nonempty subset of TYP, PCK).
2502 */
2503 Symbol findIdentInPackage(DiagnosticPosition pos,
2504 Env<AttrContext> env, TypeSymbol pck,
2505 Name name, KindSelector kind) {
2506 return checkNonExistentType(checkRestrictedType(pos, findIdentInPackageInternal(env, pck, name, kind), name));
2507 }
2508
2509 Symbol findIdentInPackageInternal(Env<AttrContext> env, TypeSymbol pck,
2510 Name name, KindSelector kind) {
2511 Name fullname = TypeSymbol.formFullName(name, pck);
2512 Symbol bestSoFar = typeNotFound;
2513 if (kind.contains(KindSelector.TYP)) {
2514 RecoveryLoadClass recoveryLoadClass =
2515 allowModules && !kind.contains(KindSelector.PCK) &&
2516 !pck.exists() && !env.info.attributionMode.isSpeculative ?
2517 doRecoveryLoadClass : noRecovery;
2518 Symbol sym = loadClass(env, fullname, recoveryLoadClass);
2519 if (sym.exists()) {
2520 // don't allow programs to use flatnames
2521 if (name == sym.name) return sym;
2522 }
2523 else bestSoFar = bestOf(bestSoFar, sym);
2524 }
2525 if (kind.contains(KindSelector.PCK)) {
2526 return lookupPackage(env, fullname);
2527 }
2528 return bestSoFar;
2529 }
2530
2531 /** Find an identifier among the members of a given type `site'.
2532 * @param pos position on which report warnings, if any;
2533 * null warnings should not be reported
2534 * @param env The current environment.
2535 * @param site The type containing the symbol to be found.
2536 * @param name The identifier's name.
2537 * @param kind Indicates the possible symbol kinds
2538 * (a subset of VAL, TYP).
2539 */
2540 Symbol findIdentInType(DiagnosticPosition pos,
2541 Env<AttrContext> env, Type site,
2542 Name name, KindSelector kind) {
2543 try {
2544 return checkNonExistentType(checkRestrictedType(pos, findIdentInTypeInternal(env, site, name, kind), name));
2545 } catch (ClassFinder.BadClassFile err) {
2546 return new BadClassFileError(err);
2547 } catch (CompletionFailure cf) {
2548 chk.completionError(pos, cf);
2549 return typeNotFound;
2550 }
2551 }
2552
2553 private Symbol checkNonExistentType(Symbol symbol) {
2554 /* Guard against returning a type is not on the class path of the current compilation,
2555 * but *was* on the class path of a separate compilation that produced a class file
2556 * that is on the class path of the current compilation. Such a type will fail completion
2557 * but the completion failure may have been silently swallowed (e.g. missing annotation types)
2558 * with an error stub symbol lingering in the symbol tables.
2559 */
2560 return symbol instanceof ClassSymbol c && c.type.isErroneous() && c.classfile == null ? typeNotFound : symbol;
2561 }
2562
2563 Symbol findIdentInTypeInternal(Env<AttrContext> env, Type site,
2564 Name name, KindSelector kind) {
2565 Symbol bestSoFar = typeNotFound;
2566 Symbol sym;
2567 if (kind.contains(KindSelector.VAL)) {
2568 sym = findField(env, site, name, site.tsym);
2569 if (sym.exists()) return sym;
2570 else bestSoFar = bestOf(bestSoFar, sym);
2571 }
2572
2573 if (kind.contains(KindSelector.TYP)) {
2574 sym = findMemberType(env, site, name, site.tsym);
2575 if (sym.exists()) return sym;
2576 else bestSoFar = bestOf(bestSoFar, sym);
2577 }
2578 return bestSoFar;
2579 }
2580
2581 private Symbol checkRestrictedType(DiagnosticPosition pos, Symbol bestSoFar, Name name) {
2582 if (bestSoFar.kind == TYP || bestSoFar.kind == ABSENT_TYP) {
2583 if (allowLocalVariableTypeInference && name.equals(names.var)) {
2584 bestSoFar = new BadRestrictedTypeError(names.var);
2585 } else if (name.equals(names.yield)) {
2586 if (allowYieldStatement) {
2587 bestSoFar = new BadRestrictedTypeError(names.yield);
2588 } else if (pos != null) {
2589 log.warning(pos, Warnings.IllegalRefToRestrictedType(names.yield));
2590 }
2591 }
2592 }
2593 return bestSoFar;
2594 }
2595
2596 /* ***************************************************************************
2597 * Access checking
2598 * The following methods convert ResolveErrors to ErrorSymbols, issuing
2599 * an error message in the process
2600 ****************************************************************************/
2601
2602 /** If `sym' is a bad symbol: report error and return errSymbol
2603 * else pass through unchanged,
2604 * additional arguments duplicate what has been used in trying to find the
2605 * symbol {@literal (--> flyweight pattern)}. This improves performance since we
2606 * expect misses to happen frequently.
2607 *
2608 * @param sym The symbol that was found, or a ResolveError.
2609 * @param pos The position to use for error reporting.
2610 * @param location The symbol the served as a context for this lookup
2611 * @param site The original type from where the selection took place.
2612 * @param name The symbol's name.
2613 * @param qualified Did we get here through a qualified expression resolution?
2614 * @param argtypes The invocation's value arguments,
2615 * if we looked for a method.
2616 * @param typeargtypes The invocation's type arguments,
2617 * if we looked for a method.
2618 * @param logResolveHelper helper class used to log resolve errors
2619 */
2620 Symbol accessInternal(Symbol sym,
2621 DiagnosticPosition pos,
2622 Symbol location,
2623 Type site,
2624 Name name,
2625 boolean qualified,
2626 List<Type> argtypes,
2627 List<Type> typeargtypes,
2628 LogResolveHelper logResolveHelper) {
2629 if (sym.kind.isResolutionError()) {
2630 ResolveError errSym = (ResolveError)sym.baseSymbol();
2631 sym = errSym.access(name, qualified ? site.tsym : syms.noSymbol);
2632 argtypes = logResolveHelper.getArgumentTypes(errSym, sym, name, argtypes);
2633 if (logResolveHelper.resolveDiagnosticNeeded(site, argtypes, typeargtypes)) {
2634 logResolveError(errSym, pos, location, site, name, argtypes, typeargtypes);
2635 }
2636 }
2637 return sym;
2638 }
2639
2640 /**
2641 * Variant of the generalized access routine, to be used for generating method
2642 * resolution diagnostics
2643 */
2644 Symbol accessMethod(Symbol sym,
2645 DiagnosticPosition pos,
2646 Symbol location,
2647 Type site,
2648 Name name,
2649 boolean qualified,
2650 List<Type> argtypes,
2651 List<Type> typeargtypes) {
2652 return accessInternal(sym, pos, location, site, name, qualified, argtypes, typeargtypes, methodLogResolveHelper);
2653 }
2654
2655 /** Same as original accessMethod(), but without location.
2656 */
2657 Symbol accessMethod(Symbol sym,
2658 DiagnosticPosition pos,
2659 Type site,
2660 Name name,
2661 boolean qualified,
2662 List<Type> argtypes,
2663 List<Type> typeargtypes) {
2664 return accessMethod(sym, pos, site.tsym, site, name, qualified, argtypes, typeargtypes);
2665 }
2666
2667 /**
2668 * Variant of the generalized access routine, to be used for generating variable,
2669 * type resolution diagnostics
2670 */
2671 Symbol accessBase(Symbol sym,
2672 DiagnosticPosition pos,
2673 Symbol location,
2674 Type site,
2675 Name name,
2676 boolean qualified) {
2677 return accessInternal(sym, pos, location, site, name, qualified, List.nil(), null, basicLogResolveHelper);
2678 }
2679
2680 /** Same as original accessBase(), but without location.
2681 */
2682 Symbol accessBase(Symbol sym,
2683 DiagnosticPosition pos,
2684 Type site,
2685 Name name,
2686 boolean qualified) {
2687 return accessBase(sym, pos, site.tsym, site, name, qualified);
2688 }
2689
2690 interface LogResolveHelper {
2691 boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes);
2692 List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes);
2693 }
2694
2695 LogResolveHelper basicLogResolveHelper = new LogResolveHelper() {
2696 public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) {
2697 return !site.isErroneous();
2698 }
2699 public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
2700 return argtypes;
2701 }
2702 };
2703
2704 LogResolveHelper silentLogResolveHelper = new LogResolveHelper() {
2705 public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) {
2706 return false;
2707 }
2708 public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
2709 return argtypes;
2710 }
2711 };
2712
2713 LogResolveHelper methodLogResolveHelper = new LogResolveHelper() {
2714 public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) {
2715 return !site.isErroneous() &&
2716 !Type.isErroneous(argtypes) &&
2717 (typeargtypes == null || !Type.isErroneous(typeargtypes));
2718 }
2719 public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
2720 return argtypes.map(new ResolveDeferredRecoveryMap(AttrMode.SPECULATIVE, accessedSym, currentResolutionContext.step));
2721 }
2722 };
2723
2724 class ResolveDeferredRecoveryMap extends DeferredAttr.RecoveryDeferredTypeMap {
2725
2726 public ResolveDeferredRecoveryMap(AttrMode mode, Symbol msym, MethodResolutionPhase step) {
2727 deferredAttr.super(mode, msym, step);
2728 }
2729
2730 @Override
2731 protected Type typeOf(DeferredType dt, Type pt) {
2732 Type res = super.typeOf(dt, pt);
2733 if (!res.isErroneous()) {
2734 switch (TreeInfo.skipParens(dt.tree).getTag()) {
2735 case LAMBDA:
2736 case REFERENCE:
2737 return dt;
2738 case CONDEXPR:
2739 return res == Type.recoveryType ?
2740 dt : res;
2741 }
2742 }
2743 return res;
2744 }
2745 }
2746
2747 /** Check that sym is not an abstract method.
2748 */
2749 void checkNonAbstract(DiagnosticPosition pos, Symbol sym) {
2750 if ((sym.flags() & ABSTRACT) != 0 && (sym.flags() & DEFAULT) == 0)
2751 log.error(pos,
2752 Errors.AbstractCantBeAccessedDirectly(kindName(sym),sym, sym.location()));
2753 }
2754
2755 /* ***************************************************************************
2756 * Name resolution
2757 * Naming conventions are as for symbol lookup
2758 * Unlike the find... methods these methods will report access errors
2759 ****************************************************************************/
2760
2761 /** Resolve an unqualified (non-method) identifier.
2762 * @param pos The position to use for error reporting.
2763 * @param env The environment current at the identifier use.
2764 * @param name The identifier's name.
2765 * @param kind The set of admissible symbol kinds for the identifier.
2766 */
2767 Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env,
2768 Name name, KindSelector kind) {
2769 return accessBase(
2770 findIdent(pos, env, name, kind),
2771 pos, env.enclClass.sym.type, name, false);
2772 }
2773
2774 /** Resolve an unqualified method identifier.
2775 * @param pos The position to use for error reporting.
2776 * @param env The environment current at the method invocation.
2777 * @param name The identifier's name.
2778 * @param argtypes The types of the invocation's value arguments.
2779 * @param typeargtypes The types of the invocation's type arguments.
2780 */
2781 Symbol resolveMethod(DiagnosticPosition pos,
2782 Env<AttrContext> env,
2783 Name name,
2784 List<Type> argtypes,
2785 List<Type> typeargtypes) {
2786 return lookupMethod(env, pos, env.enclClass.sym, resolveMethodCheck,
2787 new BasicLookupHelper(name, env.enclClass.sym.type, argtypes, typeargtypes) {
2788 @Override
2789 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2790 return findFun(env, name, argtypes, typeargtypes,
2791 phase.isBoxingRequired(),
2792 phase.isVarargsRequired());
2793 }});
2794 }
2795
2796 /** Resolve a qualified method identifier
2797 * @param pos The position to use for error reporting.
2798 * @param env The environment current at the method invocation.
2799 * @param site The type of the qualifying expression, in which
2800 * identifier is searched.
2801 * @param name The identifier's name.
2802 * @param argtypes The types of the invocation's value arguments.
2803 * @param typeargtypes The types of the invocation's type arguments.
2804 */
2805 Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
2806 Type site, Name name, List<Type> argtypes,
2807 List<Type> typeargtypes) {
2808 return resolveQualifiedMethod(pos, env, site.tsym, site, name, argtypes, typeargtypes);
2809 }
2810 Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
2811 Symbol location, Type site, Name name, List<Type> argtypes,
2812 List<Type> typeargtypes) {
2813 try {
2814 return resolveQualifiedMethod(new MethodResolutionContext(), pos, env, location, site, name, argtypes, typeargtypes);
2815 } catch (CompletionFailure cf) {
2816 chk.completionError(pos, cf);
2817 return methodNotFound.access(name, site.tsym);
2818 }
2819 }
2820 private Symbol resolveQualifiedMethod(MethodResolutionContext resolveContext,
2821 DiagnosticPosition pos, Env<AttrContext> env,
2822 Symbol location, Type site, Name name, List<Type> argtypes,
2823 List<Type> typeargtypes) {
2824 return lookupMethod(env, pos, location, resolveContext, new BasicLookupHelper(name, site, argtypes, typeargtypes) {
2825 @Override
2826 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2827 return findMethod(env, site, name, argtypes, typeargtypes,
2828 phase.isBoxingRequired(),
2829 phase.isVarargsRequired());
2830 }
2831 @Override
2832 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2833 if (sym.kind.isResolutionError()) {
2834 sym = super.access(env, pos, location, sym);
2835 } else {
2836 MethodSymbol msym = (MethodSymbol)sym;
2837 if ((msym.flags() & SIGNATURE_POLYMORPHIC) != 0) {
2838 env.info.pendingResolutionPhase = BASIC;
2839 return findPolymorphicSignatureInstance(env, sym, argtypes);
2840 }
2841 }
2842 return sym;
2843 }
2844 });
2845 }
2846
2847 /** Find or create an implicit method of exactly the given type (after erasure).
2848 * Searches in a side table, not the main scope of the site.
2849 * This emulates the lookup process required by JSR 292 in JVM.
2850 * @param env Attribution environment
2851 * @param spMethod signature polymorphic method - i.e. MH.invokeExact
2852 * @param argtypes The required argument types
2853 */
2854 Symbol findPolymorphicSignatureInstance(Env<AttrContext> env,
2855 final Symbol spMethod,
2856 List<Type> argtypes) {
2857 Type mtype = infer.instantiatePolymorphicSignatureInstance(env,
2858 (MethodSymbol)spMethod, currentResolutionContext, argtypes);
2859 return findPolymorphicSignatureInstance(spMethod, mtype);
2860 }
2861
2862 Symbol findPolymorphicSignatureInstance(final Symbol spMethod,
2863 Type mtype) {
2864 for (Symbol sym : polymorphicSignatureScope.getSymbolsByName(spMethod.name)) {
2865 // Check that there is already a method symbol for the method
2866 // type and owner
2867 if (types.isSameType(mtype, sym.type) &&
2868 spMethod.owner == sym.owner) {
2869 return sym;
2870 }
2871 }
2872
2873 Type spReturnType = spMethod.asType().getReturnType();
2874 if (types.isSameType(spReturnType, syms.objectType)) {
2875 // Polymorphic return, pass through mtype
2876 } else if (!types.isSameType(spReturnType, mtype.getReturnType())) {
2877 // Retain the sig poly method's return type, which differs from that of mtype
2878 // Will result in an incompatible return type error
2879 mtype = new MethodType(mtype.getParameterTypes(),
2880 spReturnType,
2881 mtype.getThrownTypes(),
2882 syms.methodClass);
2883 }
2884
2885 // Create the desired method
2886 // Retain static modifier is to support invocations to
2887 // MethodHandle.linkTo* methods
2888 long flags = ABSTRACT | HYPOTHETICAL |
2889 spMethod.flags() & (Flags.AccessFlags | Flags.STATIC);
2890 Symbol msym = new MethodSymbol(flags, spMethod.name, mtype, spMethod.owner) {
2891 @Override
2892 public Symbol baseSymbol() {
2893 return spMethod;
2894 }
2895 };
2896 if (!mtype.isErroneous()) { // Cache only if kosher.
2897 polymorphicSignatureScope.enter(msym);
2898 }
2899 return msym;
2900 }
2901
2902 /** Resolve a qualified method identifier, throw a fatal error if not
2903 * found.
2904 * @param pos The position to use for error reporting.
2905 * @param env The environment current at the method invocation.
2906 * @param site The type of the qualifying expression, in which
2907 * identifier is searched.
2908 * @param name The identifier's name.
2909 * @param argtypes The types of the invocation's value arguments.
2910 * @param typeargtypes The types of the invocation's type arguments.
2911 */
2912 public MethodSymbol resolveInternalMethod(DiagnosticPosition pos, Env<AttrContext> env,
2913 Type site, Name name,
2914 List<Type> argtypes,
2915 List<Type> typeargtypes) {
2916 MethodResolutionContext resolveContext = new MethodResolutionContext();
2917 resolveContext.internalResolution = true;
2918 Symbol sym = resolveQualifiedMethod(resolveContext, pos, env, site.tsym,
2919 site, name, argtypes, typeargtypes);
2920 if (sym.kind == MTH) return (MethodSymbol)sym;
2921 else throw new FatalError(
2922 diags.fragment(Fragments.FatalErrCantLocateMeth(name)));
2923 }
2924
2925 /** Resolve constructor.
2926 * @param pos The position to use for error reporting.
2927 * @param env The environment current at the constructor invocation.
2928 * @param site The type of class for which a constructor is searched.
2929 * @param argtypes The types of the constructor invocation's value
2930 * arguments.
2931 * @param typeargtypes The types of the constructor invocation's type
2932 * arguments.
2933 */
2934 Symbol resolveConstructor(DiagnosticPosition pos,
2935 Env<AttrContext> env,
2936 Type site,
2937 List<Type> argtypes,
2938 List<Type> typeargtypes) {
2939 return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes);
2940 }
2941
2942 private Symbol resolveConstructor(MethodResolutionContext resolveContext,
2943 final DiagnosticPosition pos,
2944 Env<AttrContext> env,
2945 Type site,
2946 List<Type> argtypes,
2947 List<Type> typeargtypes) {
2948 return lookupMethod(env, pos, site.tsym, resolveContext, new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
2949 @Override
2950 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2951 return findConstructor(pos, env, site, argtypes, typeargtypes,
2952 phase.isBoxingRequired(),
2953 phase.isVarargsRequired());
2954 }
2955 });
2956 }
2957
2958 /** Resolve a constructor, throw a fatal error if not found.
2959 * @param pos The position to use for error reporting.
2960 * @param env The environment current at the method invocation.
2961 * @param site The type to be constructed.
2962 * @param argtypes The types of the invocation's value arguments.
2963 * @param typeargtypes The types of the invocation's type arguments.
2964 */
2965 public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2966 Type site,
2967 List<Type> argtypes,
2968 List<Type> typeargtypes) {
2969 MethodResolutionContext resolveContext = new MethodResolutionContext();
2970 resolveContext.internalResolution = true;
2971 Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes);
2972 if (sym.kind == MTH) return (MethodSymbol)sym;
2973 else throw new FatalError(
2974 diags.fragment(Fragments.FatalErrCantLocateCtor(site)));
2975 }
2976
2977 Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2978 Type site, List<Type> argtypes,
2979 List<Type> typeargtypes,
2980 boolean allowBoxing,
2981 boolean useVarargs) {
2982 Symbol sym = findMethod(env, site,
2983 names.init, argtypes,
2984 typeargtypes, allowBoxing,
2985 useVarargs);
2986 chk.checkDeprecated(pos, env.info.scope.owner, sym);
2987 chk.checkPreview(pos, env.info.scope.owner, sym);
2988 return sym;
2989 }
2990
2991 /** Resolve constructor using diamond inference.
2992 * @param pos The position to use for error reporting.
2993 * @param env The environment current at the constructor invocation.
2994 * @param site The type of class for which a constructor is searched.
2995 * The scope of this class has been touched in attribution.
2996 * @param argtypes The types of the constructor invocation's value
2997 * arguments.
2998 * @param typeargtypes The types of the constructor invocation's type
2999 * arguments.
3000 */
3001 Symbol resolveDiamond(DiagnosticPosition pos,
3002 Env<AttrContext> env,
3003 Type site,
3004 List<Type> argtypes,
3005 List<Type> typeargtypes) {
3006 return lookupMethod(env, pos, site.tsym, resolveMethodCheck,
3007 new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
3008 @Override
3009 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3010 return findDiamond(pos, env, site, argtypes, typeargtypes,
3011 phase.isBoxingRequired(),
3012 phase.isVarargsRequired());
3013 }
3014 @Override
3015 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
3016 if (sym.kind.isResolutionError()) {
3017 if (sym.kind != WRONG_MTH &&
3018 sym.kind != WRONG_MTHS) {
3019 sym = super.access(env, pos, location, sym);
3020 } else {
3021 sym = new DiamondError(sym, currentResolutionContext);
3022 sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes);
3023 env.info.pendingResolutionPhase = currentResolutionContext.step;
3024 }
3025 }
3026 return sym;
3027 }});
3028 }
3029
3030 /** Find the constructor using diamond inference and do some checks(deprecated and preview).
3031 * @param pos The position to use for error reporting.
3032 * @param env The environment current at the constructor invocation.
3033 * @param site The type of class for which a constructor is searched.
3034 * The scope of this class has been touched in attribution.
3035 * @param argtypes The types of the constructor invocation's value arguments.
3036 * @param typeargtypes The types of the constructor invocation's type arguments.
3037 * @param allowBoxing Allow boxing conversions of arguments.
3038 * @param useVarargs Box trailing arguments into an array for varargs.
3039 */
3040 private Symbol findDiamond(DiagnosticPosition pos,
3041 Env<AttrContext> env,
3042 Type site,
3043 List<Type> argtypes,
3044 List<Type> typeargtypes,
3045 boolean allowBoxing,
3046 boolean useVarargs) {
3047 Symbol sym = findDiamond(env, site, argtypes, typeargtypes, allowBoxing, useVarargs);
3048 chk.checkDeprecated(pos, env.info.scope.owner, sym);
3049 chk.checkPreview(pos, env.info.scope.owner, sym);
3050 return sym;
3051 }
3052
3053 /** This method scans all the constructor symbol in a given class scope -
3054 * assuming that the original scope contains a constructor of the kind:
3055 * {@code Foo(X x, Y y)}, where X,Y are class type-variables declared in Foo,
3056 * a method check is executed against the modified constructor type:
3057 * {@code <X,Y>Foo<X,Y>(X x, Y y)}. This is crucial in order to enable diamond
3058 * inference. The inferred return type of the synthetic constructor IS
3059 * the inferred type for the diamond operator.
3060 */
3061 private Symbol findDiamond(Env<AttrContext> env,
3062 Type site,
3063 List<Type> argtypes,
3064 List<Type> typeargtypes,
3065 boolean allowBoxing,
3066 boolean useVarargs) {
3067 Symbol bestSoFar = methodNotFound;
3068 TypeSymbol tsym = site.tsym.isInterface() ? syms.objectType.tsym : site.tsym;
3069 for (final Symbol sym : tsym.members().getSymbolsByName(names.init)) {
3070 //- System.out.println(" e " + e.sym);
3071 if (sym.kind == MTH &&
3072 (sym.flags_field & SYNTHETIC) == 0) {
3073 List<Type> oldParams = sym.type.hasTag(FORALL) ?
3074 ((ForAll)sym.type).tvars :
3075 List.nil();
3076 Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams),
3077 types.createMethodTypeWithReturn(sym.type.asMethodType(), site));
3078 MethodSymbol newConstr = new MethodSymbol(sym.flags(), names.init, constrType, site.tsym) {
3079 @Override
3080 public Symbol baseSymbol() {
3081 return sym;
3082 }
3083 };
3084 bestSoFar = selectBest(env, site, argtypes, typeargtypes,
3085 newConstr,
3086 bestSoFar,
3087 allowBoxing,
3088 useVarargs);
3089 }
3090 }
3091 return bestSoFar;
3092 }
3093
3094 Symbol getMemberReference(DiagnosticPosition pos,
3095 Env<AttrContext> env,
3096 JCMemberReference referenceTree,
3097 Type site,
3098 Name name) {
3099
3100 site = types.capture(site);
3101
3102 ReferenceLookupHelper lookupHelper = makeReferenceLookupHelper(
3103 referenceTree, site, name, List.nil(), null, VARARITY);
3104
3105 Env<AttrContext> newEnv = env.dup(env.tree, env.info.dup());
3106 Symbol sym = lookupMethod(newEnv, env.tree.pos(), site.tsym,
3107 nilMethodCheck, lookupHelper);
3108
3109 env.info.pendingResolutionPhase = newEnv.info.pendingResolutionPhase;
3110
3111 return sym;
3112 }
3113
3114 ReferenceLookupHelper makeReferenceLookupHelper(JCMemberReference referenceTree,
3115 Type site,
3116 Name name,
3117 List<Type> argtypes,
3118 List<Type> typeargtypes,
3119 MethodResolutionPhase maxPhase) {
3120 if (!name.equals(names.init)) {
3121 //method reference
3122 return new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
3123 } else if (site.hasTag(ARRAY)) {
3124 //array constructor reference
3125 return new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
3126 } else {
3127 //class constructor reference
3128 return new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
3129 }
3130 }
3131
3132 /**
3133 * Resolution of member references is typically done as a single
3134 * overload resolution step, where the argument types A are inferred from
3135 * the target functional descriptor.
3136 *
3137 * If the member reference is a method reference with a type qualifier,
3138 * a two-step lookup process is performed. The first step uses the
3139 * expected argument list A, while the second step discards the first
3140 * type from A (which is treated as a receiver type).
3141 *
3142 * There are two cases in which inference is performed: (i) if the member
3143 * reference is a constructor reference and the qualifier type is raw - in
3144 * which case diamond inference is used to infer a parameterization for the
3145 * type qualifier; (ii) if the member reference is an unbound reference
3146 * where the type qualifier is raw - in that case, during the unbound lookup
3147 * the receiver argument type is used to infer an instantiation for the raw
3148 * qualifier type.
3149 *
3150 * When a multi-step resolution process is exploited, the process of picking
3151 * the resulting symbol is delegated to an helper class {@link com.sun.tools.javac.comp.Resolve.ReferenceChooser}.
3152 *
3153 * This routine returns a pair (T,S), where S is the member reference symbol,
3154 * and T is the type of the class in which S is defined. This is necessary as
3155 * the type T might be dynamically inferred (i.e. if constructor reference
3156 * has a raw qualifier).
3157 */
3158 Pair<Symbol, ReferenceLookupHelper> resolveMemberReference(Env<AttrContext> env,
3159 JCMemberReference referenceTree,
3160 Type site,
3161 Name name,
3162 List<Type> argtypes,
3163 List<Type> typeargtypes,
3164 Type descriptor,
3165 MethodCheck methodCheck,
3166 InferenceContext inferenceContext,
3167 ReferenceChooser referenceChooser) {
3168
3169 //step 1 - bound lookup
3170 ReferenceLookupHelper boundLookupHelper = makeReferenceLookupHelper(
3171 referenceTree, site, name, argtypes, typeargtypes, VARARITY);
3172 Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
3173 MethodResolutionContext boundSearchResolveContext = new MethodResolutionContext();
3174 boundSearchResolveContext.methodCheck = methodCheck;
3175 Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(),
3176 site.tsym, boundSearchResolveContext, boundLookupHelper);
3177 boolean isStaticSelector = TreeInfo.isStaticSelector(referenceTree.expr, names);
3178 ReferenceLookupResult boundRes = new ReferenceLookupResult(boundSym, boundSearchResolveContext, isStaticSelector);
3179 if (dumpMethodReferenceSearchResults) {
3180 dumpMethodReferenceSearchResults(referenceTree, boundSearchResolveContext, boundSym, true);
3181 }
3182
3183 //step 2 - unbound lookup
3184 Symbol unboundSym = methodNotFound;
3185 Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup());
3186 ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext);
3187 ReferenceLookupResult unboundRes = referenceNotFound;
3188 if (unboundLookupHelper != null) {
3189 MethodResolutionContext unboundSearchResolveContext =
3190 new MethodResolutionContext();
3191 unboundSearchResolveContext.methodCheck = methodCheck;
3192 unboundSym = lookupMethod(unboundEnv, env.tree.pos(),
3193 site.tsym, unboundSearchResolveContext, unboundLookupHelper);
3194 unboundRes = new ReferenceLookupResult(unboundSym, unboundSearchResolveContext, isStaticSelector);
3195 if (dumpMethodReferenceSearchResults) {
3196 dumpMethodReferenceSearchResults(referenceTree, unboundSearchResolveContext, unboundSym, false);
3197 }
3198 }
3199
3200 //merge results
3201 Pair<Symbol, ReferenceLookupHelper> res;
3202 ReferenceLookupResult bestRes = referenceChooser.result(boundRes, unboundRes);
3203 res = new Pair<>(bestRes.sym,
3204 bestRes == unboundRes ? unboundLookupHelper : boundLookupHelper);
3205 env.info.pendingResolutionPhase = bestRes == unboundRes ?
3206 unboundEnv.info.pendingResolutionPhase :
3207 boundEnv.info.pendingResolutionPhase;
3208
3209 if (!res.fst.kind.isResolutionError()) {
3210 //handle sigpoly method references
3211 MethodSymbol msym = (MethodSymbol)res.fst;
3212 if ((msym.flags() & SIGNATURE_POLYMORPHIC) != 0) {
3213 env.info.pendingResolutionPhase = BASIC;
3214 res = new Pair<>(findPolymorphicSignatureInstance(msym, descriptor), res.snd);
3215 }
3216 }
3217
3218 return res;
3219 }
3220
3221 private void dumpMethodReferenceSearchResults(JCMemberReference referenceTree,
3222 MethodResolutionContext resolutionContext,
3223 Symbol bestSoFar,
3224 boolean bound) {
3225 ListBuffer<JCDiagnostic> subDiags = new ListBuffer<>();
3226 int pos = 0;
3227 int mostSpecificPos = -1;
3228 for (Candidate c : resolutionContext.candidates) {
3229 if (resolutionContext.step != c.step || !c.isApplicable()) {
3230 continue;
3231 } else {
3232 JCDiagnostic subDiag = null;
3233 if (c.sym.type.hasTag(FORALL)) {
3234 subDiag = diags.fragment(Fragments.PartialInstSig(c.mtype));
3235 }
3236
3237 String key = subDiag == null ?
3238 "applicable.method.found.2" :
3239 "applicable.method.found.3";
3240 subDiags.append(diags.fragment(key, pos,
3241 c.sym.isStatic() ? Fragments.Static : Fragments.NonStatic, c.sym, subDiag));
3242 if (c.sym == bestSoFar)
3243 mostSpecificPos = pos;
3244 pos++;
3245 }
3246 }
3247 JCDiagnostic main = diags.note(
3248 log.currentSource(),
3249 referenceTree,
3250 "method.ref.search.results.multi",
3251 bound ? Fragments.Bound : Fragments.Unbound,
3252 referenceTree.toString(), mostSpecificPos);
3253 JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList());
3254 log.report(d);
3255 }
3256
3257 /**
3258 * This class is used to represent a method reference lookup result. It keeps track of two
3259 * things: (i) the symbol found during a method reference lookup and (ii) the static kind
3260 * of the lookup (see {@link com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind}).
3261 */
3262 static class ReferenceLookupResult {
3263
3264 /**
3265 * Static kind associated with a method reference lookup. Erroneous lookups end up with
3266 * the UNDEFINED kind; successful lookups will end up with either STATIC, NON_STATIC,
3267 * depending on whether all applicable candidates are static or non-static methods,
3268 * respectively. If a successful lookup has both static and non-static applicable methods,
3269 * its kind is set to BOTH.
3270 */
3271 enum StaticKind {
3272 STATIC,
3273 NON_STATIC,
3274 BOTH,
3275 UNDEFINED;
3276
3277 /**
3278 * Retrieve the static kind associated with a given (method) symbol.
3279 */
3280 static StaticKind from(Symbol s) {
3281 return s.isStatic() ?
3282 STATIC : NON_STATIC;
3283 }
3284
3285 /**
3286 * Merge two static kinds together.
3287 */
3288 static StaticKind reduce(StaticKind sk1, StaticKind sk2) {
3289 if (sk1 == UNDEFINED) {
3290 return sk2;
3291 } else if (sk2 == UNDEFINED) {
3292 return sk1;
3293 } else {
3294 return sk1 == sk2 ? sk1 : BOTH;
3295 }
3296 }
3297 }
3298
3299 /** The static kind. */
3300 StaticKind staticKind;
3301
3302 /** The lookup result. */
3303 Symbol sym;
3304
3305 ReferenceLookupResult(Symbol sym, MethodResolutionContext resolutionContext, boolean isStaticSelector) {
3306 this(sym, staticKind(sym, resolutionContext, isStaticSelector));
3307 }
3308
3309 private ReferenceLookupResult(Symbol sym, StaticKind staticKind) {
3310 this.staticKind = staticKind;
3311 this.sym = sym;
3312 }
3313
3314 private static StaticKind staticKind(Symbol sym, MethodResolutionContext resolutionContext, boolean isStaticSelector) {
3315 if (sym.kind == MTH && !isStaticSelector) {
3316 return StaticKind.from(sym);
3317 } else if (sym.kind == MTH || sym.kind == AMBIGUOUS) {
3318 return resolutionContext.candidates.stream()
3319 .filter(c -> c.isApplicable() && c.step == resolutionContext.step)
3320 .map(c -> StaticKind.from(c.sym))
3321 .reduce(StaticKind::reduce)
3322 .orElse(StaticKind.UNDEFINED);
3323 } else {
3324 return StaticKind.UNDEFINED;
3325 }
3326 }
3327
3328 /**
3329 * Does this result corresponds to a successful lookup (i.e. one where a method has been found?)
3330 */
3331 boolean isSuccess() {
3332 return staticKind != StaticKind.UNDEFINED;
3333 }
3334
3335 /**
3336 * Does this result have given static kind?
3337 */
3338 boolean hasKind(StaticKind sk) {
3339 return this.staticKind == sk;
3340 }
3341
3342 /**
3343 * Error recovery helper: can this lookup result be ignored (for the purpose of returning
3344 * some 'better' result) ?
3345 */
3346 boolean canIgnore() {
3347 switch (sym.kind) {
3348 case ABSENT_MTH:
3349 return true;
3350 case WRONG_MTH:
3351 InapplicableSymbolError errSym =
3352 (InapplicableSymbolError)sym.baseSymbol();
3353 return new Template(MethodCheckDiag.ARITY_MISMATCH.regex())
3354 .matches(errSym.errCandidate().snd);
3355 case WRONG_MTHS:
3356 InapplicableSymbolsError errSyms =
3357 (InapplicableSymbolsError)sym.baseSymbol();
3358 return errSyms.filterCandidates(errSyms.mapCandidates()).isEmpty();
3359 default:
3360 return false;
3361 }
3362 }
3363
3364 static ReferenceLookupResult error(Symbol sym) {
3365 return new ReferenceLookupResult(sym, StaticKind.UNDEFINED);
3366 }
3367 }
3368
3369 /**
3370 * This abstract class embodies the logic that converts one (bound lookup) or two (unbound lookup)
3371 * {@code ReferenceLookupResult} objects into a {@code Symbol}, which is then regarded as the
3372 * result of method reference resolution.
3373 */
3374 abstract class ReferenceChooser {
3375 /**
3376 * Generate a result from a pair of lookup result objects. This method delegates to the
3377 * appropriate result generation routine.
3378 */
3379 ReferenceLookupResult result(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
3380 return unboundRes != referenceNotFound ?
3381 unboundResult(boundRes, unboundRes) :
3382 boundResult(boundRes);
3383 }
3384
3385 /**
3386 * Generate a symbol from a given bound lookup result.
3387 */
3388 abstract ReferenceLookupResult boundResult(ReferenceLookupResult boundRes);
3389
3390 /**
3391 * Generate a symbol from a pair of bound/unbound lookup results.
3392 */
3393 abstract ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes);
3394 }
3395
3396 /**
3397 * This chooser implements the selection strategy used during a full lookup; this logic
3398 * is described in JLS SE 8 (15.3.2).
3399 */
3400 ReferenceChooser basicReferenceChooser = new ReferenceChooser() {
3401
3402 @Override
3403 ReferenceLookupResult boundResult(ReferenceLookupResult boundRes) {
3404 return !boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC) ?
3405 boundRes : //the search produces a non-static method
3406 ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.sym, false));
3407 }
3408
3409 @Override
3410 ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
3411 if (boundRes.isSuccess() && boundRes.sym.isStatic() &&
3412 (!unboundRes.isSuccess() || unboundRes.hasKind(StaticKind.STATIC))) {
3413 //the first search produces a static method and no non-static method is applicable
3414 //during the second search
3415 return boundRes;
3416 } else if (unboundRes.isSuccess() && !unboundRes.sym.isStatic() &&
3417 (!boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC))) {
3418 //the second search produces a non-static method and no static method is applicable
3419 //during the first search
3420 return unboundRes;
3421 } else if (boundRes.isSuccess() && unboundRes.isSuccess()) {
3422 //both searches produce some result; ambiguity (error recovery)
3423 return ReferenceLookupResult.error(ambiguityError(boundRes.sym, unboundRes.sym));
3424 } else if (boundRes.isSuccess() || unboundRes.isSuccess()) {
3425 //Both searches failed to produce a result with correct staticness (i.e. first search
3426 //produces an non-static method). Alternatively, a given search produced a result
3427 //with the right staticness, but the other search has applicable methods with wrong
3428 //staticness (error recovery)
3429 return ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.isSuccess() ?
3430 boundRes.sym : unboundRes.sym, true));
3431 } else {
3432 //both searches fail to produce a result - pick 'better' error using heuristics (error recovery)
3433 return (boundRes.canIgnore() && !unboundRes.canIgnore()) ?
3434 unboundRes : boundRes;
3435 }
3436 }
3437 };
3438
3439 /**
3440 * This chooser implements the selection strategy used during an arity-based lookup; this logic
3441 * is described in JLS SE 8 (15.12.2.1).
3442 */
3443 ReferenceChooser structuralReferenceChooser = new ReferenceChooser() {
3444
3445 @Override
3446 ReferenceLookupResult boundResult(ReferenceLookupResult boundRes) {
3447 return (!boundRes.isSuccess() || !boundRes.hasKind(StaticKind.STATIC)) ?
3448 boundRes : //the search has at least one applicable non-static method
3449 ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.sym, false));
3450 }
3451
3452 @Override
3453 ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
3454 if (boundRes.isSuccess() && !boundRes.hasKind(StaticKind.NON_STATIC)) {
3455 //the first search has at least one applicable static method
3456 return boundRes;
3457 } else if (unboundRes.isSuccess() && !unboundRes.hasKind(StaticKind.STATIC)) {
3458 //the second search has at least one applicable non-static method
3459 return unboundRes;
3460 } else if (boundRes.isSuccess() || unboundRes.isSuccess()) {
3461 //either the first search produces a non-static method, or second search produces
3462 //a non-static method (error recovery)
3463 return ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.isSuccess() ?
3464 boundRes.sym : unboundRes.sym, true));
3465 } else {
3466 //both searches fail to produce a result - pick 'better' error using heuristics (error recovery)
3467 return (boundRes.canIgnore() && !unboundRes.canIgnore()) ?
3468 unboundRes : boundRes;
3469 }
3470 }
3471 };
3472
3473 /**
3474 * Helper for defining custom method-like lookup logic; a lookup helper
3475 * provides hooks for (i) the actual lookup logic and (ii) accessing the
3476 * lookup result (this step might result in compiler diagnostics to be generated)
3477 */
3478 abstract class LookupHelper {
3479
3480 /** name of the symbol to lookup */
3481 Name name;
3482
3483 /** location in which the lookup takes place */
3484 Type site;
3485
3486 /** actual types used during the lookup */
3487 List<Type> argtypes;
3488
3489 /** type arguments used during the lookup */
3490 List<Type> typeargtypes;
3491
3492 /** Max overload resolution phase handled by this helper */
3493 MethodResolutionPhase maxPhase;
3494
3495 LookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3496 this.name = name;
3497 this.site = site;
3498 this.argtypes = argtypes;
3499 this.typeargtypes = typeargtypes;
3500 this.maxPhase = maxPhase;
3501 }
3502
3503 /**
3504 * Should lookup stop at given phase with given result
3505 */
3506 final boolean shouldStop(Symbol sym, MethodResolutionPhase phase) {
3507 return phase.ordinal() > maxPhase.ordinal() ||
3508 !sym.kind.isResolutionError() || sym.kind == AMBIGUOUS || sym.kind == STATICERR;
3509 }
3510
3511 /**
3512 * Search for a symbol under a given overload resolution phase - this method
3513 * is usually called several times, once per each overload resolution phase
3514 */
3515 abstract Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase);
3516
3517 /**
3518 * Dump overload resolution info
3519 */
3520 void debug(DiagnosticPosition pos, Symbol sym) {
3521 //do nothing
3522 }
3523
3524 /**
3525 * Validate the result of the lookup
3526 */
3527 abstract Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym);
3528 }
3529
3530 abstract class BasicLookupHelper extends LookupHelper {
3531
3532 BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes) {
3533 this(name, site, argtypes, typeargtypes, MethodResolutionPhase.VARARITY);
3534 }
3535
3536 BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3537 super(name, site, argtypes, typeargtypes, maxPhase);
3538 }
3539
3540 @Override
3541 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
3542 if (sym.kind.isResolutionError()) {
3543 //if nothing is found return the 'first' error
3544 sym = accessMethod(sym, pos, location, site, name, true, argtypes, typeargtypes);
3545 }
3546 return sym;
3547 }
3548
3549 @Override
3550 void debug(DiagnosticPosition pos, Symbol sym) {
3551 reportVerboseResolutionDiagnostic(pos, name, site, argtypes, typeargtypes, sym);
3552 }
3553 }
3554
3555 /**
3556 * Helper class for member reference lookup. A reference lookup helper
3557 * defines the basic logic for member reference lookup; a method gives
3558 * access to an 'unbound' helper used to perform an unbound member
3559 * reference lookup.
3560 */
3561 abstract class ReferenceLookupHelper extends LookupHelper {
3562
3563 /** The member reference tree */
3564 JCMemberReference referenceTree;
3565
3566 ReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3567 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3568 super(name, site, argtypes, typeargtypes, maxPhase);
3569 this.referenceTree = referenceTree;
3570 }
3571
3572 /**
3573 * Returns an unbound version of this lookup helper. By default, this
3574 * method returns an dummy lookup helper.
3575 */
3576 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3577 return null;
3578 }
3579
3580 /**
3581 * Get the kind of the member reference
3582 */
3583 abstract JCMemberReference.ReferenceKind referenceKind(Symbol sym);
3584
3585 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
3586 //skip error reporting
3587 return sym;
3588 }
3589 }
3590
3591 /**
3592 * Helper class for method reference lookup. The lookup logic is based
3593 * upon Resolve.findMethod; in certain cases, this helper class has a
3594 * corresponding unbound helper class (see UnboundMethodReferenceLookupHelper).
3595 * In such cases, non-static lookup results are thrown away.
3596 */
3597 class MethodReferenceLookupHelper extends ReferenceLookupHelper {
3598
3599 /** The original method reference lookup site. */
3600 Type originalSite;
3601
3602 MethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3603 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3604 super(referenceTree, name, types.skipTypeVars(site, true), argtypes, typeargtypes, maxPhase);
3605 this.originalSite = site;
3606 }
3607
3608 @Override
3609 final Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3610 return findMethod(env, site, name, argtypes, typeargtypes,
3611 phase.isBoxingRequired(), phase.isVarargsRequired());
3612 }
3613
3614 @Override
3615 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3616 if (TreeInfo.isStaticSelector(referenceTree.expr, names)) {
3617 if (argtypes.nonEmpty() &&
3618 (argtypes.head.hasTag(NONE) ||
3619 types.isSubtypeUnchecked(inferenceContext.asUndetVar(argtypes.head), originalSite))) {
3620 return new UnboundMethodReferenceLookupHelper(referenceTree, name,
3621 originalSite, argtypes, typeargtypes, maxPhase);
3622 } else {
3623 return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) {
3624 @Override
3625 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3626 return this;
3627 }
3628
3629 @Override
3630 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3631 return methodNotFound;
3632 }
3633
3634 @Override
3635 ReferenceKind referenceKind(Symbol sym) {
3636 Assert.error();
3637 return null;
3638 }
3639 };
3640 }
3641 } else {
3642 return super.unboundLookup(inferenceContext);
3643 }
3644 }
3645
3646 @Override
3647 ReferenceKind referenceKind(Symbol sym) {
3648 if (sym.isStatic()) {
3649 return ReferenceKind.STATIC;
3650 } else {
3651 Name selName = TreeInfo.name(referenceTree.getQualifierExpression());
3652 return selName != null && selName == names._super ?
3653 ReferenceKind.SUPER :
3654 ReferenceKind.BOUND;
3655 }
3656 }
3657
3658 @Override
3659 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
3660 if (originalSite.hasTag(TYPEVAR) && sym.kind == MTH) {
3661 sym = (sym.flags() & Flags.PRIVATE) != 0 ?
3662 new AccessError(env, site, sym) :
3663 sym;
3664 return accessBase(sym, pos, location, originalSite, name, true);
3665 } else {
3666 return super.access(env, pos, location, sym);
3667 }
3668 }
3669 }
3670
3671 /**
3672 * Helper class for unbound method reference lookup. Essentially the same
3673 * as the basic method reference lookup helper; main difference is that static
3674 * lookup results are thrown away. If qualifier type is raw, an attempt to
3675 * infer a parameterized type is made using the first actual argument (that
3676 * would otherwise be ignored during the lookup).
3677 */
3678 class UnboundMethodReferenceLookupHelper extends MethodReferenceLookupHelper {
3679
3680 UnboundMethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3681 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3682 super(referenceTree, name, site, argtypes.tail, typeargtypes, maxPhase);
3683 if (site.isRaw() && !argtypes.head.hasTag(NONE)) {
3684 Type asSuperSite = types.asSuper(argtypes.head, site.tsym);
3685 this.site = types.skipTypeVars(asSuperSite, true);
3686 }
3687 }
3688
3689 @Override
3690 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3691 return this;
3692 }
3693
3694 @Override
3695 ReferenceKind referenceKind(Symbol sym) {
3696 return ReferenceKind.UNBOUND;
3697 }
3698 }
3699
3700 /**
3701 * Helper class for array constructor lookup; an array constructor lookup
3702 * is simulated by looking up a method that returns the array type specified
3703 * as qualifier, and that accepts a single int parameter (size of the array).
3704 */
3705 class ArrayConstructorReferenceLookupHelper extends ReferenceLookupHelper {
3706
3707 ArrayConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
3708 List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3709 super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
3710 }
3711
3712 @Override
3713 protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3714 WriteableScope sc = WriteableScope.create(syms.arrayClass);
3715 MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym);
3716 arrayConstr.type = new MethodType(List.of(syms.intType), site, List.nil(), syms.methodClass);
3717 sc.enter(arrayConstr);
3718 return findMethodInScope(env, site, name, argtypes, typeargtypes, sc, methodNotFound, phase.isBoxingRequired(), phase.isVarargsRequired(), false);
3719 }
3720
3721 @Override
3722 ReferenceKind referenceKind(Symbol sym) {
3723 return ReferenceKind.ARRAY_CTOR;
3724 }
3725 }
3726
3727 /**
3728 * Helper class for constructor reference lookup. The lookup logic is based
3729 * upon either Resolve.findMethod or Resolve.findDiamond - depending on
3730 * whether the constructor reference needs diamond inference (this is the case
3731 * if the qualifier type is raw). A special erroneous symbol is returned
3732 * if the lookup returns the constructor of an inner class and there's no
3733 * enclosing instance in scope.
3734 */
3735 class ConstructorReferenceLookupHelper extends ReferenceLookupHelper {
3736
3737 boolean needsInference;
3738
3739 ConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
3740 List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3741 super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
3742 if (site.isRaw()) {
3743 this.site = new ClassType(site.getEnclosingType(),
3744 !(site.tsym.isInner() && site.getEnclosingType().isRaw()) ?
3745 site.tsym.type.getTypeArguments() : List.nil(), site.tsym, site.getMetadata());
3746 needsInference = true;
3747 }
3748 }
3749
3750 @Override
3751 protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3752 return needsInference ?
3753 findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) :
3754 findMethod(env, site, name, argtypes, typeargtypes,
3755 phase.isBoxingRequired(), phase.isVarargsRequired());
3756 }
3757
3758 @Override
3759 ReferenceKind referenceKind(Symbol sym) {
3760 return site.getEnclosingType().hasTag(NONE) ?
3761 ReferenceKind.TOPLEVEL : ReferenceKind.IMPLICIT_INNER;
3762 }
3763 }
3764
3765 /**
3766 * Main overload resolution routine. On each overload resolution step, a
3767 * lookup helper class is used to perform the method/constructor lookup;
3768 * at the end of the lookup, the helper is used to validate the results
3769 * (this last step might trigger overload resolution diagnostics).
3770 */
3771 Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, MethodCheck methodCheck, LookupHelper lookupHelper) {
3772 MethodResolutionContext resolveContext = new MethodResolutionContext();
3773 resolveContext.methodCheck = methodCheck;
3774 return lookupMethod(env, pos, location, resolveContext, lookupHelper);
3775 }
3776
3777 Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location,
3778 MethodResolutionContext resolveContext, LookupHelper lookupHelper) {
3779 MethodResolutionContext prevResolutionContext = currentResolutionContext;
3780 try {
3781 Symbol bestSoFar = methodNotFound;
3782 currentResolutionContext = resolveContext;
3783 for (MethodResolutionPhase phase : methodResolutionSteps) {
3784 if (lookupHelper.shouldStop(bestSoFar, phase))
3785 break;
3786 MethodResolutionPhase prevPhase = currentResolutionContext.step;
3787 Symbol prevBest = bestSoFar;
3788 currentResolutionContext.step = phase;
3789 Symbol sym = lookupHelper.lookup(env, phase);
3790 lookupHelper.debug(pos, sym);
3791 bestSoFar = phase.mergeResults(bestSoFar, sym);
3792 env.info.pendingResolutionPhase = (prevBest == bestSoFar) ? prevPhase : phase;
3793 }
3794 return lookupHelper.access(env, pos, location, bestSoFar);
3795 } finally {
3796 currentResolutionContext = prevResolutionContext;
3797 }
3798 }
3799
3800 /**
3801 * Find a "valid" reference to an enclosing 'A.this' such that A is a subclass of the provided class symbol.
3802 * A reference to an enclosing 'A.this' is "valid" if (a) we're not in the early-construction context for A
3803 * and (b) if the current class is not an inner class of A.
3804 */
3805 Symbol findSelfContaining(DiagnosticPosition pos,
3806 Env<AttrContext> env,
3807 TypeSymbol c,
3808 boolean isSuper) {
3809 Env<AttrContext> env1 = isSuper ? env.outer : env;
3810 boolean staticOnly = false;
3811 while (env1.outer != null) {
3812 if (isStatic(env1)) staticOnly = true;
3813 if (env1.enclClass.sym.isSubClass(c, types)) {
3814 Symbol sym = env1.info.scope.findFirst(names._this);
3815 if (sym != null) {
3816 if (staticOnly) {
3817 // current class is not an inner class, stop search
3818 return new StaticError(sym);
3819 } else if (env1.info.ctorPrologue && !isAllowedEarlyReference(pos, env1, (VarSymbol)sym)) {
3820 // early construction context, stop search
3821 return new RefBeforeCtorCalledError(sym);
3822 } else {
3823 // found it
3824 return sym;
3825 }
3826 }
3827 }
3828 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
3829 env1 = env1.outer;
3830 }
3831 return varNotFound;
3832 }
3833
3834 /**
3835 * Resolve the (method) owner of a local class. This can fail if the local class
3836 * is referenced from a static context nested inside the local class. Effectively,
3837 * this lookup succeeds if we can access a local variable declared inside the owner
3838 * method from the provided env.
3839 */
3840 Symbol findLocalClassOwner(Env<AttrContext> env, TypeSymbol c) {
3841 Symbol owner = c.owner;
3842 Assert.check(owner.kind == MTH || owner.kind == VAR);
3843 Env<AttrContext> env1 = env;
3844 boolean staticOnly = false;
3845 while (env1.outer != null) {
3846 // If the local class is defined inside a static method, and the instance creation expression
3847 // occurs in that same method, the creation occurs (technically) inside a static context, but that's ok.
3848 if (env1.info.scope.owner == owner) {
3849 return (staticOnly) ?
3850 new BadLocalClassCreation(c) :
3851 owner;
3852 } else if (isStatic(env1) || env1.enclClass.sym.isStatic()) {
3853 staticOnly = true;
3854 }
3855 env1 = env1.outer;
3856 }
3857 return owner.kind == MTH ?
3858 methodNotFound :
3859 varNotFound;
3860 }
3861
3862 /**
3863 * Resolve `c.name' where name == this or name == super.
3864 * @param pos The position to use for error reporting.
3865 * @param env The environment current at the expression.
3866 * @param c The type of the selected expression
3867 * @param tree The expression
3868 */
3869 Symbol resolveSelf(DiagnosticPosition pos,
3870 Env<AttrContext> env,
3871 TypeSymbol c,
3872 JCFieldAccess tree) {
3873 Name name = tree.name;
3874 Assert.check(name == names._this || name == names._super);
3875 Env<AttrContext> env1 = env;
3876 boolean staticOnly = false;
3877 while (env1.outer != null) {
3878 if (isStatic(env1)) staticOnly = true;
3879 if (env1.enclClass.sym == c) {
3880 Symbol sym = env1.info.scope.findFirst(name);
3881 if (sym != null) {
3882 if (staticOnly)
3883 sym = new StaticError(sym);
3884 else if (env1.info.ctorPrologue &&
3885 !isReceiverParameter(env, tree) &&
3886 !isAllowedEarlyReference(pos, env1, (VarSymbol)sym))
3887 sym = new RefBeforeCtorCalledError(sym);
3888 return accessBase(sym, pos, env.enclClass.sym.type,
3889 name, true);
3890 }
3891 }
3892 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
3893 env1 = env1.outer;
3894 }
3895 if (c.isInterface() &&
3896 name == names._super && !isStatic(env) &&
3897 types.isDirectSuperInterface(c, env.enclClass.sym)) {
3898 //this might be a default super call if one of the superinterfaces is 'c'
3899 for (Type t : pruneInterfaces(env.enclClass.type)) {
3900 if (t.tsym == c) {
3901 if (env.info.ctorPrologue)
3902 log.error(pos, Errors.CantRefBeforeCtorCalled(name));
3903 env.info.defaultSuperCallSite = t;
3904 return new VarSymbol(0, names._super,
3905 types.asSuper(env.enclClass.type, c), env.enclClass.sym);
3906 }
3907 }
3908 //find a direct supertype that is a subtype of 'c'
3909 for (Type i : types.directSupertypes(env.enclClass.type)) {
3910 if (i.tsym.isSubClass(c, types) && i.tsym != c) {
3911 log.error(pos,
3912 Errors.IllegalDefaultSuperCall(c,
3913 Fragments.RedundantSupertype(c, i)));
3914 return syms.errSymbol;
3915 }
3916 }
3917 Assert.error();
3918 }
3919 log.error(pos, Errors.NotEnclClass(c));
3920 return syms.errSymbol;
3921 }
3922 //where
3923 private List<Type> pruneInterfaces(Type t) {
3924 ListBuffer<Type> result = new ListBuffer<>();
3925 for (Type t1 : types.interfaces(t)) {
3926 boolean shouldAdd = true;
3927 for (Type t2 : types.directSupertypes(t)) {
3928 if (t1 != t2 && !t2.hasTag(ERROR) && types.isSubtypeNoCapture(t2, t1)) {
3929 shouldAdd = false;
3930 }
3931 }
3932 if (shouldAdd) {
3933 result.append(t1);
3934 }
3935 }
3936 return result.toList();
3937 }
3938 private boolean isReceiverParameter(Env<AttrContext> env, JCFieldAccess tree) {
3939 if (env.tree.getTag() != METHODDEF)
3940 return false;
3941 JCMethodDecl method = (JCMethodDecl)env.tree;
3942 return method.recvparam != null && tree == method.recvparam.nameexpr;
3943 }
3944
3945 /**
3946 * Determine if an early instance field reference may appear in a constructor prologue.
3947 *
3948 * <p>
3949 * This is only allowed when:
3950 * - The field is being assigned a value (i.e., written but not read)
3951 * - The field is not inherited from a superclass
3952 * - The assignment is not within a lambda, because that would require
3953 * capturing 'this' which is not allowed prior to super().
3954 *
3955 * <p>
3956 * Note, this method doesn't catch all such scenarios, because this method
3957 * is invoked for symbol "x" only for "x = 42" but not for "this.x = 42".
3958 * We also don't verify that the field has no initializer, which is required.
3959 * To catch those cases, we rely on similar logic in Attr.checkAssignable().
3960 */
3961 private boolean isAllowedEarlyReference(DiagnosticPosition pos, Env<AttrContext> env, VarSymbol v) {
3962
3963 // Check assumptions
3964 Assert.check(env.info.ctorPrologue);
3965 Assert.check((v.flags_field & STATIC) == 0);
3966
3967 // The symbol must appear in the LHS of an assignment statement
3968 if (!(env.tree instanceof JCAssign assign))
3969 return false;
3970
3971 // The assignment statement must not be within a lambda
3972 if (env.info.isLambda)
3973 return false;
3974
3975 // Get the symbol's qualifier, if any
3976 JCExpression lhs = TreeInfo.skipParens(assign.lhs);
3977 JCExpression base;
3978 switch (lhs.getTag()) {
3979 case IDENT:
3980 base = null;
3981 break;
3982 case SELECT:
3983 JCFieldAccess select = (JCFieldAccess)lhs;
3984 base = select.selected;
3985 if (!TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, base))
3986 return false;
3987 break;
3988 default:
3989 return false;
3990 }
3991
3992 // If an early reference, the field must not be declared in a superclass
3993 if (isEarlyReference(env, base, v) && v.owner != env.enclClass.sym)
3994 return false;
3995
3996 // The flexible constructors feature must be enabled
3997 preview.checkSourceLevel(pos, Feature.FLEXIBLE_CONSTRUCTORS);
3998
3999 // OK
4000 return true;
4001 }
4002
4003 /**
4004 * Determine if the variable appearance constitutes an early reference to the current class.
4005 *
4006 * <p>
4007 * This means the variable is an instance field of the current class and it appears
4008 * in an early initialization context of it (i.e., one of its constructor prologues).
4009 *
4010 * <p>
4011 * Such a reference is only allowed for assignments to non-initialized fields that are
4012 * not inherited from a superclass, though that is not enforced by this method.
4013 *
4014 * @param env The current environment
4015 * @param base Variable qualifier, if any, otherwise null
4016 * @param v The variable
4017 */
4018 public boolean isEarlyReference(Env<AttrContext> env, JCTree base, VarSymbol v) {
4019 if (env.info.ctorPrologue &&
4020 (v.flags() & STATIC) == 0 &&
4021 v.isMemberOf(env.enclClass.sym, types)) {
4022
4023 // Allow "Foo.this.x" when "Foo" is (also) an outer class, as this refers to the outer instance
4024 if (base != null) {
4025 return TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, base);
4026 }
4027
4028 // It's an early reference to an instance field member of the current instance
4029 return true;
4030 }
4031 return false;
4032 }
4033
4034 /* ***************************************************************************
4035 * ResolveError classes, indicating error situations when accessing symbols
4036 ****************************************************************************/
4037
4038 //used by TransTypes when checking target type of synthetic cast
4039 public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) {
4040 AccessError error = new AccessError(env, env.enclClass.type, type.tsym);
4041 logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null);
4042 }
4043 //where
4044 private void logResolveError(ResolveError error,
4045 DiagnosticPosition pos,
4046 Symbol location,
4047 Type site,
4048 Name name,
4049 List<Type> argtypes,
4050 List<Type> typeargtypes) {
4051 JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
4052 pos, location, site, name, argtypes, typeargtypes);
4053 if (d != null) {
4054 d.setFlag(DiagnosticFlag.RESOLVE_ERROR);
4055 log.report(d);
4056 }
4057 }
4058
4059 private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
4060
4061 public Object methodArguments(List<Type> argtypes) {
4062 if (argtypes == null || argtypes.isEmpty()) {
4063 return noArgs;
4064 } else {
4065 ListBuffer<Object> diagArgs = new ListBuffer<>();
4066 for (Type t : argtypes) {
4067 if (t.hasTag(DEFERRED)) {
4068 diagArgs.append(((DeferredAttr.DeferredType)t).tree);
4069 } else {
4070 diagArgs.append(t);
4071 }
4072 }
4073 return diagArgs;
4074 }
4075 }
4076
4077 /** check if a type is a subtype of Serializable, if that is available.*/
4078 boolean isSerializable(Type t) {
4079 try {
4080 syms.serializableType.complete();
4081 }
4082 catch (CompletionFailure e) {
4083 return false;
4084 }
4085 return types.isSubtype(t, syms.serializableType);
4086 }
4087
4088 /**
4089 * Root class for resolution errors. Subclass of ResolveError
4090 * represent a different kinds of resolution error - as such they must
4091 * specify how they map into concrete compiler diagnostics.
4092 */
4093 abstract class ResolveError extends Symbol {
4094
4095 /** The name of the kind of error, for debugging only. */
4096 final String debugName;
4097
4098 ResolveError(Kind kind, String debugName) {
4099 super(kind, 0, null, null, null);
4100 this.debugName = debugName;
4101 }
4102
4103 @Override @DefinedBy(Api.LANGUAGE_MODEL)
4104 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
4105 throw new AssertionError();
4106 }
4107
4108 @Override
4109 public String toString() {
4110 return debugName;
4111 }
4112
4113 @Override
4114 public boolean exists() {
4115 return false;
4116 }
4117
4118 @Override
4119 public boolean isStatic() {
4120 return false;
4121 }
4122
4123 /**
4124 * Create an external representation for this erroneous symbol to be
4125 * used during attribution - by default this returns the symbol of a
4126 * brand new error type which stores the original type found
4127 * during resolution.
4128 *
4129 * @param name the name used during resolution
4130 * @param location the location from which the symbol is accessed
4131 */
4132 protected Symbol access(Name name, TypeSymbol location) {
4133 return types.createErrorType(name, location, syms.errSymbol.type).tsym;
4134 }
4135
4136 /**
4137 * Create a diagnostic representing this resolution error.
4138 *
4139 * @param dkind The kind of the diagnostic to be created (e.g error).
4140 * @param pos The position to be used for error reporting.
4141 * @param site The original type from where the selection took place.
4142 * @param name The name of the symbol to be resolved.
4143 * @param argtypes The invocation's value arguments,
4144 * if we looked for a method.
4145 * @param typeargtypes The invocation's type arguments,
4146 * if we looked for a method.
4147 */
4148 abstract JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4149 DiagnosticPosition pos,
4150 Symbol location,
4151 Type site,
4152 Name name,
4153 List<Type> argtypes,
4154 List<Type> typeargtypes);
4155 }
4156
4157 /**
4158 * This class is the root class of all resolution errors caused by
4159 * an invalid symbol being found during resolution.
4160 */
4161 abstract class InvalidSymbolError extends ResolveError {
4162
4163 /** The invalid symbol found during resolution */
4164 Symbol sym;
4165
4166 InvalidSymbolError(Kind kind, Symbol sym, String debugName) {
4167 super(kind, debugName);
4168 this.sym = sym;
4169 }
4170
4171 @Override
4172 public boolean exists() {
4173 return true;
4174 }
4175
4176 @Override
4177 public String toString() {
4178 return super.toString() + " wrongSym=" + sym;
4179 }
4180
4181 @Override
4182 public Symbol access(Name name, TypeSymbol location) {
4183 if (!sym.kind.isResolutionError() && sym.kind.matches(KindSelector.TYP))
4184 return types.createErrorType(name, location, sym.type).tsym;
4185 else
4186 return sym;
4187 }
4188 }
4189
4190 class BadRestrictedTypeError extends ResolveError {
4191 private final Name typeName;
4192 BadRestrictedTypeError(Name typeName) {
4193 super(Kind.BAD_RESTRICTED_TYPE, "bad var use");
4194 this.typeName = typeName;
4195 }
4196
4197 @Override
4198 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4199 return diags.create(dkind, log.currentSource(), pos, "illegal.ref.to.restricted.type", typeName);
4200 }
4201 }
4202
4203 /**
4204 * InvalidSymbolError error class indicating that a symbol matching a
4205 * given name does not exists in a given site.
4206 */
4207 class SymbolNotFoundError extends ResolveError {
4208
4209 SymbolNotFoundError(Kind kind) {
4210 this(kind, "symbol not found error");
4211 }
4212
4213 SymbolNotFoundError(Kind kind, String debugName) {
4214 super(kind, debugName);
4215 }
4216
4217 @Override
4218 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4219 DiagnosticPosition pos,
4220 Symbol location,
4221 Type site,
4222 Name name,
4223 List<Type> argtypes,
4224 List<Type> typeargtypes) {
4225 argtypes = argtypes == null ? List.nil() : argtypes;
4226 typeargtypes = typeargtypes == null ? List.nil() : typeargtypes;
4227 if (name == names.error)
4228 return null;
4229
4230 boolean hasLocation = false;
4231 if (location == null) {
4232 location = site.tsym;
4233 }
4234 if (!location.name.isEmpty()) {
4235 if (location.kind == PCK && !site.tsym.exists() && location.name != names.java) {
4236 return diags.create(dkind, log.currentSource(), pos,
4237 "doesnt.exist", location);
4238 }
4239 hasLocation = !location.name.equals(names._this) &&
4240 !location.name.equals(names._super);
4241 }
4242 boolean isConstructor = name == names.init;
4243 KindName kindname = isConstructor ? KindName.CONSTRUCTOR : kind.absentKind();
4244 Name idname = isConstructor ? site.tsym.name : name;
4245 String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation);
4246 if (hasLocation) {
4247 return diags.create(dkind, log.currentSource(), pos,
4248 errKey, kindname, idname, //symbol kindname, name
4249 typeargtypes, args(argtypes), //type parameters and arguments (if any)
4250 getLocationDiag(location, site)); //location kindname, type
4251 }
4252 else {
4253 return diags.create(dkind, log.currentSource(), pos,
4254 errKey, kindname, idname, //symbol kindname, name
4255 typeargtypes, args(argtypes)); //type parameters and arguments (if any)
4256 }
4257 }
4258 //where
4259 private Object args(List<Type> args) {
4260 return args.isEmpty() ? args : methodArguments(args);
4261 }
4262
4263 private String getErrorKey(KindName kindname, boolean hasTypeArgs, boolean hasLocation) {
4264 String key = "cant.resolve";
4265 String suffix = hasLocation ? ".location" : "";
4266 switch (kindname) {
4267 case METHOD:
4268 case CONSTRUCTOR: {
4269 suffix += ".args";
4270 suffix += hasTypeArgs ? ".params" : "";
4271 }
4272 }
4273 return key + suffix;
4274 }
4275 private JCDiagnostic getLocationDiag(Symbol location, Type site) {
4276 if (location.kind == VAR) {
4277 return diags.fragment(Fragments.Location1(kindName(location),
4278 location,
4279 location.type));
4280 } else {
4281 return diags.fragment(Fragments.Location(typeKindName(site),
4282 site,
4283 null));
4284 }
4285 }
4286 }
4287
4288 /**
4289 * InvalidSymbolError error class indicating that a given symbol
4290 * (either a method, a constructor or an operand) is not applicable
4291 * given an actual arguments/type argument list.
4292 */
4293 class InapplicableSymbolError extends ResolveError {
4294
4295 protected MethodResolutionContext resolveContext;
4296
4297 InapplicableSymbolError(MethodResolutionContext context) {
4298 this(WRONG_MTH, "inapplicable symbol error", context);
4299 }
4300
4301 protected InapplicableSymbolError(Kind kind, String debugName, MethodResolutionContext context) {
4302 super(kind, debugName);
4303 this.resolveContext = context;
4304 }
4305
4306 @Override
4307 public String toString() {
4308 return super.toString();
4309 }
4310
4311 @Override
4312 public boolean exists() {
4313 return true;
4314 }
4315
4316 @Override
4317 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4318 DiagnosticPosition pos,
4319 Symbol location,
4320 Type site,
4321 Name name,
4322 List<Type> argtypes,
4323 List<Type> typeargtypes) {
4324 if (name == names.error)
4325 return null;
4326
4327 Pair<Symbol, JCDiagnostic> c = errCandidate();
4328 Symbol ws = c.fst.asMemberOf(site, types);
4329 UnaryOperator<JCDiagnostic> rewriter = compactMethodDiags ?
4330 d -> MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, c.snd) : null;
4331
4332 // If the problem is due to type arguments, then the method parameters aren't relevant,
4333 // so use the error message that omits them to avoid confusion.
4334 switch (c.snd.getCode()) {
4335 case "compiler.misc.wrong.number.type.args":
4336 case "compiler.misc.explicit.param.do.not.conform.to.bounds":
4337 return diags.create(dkind, log.currentSource(), pos,
4338 "cant.apply.symbol.noargs",
4339 rewriter,
4340 kindName(ws),
4341 ws.name == names.init ? ws.owner.name : ws.name,
4342 kindName(ws.owner),
4343 ws.owner.type,
4344 c.snd);
4345 default:
4346 // Avoid saying "constructor Array in class Array"
4347 if (ws.owner == syms.arrayClass && ws.name == names.init) {
4348 return diags.create(dkind, log.currentSource(), pos,
4349 "cant.apply.array.ctor",
4350 rewriter,
4351 methodArguments(ws.type.getParameterTypes()),
4352 methodArguments(argtypes),
4353 c.snd);
4354 }
4355 return diags.create(dkind, log.currentSource(), pos,
4356 "cant.apply.symbol",
4357 rewriter,
4358 kindName(ws),
4359 ws.name == names.init ? ws.owner.name : ws.name,
4360 methodArguments(ws.type.getParameterTypes()),
4361 methodArguments(argtypes),
4362 kindName(ws.owner),
4363 ws.owner.type,
4364 c.snd);
4365 }
4366 }
4367
4368 @Override
4369 public Symbol access(Name name, TypeSymbol location) {
4370 Pair<Symbol, JCDiagnostic> cand = errCandidate();
4371 TypeSymbol errSymbol = types.createErrorType(name, location, cand != null ? cand.fst.type : syms.errSymbol.type).tsym;
4372 if (cand != null) {
4373 attrRecover.wrongMethodSymbolCandidate(errSymbol, cand.fst, cand.snd);
4374 }
4375 return errSymbol;
4376 }
4377
4378 protected Pair<Symbol, JCDiagnostic> errCandidate() {
4379 Candidate bestSoFar = null;
4380 for (Candidate c : resolveContext.candidates) {
4381 if (c.isApplicable()) continue;
4382 bestSoFar = c;
4383 }
4384 Assert.checkNonNull(bestSoFar);
4385 return new Pair<>(bestSoFar.sym, bestSoFar.details);
4386 }
4387 }
4388
4389 /**
4390 * ResolveError error class indicating that a symbol (either methods, constructors or operand)
4391 * is not applicable given an actual arguments/type argument list.
4392 */
4393 class InapplicableSymbolsError extends InapplicableSymbolError {
4394
4395 InapplicableSymbolsError(MethodResolutionContext context) {
4396 super(WRONG_MTHS, "inapplicable symbols", context);
4397 }
4398
4399 @Override
4400 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4401 DiagnosticPosition pos,
4402 Symbol location,
4403 Type site,
4404 Name name,
4405 List<Type> argtypes,
4406 List<Type> typeargtypes) {
4407 Map<Symbol, JCDiagnostic> candidatesMap = mapCandidates();
4408 Map<Symbol, JCDiagnostic> filteredCandidates = compactMethodDiags ?
4409 filterCandidates(candidatesMap) :
4410 mapCandidates();
4411 if (filteredCandidates.isEmpty()) {
4412 filteredCandidates = candidatesMap;
4413 }
4414 boolean truncatedDiag = candidatesMap.size() != filteredCandidates.size();
4415 if (filteredCandidates.size() > 1) {
4416 JCDiagnostic err = diags.create(dkind,
4417 null,
4418 truncatedDiag ?
4419 EnumSet.of(DiagnosticFlag.COMPRESSED) :
4420 EnumSet.noneOf(DiagnosticFlag.class),
4421 log.currentSource(),
4422 pos,
4423 "cant.apply.symbols",
4424 name == names.init ? KindName.CONSTRUCTOR : kind.absentKind(),
4425 name == names.init ? site.tsym.name : name,
4426 methodArguments(argtypes));
4427 return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(filteredCandidates, site));
4428 } else if (filteredCandidates.size() == 1) {
4429 Map.Entry<Symbol, JCDiagnostic> _e =
4430 filteredCandidates.entrySet().iterator().next();
4431 final Pair<Symbol, JCDiagnostic> p = new Pair<>(_e.getKey(), _e.getValue());
4432 JCDiagnostic d = new InapplicableSymbolError(resolveContext) {
4433 @Override
4434 protected Pair<Symbol, JCDiagnostic> errCandidate() {
4435 return p;
4436 }
4437 }.getDiagnostic(dkind, pos,
4438 location, site, name, argtypes, typeargtypes);
4439 if (truncatedDiag) {
4440 d.setFlag(DiagnosticFlag.COMPRESSED);
4441 }
4442 return d;
4443 } else {
4444 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos,
4445 location, site, name, argtypes, typeargtypes);
4446 }
4447 }
4448 //where
4449 private Map<Symbol, JCDiagnostic> mapCandidates() {
4450 MostSpecificMap candidates = new MostSpecificMap();
4451 for (Candidate c : resolveContext.candidates) {
4452 if (c.isApplicable()) continue;
4453 candidates.put(c);
4454 }
4455 return candidates;
4456 }
4457
4458 @SuppressWarnings("serial")
4459 private class MostSpecificMap extends LinkedHashMap<Symbol, JCDiagnostic> {
4460 private void put(Candidate c) {
4461 ListBuffer<Symbol> overridden = new ListBuffer<>();
4462 for (Symbol s : keySet()) {
4463 if (s == c.sym) {
4464 continue;
4465 }
4466 if (c.sym.overrides(s, (TypeSymbol)s.owner, types, false)) {
4467 overridden.add(s);
4468 } else if (s.overrides(c.sym, (TypeSymbol)c.sym.owner, types, false)) {
4469 return;
4470 }
4471 }
4472 for (Symbol s : overridden) {
4473 remove(s);
4474 }
4475 put(c.sym, c.details);
4476 }
4477 }
4478
4479 Map<Symbol, JCDiagnostic> filterCandidates(Map<Symbol, JCDiagnostic> candidatesMap) {
4480 Map<Symbol, JCDiagnostic> candidates = new LinkedHashMap<>();
4481 for (Map.Entry<Symbol, JCDiagnostic> _entry : candidatesMap.entrySet()) {
4482 JCDiagnostic d = _entry.getValue();
4483 if (!new Template(MethodCheckDiag.ARITY_MISMATCH.regex()).matches(d)) {
4484 candidates.put(_entry.getKey(), d);
4485 }
4486 }
4487 return candidates;
4488 }
4489
4490 private List<JCDiagnostic> candidateDetails(Map<Symbol, JCDiagnostic> candidatesMap, Type site) {
4491 List<JCDiagnostic> details = List.nil();
4492 for (Map.Entry<Symbol, JCDiagnostic> _entry : candidatesMap.entrySet()) {
4493 Symbol sym = _entry.getKey();
4494 JCDiagnostic detailDiag =
4495 diags.fragment(Fragments.InapplicableMethod(Kinds.kindName(sym),
4496 sym.location(site, types),
4497 sym.asMemberOf(site, types),
4498 _entry.getValue()));
4499 details = details.prepend(detailDiag);
4500 }
4501 //typically members are visited in reverse order (see Scope)
4502 //so we need to reverse the candidate list so that candidates
4503 //conform to source order
4504 return details;
4505 }
4506
4507 @Override
4508 protected Pair<Symbol, JCDiagnostic> errCandidate() {
4509 Map<Symbol, JCDiagnostic> candidatesMap = mapCandidates();
4510 Map<Symbol, JCDiagnostic> filteredCandidates = filterCandidates(candidatesMap);
4511 if (filteredCandidates.size() == 1) {
4512 return Pair.of(filteredCandidates.keySet().iterator().next(),
4513 filteredCandidates.values().iterator().next());
4514 }
4515 return null;
4516 }
4517 }
4518
4519 /**
4520 * DiamondError error class indicating that a constructor symbol is not applicable
4521 * given an actual arguments/type argument list using diamond inference.
4522 */
4523 class DiamondError extends InapplicableSymbolError {
4524
4525 Symbol sym;
4526
4527 public DiamondError(Symbol sym, MethodResolutionContext context) {
4528 super(sym.kind, "diamondError", context);
4529 this.sym = sym;
4530 }
4531
4532 JCDiagnostic getDetails() {
4533 return (sym.kind == WRONG_MTH) ?
4534 ((InapplicableSymbolError)sym.baseSymbol()).errCandidate().snd :
4535 null;
4536 }
4537
4538 @Override
4539 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
4540 Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4541 JCDiagnostic details = getDetails();
4542 if (details != null && compactMethodDiags) {
4543 JCDiagnostic simpleDiag =
4544 MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, details);
4545 if (simpleDiag != null) {
4546 return simpleDiag;
4547 }
4548 }
4549 String key = details == null ?
4550 "cant.apply.diamond" :
4551 "cant.apply.diamond.1";
4552 return diags.create(dkind, log.currentSource(), pos, key,
4553 Fragments.Diamond(site.tsym), details);
4554 }
4555 }
4556
4557 /**
4558 * An InvalidSymbolError error class indicating that a symbol is not
4559 * accessible from a given site
4560 */
4561 class AccessError extends InvalidSymbolError {
4562
4563 private Env<AttrContext> env;
4564 private Type site;
4565
4566 AccessError(Env<AttrContext> env, Type site, Symbol sym) {
4567 super(HIDDEN, sym, "access error");
4568 this.env = env;
4569 this.site = site;
4570 }
4571
4572 @Override
4573 public boolean exists() {
4574 return false;
4575 }
4576
4577 @Override
4578 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4579 DiagnosticPosition pos,
4580 Symbol location,
4581 Type site,
4582 Name name,
4583 List<Type> argtypes,
4584 List<Type> typeargtypes) {
4585 if (sym.name == names.init && sym.owner != site.tsym) {
4586 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind,
4587 pos, location, site, name, argtypes, typeargtypes);
4588 }
4589 else if ((sym.flags() & PUBLIC) != 0
4590 || (env != null && this.site != null
4591 && !isAccessible(env, this.site))) {
4592 if (sym.owner.kind == PCK) {
4593 return diags.create(dkind, log.currentSource(),
4594 pos, "not.def.access.package.cant.access",
4595 sym, sym.location(), inaccessiblePackageReason(env, sym.packge()));
4596 } else if ( sym.packge() != syms.rootPackage
4597 && !symbolPackageVisible(env, sym)) {
4598 return diags.create(dkind, log.currentSource(),
4599 pos, "not.def.access.class.intf.cant.access.reason",
4600 sym, sym.location(), sym.location().packge(),
4601 inaccessiblePackageReason(env, sym.packge()));
4602 } else {
4603 return diags.create(dkind, log.currentSource(),
4604 pos, "not.def.access.class.intf.cant.access",
4605 sym, sym.location());
4606 }
4607 }
4608 else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) {
4609 return diags.create(dkind, log.currentSource(),
4610 pos, "report.access", sym,
4611 asFlagSet(sym.flags() & (PRIVATE | PROTECTED)),
4612 sym.location());
4613 }
4614 else {
4615 return diags.create(dkind, log.currentSource(),
4616 pos, "not.def.public.cant.access", sym, sym.location());
4617 }
4618 }
4619
4620 private String toString(Type type) {
4621 StringBuilder sb = new StringBuilder();
4622 sb.append(type);
4623 if (type != null) {
4624 sb.append("[tsym:").append(type.tsym);
4625 if (type.tsym != null)
4626 sb.append("packge:").append(type.tsym.packge());
4627 sb.append("]");
4628 }
4629 return sb.toString();
4630 }
4631 }
4632
4633 class InvisibleSymbolError extends InvalidSymbolError {
4634
4635 private final Env<AttrContext> env;
4636 private final boolean suppressError;
4637
4638 InvisibleSymbolError(Env<AttrContext> env, boolean suppressError, Symbol sym) {
4639 super(HIDDEN, sym, "invisible class error");
4640 this.env = env;
4641 this.suppressError = suppressError;
4642 this.name = sym.name;
4643 }
4644
4645 @Override
4646 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4647 DiagnosticPosition pos,
4648 Symbol location,
4649 Type site,
4650 Name name,
4651 List<Type> argtypes,
4652 List<Type> typeargtypes) {
4653 if (suppressError)
4654 return null;
4655
4656 if (sym.kind == PCK) {
4657 JCDiagnostic details = inaccessiblePackageReason(env, sym.packge());
4658 return diags.create(dkind, log.currentSource(),
4659 pos, "package.not.visible", sym, details);
4660 }
4661
4662 JCDiagnostic details = inaccessiblePackageReason(env, sym.packge());
4663
4664 if (pos.getTree() != null) {
4665 Symbol o = sym;
4666 JCTree tree = pos.getTree();
4667
4668 while (o.kind != PCK && tree.hasTag(SELECT)) {
4669 o = o.owner;
4670 tree = ((JCFieldAccess) tree).selected;
4671 }
4672
4673 if (o.kind == PCK) {
4674 pos = tree.pos();
4675
4676 return diags.create(dkind, log.currentSource(),
4677 pos, "package.not.visible", o, details);
4678 }
4679 }
4680
4681 return diags.create(dkind, log.currentSource(),
4682 pos, "not.def.access.package.cant.access", sym, sym.packge(), details);
4683 }
4684 }
4685
4686 JCDiagnostic inaccessiblePackageReason(Env<AttrContext> env, PackageSymbol sym) {
4687 //no dependency:
4688 if (!env.toplevel.modle.readModules.contains(sym.modle)) {
4689 //does not read:
4690 if (sym.modle != syms.unnamedModule) {
4691 if (env.toplevel.modle != syms.unnamedModule) {
4692 return diags.fragment(Fragments.NotDefAccessDoesNotRead(env.toplevel.modle,
4693 sym,
4694 sym.modle));
4695 } else {
4696 return diags.fragment(Fragments.NotDefAccessDoesNotReadFromUnnamed(sym,
4697 sym.modle));
4698 }
4699 } else {
4700 return diags.fragment(Fragments.NotDefAccessDoesNotReadUnnamed(sym,
4701 env.toplevel.modle));
4702 }
4703 } else {
4704 if (sym.packge().modle.exports.stream().anyMatch(e -> e.packge == sym)) {
4705 //not exported to this module:
4706 if (env.toplevel.modle != syms.unnamedModule) {
4707 return diags.fragment(Fragments.NotDefAccessNotExportedToModule(sym,
4708 sym.modle,
4709 env.toplevel.modle));
4710 } else {
4711 return diags.fragment(Fragments.NotDefAccessNotExportedToModuleFromUnnamed(sym,
4712 sym.modle));
4713 }
4714 } else {
4715 //not exported:
4716 if (env.toplevel.modle != syms.unnamedModule) {
4717 return diags.fragment(Fragments.NotDefAccessNotExported(sym,
4718 sym.modle));
4719 } else {
4720 return diags.fragment(Fragments.NotDefAccessNotExportedFromUnnamed(sym,
4721 sym.modle));
4722 }
4723 }
4724 }
4725 }
4726
4727 /**
4728 * InvalidSymbolError error class indicating that an instance member
4729 * has erroneously been accessed from a static context.
4730 */
4731 class StaticError extends InvalidSymbolError {
4732
4733 StaticError(Symbol sym) {
4734 this(sym, "static error");
4735 }
4736
4737 StaticError(Symbol sym, String debugName) {
4738 super(STATICERR, sym, debugName);
4739 }
4740
4741 @Override
4742 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4743 DiagnosticPosition pos,
4744 Symbol location,
4745 Type site,
4746 Name name,
4747 List<Type> argtypes,
4748 List<Type> typeargtypes) {
4749 Symbol errSym = ((sym.kind == TYP && sym.type.hasTag(CLASS))
4750 ? types.erasure(sym.type).tsym
4751 : sym);
4752 return diags.create(dkind, log.currentSource(), pos,
4753 "non-static.cant.be.ref", kindName(sym), errSym);
4754 }
4755 }
4756
4757 /**
4758 * Specialization of {@link StaticError} for illegal
4759 * creation of local class instances from a static context.
4760 */
4761 class BadLocalClassCreation extends StaticError {
4762 BadLocalClassCreation(Symbol sym) {
4763 super(sym, "bad local class creation");
4764 }
4765
4766 @Override
4767 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4768 DiagnosticPosition pos,
4769 Symbol location,
4770 Type site,
4771 Name name,
4772 List<Type> argtypes,
4773 List<Type> typeargtypes) {
4774 return diags.create(dkind, log.currentSource(), pos,
4775 "local.cant.be.inst.static", kindName(sym), sym);
4776 }
4777 }
4778
4779 /**
4780 * Specialization of {@link InvalidSymbolError} for illegal
4781 * early accesses within a constructor prologue.
4782 */
4783 class RefBeforeCtorCalledError extends StaticError {
4784
4785 RefBeforeCtorCalledError(Symbol sym) {
4786 super(sym, "prologue error");
4787 }
4788
4789 @Override
4790 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4791 DiagnosticPosition pos,
4792 Symbol location,
4793 Type site,
4794 Name name,
4795 List<Type> argtypes,
4796 List<Type> typeargtypes) {
4797 Symbol errSym = ((sym.kind == TYP && sym.type.hasTag(CLASS))
4798 ? types.erasure(sym.type).tsym
4799 : sym);
4800 return diags.create(dkind, log.currentSource(), pos,
4801 "cant.ref.before.ctor.called", errSym);
4802 }
4803 }
4804
4805 /**
4806 * InvalidSymbolError error class indicating that a pair of symbols
4807 * (either methods, constructors or operands) are ambiguous
4808 * given an actual arguments/type argument list.
4809 */
4810 class AmbiguityError extends ResolveError {
4811
4812 /** The other maximally specific symbol */
4813 List<Symbol> ambiguousSyms = List.nil();
4814
4815 @Override
4816 public boolean exists() {
4817 return true;
4818 }
4819
4820 AmbiguityError(Symbol sym1, Symbol sym2) {
4821 super(AMBIGUOUS, "ambiguity error");
4822 ambiguousSyms = flatten(sym2).appendList(flatten(sym1));
4823 }
4824
4825 private List<Symbol> flatten(Symbol sym) {
4826 if (sym.kind == AMBIGUOUS) {
4827 return ((AmbiguityError)sym.baseSymbol()).ambiguousSyms;
4828 } else {
4829 return List.of(sym);
4830 }
4831 }
4832
4833 AmbiguityError addAmbiguousSymbol(Symbol s) {
4834 ambiguousSyms = ambiguousSyms.prepend(s);
4835 return this;
4836 }
4837
4838 @Override
4839 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4840 DiagnosticPosition pos,
4841 Symbol location,
4842 Type site,
4843 Name name,
4844 List<Type> argtypes,
4845 List<Type> typeargtypes) {
4846 List<Symbol> diagSyms = ambiguousSyms.reverse();
4847 Symbol s1 = diagSyms.head;
4848 Symbol s2 = diagSyms.tail.head;
4849 Name sname = s1.name;
4850 if (sname == names.init) sname = s1.owner.name;
4851 return diags.create(dkind, log.currentSource(),
4852 pos, "ref.ambiguous", sname,
4853 kindName(s1),
4854 s1,
4855 s1.location(site, types),
4856 kindName(s2),
4857 s2,
4858 s2.location(site, types));
4859 }
4860
4861 /**
4862 * If multiple applicable methods are found during overload and none of them
4863 * is more specific than the others, attempt to merge their signatures.
4864 */
4865 Symbol mergeAbstracts(Type site) {
4866 List<Symbol> ambiguousInOrder = ambiguousSyms.reverse();
4867 return types.mergeAbstracts(ambiguousInOrder, site, true).orElse(this);
4868 }
4869
4870 @Override
4871 protected Symbol access(Name name, TypeSymbol location) {
4872 Symbol firstAmbiguity = ambiguousSyms.last();
4873 return firstAmbiguity.kind == TYP ?
4874 types.createErrorType(name, location, firstAmbiguity.type).tsym :
4875 firstAmbiguity;
4876 }
4877 }
4878
4879 class BadVarargsMethod extends ResolveError {
4880
4881 ResolveError delegatedError;
4882
4883 BadVarargsMethod(ResolveError delegatedError) {
4884 super(delegatedError.kind, "badVarargs");
4885 this.delegatedError = delegatedError;
4886 }
4887
4888 @Override
4889 public Symbol baseSymbol() {
4890 return delegatedError.baseSymbol();
4891 }
4892
4893 @Override
4894 protected Symbol access(Name name, TypeSymbol location) {
4895 return delegatedError.access(name, location);
4896 }
4897
4898 @Override
4899 public boolean exists() {
4900 return true;
4901 }
4902
4903 @Override
4904 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4905 return delegatedError.getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes);
4906 }
4907 }
4908
4909 /**
4910 * BadMethodReferenceError error class indicating that a method reference symbol has been found,
4911 * but with the wrong staticness.
4912 */
4913 class BadMethodReferenceError extends StaticError {
4914
4915 boolean unboundLookup;
4916
4917 public BadMethodReferenceError(Symbol sym, boolean unboundLookup) {
4918 super(sym, "bad method ref error");
4919 this.unboundLookup = unboundLookup;
4920 }
4921
4922 @Override
4923 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4924 final String key;
4925 if (!unboundLookup) {
4926 key = "bad.static.method.in.bound.lookup";
4927 } else if (sym.isStatic()) {
4928 key = "bad.static.method.in.unbound.lookup";
4929 } else {
4930 key = "bad.instance.method.in.unbound.lookup";
4931 }
4932 return sym.kind.isResolutionError() ?
4933 ((ResolveError)sym).getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes) :
4934 diags.create(dkind, log.currentSource(), pos, key, Kinds.kindName(sym), sym);
4935 }
4936 }
4937
4938 class BadClassFileError extends InvalidSymbolError {
4939
4940 private final CompletionFailure ex;
4941
4942 public BadClassFileError(CompletionFailure ex) {
4943 super(HIDDEN, ex.sym, "BadClassFileError");
4944 this.name = sym.name;
4945 this.ex = ex;
4946 }
4947
4948 @Override
4949 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4950 JCDiagnostic d = diags.create(dkind, log.currentSource(), pos,
4951 "cant.access", ex.sym, ex.getDetailValue());
4952
4953 d.setFlag(DiagnosticFlag.NON_DEFERRABLE);
4954 return d;
4955 }
4956
4957 }
4958
4959 /**
4960 * Helper class for method resolution diagnostic simplification.
4961 * Certain resolution diagnostic are rewritten as simpler diagnostic
4962 * where the enclosing resolution diagnostic (i.e. 'inapplicable method')
4963 * is stripped away, as it doesn't carry additional info. The logic
4964 * for matching a given diagnostic is given in terms of a template
4965 * hierarchy: a diagnostic template can be specified programmatically,
4966 * so that only certain diagnostics are matched. Each templete is then
4967 * associated with a rewriter object that carries out the task of rewtiting
4968 * the diagnostic to a simpler one.
4969 */
4970 static class MethodResolutionDiagHelper {
4971
4972 /**
4973 * A diagnostic rewriter transforms a method resolution diagnostic
4974 * into a simpler one
4975 */
4976 interface DiagnosticRewriter {
4977 JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags,
4978 DiagnosticPosition preferredPos, DiagnosticSource preferredSource,
4979 DiagnosticType preferredKind, JCDiagnostic d);
4980 }
4981
4982 /**
4983 * A diagnostic template is made up of two ingredients: (i) a regular
4984 * expression for matching a diagnostic key and (ii) a list of sub-templates
4985 * for matching diagnostic arguments.
4986 */
4987 static class Template {
4988
4989 /** regex used to match diag key */
4990 String regex;
4991
4992 /** templates used to match diagnostic args */
4993 Template[] subTemplates;
4994
4995 Template(String key, Template... subTemplates) {
4996 this.regex = key;
4997 this.subTemplates = subTemplates;
4998 }
4999
5000 /**
5001 * Returns true if the regex matches the diagnostic key and if
5002 * all diagnostic arguments are matches by corresponding sub-templates.
5003 */
5004 boolean matches(Object o) {
5005 JCDiagnostic d = (JCDiagnostic)o;
5006 Object[] args = d.getArgs();
5007 if (!d.getCode().matches(regex) ||
5008 subTemplates.length != d.getArgs().length) {
5009 return false;
5010 }
5011 for (int i = 0; i < args.length ; i++) {
5012 if (!subTemplates[i].matches(args[i])) {
5013 return false;
5014 }
5015 }
5016 return true;
5017 }
5018 }
5019
5020 /**
5021 * Common rewriter for all argument mismatch simplifications.
5022 */
5023 static class ArgMismatchRewriter implements DiagnosticRewriter {
5024
5025 /** the index of the subdiagnostic to be used as primary. */
5026 int causeIndex;
5027
5028 public ArgMismatchRewriter(int causeIndex) {
5029 this.causeIndex = causeIndex;
5030 }
5031
5032 @Override
5033 public JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags,
5034 DiagnosticPosition preferredPos, DiagnosticSource preferredSource,
5035 DiagnosticType preferredKind, JCDiagnostic d) {
5036 JCDiagnostic cause = (JCDiagnostic)d.getArgs()[causeIndex];
5037 DiagnosticPosition pos = d.getDiagnosticPosition();
5038 if (pos == null) {
5039 pos = preferredPos;
5040 }
5041 return diags.create(preferredKind, preferredSource, pos,
5042 "prob.found.req", cause);
5043 }
5044 }
5045
5046 /** a dummy template that match any diagnostic argument */
5047 static final Template skip = new Template("") {
5048 @Override
5049 boolean matches(Object d) {
5050 return true;
5051 }
5052 };
5053
5054 /** template for matching inference-free arguments mismatch failures */
5055 static final Template argMismatchTemplate = new Template(MethodCheckDiag.ARG_MISMATCH.regex(), skip);
5056
5057 /** template for matching inference related arguments mismatch failures */
5058 static final Template inferArgMismatchTemplate = new Template(MethodCheckDiag.ARG_MISMATCH.regex(), skip, skip) {
5059 @Override
5060 boolean matches(Object o) {
5061 if (!super.matches(o)) {
5062 return false;
5063 }
5064 JCDiagnostic d = (JCDiagnostic)o;
5065 @SuppressWarnings("unchecked")
5066 List<Type> tvars = (List<Type>)d.getArgs()[0];
5067 return !containsAny(d, tvars);
5068 }
5069
5070 BiPredicate<Object, List<Type>> containsPredicate = (o, ts) -> {
5071 if (o instanceof Type type) {
5072 return type.containsAny(ts);
5073 } else if (o instanceof JCDiagnostic diagnostic) {
5074 return containsAny(diagnostic, ts);
5075 } else {
5076 return false;
5077 }
5078 };
5079
5080 boolean containsAny(JCDiagnostic d, List<Type> ts) {
5081 return Stream.of(d.getArgs())
5082 .anyMatch(o -> containsPredicate.test(o, ts));
5083 }
5084 };
5085
5086 /** rewriter map used for method resolution simplification */
5087 static final Map<Template, DiagnosticRewriter> rewriters = new LinkedHashMap<>();
5088
5089 static {
5090 rewriters.put(argMismatchTemplate, new ArgMismatchRewriter(0));
5091 rewriters.put(inferArgMismatchTemplate, new ArgMismatchRewriter(1));
5092 }
5093
5094 /**
5095 * Main entry point for diagnostic rewriting - given a diagnostic, see if any templates matches it,
5096 * and rewrite it accordingly.
5097 */
5098 static JCDiagnostic rewrite(JCDiagnostic.Factory diags, DiagnosticPosition pos, DiagnosticSource source,
5099 DiagnosticType dkind, JCDiagnostic d) {
5100 for (Map.Entry<Template, DiagnosticRewriter> _entry : rewriters.entrySet()) {
5101 if (_entry.getKey().matches(d)) {
5102 JCDiagnostic simpleDiag =
5103 _entry.getValue().rewriteDiagnostic(diags, pos, source, dkind, d);
5104 simpleDiag.setFlag(DiagnosticFlag.COMPRESSED);
5105 return simpleDiag;
5106 }
5107 }
5108 return null;
5109 }
5110 }
5111
5112 enum MethodResolutionPhase {
5113 BASIC(false, false),
5114 BOX(true, false),
5115 VARARITY(true, true) {
5116 @Override
5117 public Symbol mergeResults(Symbol bestSoFar, Symbol sym) {
5118 //Check invariants (see {@code LookupHelper.shouldStop})
5119 Assert.check(bestSoFar.kind.isResolutionError() && bestSoFar.kind != AMBIGUOUS);
5120 if (!sym.kind.isResolutionError()) {
5121 //varargs resolution successful
5122 return sym;
5123 } else {
5124 //pick best error
5125 switch (bestSoFar.kind) {
5126 case WRONG_MTH:
5127 case WRONG_MTHS:
5128 //Override previous errors if they were caused by argument mismatch.
5129 //This generally means preferring current symbols - but we need to pay
5130 //attention to the fact that the varargs lookup returns 'less' candidates
5131 //than the previous rounds, and adjust that accordingly.
5132 switch (sym.kind) {
5133 case WRONG_MTH:
5134 //if the previous round matched more than one method, return that
5135 //result instead
5136 return bestSoFar.kind == WRONG_MTHS ?
5137 bestSoFar : sym;
5138 case ABSENT_MTH:
5139 //do not override erroneous symbol if the arity lookup did not
5140 //match any method
5141 return bestSoFar;
5142 case WRONG_MTHS:
5143 default:
5144 //safe to override
5145 return sym;
5146 }
5147 default:
5148 //otherwise, return first error
5149 return bestSoFar;
5150 }
5151 }
5152 }
5153 };
5154
5155 final boolean isBoxingRequired;
5156 final boolean isVarargsRequired;
5157
5158 MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) {
5159 this.isBoxingRequired = isBoxingRequired;
5160 this.isVarargsRequired = isVarargsRequired;
5161 }
5162
5163 public boolean isBoxingRequired() {
5164 return isBoxingRequired;
5165 }
5166
5167 public boolean isVarargsRequired() {
5168 return isVarargsRequired;
5169 }
5170
5171 public Symbol mergeResults(Symbol prev, Symbol sym) {
5172 return sym;
5173 }
5174 }
5175
5176 final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
5177
5178 /**
5179 * A resolution context is used to keep track of intermediate results of
5180 * overload resolution, such as list of method that are not applicable
5181 * (used to generate more precise diagnostics) and so on. Resolution contexts
5182 * can be nested - this means that when each overload resolution routine should
5183 * work within the resolution context it created.
5184 */
5185 class MethodResolutionContext {
5186
5187 private List<Candidate> candidates = List.nil();
5188
5189 MethodResolutionPhase step = null;
5190
5191 MethodCheck methodCheck = resolveMethodCheck;
5192
5193 private boolean internalResolution = false;
5194 private DeferredAttr.AttrMode attrMode = DeferredAttr.AttrMode.SPECULATIVE;
5195
5196 void addInapplicableCandidate(Symbol sym, JCDiagnostic details) {
5197 Candidate c = new Candidate(currentResolutionContext.step, sym, details, null);
5198 candidates = candidates.append(c);
5199 }
5200
5201 void addApplicableCandidate(Symbol sym, Type mtype) {
5202 Candidate c = new Candidate(currentResolutionContext.step, sym, null, mtype);
5203 candidates = candidates.append(c);
5204 }
5205
5206 DeferredAttrContext deferredAttrContext(Symbol sym, InferenceContext inferenceContext, ResultInfo pendingResult, Warner warn) {
5207 DeferredAttrContext parent = (pendingResult == null)
5208 ? deferredAttr.emptyDeferredAttrContext
5209 : pendingResult.checkContext.deferredAttrContext();
5210 return deferredAttr.new DeferredAttrContext(attrMode, sym, step,
5211 inferenceContext, parent, warn);
5212 }
5213
5214 /**
5215 * This class represents an overload resolution candidate. There are two
5216 * kinds of candidates: applicable methods and inapplicable methods;
5217 * applicable methods have a pointer to the instantiated method type,
5218 * while inapplicable candidates contain further details about the
5219 * reason why the method has been considered inapplicable.
5220 */
5221 class Candidate {
5222
5223 final MethodResolutionPhase step;
5224 final Symbol sym;
5225 final JCDiagnostic details;
5226 final Type mtype;
5227
5228 private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) {
5229 this.step = step;
5230 this.sym = sym;
5231 this.details = details;
5232 this.mtype = mtype;
5233 }
5234
5235 boolean isApplicable() {
5236 return mtype != null;
5237 }
5238 }
5239
5240 DeferredAttr.AttrMode attrMode() {
5241 return attrMode;
5242 }
5243
5244 boolean internal() {
5245 return internalResolution;
5246 }
5247 }
5248
5249 MethodResolutionContext currentResolutionContext = null;
5250 }