89 * This code and its internal interfaces are subject to change or
90 * deletion without notice.</b>
91 */
92 public class Resolve {
93 protected static final Context.Key<Resolve> resolveKey = new Context.Key<>();
94
95 Names names;
96 Log log;
97 Symtab syms;
98 Attr attr;
99 AttrRecover attrRecover;
100 DeferredAttr deferredAttr;
101 Check chk;
102 Infer infer;
103 ClassFinder finder;
104 ModuleFinder moduleFinder;
105 Types types;
106 JCDiagnostic.Factory diags;
107 public final boolean allowModules;
108 public final boolean allowRecords;
109 private final boolean compactMethodDiags;
110 private final boolean allowLocalVariableTypeInference;
111 private final boolean allowYieldStatement;
112 final EnumSet<VerboseResolutionMode> verboseResolutionMode;
113 final boolean dumpMethodReferenceSearchResults;
114
115 WriteableScope polymorphicSignatureScope;
116
117 @SuppressWarnings("this-escape")
118 protected Resolve(Context context) {
119 context.put(resolveKey, this);
120 syms = Symtab.instance(context);
121
122 varNotFound = new SymbolNotFoundError(ABSENT_VAR);
123 methodNotFound = new SymbolNotFoundError(ABSENT_MTH);
124 typeNotFound = new SymbolNotFoundError(ABSENT_TYP);
125 referenceNotFound = ReferenceLookupResult.error(methodNotFound);
126
127 names = Names.instance(context);
128 log = Log.instance(context);
129 attr = Attr.instance(context);
130 attrRecover = AttrRecover.instance(context);
131 deferredAttr = DeferredAttr.instance(context);
132 chk = Check.instance(context);
133 infer = Infer.instance(context);
134 finder = ClassFinder.instance(context);
135 moduleFinder = ModuleFinder.instance(context);
136 types = Types.instance(context);
137 diags = JCDiagnostic.Factory.instance(context);
138 Preview preview = Preview.instance(context);
139 Source source = Source.instance(context);
140 Options options = Options.instance(context);
141 compactMethodDiags = options.isSet(Option.XDIAGS, "compact") ||
142 options.isUnset(Option.XDIAGS) && options.isUnset("rawDiagnostics");
143 verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
144 Target target = Target.instance(context);
145 allowLocalVariableTypeInference = Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source);
146 allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source);
147 polymorphicSignatureScope = WriteableScope.create(syms.noSymbol);
148 allowModules = Feature.MODULES.allowedInSource(source);
149 allowRecords = Feature.RECORDS.allowedInSource(source);
150 dumpMethodReferenceSearchResults = options.isSet("debug.dumpMethodReferenceSearchResults");
151 }
152
153 /** error symbols, which are returned when resolution fails
154 */
155 private final SymbolNotFoundError varNotFound;
156 private final SymbolNotFoundError methodNotFound;
157 private final SymbolNotFoundError typeNotFound;
158
159 /** empty reference lookup result */
160 private final ReferenceLookupResult referenceNotFound;
161
162 public static Resolve instance(Context context) {
163 Resolve instance = context.get(resolveKey);
164 if (instance == null)
165 instance = new Resolve(context);
166 return instance;
167 }
168
169 private static Symbol bestOf(Symbol s1,
170 Symbol s2) {
200 if (args.contains(mode.opt)) {
201 res.add(mode);
202 } else if (args.contains("-" + mode.opt)) {
203 res.remove(mode);
204 }
205 }
206 return res;
207 }
208 }
209
210 void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site,
211 List<Type> argtypes, List<Type> typeargtypes, Symbol bestSoFar) {
212 boolean success = !bestSoFar.kind.isResolutionError();
213
214 if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) {
215 return;
216 } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) {
217 return;
218 }
219
220 if (bestSoFar.name == names.init &&
221 bestSoFar.owner == syms.objectType.tsym &&
222 !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) {
223 return; //skip diags for Object constructor resolution
224 } else if (site == syms.predefClass.type &&
225 !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) {
226 return; //skip spurious diags for predef symbols (i.e. operators)
227 } else if (currentResolutionContext.internalResolution &&
228 !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) {
229 return;
230 }
231
232 int pos = 0;
233 int mostSpecificPos = -1;
234 ListBuffer<JCDiagnostic> subDiags = new ListBuffer<>();
235 for (Candidate c : currentResolutionContext.candidates) {
236 if (currentResolutionContext.step != c.step ||
237 (c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE)) ||
238 (!c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))) {
239 continue;
240 } else {
273 return diags.fragment(Fragments.NotApplicableMethodFound(pos, sym, subDiag));
274 }
275 // </editor-fold>
276
277 /* ************************************************************************
278 * Identifier resolution
279 *************************************************************************/
280
281 /** An environment is "static" if its static level is greater than
282 * the one of its outer environment
283 */
284 protected static boolean isStatic(Env<AttrContext> env) {
285 return env.outer != null && env.info.staticLevel > env.outer.info.staticLevel;
286 }
287
288 /** An environment is an "initializer" if it is a constructor or
289 * an instance initializer.
290 */
291 static boolean isInitializer(Env<AttrContext> env) {
292 Symbol owner = env.info.scope.owner;
293 return owner.isConstructor() ||
294 owner.owner.kind == TYP &&
295 (owner.kind == VAR ||
296 owner.kind == MTH && (owner.flags() & BLOCK) != 0) &&
297 (owner.flags() & STATIC) == 0;
298 }
299
300 /** Is class accessible in given environment?
301 * @param env The current environment.
302 * @param c The class whose accessibility is checked.
303 */
304 public boolean isAccessible(Env<AttrContext> env, TypeSymbol c) {
305 return isAccessible(env, c, false);
306 }
307
308 public boolean isAccessible(Env<AttrContext> env, TypeSymbol c, boolean checkInner) {
309
310 /* 15.9.5.1: Note that it is possible for the signature of the anonymous constructor
311 to refer to an inaccessible type
312 */
313 if (env.enclMethod != null && (env.enclMethod.mods.flags & ANONCONSTR) != 0)
385 if (t.hasTag(ARRAY)) {
386 return isAccessible(env, types.cvarUpperBound(types.elemtype(t)));
387 } else if (t.isUnion()) {
388 return StreamSupport.stream(((UnionClassType) t).getAlternativeTypes().spliterator(), false)
389 .allMatch(alternative -> isAccessible(env, alternative.tsym, checkInner));
390 } else {
391 return isAccessible(env, t.tsym, checkInner);
392 }
393 }
394
395 /** Is symbol accessible as a member of given type in given environment?
396 * @param env The current environment.
397 * @param site The type of which the tested symbol is regarded
398 * as a member.
399 * @param sym The symbol.
400 */
401 public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym) {
402 return isAccessible(env, site, sym, false);
403 }
404 public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym, boolean checkInner) {
405 if (sym.name == names.init && sym.owner != site.tsym) return false;
406
407 /* 15.9.5.1: Note that it is possible for the signature of the anonymous constructor
408 to refer to an inaccessible type
409 */
410 if (env.enclMethod != null && (env.enclMethod.mods.flags & ANONCONSTR) != 0)
411 return true;
412
413 if (env.info.visitingServiceImplementation &&
414 env.toplevel.modle == sym.packge().modle) {
415 return true;
416 }
417
418 switch ((short)(sym.flags() & AccessFlags)) {
419 case PRIVATE:
420 return
421 (env.enclClass.sym == sym.owner // fast special case
422 ||
423 env.enclClass.sym.outermostClass() ==
424 sym.owner.outermostClass())
425 &&
426 sym.isInheritedIn(site.tsym, types);
427 case 0:
428 return
429 (env.toplevel.packge == sym.owner.owner // fast special case
430 ||
431 env.toplevel.packge == sym.packge())
432 &&
433 isAccessible(env, site, checkInner)
434 &&
435 sym.isInheritedIn(site.tsym, types)
436 &&
437 notOverriddenIn(site, sym);
438 case PROTECTED:
439 return
440 (env.toplevel.packge == sym.owner.owner // fast special case
441 ||
442 env.toplevel.packge == sym.packge()
443 ||
444 isProtectedAccessible(sym, env.enclClass.sym, site)
445 ||
446 // OK to select instance method or field from 'super' or type name
447 // (but type names should be disallowed elsewhere!)
448 env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP)
449 &&
450 isAccessible(env, site, checkInner)
451 &&
452 notOverriddenIn(site, sym);
453 default: // this case includes erroneous combinations as well
454 return isAccessible(env, site, checkInner) && notOverriddenIn(site, sym);
455 }
456 }
457 //where
458 /* `sym' is accessible only if not overridden by
459 * another symbol which is a member of `site'
460 * (because, if it is overridden, `sym' is not strictly
461 * speaking a member of `site'). A polymorphic signature method
462 * cannot be overridden (e.g. MH.invokeExact(Object[])).
463 */
464 private boolean notOverriddenIn(Type site, Symbol sym) {
465 if (sym.kind != MTH || sym.isConstructor() || sym.isStatic())
466 return true;
467 else {
468 Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true);
469 return (s2 == null || s2 == sym || sym.owner == s2.owner || (sym.owner.isInterface() && s2.owner == syms.objectType.tsym) ||
470 !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym)));
471 }
472 }
473 //where
474 /** Is given protected symbol accessible if it is selected from given site
475 * and the selection takes place in given class?
476 * @param sym The symbol with protected access
477 * @param c The class where the access takes place
478 * @param site The type of the qualifier
479 */
480 private
481 boolean isProtectedAccessible(Symbol sym, ClassSymbol c, Type site) {
482 Type newSite = site.hasTag(TYPEVAR) ? site.getUpperBound() : site;
483 while (c != null &&
484 !(c.isSubClass(sym.owner, types) &&
485 (c.flags() & INTERFACE) == 0 &&
486 // In JLS 2e 6.6.2.1, the subclass restriction applies
487 // only to instance fields and methods -- types are excluded
488 // regardless of whether they are declared 'static' or not.
489 ((sym.flags() & STATIC) != 0 || sym.kind == TYP || newSite.tsym.isSubClass(c, types))))
490 c = c.owner.enclClass();
491 return c != null;
1671
1672 // same signature; select (a) the non-bridge method, or
1673 // (b) the one that overrides the other, or (c) the concrete
1674 // one, or (d) merge both abstract signatures
1675 if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE))
1676 return ((m1.flags() & BRIDGE) != 0) ? m2 : m1;
1677
1678 if (m1.baseSymbol() == m2.baseSymbol()) {
1679 // this is the same imported symbol which has been cloned twice.
1680 // Return the first one (either will do).
1681 return m1;
1682 }
1683
1684 // if one overrides or hides the other, use it
1685 TypeSymbol m1Owner = (TypeSymbol)m1.owner;
1686 TypeSymbol m2Owner = (TypeSymbol)m2.owner;
1687 // the two owners can never be the same if the target methods are compiled from source,
1688 // but we need to protect against cases where the methods are defined in some classfile
1689 // and make sure we issue an ambiguity error accordingly (by skipping the logic below).
1690 if (m1Owner != m2Owner) {
1691 if (types.asSuper(m1Owner.type, m2Owner) != null &&
1692 ((m1.owner.flags_field & INTERFACE) == 0 ||
1693 (m2.owner.flags_field & INTERFACE) != 0) &&
1694 m1.overrides(m2, m1Owner, types, false))
1695 return m1;
1696 if (types.asSuper(m2Owner.type, m1Owner) != null &&
1697 ((m2.owner.flags_field & INTERFACE) == 0 ||
1698 (m1.owner.flags_field & INTERFACE) != 0) &&
1699 m2.overrides(m1, m2Owner, types, false))
1700 return m2;
1701 }
1702 boolean m1Abstract = (m1.flags() & ABSTRACT) != 0;
1703 boolean m2Abstract = (m2.flags() & ABSTRACT) != 0;
1704 if (m1Abstract && !m2Abstract) return m2;
1705 if (m2Abstract && !m1Abstract) return m1;
1706 // both abstract or both concrete
1707 return ambiguityError(m1, m2);
1708 }
1709 if (m1SignatureMoreSpecific) return m1;
1710 if (m2SignatureMoreSpecific) return m2;
1711 return ambiguityError(m1, m2);
1712 case AMBIGUOUS:
1713 //compare m1 to ambiguous methods in m2
1714 AmbiguityError e = (AmbiguityError)m2.baseSymbol();
1715 boolean m1MoreSpecificThanAnyAmbiguous = true;
1716 boolean allAmbiguousMoreSpecificThanM1 = true;
1843 return bestSoFar;
1844 }
1845 // where
1846 private Symbol findMethod(Env<AttrContext> env,
1847 Type site,
1848 Name name,
1849 List<Type> argtypes,
1850 List<Type> typeargtypes,
1851 Type intype,
1852 Symbol bestSoFar,
1853 boolean allowBoxing,
1854 boolean useVarargs) {
1855 @SuppressWarnings({"unchecked","rawtypes"})
1856 List<Type>[] itypes = (List<Type>[])new List[] { List.<Type>nil(), List.<Type>nil() };
1857
1858 InterfaceLookupPhase iphase = InterfaceLookupPhase.ABSTRACT_OK;
1859 boolean isInterface = site.tsym.isInterface();
1860 for (TypeSymbol s : isInterface ? List.of(intype.tsym) : superclasses(intype)) {
1861 bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
1862 s.members(), bestSoFar, allowBoxing, useVarargs, true);
1863 if (name == names.init) return bestSoFar;
1864 iphase = (iphase == null) ? null : iphase.update(s, this);
1865 if (iphase != null) {
1866 for (Type itype : types.interfaces(s.type)) {
1867 itypes[iphase.ordinal()] = types.union(types.closure(itype), itypes[iphase.ordinal()]);
1868 }
1869 }
1870 }
1871
1872 Symbol concrete = bestSoFar.kind.isValid() &&
1873 (bestSoFar.flags() & ABSTRACT) == 0 ?
1874 bestSoFar : methodNotFound;
1875
1876 for (InterfaceLookupPhase iphase2 : InterfaceLookupPhase.values()) {
1877 //keep searching for abstract methods
1878 for (Type itype : itypes[iphase2.ordinal()]) {
1879 if (!itype.isInterface()) continue; //skip j.l.Object (included by Types.closure())
1880 if (iphase2 == InterfaceLookupPhase.DEFAULT_OK &&
1881 (itype.tsym.flags() & DEFAULT) == 0) continue;
1882 bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
1883 itype.tsym.members(), bestSoFar, allowBoxing, useVarargs, true);
2278 bestSoFar = new AmbiguityError(bestSoFar, sym);
2279 else
2280 bestSoFar = bestOf(bestSoFar, sym);
2281 }
2282 return bestSoFar;
2283 }
2284
2285 /** Find qualified member type.
2286 * @param env The current environment.
2287 * @param site The original type from where the selection takes
2288 * place.
2289 * @param name The type's name.
2290 * @param c The class to search for the member type. This is
2291 * always a superclass or implemented interface of
2292 * site's class.
2293 */
2294 Symbol findMemberType(Env<AttrContext> env,
2295 Type site,
2296 Name name,
2297 TypeSymbol c) {
2298 Symbol sym = findImmediateMemberType(env, site, name, c);
2299
2300 if (sym != typeNotFound)
2301 return sym;
2302
2303 return findInheritedMemberType(env, site, name, c);
2304
2305 }
2306
2307 /** Find a global type in given scope and load corresponding class.
2308 * @param env The current environment.
2309 * @param scope The scope in which to look for the type.
2310 * @param name The type's name.
2311 */
2312 Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name, RecoveryLoadClass recoveryLoadClass) {
2313 Symbol bestSoFar = typeNotFound;
2314 for (Symbol s : scope.getSymbolsByName(name)) {
2315 Symbol sym = loadClass(env, s.flatName(), recoveryLoadClass);
2316 if (bestSoFar.kind == TYP && sym.kind == TYP &&
2317 bestSoFar != sym)
2326 for (Symbol sym : env.info.scope.getSymbolsByName(name)) {
2327 if (sym.kind == TYP) {
2328 if (sym.type.hasTag(TYPEVAR) &&
2329 (staticOnly || (isStatic(env) && sym.owner.kind == TYP)))
2330 // if staticOnly is set, it means that we have recursed through a static declaration,
2331 // so type variable symbols should not be accessible. If staticOnly is unset, but
2332 // we are in a static declaration (field or method), we should not allow type-variables
2333 // defined in the enclosing class to "leak" into this context.
2334 return new StaticError(sym);
2335 return sym;
2336 }
2337 }
2338 return typeNotFound;
2339 }
2340
2341 /** Find an unqualified type symbol.
2342 * @param env The current environment.
2343 * @param name The type's name.
2344 */
2345 Symbol findType(Env<AttrContext> env, Name name) {
2346 if (name == names.empty)
2347 return typeNotFound; // do not allow inadvertent "lookup" of anonymous types
2348 Symbol bestSoFar = typeNotFound;
2349 Symbol sym;
2350 boolean staticOnly = false;
2351 for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) {
2352 // First, look for a type variable and the first member type
2353 final Symbol tyvar = findTypeVar(env1, name, staticOnly);
2354 if (isStatic(env1)) staticOnly = true;
2355 sym = findImmediateMemberType(env1, env1.enclClass.sym.type,
2356 name, env1.enclClass.sym);
2357
2358 // Return the type variable if we have it, and have no
2359 // immediate member, OR the type variable is for a method.
2360 if (tyvar != typeNotFound) {
2361 if (env.baseClause || sym == typeNotFound ||
2362 (tyvar.kind == TYP && tyvar.exists() &&
2363 tyvar.owner.kind == MTH)) {
2364 return tyvar;
2365 }
2863 * @param site The type of class for which a constructor is searched.
2864 * @param argtypes The types of the constructor invocation's value
2865 * arguments.
2866 * @param typeargtypes The types of the constructor invocation's type
2867 * arguments.
2868 */
2869 Symbol resolveConstructor(DiagnosticPosition pos,
2870 Env<AttrContext> env,
2871 Type site,
2872 List<Type> argtypes,
2873 List<Type> typeargtypes) {
2874 return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes);
2875 }
2876
2877 private Symbol resolveConstructor(MethodResolutionContext resolveContext,
2878 final DiagnosticPosition pos,
2879 Env<AttrContext> env,
2880 Type site,
2881 List<Type> argtypes,
2882 List<Type> typeargtypes) {
2883 return lookupMethod(env, pos, site.tsym, resolveContext, new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
2884 @Override
2885 Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2886 return findConstructor(pos, env, site, argtypes, typeargtypes,
2887 phase.isBoxingRequired(),
2888 phase.isVarargsRequired());
2889 }
2890 });
2891 }
2892
2893 /** Resolve a constructor, throw a fatal error if not found.
2894 * @param pos The position to use for error reporting.
2895 * @param env The environment current at the method invocation.
2896 * @param site The type to be constructed.
2897 * @param argtypes The types of the invocation's value arguments.
2898 * @param typeargtypes The types of the invocation's type arguments.
2899 */
2900 public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2901 Type site,
2902 List<Type> argtypes,
2903 List<Type> typeargtypes) {
2904 MethodResolutionContext resolveContext = new MethodResolutionContext();
2905 resolveContext.internalResolution = true;
2906 Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes);
2907 if (sym.kind == MTH) return (MethodSymbol)sym;
2908 else throw new FatalError(
2909 diags.fragment(Fragments.FatalErrCantLocateCtor(site)));
2910 }
2911
2912 Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2913 Type site, List<Type> argtypes,
2914 List<Type> typeargtypes,
2915 boolean allowBoxing,
2916 boolean useVarargs) {
2917 Symbol sym = findMethod(env, site,
2918 names.init, argtypes,
2919 typeargtypes, allowBoxing,
2920 useVarargs);
2921 chk.checkDeprecated(pos, env.info.scope.owner, sym);
2922 chk.checkPreview(pos, env.info.scope.owner, sym);
2923 return sym;
2924 }
2925
2926 /** Resolve constructor using diamond inference.
2927 * @param pos The position to use for error reporting.
2928 * @param env The environment current at the constructor invocation.
2929 * @param site The type of class for which a constructor is searched.
2930 * The scope of this class has been touched in attribution.
2931 * @param argtypes The types of the constructor invocation's value
2932 * arguments.
2933 * @param typeargtypes The types of the constructor invocation's type
2934 * arguments.
2935 */
2936 Symbol resolveDiamond(DiagnosticPosition pos,
2937 Env<AttrContext> env,
2938 Type site,
2939 List<Type> argtypes,
2940 List<Type> typeargtypes) {
2941 return lookupMethod(env, pos, site.tsym, resolveMethodCheck,
2942 new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
2943 @Override
2944 Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2945 return findDiamond(pos, env, site, argtypes, typeargtypes,
2946 phase.isBoxingRequired(),
2947 phase.isVarargsRequired());
2948 }
2949 @Override
2950 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2951 if (sym.kind.isResolutionError()) {
2952 if (sym.kind != WRONG_MTH &&
2953 sym.kind != WRONG_MTHS) {
2954 sym = super.access(env, pos, location, sym);
2955 } else {
2956 sym = new DiamondError(sym, currentResolutionContext);
2957 sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes);
2958 env.info.pendingResolutionPhase = currentResolutionContext.step;
2959 }
2960 }
2961 return sym;
2962 }});
2963 }
2964
2965 /** Find the constructor using diamond inference and do some checks(deprecated and preview).
2966 * @param pos The position to use for error reporting.
2967 * @param env The environment current at the constructor invocation.
2968 * @param site The type of class for which a constructor is searched.
2969 * The scope of this class has been touched in attribution.
2970 * @param argtypes The types of the constructor invocation's value arguments.
2971 * @param typeargtypes The types of the constructor invocation's type arguments.
2972 * @param allowBoxing Allow boxing conversions of arguments.
2973 * @param useVarargs Box trailing arguments into an array for varargs.
2974 */
2975 private Symbol findDiamond(DiagnosticPosition pos,
2976 Env<AttrContext> env,
2977 Type site,
2984 chk.checkPreview(pos, env.info.scope.owner, sym);
2985 return sym;
2986 }
2987
2988 /** This method scans all the constructor symbol in a given class scope -
2989 * assuming that the original scope contains a constructor of the kind:
2990 * {@code Foo(X x, Y y)}, where X,Y are class type-variables declared in Foo,
2991 * a method check is executed against the modified constructor type:
2992 * {@code <X,Y>Foo<X,Y>(X x, Y y)}. This is crucial in order to enable diamond
2993 * inference. The inferred return type of the synthetic constructor IS
2994 * the inferred type for the diamond operator.
2995 */
2996 private Symbol findDiamond(Env<AttrContext> env,
2997 Type site,
2998 List<Type> argtypes,
2999 List<Type> typeargtypes,
3000 boolean allowBoxing,
3001 boolean useVarargs) {
3002 Symbol bestSoFar = methodNotFound;
3003 TypeSymbol tsym = site.tsym.isInterface() ? syms.objectType.tsym : site.tsym;
3004 for (final Symbol sym : tsym.members().getSymbolsByName(names.init)) {
3005 //- System.out.println(" e " + e.sym);
3006 if (sym.kind == MTH &&
3007 (sym.flags_field & SYNTHETIC) == 0) {
3008 List<Type> oldParams = sym.type.hasTag(FORALL) ?
3009 ((ForAll)sym.type).tvars :
3010 List.nil();
3011 Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams),
3012 types.createMethodTypeWithReturn(sym.type.asMethodType(), site));
3013 MethodSymbol newConstr = new MethodSymbol(sym.flags(), names.init, constrType, site.tsym) {
3014 @Override
3015 public Symbol baseSymbol() {
3016 return sym;
3017 }
3018 };
3019 bestSoFar = selectBest(env, site, argtypes, typeargtypes,
3020 newConstr,
3021 bestSoFar,
3022 allowBoxing,
3023 useVarargs);
3024 }
3025 }
3026 return bestSoFar;
3027 }
3028
3029 Symbol getMemberReference(DiagnosticPosition pos,
3030 Env<AttrContext> env,
3031 JCMemberReference referenceTree,
3032 Type site,
3033 Name name) {
3035 site = types.capture(site);
3036
3037 ReferenceLookupHelper lookupHelper = makeReferenceLookupHelper(
3038 referenceTree, site, name, List.nil(), null, VARARITY);
3039
3040 Env<AttrContext> newEnv = env.dup(env.tree, env.info.dup());
3041 Symbol sym = lookupMethod(newEnv, env.tree.pos(), site.tsym,
3042 nilMethodCheck, lookupHelper);
3043
3044 env.info.pendingResolutionPhase = newEnv.info.pendingResolutionPhase;
3045
3046 return sym;
3047 }
3048
3049 ReferenceLookupHelper makeReferenceLookupHelper(JCMemberReference referenceTree,
3050 Type site,
3051 Name name,
3052 List<Type> argtypes,
3053 List<Type> typeargtypes,
3054 MethodResolutionPhase maxPhase) {
3055 if (!name.equals(names.init)) {
3056 //method reference
3057 return new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
3058 } else if (site.hasTag(ARRAY)) {
3059 //array constructor reference
3060 return new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
3061 } else {
3062 //class constructor reference
3063 return new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
3064 }
3065 }
3066
3067 /**
3068 * Resolution of member references is typically done as a single
3069 * overload resolution step, where the argument types A are inferred from
3070 * the target functional descriptor.
3071 *
3072 * If the member reference is a method reference with a type qualifier,
3073 * a two-step lookup process is performed. The first step uses the
3074 * expected argument list A, while the second step discards the first
3075 * type from A (which is treated as a receiver type).
3550 /** The original method reference lookup site. */
3551 Type originalSite;
3552
3553 MethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3554 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3555 super(referenceTree, name, types.skipTypeVars(site, true), argtypes, typeargtypes, maxPhase);
3556 this.originalSite = site;
3557 }
3558
3559 @Override
3560 final Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3561 return findMethod(env, site, name, argtypes, typeargtypes,
3562 phase.isBoxingRequired(), phase.isVarargsRequired());
3563 }
3564
3565 @Override
3566 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3567 if (TreeInfo.isStaticSelector(referenceTree.expr, names)) {
3568 if (argtypes.nonEmpty() &&
3569 (argtypes.head.hasTag(NONE) ||
3570 types.isSubtypeUnchecked(inferenceContext.asUndetVar(argtypes.head), originalSite))) {
3571 return new UnboundMethodReferenceLookupHelper(referenceTree, name,
3572 originalSite, argtypes, typeargtypes, maxPhase);
3573 } else {
3574 return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) {
3575 @Override
3576 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3577 return this;
3578 }
3579
3580 @Override
3581 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3582 return methodNotFound;
3583 }
3584
3585 @Override
3586 ReferenceKind referenceKind(Symbol sym) {
3587 Assert.error();
3588 return null;
3589 }
3590 };
3603 return selName != null && selName == names._super ?
3604 ReferenceKind.SUPER :
3605 ReferenceKind.BOUND;
3606 }
3607 }
3608 }
3609
3610 /**
3611 * Helper class for unbound method reference lookup. Essentially the same
3612 * as the basic method reference lookup helper; main difference is that static
3613 * lookup results are thrown away. If qualifier type is raw, an attempt to
3614 * infer a parameterized type is made using the first actual argument (that
3615 * would otherwise be ignored during the lookup).
3616 */
3617 class UnboundMethodReferenceLookupHelper extends MethodReferenceLookupHelper {
3618
3619 UnboundMethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3620 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3621 super(referenceTree, name, site, argtypes.tail, typeargtypes, maxPhase);
3622 if (site.isRaw() && !argtypes.head.hasTag(NONE)) {
3623 Type asSuperSite = types.asSuper(argtypes.head, site.tsym);
3624 this.site = types.skipTypeVars(asSuperSite, true);
3625 }
3626 }
3627
3628 @Override
3629 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3630 return this;
3631 }
3632
3633 @Override
3634 ReferenceKind referenceKind(Symbol sym) {
3635 return ReferenceKind.UNBOUND;
3636 }
3637 }
3638
3639 /**
3640 * Helper class for array constructor lookup; an array constructor lookup
3641 * is simulated by looking up a method that returns the array type specified
3642 * as qualifier, and that accepts a single int parameter (size of the array).
3643 */
3644 class ArrayConstructorReferenceLookupHelper extends ReferenceLookupHelper {
3645
3646 ArrayConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
3647 List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3648 super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
3649 }
3650
3651 @Override
3652 protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3653 WriteableScope sc = WriteableScope.create(syms.arrayClass);
3654 MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym);
3655 arrayConstr.type = new MethodType(List.of(syms.intType), site, List.nil(), syms.methodClass);
3656 sc.enter(arrayConstr);
3657 return findMethodInScope(env, site, name, argtypes, typeargtypes, sc, methodNotFound, phase.isBoxingRequired(), phase.isVarargsRequired(), false);
3658 }
3659
3660 @Override
3661 ReferenceKind referenceKind(Symbol sym) {
3662 return ReferenceKind.ARRAY_CTOR;
3663 }
3664 }
3665
3666 /**
3667 * Helper class for constructor reference lookup. The lookup logic is based
3668 * upon either Resolve.findMethod or Resolve.findDiamond - depending on
3669 * whether the constructor reference needs diamond inference (this is the case
3670 * if the qualifier type is raw). A special erroneous symbol is returned
3671 * if the lookup returns the constructor of an inner class and there's no
3672 * enclosing instance in scope.
3673 */
3674 class ConstructorReferenceLookupHelper extends ReferenceLookupHelper {
3675
3676 boolean needsInference;
3677
3678 ConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
3679 List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3680 super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
3681 if (site.isRaw()) {
3682 this.site = new ClassType(site.getEnclosingType(),
3683 !(site.tsym.isInner() && site.getEnclosingType().isRaw()) ?
3684 site.tsym.type.getTypeArguments() : List.nil(), site.tsym, site.getMetadata());
3685 needsInference = true;
3686 }
3687 }
3688
3689 @Override
3690 protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3691 Symbol sym = needsInference ?
3692 findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) :
3693 findMethod(env, site, name, argtypes, typeargtypes,
3694 phase.isBoxingRequired(), phase.isVarargsRequired());
3695 return enclosingInstanceMissing(env, site) ? new BadConstructorReferenceError(sym) : sym;
3696 }
3697
3698 @Override
3699 ReferenceKind referenceKind(Symbol sym) {
3700 return site.getEnclosingType().hasTag(NONE) ?
3701 ReferenceKind.TOPLEVEL : ReferenceKind.IMPLICIT_INNER;
3702 }
3703 }
3704
3754 if (isStatic(env1)) staticOnly = true;
3755 if (env1.enclClass.sym == c) {
3756 Symbol sym = env1.info.scope.findFirst(name);
3757 if (sym != null) {
3758 if (staticOnly) sym = new StaticError(sym);
3759 return accessBase(sym, pos, env.enclClass.sym.type,
3760 name, true);
3761 }
3762 }
3763 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
3764 env1 = env1.outer;
3765 }
3766 if (c.isInterface() &&
3767 name == names._super && !isStatic(env) &&
3768 types.isDirectSuperInterface(c, env.enclClass.sym)) {
3769 //this might be a default super call if one of the superinterfaces is 'c'
3770 for (Type t : pruneInterfaces(env.enclClass.type)) {
3771 if (t.tsym == c) {
3772 env.info.defaultSuperCallSite = t;
3773 return new VarSymbol(0, names._super,
3774 types.asSuper(env.enclClass.type, c), env.enclClass.sym);
3775 }
3776 }
3777 //find a direct supertype that is a subtype of 'c'
3778 for (Type i : types.directSupertypes(env.enclClass.type)) {
3779 if (i.tsym.isSubClass(c, types) && i.tsym != c) {
3780 log.error(pos,
3781 Errors.IllegalDefaultSuperCall(c,
3782 Fragments.RedundantSupertype(c, i)));
3783 return syms.errSymbol;
3784 }
3785 }
3786 Assert.error();
3787 }
3788 log.error(pos, Errors.NotEnclClass(c));
3789 return syms.errSymbol;
3790 }
3791 //where
3792 private List<Type> pruneInterfaces(Type t) {
3793 ListBuffer<Type> result = new ListBuffer<>();
3794 for (Type t1 : types.interfaces(t)) {
4067 Name name,
4068 List<Type> argtypes,
4069 List<Type> typeargtypes) {
4070 argtypes = argtypes == null ? List.nil() : argtypes;
4071 typeargtypes = typeargtypes == null ? List.nil() : typeargtypes;
4072 if (name == names.error)
4073 return null;
4074
4075 boolean hasLocation = false;
4076 if (location == null) {
4077 location = site.tsym;
4078 }
4079 if (!location.name.isEmpty()) {
4080 if (location.kind == PCK && !site.tsym.exists() && location.name != names.java) {
4081 return diags.create(dkind, log.currentSource(), pos,
4082 "doesnt.exist", location);
4083 }
4084 hasLocation = !location.name.equals(names._this) &&
4085 !location.name.equals(names._super);
4086 }
4087 boolean isConstructor = name == names.init;
4088 KindName kindname = isConstructor ? KindName.CONSTRUCTOR : kind.absentKind();
4089 Name idname = isConstructor ? site.tsym.name : name;
4090 String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation);
4091 if (hasLocation) {
4092 return diags.create(dkind, log.currentSource(), pos,
4093 errKey, kindname, idname, //symbol kindname, name
4094 typeargtypes, args(argtypes), //type parameters and arguments (if any)
4095 getLocationDiag(location, site)); //location kindname, type
4096 }
4097 else {
4098 return diags.create(dkind, log.currentSource(), pos,
4099 errKey, kindname, idname, //symbol kindname, name
4100 typeargtypes, args(argtypes)); //type parameters and arguments (if any)
4101 }
4102 }
4103 //where
4104 private Object args(List<Type> args) {
4105 return args.isEmpty() ? args : methodArguments(args);
4106 }
4107
4166 Name name,
4167 List<Type> argtypes,
4168 List<Type> typeargtypes) {
4169 if (name == names.error)
4170 return null;
4171
4172 Pair<Symbol, JCDiagnostic> c = errCandidate();
4173 Symbol ws = c.fst.asMemberOf(site, types);
4174 UnaryOperator<JCDiagnostic> rewriter = compactMethodDiags ?
4175 d -> MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, c.snd) : null;
4176
4177 // If the problem is due to type arguments, then the method parameters aren't relevant,
4178 // so use the error message that omits them to avoid confusion.
4179 switch (c.snd.getCode()) {
4180 case "compiler.misc.wrong.number.type.args":
4181 case "compiler.misc.explicit.param.do.not.conform.to.bounds":
4182 return diags.create(dkind, log.currentSource(), pos,
4183 "cant.apply.symbol.noargs",
4184 rewriter,
4185 kindName(ws),
4186 ws.name == names.init ? ws.owner.name : ws.name,
4187 kindName(ws.owner),
4188 ws.owner.type,
4189 c.snd);
4190 default:
4191 // Avoid saying "constructor Array in class Array"
4192 if (ws.owner == syms.arrayClass && ws.name == names.init) {
4193 return diags.create(dkind, log.currentSource(), pos,
4194 "cant.apply.array.ctor",
4195 rewriter,
4196 methodArguments(ws.type.getParameterTypes()),
4197 methodArguments(argtypes),
4198 c.snd);
4199 }
4200 return diags.create(dkind, log.currentSource(), pos,
4201 "cant.apply.symbol",
4202 rewriter,
4203 kindName(ws),
4204 ws.name == names.init ? ws.owner.name : ws.name,
4205 methodArguments(ws.type.getParameterTypes()),
4206 methodArguments(argtypes),
4207 kindName(ws.owner),
4208 ws.owner.type,
4209 c.snd);
4210 }
4211 }
4212
4213 @Override
4214 public Symbol access(Name name, TypeSymbol location) {
4215 Pair<Symbol, JCDiagnostic> cand = errCandidate();
4216 TypeSymbol errSymbol = types.createErrorType(name, location, cand != null ? cand.fst.type : syms.errSymbol.type).tsym;
4217 if (cand != null) {
4218 attrRecover.wrongMethodSymbolCandidate(errSymbol, cand.fst, cand.snd);
4219 }
4220 return errSymbol;
4221 }
4222
4223 protected Pair<Symbol, JCDiagnostic> errCandidate() {
4224 Candidate bestSoFar = null;
4241 super(WRONG_MTHS, "inapplicable symbols", context);
4242 }
4243
4244 @Override
4245 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4246 DiagnosticPosition pos,
4247 Symbol location,
4248 Type site,
4249 Name name,
4250 List<Type> argtypes,
4251 List<Type> typeargtypes) {
4252 Map<Symbol, JCDiagnostic> candidatesMap = mapCandidates();
4253 Map<Symbol, JCDiagnostic> filteredCandidates = compactMethodDiags ?
4254 filterCandidates(candidatesMap) :
4255 mapCandidates();
4256 if (filteredCandidates.isEmpty()) {
4257 filteredCandidates = candidatesMap;
4258 }
4259 boolean truncatedDiag = candidatesMap.size() != filteredCandidates.size();
4260 if (filteredCandidates.size() > 1) {
4261 JCDiagnostic err = diags.create(dkind,
4262 null,
4263 truncatedDiag ?
4264 EnumSet.of(DiagnosticFlag.COMPRESSED) :
4265 EnumSet.noneOf(DiagnosticFlag.class),
4266 log.currentSource(),
4267 pos,
4268 "cant.apply.symbols",
4269 name == names.init ? KindName.CONSTRUCTOR : kind.absentKind(),
4270 name == names.init ? site.tsym.name : name,
4271 methodArguments(argtypes));
4272 return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(filteredCandidates, site));
4273 } else if (filteredCandidates.size() == 1) {
4274 Map.Entry<Symbol, JCDiagnostic> _e =
4275 filteredCandidates.entrySet().iterator().next();
4276 final Pair<Symbol, JCDiagnostic> p = new Pair<>(_e.getKey(), _e.getValue());
4277 JCDiagnostic d = new InapplicableSymbolError(resolveContext) {
4278 @Override
4279 protected Pair<Symbol, JCDiagnostic> errCandidate() {
4280 return p;
4281 }
4282 }.getDiagnostic(dkind, pos,
4283 location, site, name, argtypes, typeargtypes);
4284 if (truncatedDiag) {
4285 d.setFlag(DiagnosticFlag.COMPRESSED);
4286 }
4287 return d;
4288 } else {
4289 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos,
4290 location, site, name, argtypes, typeargtypes);
4410
4411 AccessError(Env<AttrContext> env, Type site, Symbol sym) {
4412 super(HIDDEN, sym, "access error");
4413 this.env = env;
4414 this.site = site;
4415 }
4416
4417 @Override
4418 public boolean exists() {
4419 return false;
4420 }
4421
4422 @Override
4423 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4424 DiagnosticPosition pos,
4425 Symbol location,
4426 Type site,
4427 Name name,
4428 List<Type> argtypes,
4429 List<Type> typeargtypes) {
4430 if (sym.name == names.init && sym.owner != site.tsym) {
4431 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind,
4432 pos, location, site, name, argtypes, typeargtypes);
4433 }
4434 else if ((sym.flags() & PUBLIC) != 0
4435 || (env != null && this.site != null
4436 && !isAccessible(env, this.site))) {
4437 if (sym.owner.kind == PCK) {
4438 return diags.create(dkind, log.currentSource(),
4439 pos, "not.def.access.package.cant.access",
4440 sym, sym.location(), inaccessiblePackageReason(env, sym.packge()));
4441 } else if ( sym.packge() != syms.rootPackage
4442 && !symbolPackageVisible(env, sym)) {
4443 return diags.create(dkind, log.currentSource(),
4444 pos, "not.def.access.class.intf.cant.access.reason",
4445 sym, sym.location(), sym.location().packge(),
4446 inaccessiblePackageReason(env, sym.packge()));
4447 } else {
4448 return diags.create(dkind, log.currentSource(),
4449 pos, "not.def.access.class.intf.cant.access",
4450 sym, sym.location());
4623 }
4624 }
4625
4626 AmbiguityError addAmbiguousSymbol(Symbol s) {
4627 ambiguousSyms = ambiguousSyms.prepend(s);
4628 return this;
4629 }
4630
4631 @Override
4632 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4633 DiagnosticPosition pos,
4634 Symbol location,
4635 Type site,
4636 Name name,
4637 List<Type> argtypes,
4638 List<Type> typeargtypes) {
4639 List<Symbol> diagSyms = ambiguousSyms.reverse();
4640 Symbol s1 = diagSyms.head;
4641 Symbol s2 = diagSyms.tail.head;
4642 Name sname = s1.name;
4643 if (sname == names.init) sname = s1.owner.name;
4644 return diags.create(dkind, log.currentSource(),
4645 pos, "ref.ambiguous", sname,
4646 kindName(s1),
4647 s1,
4648 s1.location(site, types),
4649 kindName(s2),
4650 s2,
4651 s2.location(site, types));
4652 }
4653
4654 /**
4655 * If multiple applicable methods are found during overload and none of them
4656 * is more specific than the others, attempt to merge their signatures.
4657 */
4658 Symbol mergeAbstracts(Type site) {
4659 List<Symbol> ambiguousInOrder = ambiguousSyms.reverse();
4660 return types.mergeAbstracts(ambiguousInOrder, site, true).orElse(this);
4661 }
4662
4663 @Override
|
89 * This code and its internal interfaces are subject to change or
90 * deletion without notice.</b>
91 */
92 public class Resolve {
93 protected static final Context.Key<Resolve> resolveKey = new Context.Key<>();
94
95 Names names;
96 Log log;
97 Symtab syms;
98 Attr attr;
99 AttrRecover attrRecover;
100 DeferredAttr deferredAttr;
101 Check chk;
102 Infer infer;
103 ClassFinder finder;
104 ModuleFinder moduleFinder;
105 Types types;
106 JCDiagnostic.Factory diags;
107 public final boolean allowModules;
108 public final boolean allowRecords;
109 public final boolean allowValueClasses;
110 private final boolean compactMethodDiags;
111 private final boolean allowLocalVariableTypeInference;
112 private final boolean allowYieldStatement;
113 final EnumSet<VerboseResolutionMode> verboseResolutionMode;
114 final boolean dumpMethodReferenceSearchResults;
115 final boolean allowPrimitiveClasses;
116
117 WriteableScope polymorphicSignatureScope;
118
119 @SuppressWarnings("this-escape")
120 protected Resolve(Context context) {
121 context.put(resolveKey, this);
122 syms = Symtab.instance(context);
123
124 varNotFound = new SymbolNotFoundError(ABSENT_VAR);
125 methodNotFound = new SymbolNotFoundError(ABSENT_MTH);
126 typeNotFound = new SymbolNotFoundError(ABSENT_TYP);
127 referenceNotFound = ReferenceLookupResult.error(methodNotFound);
128
129 names = Names.instance(context);
130 log = Log.instance(context);
131 attr = Attr.instance(context);
132 attrRecover = AttrRecover.instance(context);
133 deferredAttr = DeferredAttr.instance(context);
134 chk = Check.instance(context);
135 infer = Infer.instance(context);
136 finder = ClassFinder.instance(context);
137 moduleFinder = ModuleFinder.instance(context);
138 types = Types.instance(context);
139 diags = JCDiagnostic.Factory.instance(context);
140 Preview preview = Preview.instance(context);
141 Source source = Source.instance(context);
142 Options options = Options.instance(context);
143 compactMethodDiags = options.isSet(Option.XDIAGS, "compact") ||
144 options.isUnset(Option.XDIAGS) && options.isUnset("rawDiagnostics");
145 verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
146 Target target = Target.instance(context);
147 allowLocalVariableTypeInference = Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source);
148 allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source);
149 polymorphicSignatureScope = WriteableScope.create(syms.noSymbol);
150 allowModules = Feature.MODULES.allowedInSource(source);
151 allowRecords = Feature.RECORDS.allowedInSource(source);
152 dumpMethodReferenceSearchResults = options.isSet("debug.dumpMethodReferenceSearchResults");
153 allowValueClasses = Feature.VALUE_CLASSES.allowedInSource(source);
154 allowPrimitiveClasses = Feature.PRIMITIVE_CLASSES.allowedInSource(source) && options.isSet("enablePrimitiveClasses");
155 }
156
157 /** error symbols, which are returned when resolution fails
158 */
159 private final SymbolNotFoundError varNotFound;
160 private final SymbolNotFoundError methodNotFound;
161 private final SymbolNotFoundError typeNotFound;
162
163 /** empty reference lookup result */
164 private final ReferenceLookupResult referenceNotFound;
165
166 public static Resolve instance(Context context) {
167 Resolve instance = context.get(resolveKey);
168 if (instance == null)
169 instance = new Resolve(context);
170 return instance;
171 }
172
173 private static Symbol bestOf(Symbol s1,
174 Symbol s2) {
204 if (args.contains(mode.opt)) {
205 res.add(mode);
206 } else if (args.contains("-" + mode.opt)) {
207 res.remove(mode);
208 }
209 }
210 return res;
211 }
212 }
213
214 void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site,
215 List<Type> argtypes, List<Type> typeargtypes, Symbol bestSoFar) {
216 boolean success = !bestSoFar.kind.isResolutionError();
217
218 if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) {
219 return;
220 } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) {
221 return;
222 }
223
224 if (names.isInitOrVNew(bestSoFar.name) &&
225 bestSoFar.owner == syms.objectType.tsym &&
226 !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) {
227 return; //skip diags for Object constructor resolution
228 } else if (site == syms.predefClass.type &&
229 !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) {
230 return; //skip spurious diags for predef symbols (i.e. operators)
231 } else if (currentResolutionContext.internalResolution &&
232 !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) {
233 return;
234 }
235
236 int pos = 0;
237 int mostSpecificPos = -1;
238 ListBuffer<JCDiagnostic> subDiags = new ListBuffer<>();
239 for (Candidate c : currentResolutionContext.candidates) {
240 if (currentResolutionContext.step != c.step ||
241 (c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE)) ||
242 (!c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))) {
243 continue;
244 } else {
277 return diags.fragment(Fragments.NotApplicableMethodFound(pos, sym, subDiag));
278 }
279 // </editor-fold>
280
281 /* ************************************************************************
282 * Identifier resolution
283 *************************************************************************/
284
285 /** An environment is "static" if its static level is greater than
286 * the one of its outer environment
287 */
288 protected static boolean isStatic(Env<AttrContext> env) {
289 return env.outer != null && env.info.staticLevel > env.outer.info.staticLevel;
290 }
291
292 /** An environment is an "initializer" if it is a constructor or
293 * an instance initializer.
294 */
295 static boolean isInitializer(Env<AttrContext> env) {
296 Symbol owner = env.info.scope.owner;
297 return owner.isInitOrVNew() ||
298 owner.owner.kind == TYP &&
299 (owner.kind == VAR ||
300 owner.kind == MTH && (owner.flags() & BLOCK) != 0) &&
301 (owner.flags() & STATIC) == 0;
302 }
303
304 /** Is class accessible in given environment?
305 * @param env The current environment.
306 * @param c The class whose accessibility is checked.
307 */
308 public boolean isAccessible(Env<AttrContext> env, TypeSymbol c) {
309 return isAccessible(env, c, false);
310 }
311
312 public boolean isAccessible(Env<AttrContext> env, TypeSymbol c, boolean checkInner) {
313
314 /* 15.9.5.1: Note that it is possible for the signature of the anonymous constructor
315 to refer to an inaccessible type
316 */
317 if (env.enclMethod != null && (env.enclMethod.mods.flags & ANONCONSTR) != 0)
389 if (t.hasTag(ARRAY)) {
390 return isAccessible(env, types.cvarUpperBound(types.elemtype(t)));
391 } else if (t.isUnion()) {
392 return StreamSupport.stream(((UnionClassType) t).getAlternativeTypes().spliterator(), false)
393 .allMatch(alternative -> isAccessible(env, alternative.tsym, checkInner));
394 } else {
395 return isAccessible(env, t.tsym, checkInner);
396 }
397 }
398
399 /** Is symbol accessible as a member of given type in given environment?
400 * @param env The current environment.
401 * @param site The type of which the tested symbol is regarded
402 * as a member.
403 * @param sym The symbol.
404 */
405 public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym) {
406 return isAccessible(env, site, sym, false);
407 }
408 public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym, boolean checkInner) {
409 if (names.isInitOrVNew(sym.name) && sym.owner != site.tsym) return false;
410
411 /* 15.9.5.1: Note that it is possible for the signature of the anonymous constructor
412 to refer to an inaccessible type
413 */
414 if (env.enclMethod != null && (env.enclMethod.mods.flags & ANONCONSTR) != 0)
415 return true;
416
417 if (env.info.visitingServiceImplementation &&
418 env.toplevel.modle == sym.packge().modle) {
419 return true;
420 }
421
422 ClassSymbol enclosingCsym = env.enclClass.sym;
423 if (allowPrimitiveClasses) {
424 if (sym.kind == MTH || sym.kind == VAR) {
425 /* If any primitive class types are involved, ask the same question in the reference universe,
426 where the hierarchy is navigable
427 */
428 if (site.isPrimitiveClass())
429 site = site.referenceProjection();
430 } else if (sym.kind == TYP) {
431 // A type is accessible in a reference projection if it was
432 // accessible in the value projection.
433 if (site.isReferenceProjection())
434 site = site.valueProjection();
435 }
436 }
437 try {
438 switch ((short)(sym.flags() & AccessFlags)) {
439 case PRIVATE:
440 return
441 (env.enclClass.sym == sym.owner // fast special case
442 ||
443 env.enclClass.sym.outermostClass() ==
444 sym.owner.outermostClass())
445 &&
446 sym.isInheritedIn(site.tsym, types);
447 case 0:
448 return
449 (env.toplevel.packge == sym.owner.owner // fast special case
450 ||
451 env.toplevel.packge == sym.packge())
452 &&
453 isAccessible(env, site, checkInner)
454 &&
455 sym.isInheritedIn(site.tsym, types)
456 &&
457 notOverriddenIn(site, sym);
458 case PROTECTED:
459 return
460 (env.toplevel.packge == sym.owner.owner // fast special case
461 ||
462 env.toplevel.packge == sym.packge()
463 ||
464 isProtectedAccessible(sym, env.enclClass.sym, site)
465 ||
466 // OK to select instance method or field from 'super' or type name
467 // (but type names should be disallowed elsewhere!)
468 env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP)
469 &&
470 isAccessible(env, site, checkInner)
471 &&
472 notOverriddenIn(site, sym);
473 default: // this case includes erroneous combinations as well
474 return isAccessible(env, site, checkInner) && notOverriddenIn(site, sym);
475 }
476 } finally {
477 env.enclClass.sym = enclosingCsym;
478 }
479 }
480 //where
481 /* `sym' is accessible only if not overridden by
482 * another symbol which is a member of `site'
483 * (because, if it is overridden, `sym' is not strictly
484 * speaking a member of `site'). A polymorphic signature method
485 * cannot be overridden (e.g. MH.invokeExact(Object[])).
486 */
487 private boolean notOverriddenIn(Type site, Symbol sym) {
488 if (sym.kind != MTH || sym.isInitOrVNew() || sym.isStatic())
489 return true;
490
491 /* If any primitive class types are involved, ask the same question in the reference universe,
492 where the hierarchy is navigable
493 */
494 if (allowPrimitiveClasses && site.isPrimitiveClass()) {
495 site = site.referenceProjection();
496 }
497
498 Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true);
499 return (s2 == null || s2 == sym || sym.owner == s2.owner || (sym.owner.isInterface() && s2.owner == syms.objectType.tsym) ||
500 !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym)));
501 }
502 //where
503 /** Is given protected symbol accessible if it is selected from given site
504 * and the selection takes place in given class?
505 * @param sym The symbol with protected access
506 * @param c The class where the access takes place
507 * @param site The type of the qualifier
508 */
509 private
510 boolean isProtectedAccessible(Symbol sym, ClassSymbol c, Type site) {
511 Type newSite = site.hasTag(TYPEVAR) ? site.getUpperBound() : site;
512 while (c != null &&
513 !(c.isSubClass(sym.owner, types) &&
514 (c.flags() & INTERFACE) == 0 &&
515 // In JLS 2e 6.6.2.1, the subclass restriction applies
516 // only to instance fields and methods -- types are excluded
517 // regardless of whether they are declared 'static' or not.
518 ((sym.flags() & STATIC) != 0 || sym.kind == TYP || newSite.tsym.isSubClass(c, types))))
519 c = c.owner.enclClass();
520 return c != null;
1700
1701 // same signature; select (a) the non-bridge method, or
1702 // (b) the one that overrides the other, or (c) the concrete
1703 // one, or (d) merge both abstract signatures
1704 if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE))
1705 return ((m1.flags() & BRIDGE) != 0) ? m2 : m1;
1706
1707 if (m1.baseSymbol() == m2.baseSymbol()) {
1708 // this is the same imported symbol which has been cloned twice.
1709 // Return the first one (either will do).
1710 return m1;
1711 }
1712
1713 // if one overrides or hides the other, use it
1714 TypeSymbol m1Owner = (TypeSymbol)m1.owner;
1715 TypeSymbol m2Owner = (TypeSymbol)m2.owner;
1716 // the two owners can never be the same if the target methods are compiled from source,
1717 // but we need to protect against cases where the methods are defined in some classfile
1718 // and make sure we issue an ambiguity error accordingly (by skipping the logic below).
1719 if (m1Owner != m2Owner) {
1720 if (types.asSuper(m1Owner.type.referenceProjectionOrSelf(), m2Owner) != null &&
1721 ((m1.owner.flags_field & INTERFACE) == 0 ||
1722 (m2.owner.flags_field & INTERFACE) != 0) &&
1723 m1.overrides(m2, m1Owner, types, false))
1724 return m1;
1725 if (types.asSuper(m2Owner.type.referenceProjectionOrSelf(), m1Owner) != null &&
1726 ((m2.owner.flags_field & INTERFACE) == 0 ||
1727 (m1.owner.flags_field & INTERFACE) != 0) &&
1728 m2.overrides(m1, m2Owner, types, false))
1729 return m2;
1730 }
1731 boolean m1Abstract = (m1.flags() & ABSTRACT) != 0;
1732 boolean m2Abstract = (m2.flags() & ABSTRACT) != 0;
1733 if (m1Abstract && !m2Abstract) return m2;
1734 if (m2Abstract && !m1Abstract) return m1;
1735 // both abstract or both concrete
1736 return ambiguityError(m1, m2);
1737 }
1738 if (m1SignatureMoreSpecific) return m1;
1739 if (m2SignatureMoreSpecific) return m2;
1740 return ambiguityError(m1, m2);
1741 case AMBIGUOUS:
1742 //compare m1 to ambiguous methods in m2
1743 AmbiguityError e = (AmbiguityError)m2.baseSymbol();
1744 boolean m1MoreSpecificThanAnyAmbiguous = true;
1745 boolean allAmbiguousMoreSpecificThanM1 = true;
1872 return bestSoFar;
1873 }
1874 // where
1875 private Symbol findMethod(Env<AttrContext> env,
1876 Type site,
1877 Name name,
1878 List<Type> argtypes,
1879 List<Type> typeargtypes,
1880 Type intype,
1881 Symbol bestSoFar,
1882 boolean allowBoxing,
1883 boolean useVarargs) {
1884 @SuppressWarnings({"unchecked","rawtypes"})
1885 List<Type>[] itypes = (List<Type>[])new List[] { List.<Type>nil(), List.<Type>nil() };
1886
1887 InterfaceLookupPhase iphase = InterfaceLookupPhase.ABSTRACT_OK;
1888 boolean isInterface = site.tsym.isInterface();
1889 for (TypeSymbol s : isInterface ? List.of(intype.tsym) : superclasses(intype)) {
1890 bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
1891 s.members(), bestSoFar, allowBoxing, useVarargs, true);
1892 if (names.isInitOrVNew(name)) return bestSoFar;
1893 iphase = (iphase == null) ? null : iphase.update(s, this);
1894 if (iphase != null) {
1895 for (Type itype : types.interfaces(s.type)) {
1896 itypes[iphase.ordinal()] = types.union(types.closure(itype), itypes[iphase.ordinal()]);
1897 }
1898 }
1899 }
1900
1901 Symbol concrete = bestSoFar.kind.isValid() &&
1902 (bestSoFar.flags() & ABSTRACT) == 0 ?
1903 bestSoFar : methodNotFound;
1904
1905 for (InterfaceLookupPhase iphase2 : InterfaceLookupPhase.values()) {
1906 //keep searching for abstract methods
1907 for (Type itype : itypes[iphase2.ordinal()]) {
1908 if (!itype.isInterface()) continue; //skip j.l.Object (included by Types.closure())
1909 if (iphase2 == InterfaceLookupPhase.DEFAULT_OK &&
1910 (itype.tsym.flags() & DEFAULT) == 0) continue;
1911 bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
1912 itype.tsym.members(), bestSoFar, allowBoxing, useVarargs, true);
2307 bestSoFar = new AmbiguityError(bestSoFar, sym);
2308 else
2309 bestSoFar = bestOf(bestSoFar, sym);
2310 }
2311 return bestSoFar;
2312 }
2313
2314 /** Find qualified member type.
2315 * @param env The current environment.
2316 * @param site The original type from where the selection takes
2317 * place.
2318 * @param name The type's name.
2319 * @param c The class to search for the member type. This is
2320 * always a superclass or implemented interface of
2321 * site's class.
2322 */
2323 Symbol findMemberType(Env<AttrContext> env,
2324 Type site,
2325 Name name,
2326 TypeSymbol c) {
2327 return findMemberTypeInternal(env,site, name, c);
2328 }
2329
2330 /** Find qualified member type.
2331 * @param env The current environment.
2332 * @param site The original type from where the selection takes
2333 * place.
2334 * @param name The type's name.
2335 * @param c The class to search for the member type. This is
2336 * always a superclass or implemented interface of
2337 * site's class.
2338 */
2339 Symbol findMemberTypeInternal(Env<AttrContext> env,
2340 Type site,
2341 Name name,
2342 TypeSymbol c) {
2343 Symbol sym = findImmediateMemberType(env, site, name, c);
2344
2345 if (sym != typeNotFound)
2346 return sym;
2347
2348 return findInheritedMemberType(env, site, name, c);
2349
2350 }
2351
2352 /** Find a global type in given scope and load corresponding class.
2353 * @param env The current environment.
2354 * @param scope The scope in which to look for the type.
2355 * @param name The type's name.
2356 */
2357 Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name, RecoveryLoadClass recoveryLoadClass) {
2358 Symbol bestSoFar = typeNotFound;
2359 for (Symbol s : scope.getSymbolsByName(name)) {
2360 Symbol sym = loadClass(env, s.flatName(), recoveryLoadClass);
2361 if (bestSoFar.kind == TYP && sym.kind == TYP &&
2362 bestSoFar != sym)
2371 for (Symbol sym : env.info.scope.getSymbolsByName(name)) {
2372 if (sym.kind == TYP) {
2373 if (sym.type.hasTag(TYPEVAR) &&
2374 (staticOnly || (isStatic(env) && sym.owner.kind == TYP)))
2375 // if staticOnly is set, it means that we have recursed through a static declaration,
2376 // so type variable symbols should not be accessible. If staticOnly is unset, but
2377 // we are in a static declaration (field or method), we should not allow type-variables
2378 // defined in the enclosing class to "leak" into this context.
2379 return new StaticError(sym);
2380 return sym;
2381 }
2382 }
2383 return typeNotFound;
2384 }
2385
2386 /** Find an unqualified type symbol.
2387 * @param env The current environment.
2388 * @param name The type's name.
2389 */
2390 Symbol findType(Env<AttrContext> env, Name name) {
2391 return findTypeInternal(env, name);
2392 }
2393
2394 /** Find an unqualified type symbol.
2395 * @param env The current environment.
2396 * @param name The type's name.
2397 */
2398 Symbol findTypeInternal(Env<AttrContext> env, Name name) {
2399 if (name == names.empty)
2400 return typeNotFound; // do not allow inadvertent "lookup" of anonymous types
2401 Symbol bestSoFar = typeNotFound;
2402 Symbol sym;
2403 boolean staticOnly = false;
2404 for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) {
2405 // First, look for a type variable and the first member type
2406 final Symbol tyvar = findTypeVar(env1, name, staticOnly);
2407 if (isStatic(env1)) staticOnly = true;
2408 sym = findImmediateMemberType(env1, env1.enclClass.sym.type,
2409 name, env1.enclClass.sym);
2410
2411 // Return the type variable if we have it, and have no
2412 // immediate member, OR the type variable is for a method.
2413 if (tyvar != typeNotFound) {
2414 if (env.baseClause || sym == typeNotFound ||
2415 (tyvar.kind == TYP && tyvar.exists() &&
2416 tyvar.owner.kind == MTH)) {
2417 return tyvar;
2418 }
2916 * @param site The type of class for which a constructor is searched.
2917 * @param argtypes The types of the constructor invocation's value
2918 * arguments.
2919 * @param typeargtypes The types of the constructor invocation's type
2920 * arguments.
2921 */
2922 Symbol resolveConstructor(DiagnosticPosition pos,
2923 Env<AttrContext> env,
2924 Type site,
2925 List<Type> argtypes,
2926 List<Type> typeargtypes) {
2927 return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes);
2928 }
2929
2930 private Symbol resolveConstructor(MethodResolutionContext resolveContext,
2931 final DiagnosticPosition pos,
2932 Env<AttrContext> env,
2933 Type site,
2934 List<Type> argtypes,
2935 List<Type> typeargtypes) {
2936 Name constructorName = site.tsym.isConcreteValueClass() ? names.vnew : names.init;
2937 return lookupMethod(env, pos, site.tsym, resolveContext, new BasicLookupHelper(constructorName, site, argtypes, typeargtypes) {
2938 @Override
2939 Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2940 return findConstructor(pos, env, site, argtypes, typeargtypes,
2941 phase.isBoxingRequired(),
2942 phase.isVarargsRequired());
2943 }
2944 });
2945 }
2946
2947 /** Resolve a constructor, throw a fatal error if not found.
2948 * @param pos The position to use for error reporting.
2949 * @param env The environment current at the method invocation.
2950 * @param site The type to be constructed.
2951 * @param argtypes The types of the invocation's value arguments.
2952 * @param typeargtypes The types of the invocation's type arguments.
2953 */
2954 public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2955 Type site,
2956 List<Type> argtypes,
2957 List<Type> typeargtypes) {
2958 MethodResolutionContext resolveContext = new MethodResolutionContext();
2959 resolveContext.internalResolution = true;
2960 Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes);
2961 if (sym.kind == MTH) return (MethodSymbol)sym;
2962 else throw new FatalError(
2963 diags.fragment(Fragments.FatalErrCantLocateCtor(site)));
2964 }
2965
2966 Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2967 Type site, List<Type> argtypes,
2968 List<Type> typeargtypes,
2969 boolean allowBoxing,
2970 boolean useVarargs) {
2971 Name constructorName = site.tsym.isConcreteValueClass() ? names.vnew : names.init;
2972 Symbol sym = findMethod(env, site,
2973 constructorName, argtypes,
2974 typeargtypes, allowBoxing,
2975 useVarargs);
2976 chk.checkDeprecated(pos, env.info.scope.owner, sym);
2977 chk.checkPreview(pos, env.info.scope.owner, sym);
2978 return sym;
2979 }
2980
2981 /** Resolve constructor using diamond inference.
2982 * @param pos The position to use for error reporting.
2983 * @param env The environment current at the constructor invocation.
2984 * @param site The type of class for which a constructor is searched.
2985 * The scope of this class has been touched in attribution.
2986 * @param argtypes The types of the constructor invocation's value
2987 * arguments.
2988 * @param typeargtypes The types of the constructor invocation's type
2989 * arguments.
2990 */
2991 Symbol resolveDiamond(DiagnosticPosition pos,
2992 Env<AttrContext> env,
2993 Type site,
2994 List<Type> argtypes,
2995 List<Type> typeargtypes) {
2996 Name constructorName = allowValueClasses && site.tsym.isConcreteValueClass() ? names.vnew : names.init;
2997 return lookupMethod(env, pos, site.tsym, resolveMethodCheck,
2998 new BasicLookupHelper(constructorName, site, argtypes, typeargtypes) {
2999 @Override
3000 Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3001 return findDiamond(pos, env, site, argtypes, typeargtypes,
3002 phase.isBoxingRequired(),
3003 phase.isVarargsRequired());
3004 }
3005 @Override
3006 Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
3007 if (sym.kind.isResolutionError()) {
3008 if (sym.kind != WRONG_MTH &&
3009 sym.kind != WRONG_MTHS) {
3010 sym = super.access(env, pos, location, sym);
3011 } else {
3012 sym = new DiamondError(sym, currentResolutionContext);
3013 sym = accessMethod(sym, pos, site, constructorName, true, argtypes, typeargtypes);
3014 env.info.pendingResolutionPhase = currentResolutionContext.step;
3015 }
3016 }
3017 return sym;
3018 }});
3019 }
3020
3021 /** Find the constructor using diamond inference and do some checks(deprecated and preview).
3022 * @param pos The position to use for error reporting.
3023 * @param env The environment current at the constructor invocation.
3024 * @param site The type of class for which a constructor is searched.
3025 * The scope of this class has been touched in attribution.
3026 * @param argtypes The types of the constructor invocation's value arguments.
3027 * @param typeargtypes The types of the constructor invocation's type arguments.
3028 * @param allowBoxing Allow boxing conversions of arguments.
3029 * @param useVarargs Box trailing arguments into an array for varargs.
3030 */
3031 private Symbol findDiamond(DiagnosticPosition pos,
3032 Env<AttrContext> env,
3033 Type site,
3040 chk.checkPreview(pos, env.info.scope.owner, sym);
3041 return sym;
3042 }
3043
3044 /** This method scans all the constructor symbol in a given class scope -
3045 * assuming that the original scope contains a constructor of the kind:
3046 * {@code Foo(X x, Y y)}, where X,Y are class type-variables declared in Foo,
3047 * a method check is executed against the modified constructor type:
3048 * {@code <X,Y>Foo<X,Y>(X x, Y y)}. This is crucial in order to enable diamond
3049 * inference. The inferred return type of the synthetic constructor IS
3050 * the inferred type for the diamond operator.
3051 */
3052 private Symbol findDiamond(Env<AttrContext> env,
3053 Type site,
3054 List<Type> argtypes,
3055 List<Type> typeargtypes,
3056 boolean allowBoxing,
3057 boolean useVarargs) {
3058 Symbol bestSoFar = methodNotFound;
3059 TypeSymbol tsym = site.tsym.isInterface() ? syms.objectType.tsym : site.tsym;
3060 Name constructorName = site.tsym.isConcreteValueClass() ? names.vnew : names.init;
3061 for (final Symbol sym : tsym.members().getSymbolsByName(constructorName)) {
3062 //- System.out.println(" e " + e.sym);
3063 if (sym.kind == MTH &&
3064 (sym.flags_field & SYNTHETIC) == 0) {
3065 List<Type> oldParams = sym.type.hasTag(FORALL) ?
3066 ((ForAll)sym.type).tvars :
3067 List.nil();
3068 Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams),
3069 types.createMethodTypeWithReturn(sym.type.asMethodType(), site));
3070 MethodSymbol newConstr = new MethodSymbol(sym.flags(), constructorName, constrType, site.tsym) {
3071 @Override
3072 public Symbol baseSymbol() {
3073 return sym;
3074 }
3075 };
3076 bestSoFar = selectBest(env, site, argtypes, typeargtypes,
3077 newConstr,
3078 bestSoFar,
3079 allowBoxing,
3080 useVarargs);
3081 }
3082 }
3083 return bestSoFar;
3084 }
3085
3086 Symbol getMemberReference(DiagnosticPosition pos,
3087 Env<AttrContext> env,
3088 JCMemberReference referenceTree,
3089 Type site,
3090 Name name) {
3092 site = types.capture(site);
3093
3094 ReferenceLookupHelper lookupHelper = makeReferenceLookupHelper(
3095 referenceTree, site, name, List.nil(), null, VARARITY);
3096
3097 Env<AttrContext> newEnv = env.dup(env.tree, env.info.dup());
3098 Symbol sym = lookupMethod(newEnv, env.tree.pos(), site.tsym,
3099 nilMethodCheck, lookupHelper);
3100
3101 env.info.pendingResolutionPhase = newEnv.info.pendingResolutionPhase;
3102
3103 return sym;
3104 }
3105
3106 ReferenceLookupHelper makeReferenceLookupHelper(JCMemberReference referenceTree,
3107 Type site,
3108 Name name,
3109 List<Type> argtypes,
3110 List<Type> typeargtypes,
3111 MethodResolutionPhase maxPhase) {
3112 if (!names.isInitOrVNew(name)) {
3113 //method reference
3114 return new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
3115 } else if (site.hasTag(ARRAY)) {
3116 //array constructor reference
3117 return new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
3118 } else {
3119 //class constructor reference
3120 return new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
3121 }
3122 }
3123
3124 /**
3125 * Resolution of member references is typically done as a single
3126 * overload resolution step, where the argument types A are inferred from
3127 * the target functional descriptor.
3128 *
3129 * If the member reference is a method reference with a type qualifier,
3130 * a two-step lookup process is performed. The first step uses the
3131 * expected argument list A, while the second step discards the first
3132 * type from A (which is treated as a receiver type).
3607 /** The original method reference lookup site. */
3608 Type originalSite;
3609
3610 MethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3611 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3612 super(referenceTree, name, types.skipTypeVars(site, true), argtypes, typeargtypes, maxPhase);
3613 this.originalSite = site;
3614 }
3615
3616 @Override
3617 final Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3618 return findMethod(env, site, name, argtypes, typeargtypes,
3619 phase.isBoxingRequired(), phase.isVarargsRequired());
3620 }
3621
3622 @Override
3623 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3624 if (TreeInfo.isStaticSelector(referenceTree.expr, names)) {
3625 if (argtypes.nonEmpty() &&
3626 (argtypes.head.hasTag(NONE) ||
3627 types.isSubtypeUnchecked(inferenceContext.asUndetVar(argtypes.head.referenceProjectionOrSelf()), originalSite))) {
3628 return new UnboundMethodReferenceLookupHelper(referenceTree, name,
3629 originalSite, argtypes, typeargtypes, maxPhase);
3630 } else {
3631 return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) {
3632 @Override
3633 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3634 return this;
3635 }
3636
3637 @Override
3638 Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3639 return methodNotFound;
3640 }
3641
3642 @Override
3643 ReferenceKind referenceKind(Symbol sym) {
3644 Assert.error();
3645 return null;
3646 }
3647 };
3660 return selName != null && selName == names._super ?
3661 ReferenceKind.SUPER :
3662 ReferenceKind.BOUND;
3663 }
3664 }
3665 }
3666
3667 /**
3668 * Helper class for unbound method reference lookup. Essentially the same
3669 * as the basic method reference lookup helper; main difference is that static
3670 * lookup results are thrown away. If qualifier type is raw, an attempt to
3671 * infer a parameterized type is made using the first actual argument (that
3672 * would otherwise be ignored during the lookup).
3673 */
3674 class UnboundMethodReferenceLookupHelper extends MethodReferenceLookupHelper {
3675
3676 UnboundMethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3677 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3678 super(referenceTree, name, site, argtypes.tail, typeargtypes, maxPhase);
3679 if (site.isRaw() && !argtypes.head.hasTag(NONE)) {
3680 Type asSuperSite = types.asSuper(argtypes.head.referenceProjectionOrSelf(), site.tsym);
3681 this.site = types.skipTypeVars(asSuperSite, true);
3682 }
3683 }
3684
3685 @Override
3686 ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3687 return this;
3688 }
3689
3690 @Override
3691 ReferenceKind referenceKind(Symbol sym) {
3692 return ReferenceKind.UNBOUND;
3693 }
3694 }
3695
3696 /**
3697 * Helper class for array constructor lookup; an array constructor lookup
3698 * is simulated by looking up a method that returns the array type specified
3699 * as qualifier, and that accepts a single int parameter (size of the array).
3700 */
3701 class ArrayConstructorReferenceLookupHelper extends ReferenceLookupHelper {
3702
3703 ArrayConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
3704 List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3705 // TODO - array constructor will be <init>
3706 super(referenceTree, site.tsym.isConcreteValueClass() ? names.vnew : names.init, site, argtypes, typeargtypes, maxPhase);
3707 }
3708
3709 @Override
3710 protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3711 WriteableScope sc = WriteableScope.create(syms.arrayClass);
3712 MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym);
3713 arrayConstr.type = new MethodType(List.of(syms.intType), site, List.nil(), syms.methodClass);
3714 sc.enter(arrayConstr);
3715 return findMethodInScope(env, site, name, argtypes, typeargtypes, sc, methodNotFound, phase.isBoxingRequired(), phase.isVarargsRequired(), false);
3716 }
3717
3718 @Override
3719 ReferenceKind referenceKind(Symbol sym) {
3720 return ReferenceKind.ARRAY_CTOR;
3721 }
3722 }
3723
3724 /**
3725 * Helper class for constructor reference lookup. The lookup logic is based
3726 * upon either Resolve.findMethod or Resolve.findDiamond - depending on
3727 * whether the constructor reference needs diamond inference (this is the case
3728 * if the qualifier type is raw). A special erroneous symbol is returned
3729 * if the lookup returns the constructor of an inner class and there's no
3730 * enclosing instance in scope.
3731 */
3732 class ConstructorReferenceLookupHelper extends ReferenceLookupHelper {
3733
3734 boolean needsInference;
3735
3736 ConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
3737 List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3738 super(referenceTree, site.tsym.isConcreteValueClass() ? names.vnew : names.init, site, argtypes, typeargtypes, maxPhase);
3739 if (site.isRaw()) {
3740 this.site = new ClassType(site.getEnclosingType(),
3741 !(site.tsym.isInner() && site.getEnclosingType().isRaw()) ?
3742 site.tsym.type.getTypeArguments() : List.nil(), site.tsym, site.getMetadata(), site.getFlavor());
3743 needsInference = true;
3744 }
3745 }
3746
3747 @Override
3748 protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3749 Symbol sym = needsInference ?
3750 findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) :
3751 findMethod(env, site, name, argtypes, typeargtypes,
3752 phase.isBoxingRequired(), phase.isVarargsRequired());
3753 return enclosingInstanceMissing(env, site) ? new BadConstructorReferenceError(sym) : sym;
3754 }
3755
3756 @Override
3757 ReferenceKind referenceKind(Symbol sym) {
3758 return site.getEnclosingType().hasTag(NONE) ?
3759 ReferenceKind.TOPLEVEL : ReferenceKind.IMPLICIT_INNER;
3760 }
3761 }
3762
3812 if (isStatic(env1)) staticOnly = true;
3813 if (env1.enclClass.sym == c) {
3814 Symbol sym = env1.info.scope.findFirst(name);
3815 if (sym != null) {
3816 if (staticOnly) sym = new StaticError(sym);
3817 return accessBase(sym, pos, env.enclClass.sym.type,
3818 name, true);
3819 }
3820 }
3821 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
3822 env1 = env1.outer;
3823 }
3824 if (c.isInterface() &&
3825 name == names._super && !isStatic(env) &&
3826 types.isDirectSuperInterface(c, env.enclClass.sym)) {
3827 //this might be a default super call if one of the superinterfaces is 'c'
3828 for (Type t : pruneInterfaces(env.enclClass.type)) {
3829 if (t.tsym == c) {
3830 env.info.defaultSuperCallSite = t;
3831 return new VarSymbol(0, names._super,
3832 types.asSuper(env.enclClass.type.referenceProjectionOrSelf(), c), env.enclClass.sym);
3833 }
3834 }
3835 //find a direct supertype that is a subtype of 'c'
3836 for (Type i : types.directSupertypes(env.enclClass.type)) {
3837 if (i.tsym.isSubClass(c, types) && i.tsym != c) {
3838 log.error(pos,
3839 Errors.IllegalDefaultSuperCall(c,
3840 Fragments.RedundantSupertype(c, i)));
3841 return syms.errSymbol;
3842 }
3843 }
3844 Assert.error();
3845 }
3846 log.error(pos, Errors.NotEnclClass(c));
3847 return syms.errSymbol;
3848 }
3849 //where
3850 private List<Type> pruneInterfaces(Type t) {
3851 ListBuffer<Type> result = new ListBuffer<>();
3852 for (Type t1 : types.interfaces(t)) {
4125 Name name,
4126 List<Type> argtypes,
4127 List<Type> typeargtypes) {
4128 argtypes = argtypes == null ? List.nil() : argtypes;
4129 typeargtypes = typeargtypes == null ? List.nil() : typeargtypes;
4130 if (name == names.error)
4131 return null;
4132
4133 boolean hasLocation = false;
4134 if (location == null) {
4135 location = site.tsym;
4136 }
4137 if (!location.name.isEmpty()) {
4138 if (location.kind == PCK && !site.tsym.exists() && location.name != names.java) {
4139 return diags.create(dkind, log.currentSource(), pos,
4140 "doesnt.exist", location);
4141 }
4142 hasLocation = !location.name.equals(names._this) &&
4143 !location.name.equals(names._super);
4144 }
4145 boolean isConstructor = names.isInitOrVNew(name);
4146 KindName kindname = isConstructor ? KindName.CONSTRUCTOR : kind.absentKind();
4147 Name idname = isConstructor ? site.tsym.name : name;
4148 String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation);
4149 if (hasLocation) {
4150 return diags.create(dkind, log.currentSource(), pos,
4151 errKey, kindname, idname, //symbol kindname, name
4152 typeargtypes, args(argtypes), //type parameters and arguments (if any)
4153 getLocationDiag(location, site)); //location kindname, type
4154 }
4155 else {
4156 return diags.create(dkind, log.currentSource(), pos,
4157 errKey, kindname, idname, //symbol kindname, name
4158 typeargtypes, args(argtypes)); //type parameters and arguments (if any)
4159 }
4160 }
4161 //where
4162 private Object args(List<Type> args) {
4163 return args.isEmpty() ? args : methodArguments(args);
4164 }
4165
4224 Name name,
4225 List<Type> argtypes,
4226 List<Type> typeargtypes) {
4227 if (name == names.error)
4228 return null;
4229
4230 Pair<Symbol, JCDiagnostic> c = errCandidate();
4231 Symbol ws = c.fst.asMemberOf(site, types);
4232 UnaryOperator<JCDiagnostic> rewriter = compactMethodDiags ?
4233 d -> MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, c.snd) : null;
4234
4235 // If the problem is due to type arguments, then the method parameters aren't relevant,
4236 // so use the error message that omits them to avoid confusion.
4237 switch (c.snd.getCode()) {
4238 case "compiler.misc.wrong.number.type.args":
4239 case "compiler.misc.explicit.param.do.not.conform.to.bounds":
4240 return diags.create(dkind, log.currentSource(), pos,
4241 "cant.apply.symbol.noargs",
4242 rewriter,
4243 kindName(ws),
4244 names.isInitOrVNew(ws.name) ? ws.owner.name : ws.name,
4245 ws.owner.type,
4246 c.snd);
4247 default:
4248 // Avoid saying "constructor Array in class Array"
4249 if (ws.owner == syms.arrayClass && ws.name == names.init) {
4250 return diags.create(dkind, log.currentSource(), pos,
4251 "cant.apply.array.ctor",
4252 rewriter,
4253 methodArguments(ws.type.getParameterTypes()),
4254 methodArguments(argtypes),
4255 c.snd);
4256 }
4257 return diags.create(dkind, log.currentSource(), pos,
4258 "cant.apply.symbol",
4259 rewriter,
4260 kindName(ws),
4261 names.isInitOrVNew(ws.name) ? ws.owner.name : ws.name,
4262 methodArguments(ws.type.getParameterTypes()),
4263 methodArguments(argtypes),
4264 kindName(ws.owner),
4265 ws.owner.type,
4266 c.snd);
4267 }
4268 }
4269
4270 @Override
4271 public Symbol access(Name name, TypeSymbol location) {
4272 Pair<Symbol, JCDiagnostic> cand = errCandidate();
4273 TypeSymbol errSymbol = types.createErrorType(name, location, cand != null ? cand.fst.type : syms.errSymbol.type).tsym;
4274 if (cand != null) {
4275 attrRecover.wrongMethodSymbolCandidate(errSymbol, cand.fst, cand.snd);
4276 }
4277 return errSymbol;
4278 }
4279
4280 protected Pair<Symbol, JCDiagnostic> errCandidate() {
4281 Candidate bestSoFar = null;
4298 super(WRONG_MTHS, "inapplicable symbols", context);
4299 }
4300
4301 @Override
4302 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4303 DiagnosticPosition pos,
4304 Symbol location,
4305 Type site,
4306 Name name,
4307 List<Type> argtypes,
4308 List<Type> typeargtypes) {
4309 Map<Symbol, JCDiagnostic> candidatesMap = mapCandidates();
4310 Map<Symbol, JCDiagnostic> filteredCandidates = compactMethodDiags ?
4311 filterCandidates(candidatesMap) :
4312 mapCandidates();
4313 if (filteredCandidates.isEmpty()) {
4314 filteredCandidates = candidatesMap;
4315 }
4316 boolean truncatedDiag = candidatesMap.size() != filteredCandidates.size();
4317 if (filteredCandidates.size() > 1) {
4318 boolean isConstructor = names.isInitOrVNew(name);
4319 JCDiagnostic err = diags.create(dkind,
4320 null,
4321 truncatedDiag ?
4322 EnumSet.of(DiagnosticFlag.COMPRESSED) :
4323 EnumSet.noneOf(DiagnosticFlag.class),
4324 log.currentSource(),
4325 pos,
4326 "cant.apply.symbols",
4327 isConstructor ? KindName.CONSTRUCTOR : kind.absentKind(),
4328 isConstructor ? site.tsym.name : name,
4329 methodArguments(argtypes));
4330 return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(filteredCandidates, site));
4331 } else if (filteredCandidates.size() == 1) {
4332 Map.Entry<Symbol, JCDiagnostic> _e =
4333 filteredCandidates.entrySet().iterator().next();
4334 final Pair<Symbol, JCDiagnostic> p = new Pair<>(_e.getKey(), _e.getValue());
4335 JCDiagnostic d = new InapplicableSymbolError(resolveContext) {
4336 @Override
4337 protected Pair<Symbol, JCDiagnostic> errCandidate() {
4338 return p;
4339 }
4340 }.getDiagnostic(dkind, pos,
4341 location, site, name, argtypes, typeargtypes);
4342 if (truncatedDiag) {
4343 d.setFlag(DiagnosticFlag.COMPRESSED);
4344 }
4345 return d;
4346 } else {
4347 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos,
4348 location, site, name, argtypes, typeargtypes);
4468
4469 AccessError(Env<AttrContext> env, Type site, Symbol sym) {
4470 super(HIDDEN, sym, "access error");
4471 this.env = env;
4472 this.site = site;
4473 }
4474
4475 @Override
4476 public boolean exists() {
4477 return false;
4478 }
4479
4480 @Override
4481 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4482 DiagnosticPosition pos,
4483 Symbol location,
4484 Type site,
4485 Name name,
4486 List<Type> argtypes,
4487 List<Type> typeargtypes) {
4488 if (names.isInitOrVNew(sym.name) && sym.owner != site.tsym) {
4489 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind,
4490 pos, location, site, name, argtypes, typeargtypes);
4491 }
4492 else if ((sym.flags() & PUBLIC) != 0
4493 || (env != null && this.site != null
4494 && !isAccessible(env, this.site))) {
4495 if (sym.owner.kind == PCK) {
4496 return diags.create(dkind, log.currentSource(),
4497 pos, "not.def.access.package.cant.access",
4498 sym, sym.location(), inaccessiblePackageReason(env, sym.packge()));
4499 } else if ( sym.packge() != syms.rootPackage
4500 && !symbolPackageVisible(env, sym)) {
4501 return diags.create(dkind, log.currentSource(),
4502 pos, "not.def.access.class.intf.cant.access.reason",
4503 sym, sym.location(), sym.location().packge(),
4504 inaccessiblePackageReason(env, sym.packge()));
4505 } else {
4506 return diags.create(dkind, log.currentSource(),
4507 pos, "not.def.access.class.intf.cant.access",
4508 sym, sym.location());
4681 }
4682 }
4683
4684 AmbiguityError addAmbiguousSymbol(Symbol s) {
4685 ambiguousSyms = ambiguousSyms.prepend(s);
4686 return this;
4687 }
4688
4689 @Override
4690 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4691 DiagnosticPosition pos,
4692 Symbol location,
4693 Type site,
4694 Name name,
4695 List<Type> argtypes,
4696 List<Type> typeargtypes) {
4697 List<Symbol> diagSyms = ambiguousSyms.reverse();
4698 Symbol s1 = diagSyms.head;
4699 Symbol s2 = diagSyms.tail.head;
4700 Name sname = s1.name;
4701 if (names.isInitOrVNew(sname)) sname = s1.owner.name;
4702 return diags.create(dkind, log.currentSource(),
4703 pos, "ref.ambiguous", sname,
4704 kindName(s1),
4705 s1,
4706 s1.location(site, types),
4707 kindName(s2),
4708 s2,
4709 s2.location(site, types));
4710 }
4711
4712 /**
4713 * If multiple applicable methods are found during overload and none of them
4714 * is more specific than the others, attempt to merge their signatures.
4715 */
4716 Symbol mergeAbstracts(Type site) {
4717 List<Symbol> ambiguousInOrder = ambiguousSyms.reverse();
4718 return types.mergeAbstracts(ambiguousInOrder, site, true).orElse(this);
4719 }
4720
4721 @Override
|