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 return resolveQualifiedMethod(new MethodResolutionContext(), pos, env, location, site, name, argtypes, typeargtypes);
2814 }
2815 private Symbol resolveQualifiedMethod(MethodResolutionContext resolveContext,
2816 DiagnosticPosition pos, Env<AttrContext> env,
2817 Symbol location, Type site, Name name, List<Type> argtypes,
2818 List<Type> typeargtypes) {
2819 return lookupMethod(env, pos, location, resolveContext, new BasicLookupHelper(name, site, argtypes, typeargtypes) {
2820 @Override
2821 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2822 return findMethod(env, site, name, argtypes, typeargtypes,
2823 phase.isBoxingRequired(),
2824 phase.isVarargsRequired());
2825 }
2826 @Override
2827 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2828 if (sym.kind.isResolutionError()) {
2829 sym = super.access(env, pos, location, sym);
2830 } else {
2831 MethodSymbol msym = (MethodSymbol)sym;
2832 if ((msym.flags() & SIGNATURE_POLYMORPHIC) != 0) {
2833 env.info.pendingResolutionPhase = BASIC;
2834 return findPolymorphicSignatureInstance(env, sym, argtypes);
2835 }
2836 }
2837 return sym;
2838 }
2839 });
2840 }
2841
2842 /** Find or create an implicit method of exactly the given type (after erasure).
2843 * Searches in a side table, not the main scope of the site.
2844 * This emulates the lookup process required by JSR 292 in JVM.
2845 * @param env Attribution environment
2846 * @param spMethod signature polymorphic method - i.e. MH.invokeExact
2847 * @param argtypes The required argument types
2848 */
2849 Symbol findPolymorphicSignatureInstance(Env<AttrContext> env,
2850 final Symbol spMethod,
2851 List<Type> argtypes) {
2852 Type mtype = infer.instantiatePolymorphicSignatureInstance(env,
2853 (MethodSymbol)spMethod, currentResolutionContext, argtypes);
2854 return findPolymorphicSignatureInstance(spMethod, mtype);
2855 }
2856
2857 Symbol findPolymorphicSignatureInstance(final Symbol spMethod,
2858 Type mtype) {
2859 for (Symbol sym : polymorphicSignatureScope.getSymbolsByName(spMethod.name)) {
2860 // Check that there is already a method symbol for the method
2861 // type and owner
2862 if (types.isSameType(mtype, sym.type) &&
2863 spMethod.owner == sym.owner) {
2864 return sym;
2865 }
2866 }
2867
2868 Type spReturnType = spMethod.asType().getReturnType();
2869 if (types.isSameType(spReturnType, syms.objectType)) {
2870 // Polymorphic return, pass through mtype
2871 } else if (!types.isSameType(spReturnType, mtype.getReturnType())) {
2872 // Retain the sig poly method's return type, which differs from that of mtype
2873 // Will result in an incompatible return type error
2874 mtype = new MethodType(mtype.getParameterTypes(),
2875 spReturnType,
2876 mtype.getThrownTypes(),
2877 syms.methodClass);
2878 }
2879
2880 // Create the desired method
2881 // Retain static modifier is to support invocations to
2882 // MethodHandle.linkTo* methods
2883 long flags = ABSTRACT | HYPOTHETICAL |
2884 spMethod.flags() & (Flags.AccessFlags | Flags.STATIC);
2885 Symbol msym = new MethodSymbol(flags, spMethod.name, mtype, spMethod.owner) {
2886 @Override
2887 public Symbol baseSymbol() {
2888 return spMethod;
2889 }
2890 };
2891 if (!mtype.isErroneous()) { // Cache only if kosher.
2892 polymorphicSignatureScope.enter(msym);
2893 }
2894 return msym;
2895 }
2896
2897 /** Resolve a qualified method identifier, throw a fatal error if not
2898 * found.
2899 * @param pos The position to use for error reporting.
2900 * @param env The environment current at the method invocation.
2901 * @param site The type of the qualifying expression, in which
2902 * identifier is searched.
2903 * @param name The identifier's name.
2904 * @param argtypes The types of the invocation's value arguments.
2905 * @param typeargtypes The types of the invocation's type arguments.
2906 */
2907 public MethodSymbol resolveInternalMethod(DiagnosticPosition pos, Env<AttrContext> env,
2908 Type site, Name name,
2909 List<Type> argtypes,
2910 List<Type> typeargtypes) {
2911 MethodResolutionContext resolveContext = new MethodResolutionContext();
2912 resolveContext.internalResolution = true;
2913 Symbol sym = resolveQualifiedMethod(resolveContext, pos, env, site.tsym,
2914 site, name, argtypes, typeargtypes);
2915 if (sym.kind == MTH) return (MethodSymbol)sym;
2916 else throw new FatalError(
2917 diags.fragment(Fragments.FatalErrCantLocateMeth(name)));
2918 }
2919
2920 /** Resolve constructor.
2921 * @param pos The position to use for error reporting.
2922 * @param env The environment current at the constructor invocation.
2923 * @param site The type of class for which a constructor is searched.
2924 * @param argtypes The types of the constructor invocation's value
2925 * arguments.
2926 * @param typeargtypes The types of the constructor invocation's type
2927 * arguments.
2928 */
2929 Symbol resolveConstructor(DiagnosticPosition pos,
2930 Env<AttrContext> env,
2931 Type site,
2932 List<Type> argtypes,
2933 List<Type> typeargtypes) {
2934 return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes);
2935 }
2936
2937 private Symbol resolveConstructor(MethodResolutionContext resolveContext,
2938 final DiagnosticPosition pos,
2939 Env<AttrContext> env,
2940 Type site,
2941 List<Type> argtypes,
2942 List<Type> typeargtypes) {
2943 return lookupMethod(env, pos, site.tsym, resolveContext, new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
2944 @Override
2945 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2946 return findConstructor(pos, env, site, argtypes, typeargtypes,
2947 phase.isBoxingRequired(),
2948 phase.isVarargsRequired());
2949 }
2950 });
2951 }
2952
2953 /** Resolve a constructor, throw a fatal error if not found.
2954 * @param pos The position to use for error reporting.
2955 * @param env The environment current at the method invocation.
2956 * @param site The type to be constructed.
2957 * @param argtypes The types of the invocation's value arguments.
2958 * @param typeargtypes The types of the invocation's type arguments.
2959 */
2960 public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2961 Type site,
2962 List<Type> argtypes,
2963 List<Type> typeargtypes) {
2964 MethodResolutionContext resolveContext = new MethodResolutionContext();
2965 resolveContext.internalResolution = true;
2966 Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes);
2967 if (sym.kind == MTH) return (MethodSymbol)sym;
2968 else throw new FatalError(
2969 diags.fragment(Fragments.FatalErrCantLocateCtor(site)));
2970 }
2971
2972 Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2973 Type site, List<Type> argtypes,
2974 List<Type> typeargtypes,
2975 boolean allowBoxing,
2976 boolean useVarargs) {
2977 Symbol sym = findMethod(env, site,
2978 names.init, argtypes,
2979 typeargtypes, allowBoxing,
2980 useVarargs);
2981 chk.checkDeprecated(pos, env.info.scope.owner, sym);
2982 chk.checkPreview(pos, env.info.scope.owner, sym);
2983 return sym;
2984 }
2985
2986 /** Resolve constructor using diamond inference.
2987 * @param pos The position to use for error reporting.
2988 * @param env The environment current at the constructor invocation.
2989 * @param site The type of class for which a constructor is searched.
2990 * The scope of this class has been touched in attribution.
2991 * @param argtypes The types of the constructor invocation's value
2992 * arguments.
2993 * @param typeargtypes The types of the constructor invocation's type
2994 * arguments.
2995 */
2996 Symbol resolveDiamond(DiagnosticPosition pos,
2997 Env<AttrContext> env,
2998 Type site,
2999 List<Type> argtypes,
3000 List<Type> typeargtypes) {
3001 return lookupMethod(env, pos, site.tsym, resolveMethodCheck,
3002 new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
3003 @Override
3004 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3005 return findDiamond(pos, env, site, argtypes, typeargtypes,
3006 phase.isBoxingRequired(),
3007 phase.isVarargsRequired());
3008 }
3009 @Override
3010 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
3011 if (sym.kind.isResolutionError()) {
3012 if (sym.kind != WRONG_MTH &&
3013 sym.kind != WRONG_MTHS) {
3014 sym = super.access(env, pos, location, sym);
3015 } else {
3016 sym = new DiamondError(sym, currentResolutionContext);
3017 sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes);
3018 env.info.pendingResolutionPhase = currentResolutionContext.step;
3019 }
3020 }
3021 return sym;
3022 }});
3023 }
3024
3025 /** Find the constructor using diamond inference and do some checks(deprecated and preview).
3026 * @param pos The position to use for error reporting.
3027 * @param env The environment current at the constructor invocation.
3028 * @param site The type of class for which a constructor is searched.
3029 * The scope of this class has been touched in attribution.
3030 * @param argtypes The types of the constructor invocation's value arguments.
3031 * @param typeargtypes The types of the constructor invocation's type arguments.
3032 * @param allowBoxing Allow boxing conversions of arguments.
3033 * @param useVarargs Box trailing arguments into an array for varargs.
3034 */
3035 private Symbol findDiamond(DiagnosticPosition pos,
3036 Env<AttrContext> env,
3037 Type site,
3038 List<Type> argtypes,
3039 List<Type> typeargtypes,
3040 boolean allowBoxing,
3041 boolean useVarargs) {
3042 Symbol sym = findDiamond(env, site, argtypes, typeargtypes, allowBoxing, useVarargs);
3043 chk.checkDeprecated(pos, env.info.scope.owner, sym);
3044 chk.checkPreview(pos, env.info.scope.owner, sym);
3045 return sym;
3046 }
3047
3048 /** This method scans all the constructor symbol in a given class scope -
3049 * assuming that the original scope contains a constructor of the kind:
3050 * {@code Foo(X x, Y y)}, where X,Y are class type-variables declared in Foo,
3051 * a method check is executed against the modified constructor type:
3052 * {@code <X,Y>Foo<X,Y>(X x, Y y)}. This is crucial in order to enable diamond
3053 * inference. The inferred return type of the synthetic constructor IS
3054 * the inferred type for the diamond operator.
3055 */
3056 private Symbol findDiamond(Env<AttrContext> env,
3057 Type site,
3058 List<Type> argtypes,
3059 List<Type> typeargtypes,
3060 boolean allowBoxing,
3061 boolean useVarargs) {
3062 Symbol bestSoFar = methodNotFound;
3063 TypeSymbol tsym = site.tsym.isInterface() ? syms.objectType.tsym : site.tsym;
3064 for (final Symbol sym : tsym.members().getSymbolsByName(names.init)) {
3065 //- System.out.println(" e " + e.sym);
3066 if (sym.kind == MTH &&
3067 (sym.flags_field & SYNTHETIC) == 0) {
3068 List<Type> oldParams = sym.type.hasTag(FORALL) ?
3069 ((ForAll)sym.type).tvars :
3070 List.nil();
3071 Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams),
3072 types.createMethodTypeWithReturn(sym.type.asMethodType(), site));
3073 MethodSymbol newConstr = new MethodSymbol(sym.flags(), names.init, constrType, site.tsym) {
3074 @Override
3075 public Symbol baseSymbol() {
3076 return sym;
3077 }
3078 };
3079 bestSoFar = selectBest(env, site, argtypes, typeargtypes,
3080 newConstr,
3081 bestSoFar,
3082 allowBoxing,
3083 useVarargs);
3084 }
3085 }
3086 return bestSoFar;
3087 }
3088
3089 Symbol getMemberReference(DiagnosticPosition pos,
3090 Env<AttrContext> env,
3091 JCMemberReference referenceTree,
3092 Type site,
3093 Name name) {
3094
3095 site = types.capture(site);
3096
3097 ReferenceLookupHelper lookupHelper = makeReferenceLookupHelper(
3098 referenceTree, site, name, List.nil(), null, VARARITY);
3099
3100 Env<AttrContext> newEnv = env.dup(env.tree, env.info.dup());
3101 Symbol sym = lookupMethod(newEnv, env.tree.pos(), site.tsym,
3102 nilMethodCheck, lookupHelper);
3103
3104 env.info.pendingResolutionPhase = newEnv.info.pendingResolutionPhase;
3105
3106 return sym;
3107 }
3108
3109 ReferenceLookupHelper makeReferenceLookupHelper(JCMemberReference referenceTree,
3110 Type site,
3111 Name name,
3112 List<Type> argtypes,
3113 List<Type> typeargtypes,
3114 MethodResolutionPhase maxPhase) {
3115 if (!name.equals(names.init)) {
3116 //method reference
3117 return new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
3118 } else if (site.hasTag(ARRAY)) {
3119 //array constructor reference
3120 return new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
3121 } else {
3122 //class constructor reference
3123 return new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
3124 }
3125 }
3126
3127 /**
3128 * Resolution of member references is typically done as a single
3129 * overload resolution step, where the argument types A are inferred from
3130 * the target functional descriptor.
3131 *
3132 * If the member reference is a method reference with a type qualifier,
3133 * a two-step lookup process is performed. The first step uses the
3134 * expected argument list A, while the second step discards the first
3135 * type from A (which is treated as a receiver type).
3136 *
3137 * There are two cases in which inference is performed: (i) if the member
3138 * reference is a constructor reference and the qualifier type is raw - in
3139 * which case diamond inference is used to infer a parameterization for the
3140 * type qualifier; (ii) if the member reference is an unbound reference
3141 * where the type qualifier is raw - in that case, during the unbound lookup
3142 * the receiver argument type is used to infer an instantiation for the raw
3143 * qualifier type.
3144 *
3145 * When a multi-step resolution process is exploited, the process of picking
3146 * the resulting symbol is delegated to an helper class {@link com.sun.tools.javac.comp.Resolve.ReferenceChooser}.
3147 *
3148 * This routine returns a pair (T,S), where S is the member reference symbol,
3149 * and T is the type of the class in which S is defined. This is necessary as
3150 * the type T might be dynamically inferred (i.e. if constructor reference
3151 * has a raw qualifier).
3152 */
3153 Pair<Symbol, ReferenceLookupHelper> resolveMemberReference(Env<AttrContext> env,
3154 JCMemberReference referenceTree,
3155 Type site,
3156 Name name,
3157 List<Type> argtypes,
3158 List<Type> typeargtypes,
3159 Type descriptor,
3160 MethodCheck methodCheck,
3161 InferenceContext inferenceContext,
3162 ReferenceChooser referenceChooser) {
3163
3164 //step 1 - bound lookup
3165 ReferenceLookupHelper boundLookupHelper = makeReferenceLookupHelper(
3166 referenceTree, site, name, argtypes, typeargtypes, VARARITY);
3167 Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
3168 MethodResolutionContext boundSearchResolveContext = new MethodResolutionContext();
3169 boundSearchResolveContext.methodCheck = methodCheck;
3170 Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(),
3171 site.tsym, boundSearchResolveContext, boundLookupHelper);
3172 boolean isStaticSelector = TreeInfo.isStaticSelector(referenceTree.expr, names);
3173 ReferenceLookupResult boundRes = new ReferenceLookupResult(boundSym, boundSearchResolveContext, isStaticSelector);
3174 if (dumpMethodReferenceSearchResults) {
3175 dumpMethodReferenceSearchResults(referenceTree, boundSearchResolveContext, boundSym, true);
3176 }
3177
3178 //step 2 - unbound lookup
3179 Symbol unboundSym = methodNotFound;
3180 Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup());
3181 ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext);
3182 ReferenceLookupResult unboundRes = referenceNotFound;
3183 if (unboundLookupHelper != null) {
3184 MethodResolutionContext unboundSearchResolveContext =
3185 new MethodResolutionContext();
3186 unboundSearchResolveContext.methodCheck = methodCheck;
3187 unboundSym = lookupMethod(unboundEnv, env.tree.pos(),
3188 site.tsym, unboundSearchResolveContext, unboundLookupHelper);
3189 unboundRes = new ReferenceLookupResult(unboundSym, unboundSearchResolveContext, isStaticSelector);
3190 if (dumpMethodReferenceSearchResults) {
3191 dumpMethodReferenceSearchResults(referenceTree, unboundSearchResolveContext, unboundSym, false);
3192 }
3193 }
3194
3195 //merge results
3196 Pair<Symbol, ReferenceLookupHelper> res;
3197 ReferenceLookupResult bestRes = referenceChooser.result(boundRes, unboundRes);
3198 res = new Pair<>(bestRes.sym,
3199 bestRes == unboundRes ? unboundLookupHelper : boundLookupHelper);
3200 env.info.pendingResolutionPhase = bestRes == unboundRes ?
3201 unboundEnv.info.pendingResolutionPhase :
3202 boundEnv.info.pendingResolutionPhase;
3203
3204 if (!res.fst.kind.isResolutionError()) {
3205 //handle sigpoly method references
3206 MethodSymbol msym = (MethodSymbol)res.fst;
3207 if ((msym.flags() & SIGNATURE_POLYMORPHIC) != 0) {
3208 env.info.pendingResolutionPhase = BASIC;
3209 res = new Pair<>(findPolymorphicSignatureInstance(msym, descriptor), res.snd);
3210 }
3211 }
3212
3213 return res;
3214 }
3215
3216 private void dumpMethodReferenceSearchResults(JCMemberReference referenceTree,
3217 MethodResolutionContext resolutionContext,
3218 Symbol bestSoFar,
3219 boolean bound) {
3220 ListBuffer<JCDiagnostic> subDiags = new ListBuffer<>();
3221 int pos = 0;
3222 int mostSpecificPos = -1;
3223 for (Candidate c : resolutionContext.candidates) {
3224 if (resolutionContext.step != c.step || !c.isApplicable()) {
3225 continue;
3226 } else {
3227 JCDiagnostic subDiag = null;
3228 if (c.sym.type.hasTag(FORALL)) {
3229 subDiag = diags.fragment(Fragments.PartialInstSig(c.mtype));
3230 }
3231
3232 String key = subDiag == null ?
3233 "applicable.method.found.2" :
3234 "applicable.method.found.3";
3235 subDiags.append(diags.fragment(key, pos,
3236 c.sym.isStatic() ? Fragments.Static : Fragments.NonStatic, c.sym, subDiag));
3237 if (c.sym == bestSoFar)
3238 mostSpecificPos = pos;
3239 pos++;
3240 }
3241 }
3242 JCDiagnostic main = diags.note(
3243 log.currentSource(),
3244 referenceTree,
3245 "method.ref.search.results.multi",
3246 bound ? Fragments.Bound : Fragments.Unbound,
3247 referenceTree.toString(), mostSpecificPos);
3248 JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList());
3249 log.report(d);
3250 }
3251
3252 /**
3253 * This class is used to represent a method reference lookup result. It keeps track of two
3254 * things: (i) the symbol found during a method reference lookup and (ii) the static kind
3255 * of the lookup (see {@link com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind}).
3256 */
3257 static class ReferenceLookupResult {
3258
3259 /**
3260 * Static kind associated with a method reference lookup. Erroneous lookups end up with
3261 * the UNDEFINED kind; successful lookups will end up with either STATIC, NON_STATIC,
3262 * depending on whether all applicable candidates are static or non-static methods,
3263 * respectively. If a successful lookup has both static and non-static applicable methods,
3264 * its kind is set to BOTH.
3265 */
3266 enum StaticKind {
3267 STATIC,
3268 NON_STATIC,
3269 BOTH,
3270 UNDEFINED;
3271
3272 /**
3273 * Retrieve the static kind associated with a given (method) symbol.
3274 */
3275 static StaticKind from(Symbol s) {
3276 return s.isStatic() ?
3277 STATIC : NON_STATIC;
3278 }
3279
3280 /**
3281 * Merge two static kinds together.
3282 */
3283 static StaticKind reduce(StaticKind sk1, StaticKind sk2) {
3284 if (sk1 == UNDEFINED) {
3285 return sk2;
3286 } else if (sk2 == UNDEFINED) {
3287 return sk1;
3288 } else {
3289 return sk1 == sk2 ? sk1 : BOTH;
3290 }
3291 }
3292 }
3293
3294 /** The static kind. */
3295 StaticKind staticKind;
3296
3297 /** The lookup result. */
3298 Symbol sym;
3299
3300 ReferenceLookupResult(Symbol sym, MethodResolutionContext resolutionContext, boolean isStaticSelector) {
3301 this(sym, staticKind(sym, resolutionContext, isStaticSelector));
3302 }
3303
3304 private ReferenceLookupResult(Symbol sym, StaticKind staticKind) {
3305 this.staticKind = staticKind;
3306 this.sym = sym;
3307 }
3308
3309 private static StaticKind staticKind(Symbol sym, MethodResolutionContext resolutionContext, boolean isStaticSelector) {
3310 if (sym.kind == MTH && !isStaticSelector) {
3311 return StaticKind.from(sym);
3312 } else if (sym.kind == MTH || sym.kind == AMBIGUOUS) {
3313 return resolutionContext.candidates.stream()
3314 .filter(c -> c.isApplicable() && c.step == resolutionContext.step)
3315 .map(c -> StaticKind.from(c.sym))
3316 .reduce(StaticKind::reduce)
3317 .orElse(StaticKind.UNDEFINED);
3318 } else {
3319 return StaticKind.UNDEFINED;
3320 }
3321 }
3322
3323 /**
3324 * Does this result corresponds to a successful lookup (i.e. one where a method has been found?)
3325 */
3326 boolean isSuccess() {
3327 return staticKind != StaticKind.UNDEFINED;
3328 }
3329
3330 /**
3331 * Does this result have given static kind?
3332 */
3333 boolean hasKind(StaticKind sk) {
3334 return this.staticKind == sk;
3335 }
3336
3337 /**
3338 * Error recovery helper: can this lookup result be ignored (for the purpose of returning
3339 * some 'better' result) ?
3340 */
3341 boolean canIgnore() {
3342 switch (sym.kind) {
3343 case ABSENT_MTH:
3344 return true;
3345 case WRONG_MTH:
3346 InapplicableSymbolError errSym =
3347 (InapplicableSymbolError)sym.baseSymbol();
3348 return new Template(MethodCheckDiag.ARITY_MISMATCH.regex())
3349 .matches(errSym.errCandidate().snd);
3350 case WRONG_MTHS:
3351 InapplicableSymbolsError errSyms =
3352 (InapplicableSymbolsError)sym.baseSymbol();
3353 return errSyms.filterCandidates(errSyms.mapCandidates()).isEmpty();
3354 default:
3355 return false;
3356 }
3357 }
3358
3359 static ReferenceLookupResult error(Symbol sym) {
3360 return new ReferenceLookupResult(sym, StaticKind.UNDEFINED);
3361 }
3362 }
3363
3364 /**
3365 * This abstract class embodies the logic that converts one (bound lookup) or two (unbound lookup)
3366 * {@code ReferenceLookupResult} objects into a {@code Symbol}, which is then regarded as the
3367 * result of method reference resolution.
3368 */
3369 abstract class ReferenceChooser {
3370 /**
3371 * Generate a result from a pair of lookup result objects. This method delegates to the
3372 * appropriate result generation routine.
3373 */
3374 ReferenceLookupResult result(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
3375 return unboundRes != referenceNotFound ?
3376 unboundResult(boundRes, unboundRes) :
3377 boundResult(boundRes);
3378 }
3379
3380 /**
3381 * Generate a symbol from a given bound lookup result.
3382 */
3383 abstract ReferenceLookupResult boundResult(ReferenceLookupResult boundRes);
3384
3385 /**
3386 * Generate a symbol from a pair of bound/unbound lookup results.
3387 */
3388 abstract ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes);
3389 }
3390
3391 /**
3392 * This chooser implements the selection strategy used during a full lookup; this logic
3393 * is described in JLS SE 8 (15.3.2).
3394 */
3395 ReferenceChooser basicReferenceChooser = new ReferenceChooser() {
3396
3397 @Override
3398 ReferenceLookupResult boundResult(ReferenceLookupResult boundRes) {
3399 return !boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC) ?
3400 boundRes : //the search produces a non-static method
3401 ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.sym, false));
3402 }
3403
3404 @Override
3405 ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
3406 if (boundRes.isSuccess() && boundRes.sym.isStatic() &&
3407 (!unboundRes.isSuccess() || unboundRes.hasKind(StaticKind.STATIC))) {
3408 //the first search produces a static method and no non-static method is applicable
3409 //during the second search
3410 return boundRes;
3411 } else if (unboundRes.isSuccess() && !unboundRes.sym.isStatic() &&
3412 (!boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC))) {
3413 //the second search produces a non-static method and no static method is applicable
3414 //during the first search
3415 return unboundRes;
3416 } else if (boundRes.isSuccess() && unboundRes.isSuccess()) {
3417 //both searches produce some result; ambiguity (error recovery)
3418 return ReferenceLookupResult.error(ambiguityError(boundRes.sym, unboundRes.sym));
3419 } else if (boundRes.isSuccess() || unboundRes.isSuccess()) {
3420 //Both searches failed to produce a result with correct staticness (i.e. first search
3421 //produces an non-static method). Alternatively, a given search produced a result
3422 //with the right staticness, but the other search has applicable methods with wrong
3423 //staticness (error recovery)
3424 return ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.isSuccess() ?
3425 boundRes.sym : unboundRes.sym, true));
3426 } else {
3427 //both searches fail to produce a result - pick 'better' error using heuristics (error recovery)
3428 return (boundRes.canIgnore() && !unboundRes.canIgnore()) ?
3429 unboundRes : boundRes;
3430 }
3431 }
3432 };
3433
3434 /**
3435 * This chooser implements the selection strategy used during an arity-based lookup; this logic
3436 * is described in JLS SE 8 (15.12.2.1).
3437 */
3438 ReferenceChooser structuralReferenceChooser = new ReferenceChooser() {
3439
3440 @Override
3441 ReferenceLookupResult boundResult(ReferenceLookupResult boundRes) {
3442 return (!boundRes.isSuccess() || !boundRes.hasKind(StaticKind.STATIC)) ?
3443 boundRes : //the search has at least one applicable non-static method
3444 ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.sym, false));
3445 }
3446
3447 @Override
3448 ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
3449 if (boundRes.isSuccess() && !boundRes.hasKind(StaticKind.NON_STATIC)) {
3450 //the first search has at least one applicable static method
3451 return boundRes;
3452 } else if (unboundRes.isSuccess() && !unboundRes.hasKind(StaticKind.STATIC)) {
3453 //the second search has at least one applicable non-static method
3454 return unboundRes;
3455 } else if (boundRes.isSuccess() || unboundRes.isSuccess()) {
3456 //either the first search produces a non-static method, or second search produces
3457 //a non-static method (error recovery)
3458 return ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.isSuccess() ?
3459 boundRes.sym : unboundRes.sym, true));
3460 } else {
3461 //both searches fail to produce a result - pick 'better' error using heuristics (error recovery)
3462 return (boundRes.canIgnore() && !unboundRes.canIgnore()) ?
3463 unboundRes : boundRes;
3464 }
3465 }
3466 };
3467
3468 /**
3469 * Helper for defining custom method-like lookup logic; a lookup helper
3470 * provides hooks for (i) the actual lookup logic and (ii) accessing the
3471 * lookup result (this step might result in compiler diagnostics to be generated)
3472 */
3473 abstract class LookupHelper {
3474
3475 /** name of the symbol to lookup */
3476 Name name;
3477
3478 /** location in which the lookup takes place */
3479 Type site;
3480
3481 /** actual types used during the lookup */
3482 List<Type> argtypes;
3483
3484 /** type arguments used during the lookup */
3485 List<Type> typeargtypes;
3486
3487 /** Max overload resolution phase handled by this helper */
3488 MethodResolutionPhase maxPhase;
3489
3490 LookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3491 this.name = name;
3492 this.site = site;
3493 this.argtypes = argtypes;
3494 this.typeargtypes = typeargtypes;
3495 this.maxPhase = maxPhase;
3496 }
3497
3498 /**
3499 * Should lookup stop at given phase with given result
3500 */
3501 final boolean shouldStop(Symbol sym, MethodResolutionPhase phase) {
3502 return phase.ordinal() > maxPhase.ordinal() ||
3503 !sym.kind.isResolutionError() || sym.kind == AMBIGUOUS || sym.kind == STATICERR;
3504 }
3505
3506 /**
3507 * Search for a symbol under a given overload resolution phase - this method
3508 * is usually called several times, once per each overload resolution phase
3509 */
3510 abstract Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase);
3511
3512 /**
3513 * Dump overload resolution info
3514 */
3515 void debug(DiagnosticPosition pos, Symbol sym) {
3516 //do nothing
3517 }
3518
3519 /**
3520 * Validate the result of the lookup
3521 */
3522 abstract Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym);
3523 }
3524
3525 abstract class BasicLookupHelper extends LookupHelper {
3526
3527 BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes) {
3528 this(name, site, argtypes, typeargtypes, MethodResolutionPhase.VARARITY);
3529 }
3530
3531 BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3532 super(name, site, argtypes, typeargtypes, maxPhase);
3533 }
3534
3535 @Override
3536 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
3537 if (sym.kind.isResolutionError()) {
3538 //if nothing is found return the 'first' error
3539 sym = accessMethod(sym, pos, location, site, name, true, argtypes, typeargtypes);
3540 }
3541 return sym;
3542 }
3543
3544 @Override
3545 void debug(DiagnosticPosition pos, Symbol sym) {
3546 reportVerboseResolutionDiagnostic(pos, name, site, argtypes, typeargtypes, sym);
3547 }
3548 }
3549
3550 /**
3551 * Helper class for member reference lookup. A reference lookup helper
3552 * defines the basic logic for member reference lookup; a method gives
3553 * access to an 'unbound' helper used to perform an unbound member
3554 * reference lookup.
3555 */
3556 abstract class ReferenceLookupHelper extends LookupHelper {
3557
3558 /** The member reference tree */
3559 JCMemberReference referenceTree;
3560
3561 ReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3562 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3563 super(name, site, argtypes, typeargtypes, maxPhase);
3564 this.referenceTree = referenceTree;
3565 }
3566
3567 /**
3568 * Returns an unbound version of this lookup helper. By default, this
3569 * method returns an dummy lookup helper.
3570 */
3571 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3572 return null;
3573 }
3574
3575 /**
3576 * Get the kind of the member reference
3577 */
3578 abstract JCMemberReference.ReferenceKind referenceKind(Symbol sym);
3579
3580 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
3581 //skip error reporting
3582 return sym;
3583 }
3584 }
3585
3586 /**
3587 * Helper class for method reference lookup. The lookup logic is based
3588 * upon Resolve.findMethod; in certain cases, this helper class has a
3589 * corresponding unbound helper class (see UnboundMethodReferenceLookupHelper).
3590 * In such cases, non-static lookup results are thrown away.
3591 */
3592 class MethodReferenceLookupHelper extends ReferenceLookupHelper {
3593
3594 /** The original method reference lookup site. */
3595 Type originalSite;
3596
3597 MethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3598 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3599 super(referenceTree, name, types.skipTypeVars(site, true), argtypes, typeargtypes, maxPhase);
3600 this.originalSite = site;
3601 }
3602
3603 @Override
3604 final Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3605 return findMethod(env, site, name, argtypes, typeargtypes,
3606 phase.isBoxingRequired(), phase.isVarargsRequired());
3607 }
3608
3609 @Override
3610 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3611 if (TreeInfo.isStaticSelector(referenceTree.expr, names)) {
3612 if (argtypes.nonEmpty() &&
3613 (argtypes.head.hasTag(NONE) ||
3614 types.isSubtypeUnchecked(inferenceContext.asUndetVar(argtypes.head), originalSite))) {
3615 return new UnboundMethodReferenceLookupHelper(referenceTree, name,
3616 originalSite, argtypes, typeargtypes, maxPhase);
3617 } else {
3618 return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) {
3619 @Override
3620 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3621 return this;
3622 }
3623
3624 @Override
3625 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3626 return methodNotFound;
3627 }
3628
3629 @Override
3630 ReferenceKind referenceKind(Symbol sym) {
3631 Assert.error();
3632 return null;
3633 }
3634 };
3635 }
3636 } else {
3637 return super.unboundLookup(inferenceContext);
3638 }
3639 }
3640
3641 @Override
3642 ReferenceKind referenceKind(Symbol sym) {
3643 if (sym.isStatic()) {
3644 return ReferenceKind.STATIC;
3645 } else {
3646 Name selName = TreeInfo.name(referenceTree.getQualifierExpression());
3647 return selName != null && selName == names._super ?
3648 ReferenceKind.SUPER :
3649 ReferenceKind.BOUND;
3650 }
3651 }
3652
3653 @Override
3654 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
3655 if (originalSite.hasTag(TYPEVAR) && sym.kind == MTH) {
3656 sym = (sym.flags() & Flags.PRIVATE) != 0 ?
3657 new AccessError(env, site, sym) :
3658 sym;
3659 return accessBase(sym, pos, location, originalSite, name, true);
3660 } else {
3661 return super.access(env, pos, location, sym);
3662 }
3663 }
3664 }
3665
3666 /**
3667 * Helper class for unbound method reference lookup. Essentially the same
3668 * as the basic method reference lookup helper; main difference is that static
3669 * lookup results are thrown away. If qualifier type is raw, an attempt to
3670 * infer a parameterized type is made using the first actual argument (that
3671 * would otherwise be ignored during the lookup).
3672 */
3673 class UnboundMethodReferenceLookupHelper extends MethodReferenceLookupHelper {
3674
3675 UnboundMethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3676 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3677 super(referenceTree, name, site, argtypes.tail, typeargtypes, maxPhase);
3678 if (site.isRaw() && !argtypes.head.hasTag(NONE)) {
3679 Type asSuperSite = types.asSuper(argtypes.head, site.tsym);
3680 this.site = types.skipTypeVars(asSuperSite, true);
3681 }
3682 }
3683
3684 @Override
3685 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3686 return this;
3687 }
3688
3689 @Override
3690 ReferenceKind referenceKind(Symbol sym) {
3691 return ReferenceKind.UNBOUND;
3692 }
3693 }
3694
3695 /**
3696 * Helper class for array constructor lookup; an array constructor lookup
3697 * is simulated by looking up a method that returns the array type specified
3698 * as qualifier, and that accepts a single int parameter (size of the array).
3699 */
3700 class ArrayConstructorReferenceLookupHelper extends ReferenceLookupHelper {
3701
3702 ArrayConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
3703 List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3704 super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
3705 }
3706
3707 @Override
3708 protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3709 WriteableScope sc = WriteableScope.create(syms.arrayClass);
3710 MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym);
3711 arrayConstr.type = new MethodType(List.of(syms.intType), site, List.nil(), syms.methodClass);
3712 sc.enter(arrayConstr);
3713 return findMethodInScope(env, site, name, argtypes, typeargtypes, sc, methodNotFound, phase.isBoxingRequired(), phase.isVarargsRequired(), false);
3714 }
3715
3716 @Override
3717 ReferenceKind referenceKind(Symbol sym) {
3718 return ReferenceKind.ARRAY_CTOR;
3719 }
3720 }
3721
3722 /**
3723 * Helper class for constructor reference lookup. The lookup logic is based
3724 * upon either Resolve.findMethod or Resolve.findDiamond - depending on
3725 * whether the constructor reference needs diamond inference (this is the case
3726 * if the qualifier type is raw). A special erroneous symbol is returned
3727 * if the lookup returns the constructor of an inner class and there's no
3728 * enclosing instance in scope.
3729 */
3730 class ConstructorReferenceLookupHelper extends ReferenceLookupHelper {
3731
3732 boolean needsInference;
3733
3734 ConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
3735 List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3736 super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
3737 if (site.isRaw()) {
3738 this.site = new ClassType(site.getEnclosingType(),
3739 !(site.tsym.isInner() && site.getEnclosingType().isRaw()) ?
3740 site.tsym.type.getTypeArguments() : List.nil(), site.tsym, site.getMetadata());
3741 needsInference = true;
3742 }
3743 }
3744
3745 @Override
3746 protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3747 return needsInference ?
3748 findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) :
3749 findMethod(env, site, name, argtypes, typeargtypes,
3750 phase.isBoxingRequired(), phase.isVarargsRequired());
3751 }
3752
3753 @Override
3754 ReferenceKind referenceKind(Symbol sym) {
3755 return site.getEnclosingType().hasTag(NONE) ?
3756 ReferenceKind.TOPLEVEL : ReferenceKind.IMPLICIT_INNER;
3757 }
3758 }
3759
3760 /**
3761 * Main overload resolution routine. On each overload resolution step, a
3762 * lookup helper class is used to perform the method/constructor lookup;
3763 * at the end of the lookup, the helper is used to validate the results
3764 * (this last step might trigger overload resolution diagnostics).
3765 */
3766 Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, MethodCheck methodCheck, LookupHelper lookupHelper) {
3767 MethodResolutionContext resolveContext = new MethodResolutionContext();
3768 resolveContext.methodCheck = methodCheck;
3769 return lookupMethod(env, pos, location, resolveContext, lookupHelper);
3770 }
3771
3772 Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location,
3773 MethodResolutionContext resolveContext, LookupHelper lookupHelper) {
3774 MethodResolutionContext prevResolutionContext = currentResolutionContext;
3775 try {
3776 Symbol bestSoFar = methodNotFound;
3777 currentResolutionContext = resolveContext;
3778 for (MethodResolutionPhase phase : methodResolutionSteps) {
3779 if (lookupHelper.shouldStop(bestSoFar, phase))
3780 break;
3781 MethodResolutionPhase prevPhase = currentResolutionContext.step;
3782 Symbol prevBest = bestSoFar;
3783 currentResolutionContext.step = phase;
3784 Symbol sym = lookupHelper.lookup(env, phase);
3785 lookupHelper.debug(pos, sym);
3786 bestSoFar = phase.mergeResults(bestSoFar, sym);
3787 env.info.pendingResolutionPhase = (prevBest == bestSoFar) ? prevPhase : phase;
3788 }
3789 return lookupHelper.access(env, pos, location, bestSoFar);
3790 } finally {
3791 currentResolutionContext = prevResolutionContext;
3792 }
3793 }
3794
3795 /**
3796 * Find a "valid" reference to an enclosing 'A.this' such that A is a subclass of the provided class symbol.
3797 * A reference to an enclosing 'A.this' is "valid" if (a) we're not in the early-construction context for A
3798 * and (b) if the current class is not an inner class of A.
3799 */
3800 Symbol findSelfContaining(DiagnosticPosition pos,
3801 Env<AttrContext> env,
3802 TypeSymbol c,
3803 boolean isSuper) {
3804 Env<AttrContext> env1 = isSuper ? env.outer : env;
3805 boolean staticOnly = false;
3806 while (env1.outer != null) {
3807 if (isStatic(env1)) staticOnly = true;
3808 if (env1.enclClass.sym.isSubClass(c, types)) {
3809 Symbol sym = env1.info.scope.findFirst(names._this);
3810 if (sym != null) {
3811 if (staticOnly) {
3812 // current class is not an inner class, stop search
3813 return new StaticError(sym);
3814 } else if (env1.info.ctorPrologue && !isAllowedEarlyReference(pos, env1, (VarSymbol)sym)) {
3815 // early construction context, stop search
3816 return new RefBeforeCtorCalledError(sym);
3817 } else {
3818 // found it
3819 return sym;
3820 }
3821 }
3822 }
3823 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
3824 env1 = env1.outer;
3825 }
3826 return varNotFound;
3827 }
3828
3829 /**
3830 * Resolve the (method) owner of a local class. This can fail if the local class
3831 * is referenced from a static context nested inside the local class. Effectively,
3832 * this lookup succeeds if we can access a local variable declared inside the owner
3833 * method from the provided env.
3834 */
3835 Symbol findLocalClassOwner(Env<AttrContext> env, TypeSymbol c) {
3836 Symbol owner = c.owner;
3837 Assert.check(owner.kind == MTH || owner.kind == VAR);
3838 Env<AttrContext> env1 = env;
3839 boolean staticOnly = false;
3840 while (env1.outer != null) {
3841 if (env1.info.scope.owner == owner) {
3842 return (staticOnly) ?
3843 new BadLocalClassCreation(c) :
3844 owner;
3845 }
3846 if (isStatic(env1)) staticOnly = true;
3847 env1 = env1.outer;
3848 }
3849 return owner.kind == MTH ?
3850 methodNotFound :
3851 varNotFound;
3852 }
3853
3854 /**
3855 * Resolve `c.name' where name == this or name == super.
3856 * @param pos The position to use for error reporting.
3857 * @param env The environment current at the expression.
3858 * @param c The type of the selected expression
3859 * @param tree The expression
3860 */
3861 Symbol resolveSelf(DiagnosticPosition pos,
3862 Env<AttrContext> env,
3863 TypeSymbol c,
3864 JCFieldAccess tree) {
3865 Name name = tree.name;
3866 Assert.check(name == names._this || name == names._super);
3867 Env<AttrContext> env1 = env;
3868 boolean staticOnly = false;
3869 while (env1.outer != null) {
3870 if (isStatic(env1)) staticOnly = true;
3871 if (env1.enclClass.sym == c) {
3872 Symbol sym = env1.info.scope.findFirst(name);
3873 if (sym != null) {
3874 if (staticOnly)
3875 sym = new StaticError(sym);
3876 else if (env1.info.ctorPrologue &&
3877 !isReceiverParameter(env, tree) &&
3878 !isAllowedEarlyReference(pos, env1, (VarSymbol)sym))
3879 sym = new RefBeforeCtorCalledError(sym);
3880 return accessBase(sym, pos, env.enclClass.sym.type,
3881 name, true);
3882 }
3883 }
3884 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
3885 env1 = env1.outer;
3886 }
3887 if (c.isInterface() &&
3888 name == names._super && !isStatic(env) &&
3889 types.isDirectSuperInterface(c, env.enclClass.sym)) {
3890 //this might be a default super call if one of the superinterfaces is 'c'
3891 for (Type t : pruneInterfaces(env.enclClass.type)) {
3892 if (t.tsym == c) {
3893 if (env.info.ctorPrologue)
3894 log.error(pos, Errors.CantRefBeforeCtorCalled(name));
3895 env.info.defaultSuperCallSite = t;
3896 return new VarSymbol(0, names._super,
3897 types.asSuper(env.enclClass.type, c), env.enclClass.sym);
3898 }
3899 }
3900 //find a direct supertype that is a subtype of 'c'
3901 for (Type i : types.directSupertypes(env.enclClass.type)) {
3902 if (i.tsym.isSubClass(c, types) && i.tsym != c) {
3903 log.error(pos,
3904 Errors.IllegalDefaultSuperCall(c,
3905 Fragments.RedundantSupertype(c, i)));
3906 return syms.errSymbol;
3907 }
3908 }
3909 Assert.error();
3910 }
3911 log.error(pos, Errors.NotEnclClass(c));
3912 return syms.errSymbol;
3913 }
3914 //where
3915 private List<Type> pruneInterfaces(Type t) {
3916 ListBuffer<Type> result = new ListBuffer<>();
3917 for (Type t1 : types.interfaces(t)) {
3918 boolean shouldAdd = true;
3919 for (Type t2 : types.directSupertypes(t)) {
3920 if (t1 != t2 && !t2.hasTag(ERROR) && types.isSubtypeNoCapture(t2, t1)) {
3921 shouldAdd = false;
3922 }
3923 }
3924 if (shouldAdd) {
3925 result.append(t1);
3926 }
3927 }
3928 return result.toList();
3929 }
3930 private boolean isReceiverParameter(Env<AttrContext> env, JCFieldAccess tree) {
3931 if (env.tree.getTag() != METHODDEF)
3932 return false;
3933 JCMethodDecl method = (JCMethodDecl)env.tree;
3934 return method.recvparam != null && tree == method.recvparam.nameexpr;
3935 }
3936
3937 /**
3938 * Determine if an early instance field reference may appear in a constructor prologue.
3939 *
3940 * <p>
3941 * This is only allowed when:
3942 * - The field is being assigned a value (i.e., written but not read)
3943 * - The field is not inherited from a superclass
3944 * - The assignment is not within a lambda, because that would require
3945 * capturing 'this' which is not allowed prior to super().
3946 *
3947 * <p>
3948 * Note, this method doesn't catch all such scenarios, because this method
3949 * is invoked for symbol "x" only for "x = 42" but not for "this.x = 42".
3950 * We also don't verify that the field has no initializer, which is required.
3951 * To catch those cases, we rely on similar logic in Attr.checkAssignable().
3952 */
3953 private boolean isAllowedEarlyReference(DiagnosticPosition pos, Env<AttrContext> env, VarSymbol v) {
3954
3955 // Check assumptions
3956 Assert.check(env.info.ctorPrologue);
3957 Assert.check((v.flags_field & STATIC) == 0);
3958
3959 // The symbol must appear in the LHS of an assignment statement
3960 if (!(env.tree instanceof JCAssign assign))
3961 return false;
3962
3963 // The assignment statement must not be within a lambda
3964 if (env.info.isLambda)
3965 return false;
3966
3967 // Get the symbol's qualifier, if any
3968 JCExpression lhs = TreeInfo.skipParens(assign.lhs);
3969 JCExpression base;
3970 switch (lhs.getTag()) {
3971 case IDENT:
3972 base = null;
3973 break;
3974 case SELECT:
3975 JCFieldAccess select = (JCFieldAccess)lhs;
3976 base = select.selected;
3977 if (!TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, base))
3978 return false;
3979 break;
3980 default:
3981 return false;
3982 }
3983
3984 // If an early reference, the field must not be declared in a superclass
3985 if (isEarlyReference(env, base, v) && v.owner != env.enclClass.sym)
3986 return false;
3987
3988 // The flexible constructors feature must be enabled
3989 preview.checkSourceLevel(pos, Feature.FLEXIBLE_CONSTRUCTORS);
3990
3991 // OK
3992 return true;
3993 }
3994
3995 /**
3996 * Determine if the variable appearance constitutes an early reference to the current class.
3997 *
3998 * <p>
3999 * This means the variable is an instance field of the current class and it appears
4000 * in an early initialization context of it (i.e., one of its constructor prologues).
4001 *
4002 * <p>
4003 * Such a reference is only allowed for assignments to non-initialized fields that are
4004 * not inherited from a superclass, though that is not enforced by this method.
4005 *
4006 * @param env The current environment
4007 * @param base Variable qualifier, if any, otherwise null
4008 * @param v The variable
4009 */
4010 public boolean isEarlyReference(Env<AttrContext> env, JCTree base, VarSymbol v) {
4011 if (env.info.ctorPrologue &&
4012 (v.flags() & STATIC) == 0 &&
4013 v.isMemberOf(env.enclClass.sym, types)) {
4014
4015 // Allow "Foo.this.x" when "Foo" is (also) an outer class, as this refers to the outer instance
4016 if (base != null) {
4017 return TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, base);
4018 }
4019
4020 // It's an early reference to an instance field member of the current instance
4021 return true;
4022 }
4023 return false;
4024 }
4025
4026 /* ***************************************************************************
4027 * ResolveError classes, indicating error situations when accessing symbols
4028 ****************************************************************************/
4029
4030 //used by TransTypes when checking target type of synthetic cast
4031 public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) {
4032 AccessError error = new AccessError(env, env.enclClass.type, type.tsym);
4033 logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null);
4034 }
4035 //where
4036 private void logResolveError(ResolveError error,
4037 DiagnosticPosition pos,
4038 Symbol location,
4039 Type site,
4040 Name name,
4041 List<Type> argtypes,
4042 List<Type> typeargtypes) {
4043 JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
4044 pos, location, site, name, argtypes, typeargtypes);
4045 if (d != null) {
4046 d.setFlag(DiagnosticFlag.RESOLVE_ERROR);
4047 log.report(d);
4048 }
4049 }
4050
4051 private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
4052
4053 public Object methodArguments(List<Type> argtypes) {
4054 if (argtypes == null || argtypes.isEmpty()) {
4055 return noArgs;
4056 } else {
4057 ListBuffer<Object> diagArgs = new ListBuffer<>();
4058 for (Type t : argtypes) {
4059 if (t.hasTag(DEFERRED)) {
4060 diagArgs.append(((DeferredAttr.DeferredType)t).tree);
4061 } else {
4062 diagArgs.append(t);
4063 }
4064 }
4065 return diagArgs;
4066 }
4067 }
4068
4069 /** check if a type is a subtype of Serializable, if that is available.*/
4070 boolean isSerializable(Type t) {
4071 try {
4072 syms.serializableType.complete();
4073 }
4074 catch (CompletionFailure e) {
4075 return false;
4076 }
4077 return types.isSubtype(t, syms.serializableType);
4078 }
4079
4080 /**
4081 * Root class for resolution errors. Subclass of ResolveError
4082 * represent a different kinds of resolution error - as such they must
4083 * specify how they map into concrete compiler diagnostics.
4084 */
4085 abstract class ResolveError extends Symbol {
4086
4087 /** The name of the kind of error, for debugging only. */
4088 final String debugName;
4089
4090 ResolveError(Kind kind, String debugName) {
4091 super(kind, 0, null, null, null);
4092 this.debugName = debugName;
4093 }
4094
4095 @Override @DefinedBy(Api.LANGUAGE_MODEL)
4096 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
4097 throw new AssertionError();
4098 }
4099
4100 @Override
4101 public String toString() {
4102 return debugName;
4103 }
4104
4105 @Override
4106 public boolean exists() {
4107 return false;
4108 }
4109
4110 @Override
4111 public boolean isStatic() {
4112 return false;
4113 }
4114
4115 /**
4116 * Create an external representation for this erroneous symbol to be
4117 * used during attribution - by default this returns the symbol of a
4118 * brand new error type which stores the original type found
4119 * during resolution.
4120 *
4121 * @param name the name used during resolution
4122 * @param location the location from which the symbol is accessed
4123 */
4124 protected Symbol access(Name name, TypeSymbol location) {
4125 return types.createErrorType(name, location, syms.errSymbol.type).tsym;
4126 }
4127
4128 /**
4129 * Create a diagnostic representing this resolution error.
4130 *
4131 * @param dkind The kind of the diagnostic to be created (e.g error).
4132 * @param pos The position to be used for error reporting.
4133 * @param site The original type from where the selection took place.
4134 * @param name The name of the symbol to be resolved.
4135 * @param argtypes The invocation's value arguments,
4136 * if we looked for a method.
4137 * @param typeargtypes The invocation's type arguments,
4138 * if we looked for a method.
4139 */
4140 abstract JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4141 DiagnosticPosition pos,
4142 Symbol location,
4143 Type site,
4144 Name name,
4145 List<Type> argtypes,
4146 List<Type> typeargtypes);
4147 }
4148
4149 /**
4150 * This class is the root class of all resolution errors caused by
4151 * an invalid symbol being found during resolution.
4152 */
4153 abstract class InvalidSymbolError extends ResolveError {
4154
4155 /** The invalid symbol found during resolution */
4156 Symbol sym;
4157
4158 InvalidSymbolError(Kind kind, Symbol sym, String debugName) {
4159 super(kind, debugName);
4160 this.sym = sym;
4161 }
4162
4163 @Override
4164 public boolean exists() {
4165 return true;
4166 }
4167
4168 @Override
4169 public String toString() {
4170 return super.toString() + " wrongSym=" + sym;
4171 }
4172
4173 @Override
4174 public Symbol access(Name name, TypeSymbol location) {
4175 if (!sym.kind.isResolutionError() && sym.kind.matches(KindSelector.TYP))
4176 return types.createErrorType(name, location, sym.type).tsym;
4177 else
4178 return sym;
4179 }
4180 }
4181
4182 class BadRestrictedTypeError extends ResolveError {
4183 private final Name typeName;
4184 BadRestrictedTypeError(Name typeName) {
4185 super(Kind.BAD_RESTRICTED_TYPE, "bad var use");
4186 this.typeName = typeName;
4187 }
4188
4189 @Override
4190 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4191 return diags.create(dkind, log.currentSource(), pos, "illegal.ref.to.restricted.type", typeName);
4192 }
4193 }
4194
4195 /**
4196 * InvalidSymbolError error class indicating that a symbol matching a
4197 * given name does not exists in a given site.
4198 */
4199 class SymbolNotFoundError extends ResolveError {
4200
4201 SymbolNotFoundError(Kind kind) {
4202 this(kind, "symbol not found error");
4203 }
4204
4205 SymbolNotFoundError(Kind kind, String debugName) {
4206 super(kind, debugName);
4207 }
4208
4209 @Override
4210 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4211 DiagnosticPosition pos,
4212 Symbol location,
4213 Type site,
4214 Name name,
4215 List<Type> argtypes,
4216 List<Type> typeargtypes) {
4217 argtypes = argtypes == null ? List.nil() : argtypes;
4218 typeargtypes = typeargtypes == null ? List.nil() : typeargtypes;
4219 if (name == names.error)
4220 return null;
4221
4222 boolean hasLocation = false;
4223 if (location == null) {
4224 location = site.tsym;
4225 }
4226 if (!location.name.isEmpty()) {
4227 if (location.kind == PCK && !site.tsym.exists() && location.name != names.java) {
4228 return diags.create(dkind, log.currentSource(), pos,
4229 "doesnt.exist", location);
4230 }
4231 hasLocation = !location.name.equals(names._this) &&
4232 !location.name.equals(names._super);
4233 }
4234 boolean isConstructor = name == names.init;
4235 KindName kindname = isConstructor ? KindName.CONSTRUCTOR : kind.absentKind();
4236 Name idname = isConstructor ? site.tsym.name : name;
4237 String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation);
4238 if (hasLocation) {
4239 return diags.create(dkind, log.currentSource(), pos,
4240 errKey, kindname, idname, //symbol kindname, name
4241 typeargtypes, args(argtypes), //type parameters and arguments (if any)
4242 getLocationDiag(location, site)); //location kindname, type
4243 }
4244 else {
4245 return diags.create(dkind, log.currentSource(), pos,
4246 errKey, kindname, idname, //symbol kindname, name
4247 typeargtypes, args(argtypes)); //type parameters and arguments (if any)
4248 }
4249 }
4250 //where
4251 private Object args(List<Type> args) {
4252 return args.isEmpty() ? args : methodArguments(args);
4253 }
4254
4255 private String getErrorKey(KindName kindname, boolean hasTypeArgs, boolean hasLocation) {
4256 String key = "cant.resolve";
4257 String suffix = hasLocation ? ".location" : "";
4258 switch (kindname) {
4259 case METHOD:
4260 case CONSTRUCTOR: {
4261 suffix += ".args";
4262 suffix += hasTypeArgs ? ".params" : "";
4263 }
4264 }
4265 return key + suffix;
4266 }
4267 private JCDiagnostic getLocationDiag(Symbol location, Type site) {
4268 if (location.kind == VAR) {
4269 return diags.fragment(Fragments.Location1(kindName(location),
4270 location,
4271 location.type));
4272 } else {
4273 return diags.fragment(Fragments.Location(typeKindName(site),
4274 site,
4275 null));
4276 }
4277 }
4278 }
4279
4280 /**
4281 * InvalidSymbolError error class indicating that a given symbol
4282 * (either a method, a constructor or an operand) is not applicable
4283 * given an actual arguments/type argument list.
4284 */
4285 class InapplicableSymbolError extends ResolveError {
4286
4287 protected MethodResolutionContext resolveContext;
4288
4289 InapplicableSymbolError(MethodResolutionContext context) {
4290 this(WRONG_MTH, "inapplicable symbol error", context);
4291 }
4292
4293 protected InapplicableSymbolError(Kind kind, String debugName, MethodResolutionContext context) {
4294 super(kind, debugName);
4295 this.resolveContext = context;
4296 }
4297
4298 @Override
4299 public String toString() {
4300 return super.toString();
4301 }
4302
4303 @Override
4304 public boolean exists() {
4305 return true;
4306 }
4307
4308 @Override
4309 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4310 DiagnosticPosition pos,
4311 Symbol location,
4312 Type site,
4313 Name name,
4314 List<Type> argtypes,
4315 List<Type> typeargtypes) {
4316 if (name == names.error)
4317 return null;
4318
4319 Pair<Symbol, JCDiagnostic> c = errCandidate();
4320 Symbol ws = c.fst.asMemberOf(site, types);
4321 UnaryOperator<JCDiagnostic> rewriter = compactMethodDiags ?
4322 d -> MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, c.snd) : null;
4323
4324 // If the problem is due to type arguments, then the method parameters aren't relevant,
4325 // so use the error message that omits them to avoid confusion.
4326 switch (c.snd.getCode()) {
4327 case "compiler.misc.wrong.number.type.args":
4328 case "compiler.misc.explicit.param.do.not.conform.to.bounds":
4329 return diags.create(dkind, log.currentSource(), pos,
4330 "cant.apply.symbol.noargs",
4331 rewriter,
4332 kindName(ws),
4333 ws.name == names.init ? ws.owner.name : ws.name,
4334 kindName(ws.owner),
4335 ws.owner.type,
4336 c.snd);
4337 default:
4338 // Avoid saying "constructor Array in class Array"
4339 if (ws.owner == syms.arrayClass && ws.name == names.init) {
4340 return diags.create(dkind, log.currentSource(), pos,
4341 "cant.apply.array.ctor",
4342 rewriter,
4343 methodArguments(ws.type.getParameterTypes()),
4344 methodArguments(argtypes),
4345 c.snd);
4346 }
4347 return diags.create(dkind, log.currentSource(), pos,
4348 "cant.apply.symbol",
4349 rewriter,
4350 kindName(ws),
4351 ws.name == names.init ? ws.owner.name : ws.name,
4352 methodArguments(ws.type.getParameterTypes()),
4353 methodArguments(argtypes),
4354 kindName(ws.owner),
4355 ws.owner.type,
4356 c.snd);
4357 }
4358 }
4359
4360 @Override
4361 public Symbol access(Name name, TypeSymbol location) {
4362 Pair<Symbol, JCDiagnostic> cand = errCandidate();
4363 TypeSymbol errSymbol = types.createErrorType(name, location, cand != null ? cand.fst.type : syms.errSymbol.type).tsym;
4364 if (cand != null) {
4365 attrRecover.wrongMethodSymbolCandidate(errSymbol, cand.fst, cand.snd);
4366 }
4367 return errSymbol;
4368 }
4369
4370 protected Pair<Symbol, JCDiagnostic> errCandidate() {
4371 Candidate bestSoFar = null;
4372 for (Candidate c : resolveContext.candidates) {
4373 if (c.isApplicable()) continue;
4374 bestSoFar = c;
4375 }
4376 Assert.checkNonNull(bestSoFar);
4377 return new Pair<>(bestSoFar.sym, bestSoFar.details);
4378 }
4379 }
4380
4381 /**
4382 * ResolveError error class indicating that a symbol (either methods, constructors or operand)
4383 * is not applicable given an actual arguments/type argument list.
4384 */
4385 class InapplicableSymbolsError extends InapplicableSymbolError {
4386
4387 InapplicableSymbolsError(MethodResolutionContext context) {
4388 super(WRONG_MTHS, "inapplicable symbols", context);
4389 }
4390
4391 @Override
4392 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4393 DiagnosticPosition pos,
4394 Symbol location,
4395 Type site,
4396 Name name,
4397 List<Type> argtypes,
4398 List<Type> typeargtypes) {
4399 Map<Symbol, JCDiagnostic> candidatesMap = mapCandidates();
4400 Map<Symbol, JCDiagnostic> filteredCandidates = compactMethodDiags ?
4401 filterCandidates(candidatesMap) :
4402 mapCandidates();
4403 if (filteredCandidates.isEmpty()) {
4404 filteredCandidates = candidatesMap;
4405 }
4406 boolean truncatedDiag = candidatesMap.size() != filteredCandidates.size();
4407 if (filteredCandidates.size() > 1) {
4408 JCDiagnostic err = diags.create(dkind,
4409 null,
4410 truncatedDiag ?
4411 EnumSet.of(DiagnosticFlag.COMPRESSED) :
4412 EnumSet.noneOf(DiagnosticFlag.class),
4413 log.currentSource(),
4414 pos,
4415 "cant.apply.symbols",
4416 name == names.init ? KindName.CONSTRUCTOR : kind.absentKind(),
4417 name == names.init ? site.tsym.name : name,
4418 methodArguments(argtypes));
4419 return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(filteredCandidates, site));
4420 } else if (filteredCandidates.size() == 1) {
4421 Map.Entry<Symbol, JCDiagnostic> _e =
4422 filteredCandidates.entrySet().iterator().next();
4423 final Pair<Symbol, JCDiagnostic> p = new Pair<>(_e.getKey(), _e.getValue());
4424 JCDiagnostic d = new InapplicableSymbolError(resolveContext) {
4425 @Override
4426 protected Pair<Symbol, JCDiagnostic> errCandidate() {
4427 return p;
4428 }
4429 }.getDiagnostic(dkind, pos,
4430 location, site, name, argtypes, typeargtypes);
4431 if (truncatedDiag) {
4432 d.setFlag(DiagnosticFlag.COMPRESSED);
4433 }
4434 return d;
4435 } else {
4436 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos,
4437 location, site, name, argtypes, typeargtypes);
4438 }
4439 }
4440 //where
4441 private Map<Symbol, JCDiagnostic> mapCandidates() {
4442 MostSpecificMap candidates = new MostSpecificMap();
4443 for (Candidate c : resolveContext.candidates) {
4444 if (c.isApplicable()) continue;
4445 candidates.put(c);
4446 }
4447 return candidates;
4448 }
4449
4450 @SuppressWarnings("serial")
4451 private class MostSpecificMap extends LinkedHashMap<Symbol, JCDiagnostic> {
4452 private void put(Candidate c) {
4453 ListBuffer<Symbol> overridden = new ListBuffer<>();
4454 for (Symbol s : keySet()) {
4455 if (s == c.sym) {
4456 continue;
4457 }
4458 if (c.sym.overrides(s, (TypeSymbol)s.owner, types, false)) {
4459 overridden.add(s);
4460 } else if (s.overrides(c.sym, (TypeSymbol)c.sym.owner, types, false)) {
4461 return;
4462 }
4463 }
4464 for (Symbol s : overridden) {
4465 remove(s);
4466 }
4467 put(c.sym, c.details);
4468 }
4469 }
4470
4471 Map<Symbol, JCDiagnostic> filterCandidates(Map<Symbol, JCDiagnostic> candidatesMap) {
4472 Map<Symbol, JCDiagnostic> candidates = new LinkedHashMap<>();
4473 for (Map.Entry<Symbol, JCDiagnostic> _entry : candidatesMap.entrySet()) {
4474 JCDiagnostic d = _entry.getValue();
4475 if (!new Template(MethodCheckDiag.ARITY_MISMATCH.regex()).matches(d)) {
4476 candidates.put(_entry.getKey(), d);
4477 }
4478 }
4479 return candidates;
4480 }
4481
4482 private List<JCDiagnostic> candidateDetails(Map<Symbol, JCDiagnostic> candidatesMap, Type site) {
4483 List<JCDiagnostic> details = List.nil();
4484 for (Map.Entry<Symbol, JCDiagnostic> _entry : candidatesMap.entrySet()) {
4485 Symbol sym = _entry.getKey();
4486 JCDiagnostic detailDiag =
4487 diags.fragment(Fragments.InapplicableMethod(Kinds.kindName(sym),
4488 sym.location(site, types),
4489 sym.asMemberOf(site, types),
4490 _entry.getValue()));
4491 details = details.prepend(detailDiag);
4492 }
4493 //typically members are visited in reverse order (see Scope)
4494 //so we need to reverse the candidate list so that candidates
4495 //conform to source order
4496 return details;
4497 }
4498
4499 @Override
4500 protected Pair<Symbol, JCDiagnostic> errCandidate() {
4501 Map<Symbol, JCDiagnostic> candidatesMap = mapCandidates();
4502 Map<Symbol, JCDiagnostic> filteredCandidates = filterCandidates(candidatesMap);
4503 if (filteredCandidates.size() == 1) {
4504 return Pair.of(filteredCandidates.keySet().iterator().next(),
4505 filteredCandidates.values().iterator().next());
4506 }
4507 return null;
4508 }
4509 }
4510
4511 /**
4512 * DiamondError error class indicating that a constructor symbol is not applicable
4513 * given an actual arguments/type argument list using diamond inference.
4514 */
4515 class DiamondError extends InapplicableSymbolError {
4516
4517 Symbol sym;
4518
4519 public DiamondError(Symbol sym, MethodResolutionContext context) {
4520 super(sym.kind, "diamondError", context);
4521 this.sym = sym;
4522 }
4523
4524 JCDiagnostic getDetails() {
4525 return (sym.kind == WRONG_MTH) ?
4526 ((InapplicableSymbolError)sym.baseSymbol()).errCandidate().snd :
4527 null;
4528 }
4529
4530 @Override
4531 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
4532 Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4533 JCDiagnostic details = getDetails();
4534 if (details != null && compactMethodDiags) {
4535 JCDiagnostic simpleDiag =
4536 MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, details);
4537 if (simpleDiag != null) {
4538 return simpleDiag;
4539 }
4540 }
4541 String key = details == null ?
4542 "cant.apply.diamond" :
4543 "cant.apply.diamond.1";
4544 return diags.create(dkind, log.currentSource(), pos, key,
4545 Fragments.Diamond(site.tsym), details);
4546 }
4547 }
4548
4549 /**
4550 * An InvalidSymbolError error class indicating that a symbol is not
4551 * accessible from a given site
4552 */
4553 class AccessError extends InvalidSymbolError {
4554
4555 private Env<AttrContext> env;
4556 private Type site;
4557
4558 AccessError(Env<AttrContext> env, Type site, Symbol sym) {
4559 super(HIDDEN, sym, "access error");
4560 this.env = env;
4561 this.site = site;
4562 }
4563
4564 @Override
4565 public boolean exists() {
4566 return false;
4567 }
4568
4569 @Override
4570 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4571 DiagnosticPosition pos,
4572 Symbol location,
4573 Type site,
4574 Name name,
4575 List<Type> argtypes,
4576 List<Type> typeargtypes) {
4577 if (sym.name == names.init && sym.owner != site.tsym) {
4578 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind,
4579 pos, location, site, name, argtypes, typeargtypes);
4580 }
4581 else if ((sym.flags() & PUBLIC) != 0
4582 || (env != null && this.site != null
4583 && !isAccessible(env, this.site))) {
4584 if (sym.owner.kind == PCK) {
4585 return diags.create(dkind, log.currentSource(),
4586 pos, "not.def.access.package.cant.access",
4587 sym, sym.location(), inaccessiblePackageReason(env, sym.packge()));
4588 } else if ( sym.packge() != syms.rootPackage
4589 && !symbolPackageVisible(env, sym)) {
4590 return diags.create(dkind, log.currentSource(),
4591 pos, "not.def.access.class.intf.cant.access.reason",
4592 sym, sym.location(), sym.location().packge(),
4593 inaccessiblePackageReason(env, sym.packge()));
4594 } else {
4595 return diags.create(dkind, log.currentSource(),
4596 pos, "not.def.access.class.intf.cant.access",
4597 sym, sym.location());
4598 }
4599 }
4600 else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) {
4601 return diags.create(dkind, log.currentSource(),
4602 pos, "report.access", sym,
4603 asFlagSet(sym.flags() & (PRIVATE | PROTECTED)),
4604 sym.location());
4605 }
4606 else {
4607 return diags.create(dkind, log.currentSource(),
4608 pos, "not.def.public.cant.access", sym, sym.location());
4609 }
4610 }
4611
4612 private String toString(Type type) {
4613 StringBuilder sb = new StringBuilder();
4614 sb.append(type);
4615 if (type != null) {
4616 sb.append("[tsym:").append(type.tsym);
4617 if (type.tsym != null)
4618 sb.append("packge:").append(type.tsym.packge());
4619 sb.append("]");
4620 }
4621 return sb.toString();
4622 }
4623 }
4624
4625 class InvisibleSymbolError extends InvalidSymbolError {
4626
4627 private final Env<AttrContext> env;
4628 private final boolean suppressError;
4629
4630 InvisibleSymbolError(Env<AttrContext> env, boolean suppressError, Symbol sym) {
4631 super(HIDDEN, sym, "invisible class error");
4632 this.env = env;
4633 this.suppressError = suppressError;
4634 this.name = sym.name;
4635 }
4636
4637 @Override
4638 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4639 DiagnosticPosition pos,
4640 Symbol location,
4641 Type site,
4642 Name name,
4643 List<Type> argtypes,
4644 List<Type> typeargtypes) {
4645 if (suppressError)
4646 return null;
4647
4648 if (sym.kind == PCK) {
4649 JCDiagnostic details = inaccessiblePackageReason(env, sym.packge());
4650 return diags.create(dkind, log.currentSource(),
4651 pos, "package.not.visible", sym, details);
4652 }
4653
4654 JCDiagnostic details = inaccessiblePackageReason(env, sym.packge());
4655
4656 if (pos.getTree() != null) {
4657 Symbol o = sym;
4658 JCTree tree = pos.getTree();
4659
4660 while (o.kind != PCK && tree.hasTag(SELECT)) {
4661 o = o.owner;
4662 tree = ((JCFieldAccess) tree).selected;
4663 }
4664
4665 if (o.kind == PCK) {
4666 pos = tree.pos();
4667
4668 return diags.create(dkind, log.currentSource(),
4669 pos, "package.not.visible", o, details);
4670 }
4671 }
4672
4673 return diags.create(dkind, log.currentSource(),
4674 pos, "not.def.access.package.cant.access", sym, sym.packge(), details);
4675 }
4676 }
4677
4678 JCDiagnostic inaccessiblePackageReason(Env<AttrContext> env, PackageSymbol sym) {
4679 //no dependency:
4680 if (!env.toplevel.modle.readModules.contains(sym.modle)) {
4681 //does not read:
4682 if (sym.modle != syms.unnamedModule) {
4683 if (env.toplevel.modle != syms.unnamedModule) {
4684 return diags.fragment(Fragments.NotDefAccessDoesNotRead(env.toplevel.modle,
4685 sym,
4686 sym.modle));
4687 } else {
4688 return diags.fragment(Fragments.NotDefAccessDoesNotReadFromUnnamed(sym,
4689 sym.modle));
4690 }
4691 } else {
4692 return diags.fragment(Fragments.NotDefAccessDoesNotReadUnnamed(sym,
4693 env.toplevel.modle));
4694 }
4695 } else {
4696 if (sym.packge().modle.exports.stream().anyMatch(e -> e.packge == sym)) {
4697 //not exported to this module:
4698 if (env.toplevel.modle != syms.unnamedModule) {
4699 return diags.fragment(Fragments.NotDefAccessNotExportedToModule(sym,
4700 sym.modle,
4701 env.toplevel.modle));
4702 } else {
4703 return diags.fragment(Fragments.NotDefAccessNotExportedToModuleFromUnnamed(sym,
4704 sym.modle));
4705 }
4706 } else {
4707 //not exported:
4708 if (env.toplevel.modle != syms.unnamedModule) {
4709 return diags.fragment(Fragments.NotDefAccessNotExported(sym,
4710 sym.modle));
4711 } else {
4712 return diags.fragment(Fragments.NotDefAccessNotExportedFromUnnamed(sym,
4713 sym.modle));
4714 }
4715 }
4716 }
4717 }
4718
4719 /**
4720 * InvalidSymbolError error class indicating that an instance member
4721 * has erroneously been accessed from a static context.
4722 */
4723 class StaticError extends InvalidSymbolError {
4724
4725 StaticError(Symbol sym) {
4726 this(sym, "static error");
4727 }
4728
4729 StaticError(Symbol sym, String debugName) {
4730 super(STATICERR, sym, debugName);
4731 }
4732
4733 @Override
4734 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4735 DiagnosticPosition pos,
4736 Symbol location,
4737 Type site,
4738 Name name,
4739 List<Type> argtypes,
4740 List<Type> typeargtypes) {
4741 Symbol errSym = ((sym.kind == TYP && sym.type.hasTag(CLASS))
4742 ? types.erasure(sym.type).tsym
4743 : sym);
4744 return diags.create(dkind, log.currentSource(), pos,
4745 "non-static.cant.be.ref", kindName(sym), errSym);
4746 }
4747 }
4748
4749 /**
4750 * Specialization of {@link StaticError} for illegal
4751 * creation of local class instances from a static context.
4752 */
4753 class BadLocalClassCreation extends StaticError {
4754 BadLocalClassCreation(Symbol sym) {
4755 super(sym, "bad local class creation");
4756 }
4757
4758 @Override
4759 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4760 DiagnosticPosition pos,
4761 Symbol location,
4762 Type site,
4763 Name name,
4764 List<Type> argtypes,
4765 List<Type> typeargtypes) {
4766 return diags.create(dkind, log.currentSource(), pos,
4767 "local.cant.be.inst.static", kindName(sym), sym);
4768 }
4769 }
4770
4771 /**
4772 * Specialization of {@link InvalidSymbolError} for illegal
4773 * early accesses within a constructor prologue.
4774 */
4775 class RefBeforeCtorCalledError extends StaticError {
4776
4777 RefBeforeCtorCalledError(Symbol sym) {
4778 super(sym, "prologue error");
4779 }
4780
4781 @Override
4782 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4783 DiagnosticPosition pos,
4784 Symbol location,
4785 Type site,
4786 Name name,
4787 List<Type> argtypes,
4788 List<Type> typeargtypes) {
4789 Symbol errSym = ((sym.kind == TYP && sym.type.hasTag(CLASS))
4790 ? types.erasure(sym.type).tsym
4791 : sym);
4792 return diags.create(dkind, log.currentSource(), pos,
4793 "cant.ref.before.ctor.called", errSym);
4794 }
4795 }
4796
4797 /**
4798 * InvalidSymbolError error class indicating that a pair of symbols
4799 * (either methods, constructors or operands) are ambiguous
4800 * given an actual arguments/type argument list.
4801 */
4802 class AmbiguityError extends ResolveError {
4803
4804 /** The other maximally specific symbol */
4805 List<Symbol> ambiguousSyms = List.nil();
4806
4807 @Override
4808 public boolean exists() {
4809 return true;
4810 }
4811
4812 AmbiguityError(Symbol sym1, Symbol sym2) {
4813 super(AMBIGUOUS, "ambiguity error");
4814 ambiguousSyms = flatten(sym2).appendList(flatten(sym1));
4815 }
4816
4817 private List<Symbol> flatten(Symbol sym) {
4818 if (sym.kind == AMBIGUOUS) {
4819 return ((AmbiguityError)sym.baseSymbol()).ambiguousSyms;
4820 } else {
4821 return List.of(sym);
4822 }
4823 }
4824
4825 AmbiguityError addAmbiguousSymbol(Symbol s) {
4826 ambiguousSyms = ambiguousSyms.prepend(s);
4827 return this;
4828 }
4829
4830 @Override
4831 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4832 DiagnosticPosition pos,
4833 Symbol location,
4834 Type site,
4835 Name name,
4836 List<Type> argtypes,
4837 List<Type> typeargtypes) {
4838 List<Symbol> diagSyms = ambiguousSyms.reverse();
4839 Symbol s1 = diagSyms.head;
4840 Symbol s2 = diagSyms.tail.head;
4841 Name sname = s1.name;
4842 if (sname == names.init) sname = s1.owner.name;
4843 return diags.create(dkind, log.currentSource(),
4844 pos, "ref.ambiguous", sname,
4845 kindName(s1),
4846 s1,
4847 s1.location(site, types),
4848 kindName(s2),
4849 s2,
4850 s2.location(site, types));
4851 }
4852
4853 /**
4854 * If multiple applicable methods are found during overload and none of them
4855 * is more specific than the others, attempt to merge their signatures.
4856 */
4857 Symbol mergeAbstracts(Type site) {
4858 List<Symbol> ambiguousInOrder = ambiguousSyms.reverse();
4859 return types.mergeAbstracts(ambiguousInOrder, site, true).orElse(this);
4860 }
4861
4862 @Override
4863 protected Symbol access(Name name, TypeSymbol location) {
4864 Symbol firstAmbiguity = ambiguousSyms.last();
4865 return firstAmbiguity.kind == TYP ?
4866 types.createErrorType(name, location, firstAmbiguity.type).tsym :
4867 firstAmbiguity;
4868 }
4869 }
4870
4871 class BadVarargsMethod extends ResolveError {
4872
4873 ResolveError delegatedError;
4874
4875 BadVarargsMethod(ResolveError delegatedError) {
4876 super(delegatedError.kind, "badVarargs");
4877 this.delegatedError = delegatedError;
4878 }
4879
4880 @Override
4881 public Symbol baseSymbol() {
4882 return delegatedError.baseSymbol();
4883 }
4884
4885 @Override
4886 protected Symbol access(Name name, TypeSymbol location) {
4887 return delegatedError.access(name, location);
4888 }
4889
4890 @Override
4891 public boolean exists() {
4892 return true;
4893 }
4894
4895 @Override
4896 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4897 return delegatedError.getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes);
4898 }
4899 }
4900
4901 /**
4902 * BadMethodReferenceError error class indicating that a method reference symbol has been found,
4903 * but with the wrong staticness.
4904 */
4905 class BadMethodReferenceError extends StaticError {
4906
4907 boolean unboundLookup;
4908
4909 public BadMethodReferenceError(Symbol sym, boolean unboundLookup) {
4910 super(sym, "bad method ref error");
4911 this.unboundLookup = unboundLookup;
4912 }
4913
4914 @Override
4915 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4916 final String key;
4917 if (!unboundLookup) {
4918 key = "bad.static.method.in.bound.lookup";
4919 } else if (sym.isStatic()) {
4920 key = "bad.static.method.in.unbound.lookup";
4921 } else {
4922 key = "bad.instance.method.in.unbound.lookup";
4923 }
4924 return sym.kind.isResolutionError() ?
4925 ((ResolveError)sym).getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes) :
4926 diags.create(dkind, log.currentSource(), pos, key, Kinds.kindName(sym), sym);
4927 }
4928 }
4929
4930 class BadClassFileError extends InvalidSymbolError {
4931
4932 private final CompletionFailure ex;
4933
4934 public BadClassFileError(CompletionFailure ex) {
4935 super(HIDDEN, ex.sym, "BadClassFileError");
4936 this.name = sym.name;
4937 this.ex = ex;
4938 }
4939
4940 @Override
4941 JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4942 JCDiagnostic d = diags.create(dkind, log.currentSource(), pos,
4943 "cant.access", ex.sym, ex.getDetailValue());
4944
4945 d.setFlag(DiagnosticFlag.NON_DEFERRABLE);
4946 return d;
4947 }
4948
4949 }
4950
4951 /**
4952 * Helper class for method resolution diagnostic simplification.
4953 * Certain resolution diagnostic are rewritten as simpler diagnostic
4954 * where the enclosing resolution diagnostic (i.e. 'inapplicable method')
4955 * is stripped away, as it doesn't carry additional info. The logic
4956 * for matching a given diagnostic is given in terms of a template
4957 * hierarchy: a diagnostic template can be specified programmatically,
4958 * so that only certain diagnostics are matched. Each templete is then
4959 * associated with a rewriter object that carries out the task of rewtiting
4960 * the diagnostic to a simpler one.
4961 */
4962 static class MethodResolutionDiagHelper {
4963
4964 /**
4965 * A diagnostic rewriter transforms a method resolution diagnostic
4966 * into a simpler one
4967 */
4968 interface DiagnosticRewriter {
4969 JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags,
4970 DiagnosticPosition preferredPos, DiagnosticSource preferredSource,
4971 DiagnosticType preferredKind, JCDiagnostic d);
4972 }
4973
4974 /**
4975 * A diagnostic template is made up of two ingredients: (i) a regular
4976 * expression for matching a diagnostic key and (ii) a list of sub-templates
4977 * for matching diagnostic arguments.
4978 */
4979 static class Template {
4980
4981 /** regex used to match diag key */
4982 String regex;
4983
4984 /** templates used to match diagnostic args */
4985 Template[] subTemplates;
4986
4987 Template(String key, Template... subTemplates) {
4988 this.regex = key;
4989 this.subTemplates = subTemplates;
4990 }
4991
4992 /**
4993 * Returns true if the regex matches the diagnostic key and if
4994 * all diagnostic arguments are matches by corresponding sub-templates.
4995 */
4996 boolean matches(Object o) {
4997 JCDiagnostic d = (JCDiagnostic)o;
4998 Object[] args = d.getArgs();
4999 if (!d.getCode().matches(regex) ||
5000 subTemplates.length != d.getArgs().length) {
5001 return false;
5002 }
5003 for (int i = 0; i < args.length ; i++) {
5004 if (!subTemplates[i].matches(args[i])) {
5005 return false;
5006 }
5007 }
5008 return true;
5009 }
5010 }
5011
5012 /**
5013 * Common rewriter for all argument mismatch simplifications.
5014 */
5015 static class ArgMismatchRewriter implements DiagnosticRewriter {
5016
5017 /** the index of the subdiagnostic to be used as primary. */
5018 int causeIndex;
5019
5020 public ArgMismatchRewriter(int causeIndex) {
5021 this.causeIndex = causeIndex;
5022 }
5023
5024 @Override
5025 public JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags,
5026 DiagnosticPosition preferredPos, DiagnosticSource preferredSource,
5027 DiagnosticType preferredKind, JCDiagnostic d) {
5028 JCDiagnostic cause = (JCDiagnostic)d.getArgs()[causeIndex];
5029 DiagnosticPosition pos = d.getDiagnosticPosition();
5030 if (pos == null) {
5031 pos = preferredPos;
5032 }
5033 return diags.create(preferredKind, preferredSource, pos,
5034 "prob.found.req", cause);
5035 }
5036 }
5037
5038 /** a dummy template that match any diagnostic argument */
5039 static final Template skip = new Template("") {
5040 @Override
5041 boolean matches(Object d) {
5042 return true;
5043 }
5044 };
5045
5046 /** template for matching inference-free arguments mismatch failures */
5047 static final Template argMismatchTemplate = new Template(MethodCheckDiag.ARG_MISMATCH.regex(), skip);
5048
5049 /** template for matching inference related arguments mismatch failures */
5050 static final Template inferArgMismatchTemplate = new Template(MethodCheckDiag.ARG_MISMATCH.regex(), skip, skip) {
5051 @Override
5052 boolean matches(Object o) {
5053 if (!super.matches(o)) {
5054 return false;
5055 }
5056 JCDiagnostic d = (JCDiagnostic)o;
5057 @SuppressWarnings("unchecked")
5058 List<Type> tvars = (List<Type>)d.getArgs()[0];
5059 return !containsAny(d, tvars);
5060 }
5061
5062 BiPredicate<Object, List<Type>> containsPredicate = (o, ts) -> {
5063 if (o instanceof Type type) {
5064 return type.containsAny(ts);
5065 } else if (o instanceof JCDiagnostic diagnostic) {
5066 return containsAny(diagnostic, ts);
5067 } else {
5068 return false;
5069 }
5070 };
5071
5072 boolean containsAny(JCDiagnostic d, List<Type> ts) {
5073 return Stream.of(d.getArgs())
5074 .anyMatch(o -> containsPredicate.test(o, ts));
5075 }
5076 };
5077
5078 /** rewriter map used for method resolution simplification */
5079 static final Map<Template, DiagnosticRewriter> rewriters = new LinkedHashMap<>();
5080
5081 static {
5082 rewriters.put(argMismatchTemplate, new ArgMismatchRewriter(0));
5083 rewriters.put(inferArgMismatchTemplate, new ArgMismatchRewriter(1));
5084 }
5085
5086 /**
5087 * Main entry point for diagnostic rewriting - given a diagnostic, see if any templates matches it,
5088 * and rewrite it accordingly.
5089 */
5090 static JCDiagnostic rewrite(JCDiagnostic.Factory diags, DiagnosticPosition pos, DiagnosticSource source,
5091 DiagnosticType dkind, JCDiagnostic d) {
5092 for (Map.Entry<Template, DiagnosticRewriter> _entry : rewriters.entrySet()) {
5093 if (_entry.getKey().matches(d)) {
5094 JCDiagnostic simpleDiag =
5095 _entry.getValue().rewriteDiagnostic(diags, pos, source, dkind, d);
5096 simpleDiag.setFlag(DiagnosticFlag.COMPRESSED);
5097 return simpleDiag;
5098 }
5099 }
5100 return null;
5101 }
5102 }
5103
5104 enum MethodResolutionPhase {
5105 BASIC(false, false),
5106 BOX(true, false),
5107 VARARITY(true, true) {
5108 @Override
5109 public Symbol mergeResults(Symbol bestSoFar, Symbol sym) {
5110 //Check invariants (see {@code LookupHelper.shouldStop})
5111 Assert.check(bestSoFar.kind.isResolutionError() && bestSoFar.kind != AMBIGUOUS);
5112 if (!sym.kind.isResolutionError()) {
5113 //varargs resolution successful
5114 return sym;
5115 } else {
5116 //pick best error
5117 switch (bestSoFar.kind) {
5118 case WRONG_MTH:
5119 case WRONG_MTHS:
5120 //Override previous errors if they were caused by argument mismatch.
5121 //This generally means preferring current symbols - but we need to pay
5122 //attention to the fact that the varargs lookup returns 'less' candidates
5123 //than the previous rounds, and adjust that accordingly.
5124 switch (sym.kind) {
5125 case WRONG_MTH:
5126 //if the previous round matched more than one method, return that
5127 //result instead
5128 return bestSoFar.kind == WRONG_MTHS ?
5129 bestSoFar : sym;
5130 case ABSENT_MTH:
5131 //do not override erroneous symbol if the arity lookup did not
5132 //match any method
5133 return bestSoFar;
5134 case WRONG_MTHS:
5135 default:
5136 //safe to override
5137 return sym;
5138 }
5139 default:
5140 //otherwise, return first error
5141 return bestSoFar;
5142 }
5143 }
5144 }
5145 };
5146
5147 final boolean isBoxingRequired;
5148 final boolean isVarargsRequired;
5149
5150 MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) {
5151 this.isBoxingRequired = isBoxingRequired;
5152 this.isVarargsRequired = isVarargsRequired;
5153 }
5154
5155 public boolean isBoxingRequired() {
5156 return isBoxingRequired;
5157 }
5158
5159 public boolean isVarargsRequired() {
5160 return isVarargsRequired;
5161 }
5162
5163 public Symbol mergeResults(Symbol prev, Symbol sym) {
5164 return sym;
5165 }
5166 }
5167
5168 final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
5169
5170 /**
5171 * A resolution context is used to keep track of intermediate results of
5172 * overload resolution, such as list of method that are not applicable
5173 * (used to generate more precise diagnostics) and so on. Resolution contexts
5174 * can be nested - this means that when each overload resolution routine should
5175 * work within the resolution context it created.
5176 */
5177 class MethodResolutionContext {
5178
5179 private List<Candidate> candidates = List.nil();
5180
5181 MethodResolutionPhase step = null;
5182
5183 MethodCheck methodCheck = resolveMethodCheck;
5184
5185 private boolean internalResolution = false;
5186 private DeferredAttr.AttrMode attrMode = DeferredAttr.AttrMode.SPECULATIVE;
5187
5188 void addInapplicableCandidate(Symbol sym, JCDiagnostic details) {
5189 Candidate c = new Candidate(currentResolutionContext.step, sym, details, null);
5190 candidates = candidates.append(c);
5191 }
5192
5193 void addApplicableCandidate(Symbol sym, Type mtype) {
5194 Candidate c = new Candidate(currentResolutionContext.step, sym, null, mtype);
5195 candidates = candidates.append(c);
5196 }
5197
5198 DeferredAttrContext deferredAttrContext(Symbol sym, InferenceContext inferenceContext, ResultInfo pendingResult, Warner warn) {
5199 DeferredAttrContext parent = (pendingResult == null)
5200 ? deferredAttr.emptyDeferredAttrContext
5201 : pendingResult.checkContext.deferredAttrContext();
5202 return deferredAttr.new DeferredAttrContext(attrMode, sym, step,
5203 inferenceContext, parent, warn);
5204 }
5205
5206 /**
5207 * This class represents an overload resolution candidate. There are two
5208 * kinds of candidates: applicable methods and inapplicable methods;
5209 * applicable methods have a pointer to the instantiated method type,
5210 * while inapplicable candidates contain further details about the
5211 * reason why the method has been considered inapplicable.
5212 */
5213 class Candidate {
5214
5215 final MethodResolutionPhase step;
5216 final Symbol sym;
5217 final JCDiagnostic details;
5218 final Type mtype;
5219
5220 private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) {
5221 this.step = step;
5222 this.sym = sym;
5223 this.details = details;
5224 this.mtype = mtype;
5225 }
5226
5227 boolean isApplicable() {
5228 return mtype != null;
5229 }
5230 }
5231
5232 DeferredAttr.AttrMode attrMode() {
5233 return attrMode;
5234 }
5235
5236 boolean internal() {
5237 return internalResolution;
5238 }
5239 }
5240
5241 MethodResolutionContext currentResolutionContext = null;
5242 }