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) {
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 {
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)
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) {
3799
3800 /**
3801 * Find a "valid" reference to an enclosing 'A.this' such that A is a subclass of the provided class symbol.
3802 * A reference to an enclosing 'A.this' is "valid" if (a) we're not in the early-construction context for A
3803 * and (b) if the current class is not an inner class of A.
3804 */
3805 Symbol findSelfContaining(DiagnosticPosition pos,
3806 Env<AttrContext> env,
3807 TypeSymbol c,
3808 boolean isSuper) {
3809 Env<AttrContext> env1 = isSuper ? env.outer : env;
3810 boolean staticOnly = false;
3811 while (env1.outer != null) {
3812 if (isStatic(env1)) staticOnly = true;
3813 if (env1.enclClass.sym.isSubClass(c, types)) {
3814 Symbol sym = env1.info.scope.findFirst(names._this);
3815 if (sym != null) {
3816 if (staticOnly) {
3817 // current class is not an inner class, stop search
3818 return new StaticError(sym);
3819 } else if (env1.info.ctorPrologue && !isAllowedEarlyReference(pos, env1, (VarSymbol)sym)) {
3820 // early construction context, stop search
3821 return new RefBeforeCtorCalledError(sym);
3822 } else {
3823 // found it
3824 return sym;
3825 }
3826 }
3827 }
3828 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
3829 env1 = env1.outer;
3830 }
3831 return varNotFound;
3832 }
3833
3834 /**
3835 * Resolve the (method) owner of a local class. This can fail if the local class
3836 * is referenced from a static context nested inside the local class. Effectively,
3837 * this lookup succeeds if we can access a local variable declared inside the owner
3838 * method from the provided env.
3839 */
3840 Symbol findLocalClassOwner(Env<AttrContext> env, TypeSymbol c) {
3841 Symbol owner = c.owner;
3864 * @param pos The position to use for error reporting.
3865 * @param env The environment current at the expression.
3866 * @param c The type of the selected expression
3867 * @param tree The expression
3868 */
3869 Symbol resolveSelf(DiagnosticPosition pos,
3870 Env<AttrContext> env,
3871 TypeSymbol c,
3872 JCFieldAccess tree) {
3873 Name name = tree.name;
3874 Assert.check(name == names._this || name == names._super);
3875 Env<AttrContext> env1 = env;
3876 boolean staticOnly = false;
3877 while (env1.outer != null) {
3878 if (isStatic(env1)) staticOnly = true;
3879 if (env1.enclClass.sym == c) {
3880 Symbol sym = env1.info.scope.findFirst(name);
3881 if (sym != null) {
3882 if (staticOnly)
3883 sym = new StaticError(sym);
3884 else if (env1.info.ctorPrologue &&
3885 !isReceiverParameter(env, tree) &&
3886 !isAllowedEarlyReference(pos, env1, (VarSymbol)sym))
3887 sym = new RefBeforeCtorCalledError(sym);
3888 return accessBase(sym, pos, env.enclClass.sym.type,
3889 name, true);
3890 }
3891 }
3892 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
3893 env1 = env1.outer;
3894 }
3895 if (c.isInterface() &&
3896 name == names._super && !isStatic(env) &&
3897 types.isDirectSuperInterface(c, env.enclClass.sym)) {
3898 //this might be a default super call if one of the superinterfaces is 'c'
3899 for (Type t : pruneInterfaces(env.enclClass.type)) {
3900 if (t.tsym == c) {
3901 if (env.info.ctorPrologue)
3902 log.error(pos, Errors.CantRefBeforeCtorCalled(name));
3903 env.info.defaultSuperCallSite = t;
3904 return new VarSymbol(0, names._super,
3905 types.asSuper(env.enclClass.type, c), env.enclClass.sym);
3906 }
3907 }
3908 //find a direct supertype that is a subtype of 'c'
3909 for (Type i : types.directSupertypes(env.enclClass.type)) {
3910 if (i.tsym.isSubClass(c, types) && i.tsym != c) {
3911 log.error(pos,
3912 Errors.IllegalDefaultSuperCall(c,
3913 Fragments.RedundantSupertype(c, i)));
3914 return syms.errSymbol;
3915 }
3916 }
3917 Assert.error();
3918 }
3919 log.error(pos, Errors.NotEnclClass(c));
3920 return syms.errSymbol;
3921 }
3922 //where
3923 private List<Type> pruneInterfaces(Type t) {
3924 ListBuffer<Type> result = new ListBuffer<>();
3925 for (Type t1 : types.interfaces(t)) {
3926 boolean shouldAdd = true;
3927 for (Type t2 : types.directSupertypes(t)) {
3928 if (t1 != t2 && !t2.hasTag(ERROR) && types.isSubtypeNoCapture(t2, t1)) {
3929 shouldAdd = false;
3930 }
3931 }
3932 if (shouldAdd) {
3933 result.append(t1);
3934 }
3935 }
3936 return result.toList();
3937 }
3938 private boolean isReceiverParameter(Env<AttrContext> env, JCFieldAccess tree) {
3939 if (env.tree.getTag() != METHODDEF)
3940 return false;
3941 JCMethodDecl method = (JCMethodDecl)env.tree;
3942 return method.recvparam != null && tree == method.recvparam.nameexpr;
3943 }
3944
3945 /**
3946 * Determine if an early instance field reference may appear in a constructor prologue.
3947 *
3948 * <p>
3949 * This is only allowed when:
3950 * - The field is being assigned a value (i.e., written but not read)
3951 * - The field is not inherited from a superclass
3952 * - The assignment is not within a lambda, because that would require
3953 * capturing 'this' which is not allowed prior to super().
3954 *
3955 * <p>
3956 * Note, this method doesn't catch all such scenarios, because this method
3957 * is invoked for symbol "x" only for "x = 42" but not for "this.x = 42".
3958 * We also don't verify that the field has no initializer, which is required.
3959 * To catch those cases, we rely on similar logic in Attr.checkAssignable().
3960 */
3961 private boolean isAllowedEarlyReference(DiagnosticPosition pos, Env<AttrContext> env, VarSymbol v) {
3962
3963 // Check assumptions
3964 Assert.check(env.info.ctorPrologue);
3965 Assert.check((v.flags_field & STATIC) == 0);
3966
3967 // The symbol must appear in the LHS of an assignment statement
3968 if (!(env.tree instanceof JCAssign assign))
3969 return false;
3970
3971 // The assignment statement must not be within a lambda
3972 if (env.info.isLambda)
3973 return false;
3974
3975 // Get the symbol's qualifier, if any
3976 JCExpression lhs = TreeInfo.skipParens(assign.lhs);
3977 JCExpression base;
3978 switch (lhs.getTag()) {
3979 case IDENT:
3980 base = null;
3981 break;
3982 case SELECT:
3983 JCFieldAccess select = (JCFieldAccess)lhs;
3984 base = select.selected;
3985 if (!TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, base))
3986 return false;
3987 break;
3988 default:
3989 return false;
3990 }
3991
3992 // If an early reference, the field must not be declared in a superclass
3993 if (isEarlyReference(env, base, v) && v.owner != env.enclClass.sym)
3994 return false;
3995
3996 // The flexible constructors feature must be enabled
3997 preview.checkSourceLevel(pos, Feature.FLEXIBLE_CONSTRUCTORS);
3998
3999 // OK
4000 return true;
4001 }
4002
4003 /**
4004 * Determine if the variable appearance constitutes an early reference to the current class.
4005 *
4006 * <p>
4007 * This means the variable is an instance field of the current class and it appears
4008 * in an early initialization context of it (i.e., one of its constructor prologues).
4009 *
4010 * <p>
4011 * Such a reference is only allowed for assignments to non-initialized fields that are
4012 * not inherited from a superclass, though that is not enforced by this method.
4013 *
4014 * @param env The current environment
4015 * @param base Variable qualifier, if any, otherwise null
4016 * @param v The variable
4017 */
4018 public boolean isEarlyReference(Env<AttrContext> env, JCTree base, VarSymbol v) {
4019 if (env.info.ctorPrologue &&
4020 (v.flags() & STATIC) == 0 &&
4021 v.isMemberOf(env.enclClass.sym, types)) {
4022
4023 // Allow "Foo.this.x" when "Foo" is (also) an outer class, as this refers to the outer instance
4024 if (base != null) {
4025 return TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, base);
4026 }
4027
4028 // It's an early reference to an instance field member of the current instance
4029 return true;
4030 }
4031 return false;
4032 }
4033
4034 /* ***************************************************************************
4035 * ResolveError classes, indicating error situations when accessing symbols
4036 ****************************************************************************/
4037
4038 //used by TransTypes when checking target type of synthetic cast
4039 public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) {
4040 AccessError error = new AccessError(env, env.enclClass.type, type.tsym);
4041 logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null);
4042 }
4043 //where
4044 private void logResolveError(ResolveError error,
4045 DiagnosticPosition pos,
4046 Symbol location,
4047 Type site,
4048 Name name,
4049 List<Type> argtypes,
4050 List<Type> typeargtypes) {
4051 JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
4052 pos, location, site, name, argtypes, typeargtypes);
4322 List<Type> argtypes,
4323 List<Type> typeargtypes) {
4324 if (name == names.error)
4325 return null;
4326
4327 Pair<Symbol, JCDiagnostic> c = errCandidate();
4328 Symbol ws = c.fst.asMemberOf(site, types);
4329 UnaryOperator<JCDiagnostic> rewriter = compactMethodDiags ?
4330 d -> MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, c.snd) : null;
4331
4332 // If the problem is due to type arguments, then the method parameters aren't relevant,
4333 // so use the error message that omits them to avoid confusion.
4334 switch (c.snd.getCode()) {
4335 case "compiler.misc.wrong.number.type.args":
4336 case "compiler.misc.explicit.param.do.not.conform.to.bounds":
4337 return diags.create(dkind, log.currentSource(), pos,
4338 "cant.apply.symbol.noargs",
4339 rewriter,
4340 kindName(ws),
4341 ws.name == names.init ? ws.owner.name : ws.name,
4342 kindName(ws.owner),
4343 ws.owner.type,
4344 c.snd);
4345 default:
4346 // Avoid saying "constructor Array in class Array"
4347 if (ws.owner == syms.arrayClass && ws.name == names.init) {
4348 return diags.create(dkind, log.currentSource(), pos,
4349 "cant.apply.array.ctor",
4350 rewriter,
4351 methodArguments(ws.type.getParameterTypes()),
4352 methodArguments(argtypes),
4353 c.snd);
4354 }
4355 return diags.create(dkind, log.currentSource(), pos,
4356 "cant.apply.symbol",
4357 rewriter,
4358 kindName(ws),
4359 ws.name == names.init ? ws.owner.name : ws.name,
4360 methodArguments(ws.type.getParameterTypes()),
4361 methodArguments(argtypes),
4362 kindName(ws.owner),
5223 final MethodResolutionPhase step;
5224 final Symbol sym;
5225 final JCDiagnostic details;
5226 final Type mtype;
5227
5228 private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) {
5229 this.step = step;
5230 this.sym = sym;
5231 this.details = details;
5232 this.mtype = mtype;
5233 }
5234
5235 boolean isApplicable() {
5236 return mtype != null;
5237 }
5238 }
5239
5240 DeferredAttr.AttrMode attrMode() {
5241 return attrMode;
5242 }
5243
5244 boolean internal() {
5245 return internalResolution;
5246 }
5247 }
5248
5249 MethodResolutionContext currentResolutionContext = null;
5250 }
|
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 private final LocalProxyVarsGen localProxyVarsGen;
119
120 WriteableScope polymorphicSignatureScope;
121
122 @SuppressWarnings("this-escape")
123 protected Resolve(Context context) {
124 context.put(resolveKey, this);
125 syms = Symtab.instance(context);
126
127 varNotFound = new SymbolNotFoundError(ABSENT_VAR);
128 methodNotFound = new SymbolNotFoundError(ABSENT_MTH);
129 typeNotFound = new SymbolNotFoundError(ABSENT_TYP);
130 referenceNotFound = ReferenceLookupResult.error(methodNotFound);
131
132 names = Names.instance(context);
133 log = Log.instance(context);
134 attr = Attr.instance(context);
135 attrRecover = AttrRecover.instance(context);
136 deferredAttr = DeferredAttr.instance(context);
137 chk = Check.instance(context);
138 infer = Infer.instance(context);
139 finder = ClassFinder.instance(context);
140 moduleFinder = ModuleFinder.instance(context);
141 types = Types.instance(context);
142 diags = JCDiagnostic.Factory.instance(context);
143 preview = Preview.instance(context);
144 Source source = Source.instance(context);
145 Options options = Options.instance(context);
146 compactMethodDiags = options.isSet(Option.XDIAGS, "compact") ||
147 options.isUnset(Option.XDIAGS) && options.isUnset("rawDiagnostics");
148 verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
149 Target target = Target.instance(context);
150 allowLocalVariableTypeInference = Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source);
151 allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source);
152 allowPrivateMembersInPermitsClause = Feature.PRIVATE_MEMBERS_IN_PERMITS_CLAUSE.allowedInSource(source);
153 polymorphicSignatureScope = WriteableScope.create(syms.noSymbol);
154 allowModules = Feature.MODULES.allowedInSource(source);
155 allowRecords = Feature.RECORDS.allowedInSource(source);
156 dumpMethodReferenceSearchResults = options.isSet("debug.dumpMethodReferenceSearchResults");
157 dumpStacktraceOnError = options.isSet("dev") || options.isSet(DOE);
158 localProxyVarsGen = LocalProxyVarsGen.instance(context);
159 }
160
161 /** error symbols, which are returned when resolution fails
162 */
163 private final SymbolNotFoundError varNotFound;
164 private final SymbolNotFoundError methodNotFound;
165 private final SymbolNotFoundError typeNotFound;
166
167 /** empty reference lookup result */
168 private final ReferenceLookupResult referenceNotFound;
169
170 public static Resolve instance(Context context) {
171 Resolve instance = context.get(resolveKey);
172 if (instance == null)
173 instance = new Resolve(context);
174 return instance;
175 }
176
177 private static Symbol bestOf(Symbol s1,
178 Symbol s2) {
406 * as a member.
407 * @param sym The symbol.
408 */
409 public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym) {
410 return isAccessible(env, site, sym, false);
411 }
412 public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym, boolean checkInner) {
413 if (sym.name == names.init && sym.owner != site.tsym) return false;
414
415 /* 15.9.5.1: Note that it is possible for the signature of the anonymous constructor
416 to refer to an inaccessible type
417 */
418 if (env.enclMethod != null && (env.enclMethod.mods.flags & ANONCONSTR) != 0)
419 return true;
420
421 if (env.info.visitingServiceImplementation &&
422 env.toplevel.modle == sym.packge().modle) {
423 return true;
424 }
425
426 ClassSymbol enclosingCsym = env.enclClass.sym;
427 try {
428 switch ((short)(sym.flags() & AccessFlags)) {
429 case PRIVATE:
430 return
431 (env.enclClass.sym == sym.owner // fast special case
432 ||
433 env.enclClass.sym.outermostClass() ==
434 sym.owner.outermostClass()
435 ||
436 privateMemberInPermitsClauseIfAllowed(env, sym))
437 &&
438 sym.isInheritedIn(site.tsym, types);
439 case 0:
440 return
441 (env.toplevel.packge == sym.owner.owner // fast special case
442 ||
443 env.toplevel.packge == sym.packge())
444 &&
445 isAccessible(env, site, checkInner)
446 &&
447 sym.isInheritedIn(site.tsym, types)
448 &&
449 notOverriddenIn(site, sym);
450 case PROTECTED:
451 return
452 (env.toplevel.packge == sym.owner.owner // fast special case
453 ||
454 env.toplevel.packge == sym.packge()
455 ||
456 isProtectedAccessible(sym, env.enclClass.sym, site)
457 ||
458 // OK to select instance method or field from 'super' or type name
459 // (but type names should be disallowed elsewhere!)
460 env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP)
461 &&
462 isAccessible(env, site, checkInner)
463 &&
464 notOverriddenIn(site, sym);
465 default: // this case includes erroneous combinations as well
466 return isAccessible(env, site, checkInner) && notOverriddenIn(site, sym);
467 }
468 } finally {
469 env.enclClass.sym = enclosingCsym;
470 }
471 }
472
473 private boolean privateMemberInPermitsClauseIfAllowed(Env<AttrContext> env, Symbol sym) {
474 return allowPrivateMembersInPermitsClause &&
475 env.info.isPermitsClause &&
476 ((JCClassDecl) env.tree).sym.outermostClass() == sym.owner.outermostClass();
477 }
478
479 //where
480 /* `sym' is accessible only if not overridden by
481 * another symbol which is a member of `site'
482 * (because, if it is overridden, `sym' is not strictly
483 * speaking a member of `site'). A polymorphic signature method
484 * cannot be overridden (e.g. MH.invokeExact(Object[])).
485 */
486 private boolean notOverriddenIn(Type site, Symbol sym) {
487 if (sym.kind != MTH || sym.isConstructor() || sym.isStatic())
488 return true;
489 else {
1520 Symbol sym = null;
1521 for (Symbol s : env1.info.scope.getSymbolsByName(name)) {
1522 if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) {
1523 sym = s;
1524 if (staticOnly) {
1525 return new StaticError(sym);
1526 }
1527 break;
1528 }
1529 }
1530 if (isStatic(env1)) staticOnly = true;
1531 if (sym == null) {
1532 sym = findField(env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
1533 }
1534 if (sym.exists()) {
1535 if (sym.kind == VAR &&
1536 sym.owner.kind == TYP &&
1537 (sym.flags() & STATIC) == 0) {
1538 if (staticOnly)
1539 return new StaticError(sym);
1540 }
1541 return sym;
1542 } else {
1543 bestSoFar = bestOf(bestSoFar, sym);
1544 }
1545
1546 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
1547 env1 = env1.outer;
1548 }
1549
1550 Symbol sym = findField(env, syms.predefClass.type, name, syms.predefClass);
1551 if (sym.exists())
1552 return sym;
1553 if (bestSoFar.exists())
1554 return bestSoFar;
1555
1556 Symbol origin = null;
1557 for (Scope sc : new Scope[] { env.toplevel.namedImportScope, env.toplevel.starImportScope }) {
1558 for (Symbol currentSymbol : sc.getSymbolsByName(name)) {
1559 if (currentSymbol.kind != VAR)
2027 Symbol findFun(Env<AttrContext> env, Name name,
2028 List<Type> argtypes, List<Type> typeargtypes,
2029 boolean allowBoxing, boolean useVarargs) {
2030 Symbol bestSoFar = methodNotFound;
2031 Env<AttrContext> env1 = env;
2032 boolean staticOnly = false;
2033 while (env1.outer != null) {
2034 if (isStatic(env1)) staticOnly = true;
2035 Assert.check(env1.info.preferredTreeForDiagnostics == null);
2036 env1.info.preferredTreeForDiagnostics = env.tree;
2037 try {
2038 Symbol sym = findMethod(
2039 env1, env1.enclClass.sym.type, name, argtypes, typeargtypes,
2040 allowBoxing, useVarargs);
2041 if (sym.exists()) {
2042 if (sym.kind == MTH &&
2043 sym.owner.kind == TYP &&
2044 (sym.flags() & STATIC) == 0) {
2045 if (staticOnly)
2046 return new StaticError(sym);
2047 }
2048 return sym;
2049 } else {
2050 bestSoFar = bestOf(bestSoFar, sym);
2051 }
2052 } finally {
2053 env1.info.preferredTreeForDiagnostics = null;
2054 }
2055 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
2056 env1 = env1.outer;
2057 }
2058
2059 Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
2060 typeargtypes, allowBoxing, useVarargs);
2061 if (sym.exists())
2062 return sym;
2063
2064 for (Symbol currentSym : env.toplevel.namedImportScope.getSymbolsByName(name)) {
2065 Symbol origin = env.toplevel.namedImportScope.getOrigin(currentSym).owner;
2066 if (currentSym.kind == MTH) {
3802
3803 /**
3804 * Find a "valid" reference to an enclosing 'A.this' such that A is a subclass of the provided class symbol.
3805 * A reference to an enclosing 'A.this' is "valid" if (a) we're not in the early-construction context for A
3806 * and (b) if the current class is not an inner class of A.
3807 */
3808 Symbol findSelfContaining(DiagnosticPosition pos,
3809 Env<AttrContext> env,
3810 TypeSymbol c,
3811 boolean isSuper) {
3812 Env<AttrContext> env1 = isSuper ? env.outer : env;
3813 boolean staticOnly = false;
3814 while (env1.outer != null) {
3815 if (isStatic(env1)) staticOnly = true;
3816 if (env1.enclClass.sym.isSubClass(c, types)) {
3817 Symbol sym = env1.info.scope.findFirst(names._this);
3818 if (sym != null) {
3819 if (staticOnly) {
3820 // current class is not an inner class, stop search
3821 return new StaticError(sym);
3822 } else {
3823 // found it
3824 return sym;
3825 }
3826 }
3827 }
3828 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
3829 env1 = env1.outer;
3830 }
3831 return varNotFound;
3832 }
3833
3834 /**
3835 * Resolve the (method) owner of a local class. This can fail if the local class
3836 * is referenced from a static context nested inside the local class. Effectively,
3837 * this lookup succeeds if we can access a local variable declared inside the owner
3838 * method from the provided env.
3839 */
3840 Symbol findLocalClassOwner(Env<AttrContext> env, TypeSymbol c) {
3841 Symbol owner = c.owner;
3864 * @param pos The position to use for error reporting.
3865 * @param env The environment current at the expression.
3866 * @param c The type of the selected expression
3867 * @param tree The expression
3868 */
3869 Symbol resolveSelf(DiagnosticPosition pos,
3870 Env<AttrContext> env,
3871 TypeSymbol c,
3872 JCFieldAccess tree) {
3873 Name name = tree.name;
3874 Assert.check(name == names._this || name == names._super);
3875 Env<AttrContext> env1 = env;
3876 boolean staticOnly = false;
3877 while (env1.outer != null) {
3878 if (isStatic(env1)) staticOnly = true;
3879 if (env1.enclClass.sym == c) {
3880 Symbol sym = env1.info.scope.findFirst(name);
3881 if (sym != null) {
3882 if (staticOnly)
3883 sym = new StaticError(sym);
3884 return accessBase(sym, pos, env.enclClass.sym.type,
3885 name, true);
3886 }
3887 }
3888 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
3889 env1 = env1.outer;
3890 }
3891 if (c.isInterface() &&
3892 name == names._super && !isStatic(env) &&
3893 types.isDirectSuperInterface(c, env.enclClass.sym)) {
3894 //this might be a default super call if one of the superinterfaces is 'c'
3895 for (Type t : pruneInterfaces(env.enclClass.type)) {
3896 if (t.tsym == c) {
3897 env.info.defaultSuperCallSite = t;
3898 return new VarSymbol(0, names._super,
3899 types.asSuper(env.enclClass.type, c), env.enclClass.sym);
3900 }
3901 }
3902 //find a direct supertype that is a subtype of 'c'
3903 for (Type i : types.directSupertypes(env.enclClass.type)) {
3904 if (i.tsym.isSubClass(c, types) && i.tsym != c) {
3905 log.error(pos,
3906 Errors.IllegalDefaultSuperCall(c,
3907 Fragments.RedundantSupertype(c, i)));
3908 return syms.errSymbol;
3909 }
3910 }
3911 Assert.error();
3912 }
3913 log.error(pos, Errors.NotEnclClass(c));
3914 return syms.errSymbol;
3915 }
3916 //where
3917 private List<Type> pruneInterfaces(Type t) {
3918 ListBuffer<Type> result = new ListBuffer<>();
3919 for (Type t1 : types.interfaces(t)) {
3920 boolean shouldAdd = true;
3921 for (Type t2 : types.directSupertypes(t)) {
3922 if (t1 != t2 && !t2.hasTag(ERROR) && types.isSubtypeNoCapture(t2, t1)) {
3923 shouldAdd = false;
3924 }
3925 }
3926 if (shouldAdd) {
3927 result.append(t1);
3928 }
3929 }
3930 return result.toList();
3931 }
3932
3933 /* ***************************************************************************
3934 * ResolveError classes, indicating error situations when accessing symbols
3935 ****************************************************************************/
3936
3937 //used by TransTypes when checking target type of synthetic cast
3938 public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) {
3939 AccessError error = new AccessError(env, env.enclClass.type, type.tsym);
3940 logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null);
3941 }
3942 //where
3943 private void logResolveError(ResolveError error,
3944 DiagnosticPosition pos,
3945 Symbol location,
3946 Type site,
3947 Name name,
3948 List<Type> argtypes,
3949 List<Type> typeargtypes) {
3950 JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
3951 pos, location, site, name, argtypes, typeargtypes);
4221 List<Type> argtypes,
4222 List<Type> typeargtypes) {
4223 if (name == names.error)
4224 return null;
4225
4226 Pair<Symbol, JCDiagnostic> c = errCandidate();
4227 Symbol ws = c.fst.asMemberOf(site, types);
4228 UnaryOperator<JCDiagnostic> rewriter = compactMethodDiags ?
4229 d -> MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, c.snd) : null;
4230
4231 // If the problem is due to type arguments, then the method parameters aren't relevant,
4232 // so use the error message that omits them to avoid confusion.
4233 switch (c.snd.getCode()) {
4234 case "compiler.misc.wrong.number.type.args":
4235 case "compiler.misc.explicit.param.do.not.conform.to.bounds":
4236 return diags.create(dkind, log.currentSource(), pos,
4237 "cant.apply.symbol.noargs",
4238 rewriter,
4239 kindName(ws),
4240 ws.name == names.init ? ws.owner.name : ws.name,
4241 ws.owner.type,
4242 c.snd);
4243 default:
4244 // Avoid saying "constructor Array in class Array"
4245 if (ws.owner == syms.arrayClass && ws.name == names.init) {
4246 return diags.create(dkind, log.currentSource(), pos,
4247 "cant.apply.array.ctor",
4248 rewriter,
4249 methodArguments(ws.type.getParameterTypes()),
4250 methodArguments(argtypes),
4251 c.snd);
4252 }
4253 return diags.create(dkind, log.currentSource(), pos,
4254 "cant.apply.symbol",
4255 rewriter,
4256 kindName(ws),
4257 ws.name == names.init ? ws.owner.name : ws.name,
4258 methodArguments(ws.type.getParameterTypes()),
4259 methodArguments(argtypes),
4260 kindName(ws.owner),
5121 final MethodResolutionPhase step;
5122 final Symbol sym;
5123 final JCDiagnostic details;
5124 final Type mtype;
5125
5126 private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) {
5127 this.step = step;
5128 this.sym = sym;
5129 this.details = details;
5130 this.mtype = mtype;
5131 }
5132
5133 boolean isApplicable() {
5134 return mtype != null;
5135 }
5136 }
5137
5138 DeferredAttr.AttrMode attrMode() {
5139 return attrMode;
5140 }
5141 }
5142
5143 MethodResolutionContext currentResolutionContext = null;
5144 }
|