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) {
3803
3804 /**
3805 * Find a "valid" reference to an enclosing 'A.this' such that A is a subclass of the provided class symbol.
3806 * A reference to an enclosing 'A.this' is "valid" if (a) we're not in the early-construction context for A
3807 * and (b) if the current class is not an inner class of A.
3808 */
3809 Symbol findSelfContaining(DiagnosticPosition pos,
3810 Env<AttrContext> env,
3811 TypeSymbol c,
3812 boolean isSuper) {
3813 Env<AttrContext> env1 = isSuper ? env.outer : env;
3814 boolean staticOnly = false;
3815 while (env1.outer != null) {
3816 if (isStatic(env1)) staticOnly = true;
3817 if (env1.enclClass.sym.isSubClass(c, types)) {
3818 Symbol sym = env1.info.scope.findFirst(names._this);
3819 if (sym != null) {
3820 if (staticOnly) {
3821 // current class is not an inner class, stop search
3822 return new StaticError(sym);
3823 } else if (env1.info.ctorPrologue && !isAllowedEarlyReference(pos, env1, (VarSymbol)sym)) {
3824 // early construction context, stop search
3825 return new RefBeforeCtorCalledError(sym);
3826 } else {
3827 // found it
3828 return sym;
3829 }
3830 }
3831 }
3832 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
3833 env1 = env1.outer;
3834 }
3835 return varNotFound;
3836 }
3837
3838 /**
3839 * Resolve the (method) owner of a local class. This can fail if the local class
3840 * is referenced from a static context nested inside the local class. Effectively,
3841 * this lookup succeeds if we can access a local variable declared inside the owner
3842 * method from the provided env.
3843 */
3844 Symbol findLocalClassOwner(Env<AttrContext> env, TypeSymbol c) {
3845 Symbol owner = c.owner;
3868 * @param pos The position to use for error reporting.
3869 * @param env The environment current at the expression.
3870 * @param c The type of the selected expression
3871 * @param tree The expression
3872 */
3873 Symbol resolveSelf(DiagnosticPosition pos,
3874 Env<AttrContext> env,
3875 TypeSymbol c,
3876 JCFieldAccess tree) {
3877 Name name = tree.name;
3878 Assert.check(name == names._this || name == names._super);
3879 Env<AttrContext> env1 = env;
3880 boolean staticOnly = false;
3881 while (env1.outer != null) {
3882 if (isStatic(env1)) staticOnly = true;
3883 if (env1.enclClass.sym == c) {
3884 Symbol sym = env1.info.scope.findFirst(name);
3885 if (sym != null) {
3886 if (staticOnly)
3887 sym = new StaticError(sym);
3888 else if (env1.info.ctorPrologue &&
3889 !isReceiverParameter(env, tree) &&
3890 !isAllowedEarlyReference(pos, env1, (VarSymbol)sym))
3891 sym = new RefBeforeCtorCalledError(sym);
3892 return accessBase(sym, pos, env.enclClass.sym.type,
3893 name, true);
3894 }
3895 }
3896 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
3897 env1 = env1.outer;
3898 }
3899 if (c.isInterface() &&
3900 name == names._super && !isStatic(env) &&
3901 types.isDirectSuperInterface(c, env.enclClass.sym)) {
3902 //this might be a default super call if one of the superinterfaces is 'c'
3903 for (Type t : pruneInterfaces(env.enclClass.type)) {
3904 if (t.tsym == c) {
3905 if (env.info.ctorPrologue)
3906 log.error(pos, Errors.CantRefBeforeCtorCalled(name));
3907 env.info.defaultSuperCallSite = t;
3908 return new VarSymbol(0, names._super,
3909 types.asSuper(env.enclClass.type, c), env.enclClass.sym);
3910 }
3911 }
3912 //find a direct supertype that is a subtype of 'c'
3913 for (Type i : types.directSupertypes(env.enclClass.type)) {
3914 if (i.tsym.isSubClass(c, types) && i.tsym != c) {
3915 log.error(pos,
3916 Errors.IllegalDefaultSuperCall(c,
3917 Fragments.RedundantSupertype(c, i)));
3918 return syms.errSymbol;
3919 }
3920 }
3921 Assert.error();
3922 }
3923 log.error(pos, Errors.NotEnclClass(c));
3924 return syms.errSymbol;
3925 }
3926 //where
3927 private List<Type> pruneInterfaces(Type t) {
3928 ListBuffer<Type> result = new ListBuffer<>();
3929 for (Type t1 : types.interfaces(t)) {
3930 boolean shouldAdd = true;
3931 for (Type t2 : types.directSupertypes(t)) {
3932 if (t1 != t2 && !t2.hasTag(ERROR) && types.isSubtypeNoCapture(t2, t1)) {
3933 shouldAdd = false;
3934 }
3935 }
3936 if (shouldAdd) {
3937 result.append(t1);
3938 }
3939 }
3940 return result.toList();
3941 }
3942 private boolean isReceiverParameter(Env<AttrContext> env, JCFieldAccess tree) {
3943 if (env.tree.getTag() != METHODDEF)
3944 return false;
3945 JCMethodDecl method = (JCMethodDecl)env.tree;
3946 return method.recvparam != null && tree == method.recvparam.nameexpr;
3947 }
3948
3949 /**
3950 * Determine if an early instance field reference may appear in a constructor prologue.
3951 *
3952 * <p>
3953 * This is only allowed when:
3954 * - The field is being assigned a value (i.e., written but not read)
3955 * - The field is not inherited from a superclass
3956 * - The assignment is not within a lambda, because that would require
3957 * capturing 'this' which is not allowed prior to super().
3958 *
3959 * <p>
3960 * Note, this method doesn't catch all such scenarios, because this method
3961 * is invoked for symbol "x" only for "x = 42" but not for "this.x = 42".
3962 * We also don't verify that the field has no initializer, which is required.
3963 * To catch those cases, we rely on similar logic in Attr.checkAssignable().
3964 */
3965 private boolean isAllowedEarlyReference(DiagnosticPosition pos, Env<AttrContext> env, VarSymbol v) {
3966
3967 // Check assumptions
3968 Assert.check(env.info.ctorPrologue);
3969 Assert.check((v.flags_field & STATIC) == 0);
3970
3971 // The symbol must appear in the LHS of an assignment statement
3972 if (!(env.tree instanceof JCAssign assign))
3973 return false;
3974
3975 // The assignment statement must not be within a lambda
3976 if (env.info.isLambda)
3977 return false;
3978
3979 // Get the symbol's qualifier, if any
3980 JCExpression lhs = TreeInfo.skipParens(assign.lhs);
3981 JCExpression base;
3982 switch (lhs.getTag()) {
3983 case IDENT:
3984 base = null;
3985 break;
3986 case SELECT:
3987 JCFieldAccess select = (JCFieldAccess)lhs;
3988 base = select.selected;
3989 if (!TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, base))
3990 return false;
3991 break;
3992 default:
3993 return false;
3994 }
3995
3996 // If an early reference, the field must not be declared in a superclass
3997 if (isEarlyReference(env, base, v) && v.owner != env.enclClass.sym)
3998 return false;
3999
4000 // The flexible constructors feature must be enabled
4001 preview.checkSourceLevel(pos, Feature.FLEXIBLE_CONSTRUCTORS);
4002
4003 // OK
4004 return true;
4005 }
4006
4007 /**
4008 * Determine if the variable appearance constitutes an early reference to the current class.
4009 *
4010 * <p>
4011 * This means the variable is an instance field of the current class and it appears
4012 * in an early initialization context of it (i.e., one of its constructor prologues).
4013 *
4014 * <p>
4015 * Such a reference is only allowed for assignments to non-initialized fields that are
4016 * not inherited from a superclass, though that is not enforced by this method.
4017 *
4018 * @param env The current environment
4019 * @param base Variable qualifier, if any, otherwise null
4020 * @param v The variable
4021 */
4022 public boolean isEarlyReference(Env<AttrContext> env, JCTree base, VarSymbol v) {
4023 if (env.info.ctorPrologue &&
4024 (v.flags() & STATIC) == 0 &&
4025 v.isMemberOf(env.enclClass.sym, types)) {
4026
4027 // Allow "Foo.this.x" when "Foo" is (also) an outer class, as this refers to the outer instance
4028 if (base != null) {
4029 return TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, base);
4030 }
4031
4032 // It's an early reference to an instance field member of the current instance
4033 return true;
4034 }
4035 return false;
4036 }
4037
4038 /* ***************************************************************************
4039 * ResolveError classes, indicating error situations when accessing symbols
4040 ****************************************************************************/
4041
4042 //used by TransTypes when checking target type of synthetic cast
4043 public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) {
4044 AccessError error = new AccessError(env, env.enclClass.type, type.tsym);
4045 logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null);
4046 }
4047 //where
4048 private void logResolveError(ResolveError error,
4049 DiagnosticPosition pos,
4050 Symbol location,
4051 Type site,
4052 Name name,
4053 List<Type> argtypes,
4054 List<Type> typeargtypes) {
4055 JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
4056 pos, location, site, name, argtypes, typeargtypes);
4351 List<Type> argtypes,
4352 List<Type> typeargtypes) {
4353 if (name == names.error)
4354 return null;
4355
4356 Pair<Symbol, JCDiagnostic> c = errCandidate();
4357 Symbol ws = c.fst.asMemberOf(site, types);
4358 UnaryOperator<JCDiagnostic> rewriter = compactMethodDiags ?
4359 d -> MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, c.snd) : null;
4360
4361 // If the problem is due to type arguments, then the method parameters aren't relevant,
4362 // so use the error message that omits them to avoid confusion.
4363 switch (c.snd.getCode()) {
4364 case "compiler.misc.wrong.number.type.args":
4365 case "compiler.misc.explicit.param.do.not.conform.to.bounds":
4366 return diags.create(dkind, log.currentSource(), pos,
4367 "cant.apply.symbol.noargs",
4368 rewriter,
4369 kindName(ws),
4370 ws.name == names.init ? ws.owner.name : ws.name,
4371 kindName(ws.owner),
4372 ws.owner.type,
4373 c.snd);
4374 default:
4375 // Avoid saying "constructor Array in class Array"
4376 if (ws.owner == syms.arrayClass && ws.name == names.init) {
4377 return diags.create(dkind, log.currentSource(), pos,
4378 "cant.apply.array.ctor",
4379 rewriter,
4380 methodArguments(ws.type.getParameterTypes()),
4381 methodArguments(argtypes),
4382 c.snd);
4383 }
4384 return diags.create(dkind, log.currentSource(), pos,
4385 "cant.apply.symbol",
4386 rewriter,
4387 kindName(ws),
4388 ws.name == names.init ? ws.owner.name : ws.name,
4389 methodArguments(ws.type.getParameterTypes()),
4390 methodArguments(argtypes),
4391 kindName(ws.owner),
5252 final MethodResolutionPhase step;
5253 final Symbol sym;
5254 final JCDiagnostic details;
5255 final Type mtype;
5256
5257 private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) {
5258 this.step = step;
5259 this.sym = sym;
5260 this.details = details;
5261 this.mtype = mtype;
5262 }
5263
5264 boolean isApplicable() {
5265 return mtype != null;
5266 }
5267 }
5268
5269 DeferredAttr.AttrMode attrMode() {
5270 return attrMode;
5271 }
5272
5273 boolean internal() {
5274 return internalResolution;
5275 }
5276 }
5277
5278 MethodResolutionContext currentResolutionContext = null;
5279 }
|
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) {
3806
3807 /**
3808 * Find a "valid" reference to an enclosing 'A.this' such that A is a subclass of the provided class symbol.
3809 * A reference to an enclosing 'A.this' is "valid" if (a) we're not in the early-construction context for A
3810 * and (b) if the current class is not an inner class of A.
3811 */
3812 Symbol findSelfContaining(DiagnosticPosition pos,
3813 Env<AttrContext> env,
3814 TypeSymbol c,
3815 boolean isSuper) {
3816 Env<AttrContext> env1 = isSuper ? env.outer : env;
3817 boolean staticOnly = false;
3818 while (env1.outer != null) {
3819 if (isStatic(env1)) staticOnly = true;
3820 if (env1.enclClass.sym.isSubClass(c, types)) {
3821 Symbol sym = env1.info.scope.findFirst(names._this);
3822 if (sym != null) {
3823 if (staticOnly) {
3824 // current class is not an inner class, stop search
3825 return new StaticError(sym);
3826 } else {
3827 // found it
3828 return sym;
3829 }
3830 }
3831 }
3832 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
3833 env1 = env1.outer;
3834 }
3835 return varNotFound;
3836 }
3837
3838 /**
3839 * Resolve the (method) owner of a local class. This can fail if the local class
3840 * is referenced from a static context nested inside the local class. Effectively,
3841 * this lookup succeeds if we can access a local variable declared inside the owner
3842 * method from the provided env.
3843 */
3844 Symbol findLocalClassOwner(Env<AttrContext> env, TypeSymbol c) {
3845 Symbol owner = c.owner;
3868 * @param pos The position to use for error reporting.
3869 * @param env The environment current at the expression.
3870 * @param c The type of the selected expression
3871 * @param tree The expression
3872 */
3873 Symbol resolveSelf(DiagnosticPosition pos,
3874 Env<AttrContext> env,
3875 TypeSymbol c,
3876 JCFieldAccess tree) {
3877 Name name = tree.name;
3878 Assert.check(name == names._this || name == names._super);
3879 Env<AttrContext> env1 = env;
3880 boolean staticOnly = false;
3881 while (env1.outer != null) {
3882 if (isStatic(env1)) staticOnly = true;
3883 if (env1.enclClass.sym == c) {
3884 Symbol sym = env1.info.scope.findFirst(name);
3885 if (sym != null) {
3886 if (staticOnly)
3887 sym = new StaticError(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 env.info.defaultSuperCallSite = t;
3902 return new VarSymbol(0, names._super,
3903 types.asSuper(env.enclClass.type, c), env.enclClass.sym);
3904 }
3905 }
3906 //find a direct supertype that is a subtype of 'c'
3907 for (Type i : types.directSupertypes(env.enclClass.type)) {
3908 if (i.tsym.isSubClass(c, types) && i.tsym != c) {
3909 log.error(pos,
3910 Errors.IllegalDefaultSuperCall(c,
3911 Fragments.RedundantSupertype(c, i)));
3912 return syms.errSymbol;
3913 }
3914 }
3915 Assert.error();
3916 }
3917 log.error(pos, Errors.NotEnclClass(c));
3918 return syms.errSymbol;
3919 }
3920 //where
3921 private List<Type> pruneInterfaces(Type t) {
3922 ListBuffer<Type> result = new ListBuffer<>();
3923 for (Type t1 : types.interfaces(t)) {
3924 boolean shouldAdd = true;
3925 for (Type t2 : types.directSupertypes(t)) {
3926 if (t1 != t2 && !t2.hasTag(ERROR) && types.isSubtypeNoCapture(t2, t1)) {
3927 shouldAdd = false;
3928 }
3929 }
3930 if (shouldAdd) {
3931 result.append(t1);
3932 }
3933 }
3934 return result.toList();
3935 }
3936
3937 /* ***************************************************************************
3938 * ResolveError classes, indicating error situations when accessing symbols
3939 ****************************************************************************/
3940
3941 //used by TransTypes when checking target type of synthetic cast
3942 public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) {
3943 AccessError error = new AccessError(env, env.enclClass.type, type.tsym);
3944 logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null);
3945 }
3946 //where
3947 private void logResolveError(ResolveError error,
3948 DiagnosticPosition pos,
3949 Symbol location,
3950 Type site,
3951 Name name,
3952 List<Type> argtypes,
3953 List<Type> typeargtypes) {
3954 JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
3955 pos, location, site, name, argtypes, typeargtypes);
4250 List<Type> argtypes,
4251 List<Type> typeargtypes) {
4252 if (name == names.error)
4253 return null;
4254
4255 Pair<Symbol, JCDiagnostic> c = errCandidate();
4256 Symbol ws = c.fst.asMemberOf(site, types);
4257 UnaryOperator<JCDiagnostic> rewriter = compactMethodDiags ?
4258 d -> MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, c.snd) : null;
4259
4260 // If the problem is due to type arguments, then the method parameters aren't relevant,
4261 // so use the error message that omits them to avoid confusion.
4262 switch (c.snd.getCode()) {
4263 case "compiler.misc.wrong.number.type.args":
4264 case "compiler.misc.explicit.param.do.not.conform.to.bounds":
4265 return diags.create(dkind, log.currentSource(), pos,
4266 "cant.apply.symbol.noargs",
4267 rewriter,
4268 kindName(ws),
4269 ws.name == names.init ? ws.owner.name : ws.name,
4270 ws.owner.type,
4271 c.snd);
4272 default:
4273 // Avoid saying "constructor Array in class Array"
4274 if (ws.owner == syms.arrayClass && ws.name == names.init) {
4275 return diags.create(dkind, log.currentSource(), pos,
4276 "cant.apply.array.ctor",
4277 rewriter,
4278 methodArguments(ws.type.getParameterTypes()),
4279 methodArguments(argtypes),
4280 c.snd);
4281 }
4282 return diags.create(dkind, log.currentSource(), pos,
4283 "cant.apply.symbol",
4284 rewriter,
4285 kindName(ws),
4286 ws.name == names.init ? ws.owner.name : ws.name,
4287 methodArguments(ws.type.getParameterTypes()),
4288 methodArguments(argtypes),
4289 kindName(ws.owner),
5150 final MethodResolutionPhase step;
5151 final Symbol sym;
5152 final JCDiagnostic details;
5153 final Type mtype;
5154
5155 private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) {
5156 this.step = step;
5157 this.sym = sym;
5158 this.details = details;
5159 this.mtype = mtype;
5160 }
5161
5162 boolean isApplicable() {
5163 return mtype != null;
5164 }
5165 }
5166
5167 DeferredAttr.AttrMode attrMode() {
5168 return attrMode;
5169 }
5170 }
5171
5172 MethodResolutionContext currentResolutionContext = null;
5173 }
|