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) {
3794
3795 /**
3796 * Find a "valid" reference to an enclosing 'A.this' such that A is a subclass of the provided class symbol.
3797 * A reference to an enclosing 'A.this' is "valid" if (a) we're not in the early-construction context for A
3798 * and (b) if the current class is not an inner class of A.
3799 */
3800 Symbol findSelfContaining(DiagnosticPosition pos,
3801 Env<AttrContext> env,
3802 TypeSymbol c,
3803 boolean isSuper) {
3804 Env<AttrContext> env1 = isSuper ? env.outer : env;
3805 boolean staticOnly = false;
3806 while (env1.outer != null) {
3807 if (isStatic(env1)) staticOnly = true;
3808 if (env1.enclClass.sym.isSubClass(c, types)) {
3809 Symbol sym = env1.info.scope.findFirst(names._this);
3810 if (sym != null) {
3811 if (staticOnly) {
3812 // current class is not an inner class, stop search
3813 return new StaticError(sym);
3814 } else if (env1.info.ctorPrologue && !isAllowedEarlyReference(pos, env1, (VarSymbol)sym)) {
3815 // early construction context, stop search
3816 return new RefBeforeCtorCalledError(sym);
3817 } else {
3818 // found it
3819 return sym;
3820 }
3821 }
3822 }
3823 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
3824 env1 = env1.outer;
3825 }
3826 return varNotFound;
3827 }
3828
3829 /**
3830 * Resolve the (method) owner of a local class. This can fail if the local class
3831 * is referenced from a static context nested inside the local class. Effectively,
3832 * this lookup succeeds if we can access a local variable declared inside the owner
3833 * method from the provided env.
3834 */
3835 Symbol findLocalClassOwner(Env<AttrContext> env, TypeSymbol c) {
3836 Symbol owner = c.owner;
3856 * @param pos The position to use for error reporting.
3857 * @param env The environment current at the expression.
3858 * @param c The type of the selected expression
3859 * @param tree The expression
3860 */
3861 Symbol resolveSelf(DiagnosticPosition pos,
3862 Env<AttrContext> env,
3863 TypeSymbol c,
3864 JCFieldAccess tree) {
3865 Name name = tree.name;
3866 Assert.check(name == names._this || name == names._super);
3867 Env<AttrContext> env1 = env;
3868 boolean staticOnly = false;
3869 while (env1.outer != null) {
3870 if (isStatic(env1)) staticOnly = true;
3871 if (env1.enclClass.sym == c) {
3872 Symbol sym = env1.info.scope.findFirst(name);
3873 if (sym != null) {
3874 if (staticOnly)
3875 sym = new StaticError(sym);
3876 else if (env1.info.ctorPrologue &&
3877 !isReceiverParameter(env, tree) &&
3878 !isAllowedEarlyReference(pos, env1, (VarSymbol)sym))
3879 sym = new RefBeforeCtorCalledError(sym);
3880 return accessBase(sym, pos, env.enclClass.sym.type,
3881 name, true);
3882 }
3883 }
3884 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
3885 env1 = env1.outer;
3886 }
3887 if (c.isInterface() &&
3888 name == names._super && !isStatic(env) &&
3889 types.isDirectSuperInterface(c, env.enclClass.sym)) {
3890 //this might be a default super call if one of the superinterfaces is 'c'
3891 for (Type t : pruneInterfaces(env.enclClass.type)) {
3892 if (t.tsym == c) {
3893 if (env.info.ctorPrologue)
3894 log.error(pos, Errors.CantRefBeforeCtorCalled(name));
3895 env.info.defaultSuperCallSite = t;
3896 return new VarSymbol(0, names._super,
3897 types.asSuper(env.enclClass.type, c), env.enclClass.sym);
3898 }
3899 }
3900 //find a direct supertype that is a subtype of 'c'
3901 for (Type i : types.directSupertypes(env.enclClass.type)) {
3902 if (i.tsym.isSubClass(c, types) && i.tsym != c) {
3903 log.error(pos,
3904 Errors.IllegalDefaultSuperCall(c,
3905 Fragments.RedundantSupertype(c, i)));
3906 return syms.errSymbol;
3907 }
3908 }
3909 Assert.error();
3910 }
3911 log.error(pos, Errors.NotEnclClass(c));
3912 return syms.errSymbol;
3913 }
3914 //where
3915 private List<Type> pruneInterfaces(Type t) {
3916 ListBuffer<Type> result = new ListBuffer<>();
3917 for (Type t1 : types.interfaces(t)) {
3918 boolean shouldAdd = true;
3919 for (Type t2 : types.directSupertypes(t)) {
3920 if (t1 != t2 && !t2.hasTag(ERROR) && types.isSubtypeNoCapture(t2, t1)) {
3921 shouldAdd = false;
3922 }
3923 }
3924 if (shouldAdd) {
3925 result.append(t1);
3926 }
3927 }
3928 return result.toList();
3929 }
3930 private boolean isReceiverParameter(Env<AttrContext> env, JCFieldAccess tree) {
3931 if (env.tree.getTag() != METHODDEF)
3932 return false;
3933 JCMethodDecl method = (JCMethodDecl)env.tree;
3934 return method.recvparam != null && tree == method.recvparam.nameexpr;
3935 }
3936
3937 /**
3938 * Determine if an early instance field reference may appear in a constructor prologue.
3939 *
3940 * <p>
3941 * This is only allowed when:
3942 * - The field is being assigned a value (i.e., written but not read)
3943 * - The field is not inherited from a superclass
3944 * - The assignment is not within a lambda, because that would require
3945 * capturing 'this' which is not allowed prior to super().
3946 *
3947 * <p>
3948 * Note, this method doesn't catch all such scenarios, because this method
3949 * is invoked for symbol "x" only for "x = 42" but not for "this.x = 42".
3950 * We also don't verify that the field has no initializer, which is required.
3951 * To catch those cases, we rely on similar logic in Attr.checkAssignable().
3952 */
3953 private boolean isAllowedEarlyReference(DiagnosticPosition pos, Env<AttrContext> env, VarSymbol v) {
3954
3955 // Check assumptions
3956 Assert.check(env.info.ctorPrologue);
3957 Assert.check((v.flags_field & STATIC) == 0);
3958
3959 // The symbol must appear in the LHS of an assignment statement
3960 if (!(env.tree instanceof JCAssign assign))
3961 return false;
3962
3963 // The assignment statement must not be within a lambda
3964 if (env.info.isLambda)
3965 return false;
3966
3967 // Get the symbol's qualifier, if any
3968 JCExpression lhs = TreeInfo.skipParens(assign.lhs);
3969 JCExpression base;
3970 switch (lhs.getTag()) {
3971 case IDENT:
3972 base = null;
3973 break;
3974 case SELECT:
3975 JCFieldAccess select = (JCFieldAccess)lhs;
3976 base = select.selected;
3977 if (!TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, base))
3978 return false;
3979 break;
3980 default:
3981 return false;
3982 }
3983
3984 // If an early reference, the field must not be declared in a superclass
3985 if (isEarlyReference(env, base, v) && v.owner != env.enclClass.sym)
3986 return false;
3987
3988 // The flexible constructors feature must be enabled
3989 preview.checkSourceLevel(pos, Feature.FLEXIBLE_CONSTRUCTORS);
3990
3991 // OK
3992 return true;
3993 }
3994
3995 /**
3996 * Determine if the variable appearance constitutes an early reference to the current class.
3997 *
3998 * <p>
3999 * This means the variable is an instance field of the current class and it appears
4000 * in an early initialization context of it (i.e., one of its constructor prologues).
4001 *
4002 * <p>
4003 * Such a reference is only allowed for assignments to non-initialized fields that are
4004 * not inherited from a superclass, though that is not enforced by this method.
4005 *
4006 * @param env The current environment
4007 * @param base Variable qualifier, if any, otherwise null
4008 * @param v The variable
4009 */
4010 public boolean isEarlyReference(Env<AttrContext> env, JCTree base, VarSymbol v) {
4011 if (env.info.ctorPrologue &&
4012 (v.flags() & STATIC) == 0 &&
4013 v.isMemberOf(env.enclClass.sym, types)) {
4014
4015 // Allow "Foo.this.x" when "Foo" is (also) an outer class, as this refers to the outer instance
4016 if (base != null) {
4017 return TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, base);
4018 }
4019
4020 // It's an early reference to an instance field member of the current instance
4021 return true;
4022 }
4023 return false;
4024 }
4025
4026 /* ***************************************************************************
4027 * ResolveError classes, indicating error situations when accessing symbols
4028 ****************************************************************************/
4029
4030 //used by TransTypes when checking target type of synthetic cast
4031 public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) {
4032 AccessError error = new AccessError(env, env.enclClass.type, type.tsym);
4033 logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null);
4034 }
4035 //where
4036 private void logResolveError(ResolveError error,
4037 DiagnosticPosition pos,
4038 Symbol location,
4039 Type site,
4040 Name name,
4041 List<Type> argtypes,
4042 List<Type> typeargtypes) {
4043 JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
4044 pos, location, site, name, argtypes, typeargtypes);
4314 List<Type> argtypes,
4315 List<Type> typeargtypes) {
4316 if (name == names.error)
4317 return null;
4318
4319 Pair<Symbol, JCDiagnostic> c = errCandidate();
4320 Symbol ws = c.fst.asMemberOf(site, types);
4321 UnaryOperator<JCDiagnostic> rewriter = compactMethodDiags ?
4322 d -> MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, c.snd) : null;
4323
4324 // If the problem is due to type arguments, then the method parameters aren't relevant,
4325 // so use the error message that omits them to avoid confusion.
4326 switch (c.snd.getCode()) {
4327 case "compiler.misc.wrong.number.type.args":
4328 case "compiler.misc.explicit.param.do.not.conform.to.bounds":
4329 return diags.create(dkind, log.currentSource(), pos,
4330 "cant.apply.symbol.noargs",
4331 rewriter,
4332 kindName(ws),
4333 ws.name == names.init ? ws.owner.name : ws.name,
4334 kindName(ws.owner),
4335 ws.owner.type,
4336 c.snd);
4337 default:
4338 // Avoid saying "constructor Array in class Array"
4339 if (ws.owner == syms.arrayClass && ws.name == names.init) {
4340 return diags.create(dkind, log.currentSource(), pos,
4341 "cant.apply.array.ctor",
4342 rewriter,
4343 methodArguments(ws.type.getParameterTypes()),
4344 methodArguments(argtypes),
4345 c.snd);
4346 }
4347 return diags.create(dkind, log.currentSource(), pos,
4348 "cant.apply.symbol",
4349 rewriter,
4350 kindName(ws),
4351 ws.name == names.init ? ws.owner.name : ws.name,
4352 methodArguments(ws.type.getParameterTypes()),
4353 methodArguments(argtypes),
4354 kindName(ws.owner),
5215 final MethodResolutionPhase step;
5216 final Symbol sym;
5217 final JCDiagnostic details;
5218 final Type mtype;
5219
5220 private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) {
5221 this.step = step;
5222 this.sym = sym;
5223 this.details = details;
5224 this.mtype = mtype;
5225 }
5226
5227 boolean isApplicable() {
5228 return mtype != null;
5229 }
5230 }
5231
5232 DeferredAttr.AttrMode attrMode() {
5233 return attrMode;
5234 }
5235
5236 boolean internal() {
5237 return internalResolution;
5238 }
5239 }
5240
5241 MethodResolutionContext currentResolutionContext = null;
5242 }
|
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) {
3797
3798 /**
3799 * Find a "valid" reference to an enclosing 'A.this' such that A is a subclass of the provided class symbol.
3800 * A reference to an enclosing 'A.this' is "valid" if (a) we're not in the early-construction context for A
3801 * and (b) if the current class is not an inner class of A.
3802 */
3803 Symbol findSelfContaining(DiagnosticPosition pos,
3804 Env<AttrContext> env,
3805 TypeSymbol c,
3806 boolean isSuper) {
3807 Env<AttrContext> env1 = isSuper ? env.outer : env;
3808 boolean staticOnly = false;
3809 while (env1.outer != null) {
3810 if (isStatic(env1)) staticOnly = true;
3811 if (env1.enclClass.sym.isSubClass(c, types)) {
3812 Symbol sym = env1.info.scope.findFirst(names._this);
3813 if (sym != null) {
3814 if (staticOnly) {
3815 // current class is not an inner class, stop search
3816 return new StaticError(sym);
3817 } else {
3818 // found it
3819 return sym;
3820 }
3821 }
3822 }
3823 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
3824 env1 = env1.outer;
3825 }
3826 return varNotFound;
3827 }
3828
3829 /**
3830 * Resolve the (method) owner of a local class. This can fail if the local class
3831 * is referenced from a static context nested inside the local class. Effectively,
3832 * this lookup succeeds if we can access a local variable declared inside the owner
3833 * method from the provided env.
3834 */
3835 Symbol findLocalClassOwner(Env<AttrContext> env, TypeSymbol c) {
3836 Symbol owner = c.owner;
3856 * @param pos The position to use for error reporting.
3857 * @param env The environment current at the expression.
3858 * @param c The type of the selected expression
3859 * @param tree The expression
3860 */
3861 Symbol resolveSelf(DiagnosticPosition pos,
3862 Env<AttrContext> env,
3863 TypeSymbol c,
3864 JCFieldAccess tree) {
3865 Name name = tree.name;
3866 Assert.check(name == names._this || name == names._super);
3867 Env<AttrContext> env1 = env;
3868 boolean staticOnly = false;
3869 while (env1.outer != null) {
3870 if (isStatic(env1)) staticOnly = true;
3871 if (env1.enclClass.sym == c) {
3872 Symbol sym = env1.info.scope.findFirst(name);
3873 if (sym != null) {
3874 if (staticOnly)
3875 sym = new StaticError(sym);
3876 return accessBase(sym, pos, env.enclClass.sym.type,
3877 name, true);
3878 }
3879 }
3880 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
3881 env1 = env1.outer;
3882 }
3883 if (c.isInterface() &&
3884 name == names._super && !isStatic(env) &&
3885 types.isDirectSuperInterface(c, env.enclClass.sym)) {
3886 //this might be a default super call if one of the superinterfaces is 'c'
3887 for (Type t : pruneInterfaces(env.enclClass.type)) {
3888 if (t.tsym == c) {
3889 env.info.defaultSuperCallSite = t;
3890 return new VarSymbol(0, names._super,
3891 types.asSuper(env.enclClass.type, c), env.enclClass.sym);
3892 }
3893 }
3894 //find a direct supertype that is a subtype of 'c'
3895 for (Type i : types.directSupertypes(env.enclClass.type)) {
3896 if (i.tsym.isSubClass(c, types) && i.tsym != c) {
3897 log.error(pos,
3898 Errors.IllegalDefaultSuperCall(c,
3899 Fragments.RedundantSupertype(c, i)));
3900 return syms.errSymbol;
3901 }
3902 }
3903 Assert.error();
3904 }
3905 log.error(pos, Errors.NotEnclClass(c));
3906 return syms.errSymbol;
3907 }
3908 //where
3909 private List<Type> pruneInterfaces(Type t) {
3910 ListBuffer<Type> result = new ListBuffer<>();
3911 for (Type t1 : types.interfaces(t)) {
3912 boolean shouldAdd = true;
3913 for (Type t2 : types.directSupertypes(t)) {
3914 if (t1 != t2 && !t2.hasTag(ERROR) && types.isSubtypeNoCapture(t2, t1)) {
3915 shouldAdd = false;
3916 }
3917 }
3918 if (shouldAdd) {
3919 result.append(t1);
3920 }
3921 }
3922 return result.toList();
3923 }
3924
3925 /* ***************************************************************************
3926 * ResolveError classes, indicating error situations when accessing symbols
3927 ****************************************************************************/
3928
3929 //used by TransTypes when checking target type of synthetic cast
3930 public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) {
3931 AccessError error = new AccessError(env, env.enclClass.type, type.tsym);
3932 logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null);
3933 }
3934 //where
3935 private void logResolveError(ResolveError error,
3936 DiagnosticPosition pos,
3937 Symbol location,
3938 Type site,
3939 Name name,
3940 List<Type> argtypes,
3941 List<Type> typeargtypes) {
3942 JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
3943 pos, location, site, name, argtypes, typeargtypes);
4213 List<Type> argtypes,
4214 List<Type> typeargtypes) {
4215 if (name == names.error)
4216 return null;
4217
4218 Pair<Symbol, JCDiagnostic> c = errCandidate();
4219 Symbol ws = c.fst.asMemberOf(site, types);
4220 UnaryOperator<JCDiagnostic> rewriter = compactMethodDiags ?
4221 d -> MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, c.snd) : null;
4222
4223 // If the problem is due to type arguments, then the method parameters aren't relevant,
4224 // so use the error message that omits them to avoid confusion.
4225 switch (c.snd.getCode()) {
4226 case "compiler.misc.wrong.number.type.args":
4227 case "compiler.misc.explicit.param.do.not.conform.to.bounds":
4228 return diags.create(dkind, log.currentSource(), pos,
4229 "cant.apply.symbol.noargs",
4230 rewriter,
4231 kindName(ws),
4232 ws.name == names.init ? ws.owner.name : ws.name,
4233 ws.owner.type,
4234 c.snd);
4235 default:
4236 // Avoid saying "constructor Array in class Array"
4237 if (ws.owner == syms.arrayClass && ws.name == names.init) {
4238 return diags.create(dkind, log.currentSource(), pos,
4239 "cant.apply.array.ctor",
4240 rewriter,
4241 methodArguments(ws.type.getParameterTypes()),
4242 methodArguments(argtypes),
4243 c.snd);
4244 }
4245 return diags.create(dkind, log.currentSource(), pos,
4246 "cant.apply.symbol",
4247 rewriter,
4248 kindName(ws),
4249 ws.name == names.init ? ws.owner.name : ws.name,
4250 methodArguments(ws.type.getParameterTypes()),
4251 methodArguments(argtypes),
4252 kindName(ws.owner),
5113 final MethodResolutionPhase step;
5114 final Symbol sym;
5115 final JCDiagnostic details;
5116 final Type mtype;
5117
5118 private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) {
5119 this.step = step;
5120 this.sym = sym;
5121 this.details = details;
5122 this.mtype = mtype;
5123 }
5124
5125 boolean isApplicable() {
5126 return mtype != null;
5127 }
5128 }
5129
5130 DeferredAttr.AttrMode attrMode() {
5131 return attrMode;
5132 }
5133 }
5134
5135 MethodResolutionContext currentResolutionContext = null;
5136 }
|