26 package com.sun.tools.javac.comp;
27
28 import com.sun.tools.javac.api.Formattable.LocalizedString;
29 import com.sun.tools.javac.code.*;
30 import com.sun.tools.javac.code.Scope.WriteableScope;
31 import com.sun.tools.javac.code.Source.Feature;
32 import com.sun.tools.javac.code.Symbol.*;
33 import com.sun.tools.javac.code.Type.*;
34 import com.sun.tools.javac.comp.Attr.ResultInfo;
35 import com.sun.tools.javac.comp.Check.CheckContext;
36 import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
37 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
38 import com.sun.tools.javac.comp.DeferredAttr.DeferredType;
39 import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
40 import com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.Template;
41 import com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind;
42 import com.sun.tools.javac.jvm.*;
43 import com.sun.tools.javac.main.Option;
44 import com.sun.tools.javac.resources.CompilerProperties.Errors;
45 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
46 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
47 import com.sun.tools.javac.tree.*;
48 import com.sun.tools.javac.tree.JCTree.*;
49 import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
50 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
51 import com.sun.tools.javac.util.*;
52 import com.sun.tools.javac.util.DefinedBy.Api;
53 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
54 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
55 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
56
57 import java.util.Arrays;
58 import java.util.Collection;
59 import java.util.EnumSet;
60 import java.util.HashSet;
61 import java.util.Iterator;
62 import java.util.LinkedHashMap;
63 import java.util.Map;
64 import java.util.Set;
65 import java.util.function.BiFunction;
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) {
1488 * @param pos The position to use for error reporting.
1489 * @param env The environment current at the method invocation.
1490 * @param site The type of the qualifying expression, in which
1491 * identifier is searched.
1492 * @param name The identifier's name.
1493 */
1494 public VarSymbol resolveInternalField(DiagnosticPosition pos, Env<AttrContext> env,
1495 Type site, Name name) {
1496 Symbol sym = findField(env, site, name, site.tsym);
1497 if (sym.kind == VAR) return (VarSymbol)sym;
1498 else throw new FatalError(
1499 diags.fragment(Fragments.FatalErrCantLocateField(name)));
1500 }
1501
1502 /** Find unqualified variable or field with given name.
1503 * Synthetic fields always skipped.
1504 * @param pos The position to use for error reporting.
1505 * @param env The current environment.
1506 * @param name The name of the variable or field.
1507 */
1508 Symbol findVar(DiagnosticPosition pos, Env<AttrContext> env, Name name) {
1509 Symbol bestSoFar = varNotFound;
1510 Env<AttrContext> env1 = env;
1511 boolean staticOnly = false;
1512 while (env1.outer != null) {
1513 Symbol sym = null;
1514 for (Symbol s : env1.info.scope.getSymbolsByName(name)) {
1515 if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) {
1516 sym = s;
1517 if (staticOnly) {
1518 return new StaticError(sym);
1519 }
1520 break;
1521 }
1522 }
1523 if (isStatic(env1)) staticOnly = true;
1524 if (sym == null) {
1525 sym = findField(env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
1526 }
1527 if (sym.exists()) {
1528 if (sym.kind == VAR &&
1529 sym.owner.kind == TYP &&
1530 (sym.flags() & STATIC) == 0) {
1531 if (staticOnly)
1532 return new StaticError(sym);
1533 if (env1.info.ctorPrologue && !isAllowedEarlyReference(pos, env1, (VarSymbol)sym))
1534 return new RefBeforeCtorCalledError(sym);
1535 }
1536 return sym;
1537 } else {
1538 bestSoFar = bestOf(bestSoFar, sym);
1539 }
1540
1541 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
1542 env1 = env1.outer;
1543 }
1544
1545 Symbol sym = findField(env, syms.predefClass.type, name, syms.predefClass);
1546 if (sym.exists())
1547 return sym;
1548 if (bestSoFar.exists())
1549 return bestSoFar;
1550
1551 Symbol origin = null;
1552 for (Scope sc : new Scope[] { env.toplevel.namedImportScope, env.toplevel.starImportScope }) {
1553 for (Symbol currentSymbol : sc.getSymbolsByName(name)) {
1554 if (currentSymbol.kind != VAR)
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) {
2463 * @param name The identifier's name.
2464 * @param kind Indicates the possible symbol kinds
2465 * (a subset of VAL, TYP, PCK).
2466 */
2467 Symbol findIdent(DiagnosticPosition pos, Env<AttrContext> env, Name name, KindSelector kind) {
2468 try {
2469 return checkNonExistentType(checkRestrictedType(pos, findIdentInternal(pos, env, name, kind), name));
2470 } catch (ClassFinder.BadClassFile err) {
2471 return new BadClassFileError(err);
2472 } catch (CompletionFailure cf) {
2473 chk.completionError(pos, cf);
2474 return typeNotFound;
2475 }
2476 }
2477
2478 Symbol findIdentInternal(DiagnosticPosition pos, Env<AttrContext> env, Name name, KindSelector kind) {
2479 Symbol bestSoFar = typeNotFound;
2480 Symbol sym;
2481
2482 if (kind.contains(KindSelector.VAL)) {
2483 sym = findVar(pos, env, name);
2484 if (sym.exists()) return sym;
2485 else bestSoFar = bestOf(bestSoFar, sym);
2486 }
2487
2488 if (kind.contains(KindSelector.TYP)) {
2489 sym = findType(env, name);
2490 if (sym.exists()) return sym;
2491 else bestSoFar = bestOf(bestSoFar, sym);
2492 }
2493
2494 if (kind.contains(KindSelector.PCK))
2495 return lookupPackage(env, name);
2496 else return bestSoFar;
2497 }
2498
2499 /** Find an identifier in a package which matches a specified kind set.
2500 * @param pos position on which report warnings, if any;
2501 * null warnings should not be reported
2502 * @param env The current environment.
2503 * @param name The identifier's name.
2526 }
2527 else bestSoFar = bestOf(bestSoFar, sym);
2528 }
2529 if (kind.contains(KindSelector.PCK)) {
2530 return lookupPackage(env, fullname);
2531 }
2532 return bestSoFar;
2533 }
2534
2535 /** Find an identifier among the members of a given type `site'.
2536 * @param pos position on which report warnings, if any;
2537 * null warnings should not be reported
2538 * @param env The current environment.
2539 * @param site The type containing the symbol to be found.
2540 * @param name The identifier's name.
2541 * @param kind Indicates the possible symbol kinds
2542 * (a subset of VAL, TYP).
2543 */
2544 Symbol findIdentInType(DiagnosticPosition pos,
2545 Env<AttrContext> env, Type site,
2546 Name name, KindSelector kind) {
2547 try {
2548 return checkNonExistentType(checkRestrictedType(pos, findIdentInTypeInternal(env, site, name, kind), name));
2549 } catch (ClassFinder.BadClassFile err) {
2550 return new BadClassFileError(err);
2551 } catch (CompletionFailure cf) {
2552 chk.completionError(pos, cf);
2553 return typeNotFound;
2554 }
2555 }
2556
2557 private Symbol checkNonExistentType(Symbol symbol) {
2558 /* Guard against returning a type is not on the class path of the current compilation,
2559 * but *was* on the class path of a separate compilation that produced a class file
2560 * that is on the class path of the current compilation. Such a type will fail completion
2561 * but the completion failure may have been silently swallowed (e.g. missing annotation types)
2562 * with an error stub symbol lingering in the symbol tables.
2563 */
2564 return symbol instanceof ClassSymbol c && c.type.isErroneous() && c.classfile == null ? typeNotFound : symbol;
2565 }
2566
2567 Symbol findIdentInTypeInternal(Env<AttrContext> env, Type site,
2568 Name name, KindSelector kind) {
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,
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),
4789 */
4790 class BadLocalClassCreation extends StaticError {
4791 BadLocalClassCreation(Symbol sym) {
4792 super(sym, "bad local class creation");
4793 }
4794
4795 @Override
4796 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4797 DiagnosticPosition pos,
4798 Symbol location,
4799 Type site,
4800 Name name,
4801 List<Type> argtypes,
4802 List<Type> typeargtypes) {
4803 return diags.create(dkind, log.currentSource(), pos,
4804 "local.cant.be.inst.static", kindName(sym), sym);
4805 }
4806 }
4807
4808 /**
4809 * Specialization of {@link InvalidSymbolError} for illegal
4810 * early accesses within a constructor prologue.
4811 */
4812 class RefBeforeCtorCalledError extends StaticError {
4813
4814 RefBeforeCtorCalledError(Symbol sym) {
4815 super(sym, "prologue error");
4816 }
4817
4818 @Override
4819 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4820 DiagnosticPosition pos,
4821 Symbol location,
4822 Type site,
4823 Name name,
4824 List<Type> argtypes,
4825 List<Type> typeargtypes) {
4826 Symbol errSym = ((sym.kind == TYP && sym.type.hasTag(CLASS))
4827 ? types.erasure(sym.type).tsym
4828 : sym);
4829 return diags.create(dkind, log.currentSource(), pos,
4830 "cant.ref.before.ctor.called", errSym);
4831 }
4832 }
4833
4834 /**
4835 * InvalidSymbolError error class indicating that a pair of symbols
4836 * (either methods, constructors or operands) are ambiguous
4837 * given an actual arguments/type argument list.
4838 */
4839 class AmbiguityError extends ResolveError {
4840
4841 /** The other maximally specific symbol */
4842 List<Symbol> ambiguousSyms = List.nil();
4843
4844 @Override
4845 public boolean exists() {
4846 return true;
4847 }
4848
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 }
|
26 package com.sun.tools.javac.comp;
27
28 import com.sun.tools.javac.api.Formattable.LocalizedString;
29 import com.sun.tools.javac.code.*;
30 import com.sun.tools.javac.code.Scope.WriteableScope;
31 import com.sun.tools.javac.code.Source.Feature;
32 import com.sun.tools.javac.code.Symbol.*;
33 import com.sun.tools.javac.code.Type.*;
34 import com.sun.tools.javac.comp.Attr.ResultInfo;
35 import com.sun.tools.javac.comp.Check.CheckContext;
36 import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
37 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
38 import com.sun.tools.javac.comp.DeferredAttr.DeferredType;
39 import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
40 import com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.Template;
41 import com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind;
42 import com.sun.tools.javac.jvm.*;
43 import com.sun.tools.javac.main.Option;
44 import com.sun.tools.javac.resources.CompilerProperties.Errors;
45 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
46 import com.sun.tools.javac.resources.CompilerProperties.LintWarnings;
47 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
48 import com.sun.tools.javac.tree.*;
49 import com.sun.tools.javac.tree.JCTree.*;
50 import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
51 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
52 import com.sun.tools.javac.util.*;
53 import com.sun.tools.javac.util.DefinedBy.Api;
54 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
55 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
56 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
57
58 import java.util.Arrays;
59 import java.util.Collection;
60 import java.util.EnumSet;
61 import java.util.HashSet;
62 import java.util.Iterator;
63 import java.util.LinkedHashMap;
64 import java.util.Map;
65 import java.util.Set;
66 import java.util.function.BiFunction;
99 Symtab syms;
100 Attr attr;
101 AttrRecover attrRecover;
102 DeferredAttr deferredAttr;
103 Check chk;
104 Infer infer;
105 Preview preview;
106 ClassFinder finder;
107 ModuleFinder moduleFinder;
108 Types types;
109 JCDiagnostic.Factory diags;
110 public final boolean allowModules;
111 public final boolean allowRecords;
112 private final boolean compactMethodDiags;
113 private final boolean allowLocalVariableTypeInference;
114 private final boolean allowYieldStatement;
115 private final boolean allowPrivateMembersInPermitsClause;
116 final EnumSet<VerboseResolutionMode> verboseResolutionMode;
117 final boolean dumpMethodReferenceSearchResults;
118 final boolean dumpStacktraceOnError;
119 private final LocalProxyVarsGen localProxyVarsGen;
120
121 WriteableScope polymorphicSignatureScope;
122
123 @SuppressWarnings("this-escape")
124 protected Resolve(Context context) {
125 context.put(resolveKey, this);
126 syms = Symtab.instance(context);
127
128 varNotFound = new SymbolNotFoundError(ABSENT_VAR);
129 methodNotFound = new SymbolNotFoundError(ABSENT_MTH);
130 typeNotFound = new SymbolNotFoundError(ABSENT_TYP);
131 referenceNotFound = ReferenceLookupResult.error(methodNotFound);
132
133 names = Names.instance(context);
134 log = Log.instance(context);
135 attr = Attr.instance(context);
136 attrRecover = AttrRecover.instance(context);
137 deferredAttr = DeferredAttr.instance(context);
138 chk = Check.instance(context);
139 infer = Infer.instance(context);
140 finder = ClassFinder.instance(context);
141 moduleFinder = ModuleFinder.instance(context);
142 types = Types.instance(context);
143 diags = JCDiagnostic.Factory.instance(context);
144 preview = Preview.instance(context);
145 Source source = Source.instance(context);
146 Options options = Options.instance(context);
147 compactMethodDiags = options.isSet(Option.XDIAGS, "compact") ||
148 options.isUnset(Option.XDIAGS) && options.isUnset("rawDiagnostics");
149 verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
150 Target target = Target.instance(context);
151 allowLocalVariableTypeInference = Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source);
152 allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source);
153 allowPrivateMembersInPermitsClause = Feature.PRIVATE_MEMBERS_IN_PERMITS_CLAUSE.allowedInSource(source);
154 polymorphicSignatureScope = WriteableScope.create(syms.noSymbol);
155 allowModules = Feature.MODULES.allowedInSource(source);
156 allowRecords = Feature.RECORDS.allowedInSource(source);
157 dumpMethodReferenceSearchResults = options.isSet("debug.dumpMethodReferenceSearchResults");
158 dumpStacktraceOnError = options.isSet("dev") || options.isSet(DOE);
159 localProxyVarsGen = LocalProxyVarsGen.instance(context);
160 }
161
162 /** error symbols, which are returned when resolution fails
163 */
164 private final SymbolNotFoundError varNotFound;
165 private final SymbolNotFoundError methodNotFound;
166 private final SymbolNotFoundError typeNotFound;
167
168 /** empty reference lookup result */
169 private final ReferenceLookupResult referenceNotFound;
170
171 public static Resolve instance(Context context) {
172 Resolve instance = context.get(resolveKey);
173 if (instance == null)
174 instance = new Resolve(context);
175 return instance;
176 }
177
178 private static Symbol bestOf(Symbol s1,
179 Symbol s2) {
1491 * @param pos The position to use for error reporting.
1492 * @param env The environment current at the method invocation.
1493 * @param site The type of the qualifying expression, in which
1494 * identifier is searched.
1495 * @param name The identifier's name.
1496 */
1497 public VarSymbol resolveInternalField(DiagnosticPosition pos, Env<AttrContext> env,
1498 Type site, Name name) {
1499 Symbol sym = findField(env, site, name, site.tsym);
1500 if (sym.kind == VAR) return (VarSymbol)sym;
1501 else throw new FatalError(
1502 diags.fragment(Fragments.FatalErrCantLocateField(name)));
1503 }
1504
1505 /** Find unqualified variable or field with given name.
1506 * Synthetic fields always skipped.
1507 * @param pos The position to use for error reporting.
1508 * @param env The current environment.
1509 * @param name The name of the variable or field.
1510 */
1511 Symbol findVar(DiagnosticPosition pos, Env<AttrContext> env, Name name, boolean writeOnlyTarget) {
1512 Symbol bestSoFar = varNotFound;
1513 Env<AttrContext> env1 = env;
1514 boolean staticOnly = false;
1515 while (env1.outer != null) {
1516 Symbol sym = null;
1517 for (Symbol s : env1.info.scope.getSymbolsByName(name)) {
1518 if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) {
1519 sym = s;
1520 if (staticOnly) {
1521 return new StaticError(sym);
1522 }
1523 break;
1524 }
1525 }
1526 if (isStatic(env1)) staticOnly = true;
1527 if (sym == null) {
1528 sym = findField(env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
1529 }
1530 if (sym.exists()) {
1531 if (sym.kind == VAR &&
1532 sym.owner.kind == TYP &&
1533 (sym.flags() & STATIC) == 0) {
1534 if (staticOnly)
1535 return new StaticError(sym);
1536 if (env1.info.earlyContext != EarlyConstructionContext.NONE) {
1537 sym = checkEarlyFieldRef(pos, env1, null, (VarSymbol)sym,
1538 writeOnlyTarget);
1539 }
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 if (env1 == env) {
2048 EarlyConstructionContext context = env1.info.earlyContext;
2049 if (env1.enclClass.sym == context.owner()) {
2050 Assert.check(env.tree.hasTag(APPLY));
2051 return earlyRefResult(((JCMethodInvocation)env.tree).meth, context, sym, false);
2052 }
2053 }
2054 }
2055 return sym;
2056 } else {
2057 bestSoFar = bestOf(bestSoFar, sym);
2058 }
2059 } finally {
2060 env1.info.preferredTreeForDiagnostics = null;
2061 }
2062 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
2063 env1 = env1.outer;
2064 }
2065
2066 Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
2067 typeargtypes, allowBoxing, useVarargs);
2068 if (sym.exists())
2069 return sym;
2070
2071 for (Symbol currentSym : env.toplevel.namedImportScope.getSymbolsByName(name)) {
2072 Symbol origin = env.toplevel.namedImportScope.getOrigin(currentSym).owner;
2073 if (currentSym.kind == MTH) {
2473 * @param name The identifier's name.
2474 * @param kind Indicates the possible symbol kinds
2475 * (a subset of VAL, TYP, PCK).
2476 */
2477 Symbol findIdent(DiagnosticPosition pos, Env<AttrContext> env, Name name, KindSelector kind) {
2478 try {
2479 return checkNonExistentType(checkRestrictedType(pos, findIdentInternal(pos, env, name, kind), name));
2480 } catch (ClassFinder.BadClassFile err) {
2481 return new BadClassFileError(err);
2482 } catch (CompletionFailure cf) {
2483 chk.completionError(pos, cf);
2484 return typeNotFound;
2485 }
2486 }
2487
2488 Symbol findIdentInternal(DiagnosticPosition pos, Env<AttrContext> env, Name name, KindSelector kind) {
2489 Symbol bestSoFar = typeNotFound;
2490 Symbol sym;
2491
2492 if (kind.contains(KindSelector.VAL)) {
2493 sym = findVar(pos, env, name, kind.isAssignment());
2494 if (sym.exists()) return sym;
2495 else bestSoFar = bestOf(bestSoFar, sym);
2496 }
2497
2498 if (kind.contains(KindSelector.TYP)) {
2499 sym = findType(env, name);
2500 if (sym.exists()) return sym;
2501 else bestSoFar = bestOf(bestSoFar, sym);
2502 }
2503
2504 if (kind.contains(KindSelector.PCK))
2505 return lookupPackage(env, name);
2506 else return bestSoFar;
2507 }
2508
2509 /** Find an identifier in a package which matches a specified kind set.
2510 * @param pos position on which report warnings, if any;
2511 * null warnings should not be reported
2512 * @param env The current environment.
2513 * @param name The identifier's name.
2536 }
2537 else bestSoFar = bestOf(bestSoFar, sym);
2538 }
2539 if (kind.contains(KindSelector.PCK)) {
2540 return lookupPackage(env, fullname);
2541 }
2542 return bestSoFar;
2543 }
2544
2545 /** Find an identifier among the members of a given type `site'.
2546 * @param pos position on which report warnings, if any;
2547 * null warnings should not be reported
2548 * @param env The current environment.
2549 * @param site The type containing the symbol to be found.
2550 * @param name The identifier's name.
2551 * @param kind Indicates the possible symbol kinds
2552 * (a subset of VAL, TYP).
2553 */
2554 Symbol findIdentInType(DiagnosticPosition pos,
2555 Env<AttrContext> env, Type site,
2556 Name name, KindSelector kind,
2557 JCTree earlyFieldQualifier) {
2558 try {
2559 Symbol sym = findIdentInTypeInternal(env, site, name, kind);
2560 if (sym.kind == VAR &&
2561 env.info.earlyContext != EarlyConstructionContext.NONE &&
2562 earlyFieldQualifier != null) {
2563 Assert.check(sym.owner.kind == TYP);
2564 sym = checkEarlyFieldRef(pos, env, earlyFieldQualifier, (VarSymbol)sym, kind.isAssignment());
2565 }
2566 return checkNonExistentType(checkRestrictedType(pos, sym, name));
2567 } catch (ClassFinder.BadClassFile err) {
2568 return new BadClassFileError(err);
2569 } catch (CompletionFailure cf) {
2570 chk.completionError(pos, cf);
2571 return typeNotFound;
2572 }
2573 }
2574
2575 private Symbol checkNonExistentType(Symbol symbol) {
2576 /* Guard against returning a type is not on the class path of the current compilation,
2577 * but *was* on the class path of a separate compilation that produced a class file
2578 * that is on the class path of the current compilation. Such a type will fail completion
2579 * but the completion failure may have been silently swallowed (e.g. missing annotation types)
2580 * with an error stub symbol lingering in the symbol tables.
2581 */
2582 return symbol instanceof ClassSymbol c && c.type.isErroneous() && c.classfile == null ? typeNotFound : symbol;
2583 }
2584
2585 Symbol findIdentInTypeInternal(Env<AttrContext> env, Type site,
2586 Name name, KindSelector kind) {
3821
3822 /**
3823 * Find a "valid" reference to an enclosing 'A.this' such that A is a subclass of the provided class symbol.
3824 * A reference to an enclosing 'A.this' is "valid" if (a) we're not in the early-construction context for A
3825 * and (b) if the current class is not an inner class of A.
3826 */
3827 Symbol findSelfContaining(DiagnosticPosition pos,
3828 Env<AttrContext> env,
3829 TypeSymbol c,
3830 boolean isSuper) {
3831 Env<AttrContext> env1 = isSuper ? env.outer : env;
3832 boolean staticOnly = false;
3833 while (env1.outer != null) {
3834 if (isStatic(env1)) staticOnly = true;
3835 if (env1.enclClass.sym.isSubClass(c, types)) {
3836 Symbol sym = env1.info.scope.findFirst(names._this);
3837 if (sym != null) {
3838 if (staticOnly) {
3839 // current class is not an inner class, stop search
3840 return new StaticError(sym);
3841 } else if (env1.enclClass.sym == env1.info.earlyContext.owner()) {
3842 // early construction context, stop search
3843 return earlyRefResult(pos, env1.info.earlyContext, sym, false);
3844 } else {
3845 // found it
3846 return sym;
3847 }
3848 }
3849 }
3850 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
3851 env1 = env1.outer;
3852 }
3853 return varNotFound;
3854 }
3855
3856 /**
3857 * Resolve the (method) owner of a local class. This can fail if the local class
3858 * is referenced from a static context nested inside the local class. Effectively,
3859 * this lookup succeeds if we can access a local variable declared inside the owner
3860 * method from the provided env.
3861 */
3862 Symbol findLocalClassOwner(Env<AttrContext> env, TypeSymbol c) {
3863 Symbol owner = c.owner;
3886 * @param pos The position to use for error reporting.
3887 * @param env The environment current at the expression.
3888 * @param c The type of the selected expression
3889 * @param tree The expression
3890 */
3891 Symbol resolveSelf(DiagnosticPosition pos,
3892 Env<AttrContext> env,
3893 TypeSymbol c,
3894 JCFieldAccess tree) {
3895 Name name = tree.name;
3896 Assert.check(name == names._this || name == names._super);
3897 Env<AttrContext> env1 = env;
3898 boolean staticOnly = false;
3899 while (env1.outer != null) {
3900 if (isStatic(env1)) staticOnly = true;
3901 if (env1.enclClass.sym == c) {
3902 Symbol sym = env1.info.scope.findFirst(name);
3903 if (sym != null) {
3904 if (staticOnly)
3905 sym = new StaticError(sym);
3906 else {
3907 EarlyConstructionContext context = env1.info.earlyContext;
3908 if (sym.owner == context.owner() &&
3909 !isReceiverParameter(env, tree)) {
3910 sym = earlyRefResult(pos, context, sym, false);
3911 }
3912 }
3913 return sym;
3914 }
3915 }
3916 if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
3917 env1 = env1.outer;
3918 }
3919 if (c.isInterface() &&
3920 name == names._super && !isStatic(env) &&
3921 types.isDirectSuperInterface(c, env.enclClass.sym)) {
3922 //this might be a default super call if one of the superinterfaces is 'c'
3923 for (Type t : pruneInterfaces(env.enclClass.type)) {
3924 if (t.tsym == c) {
3925 Symbol sym = new VarSymbol(0, names._super,
3926 types.asSuper(env.enclClass.type, c), env.enclClass.sym);
3927 EarlyConstructionContext context = env.info.earlyContext;
3928 if (context != EarlyConstructionContext.NONE) {
3929 sym = earlyRefResult(pos, context, sym, false);
3930 }
3931 env.info.defaultSuperCallSite = t;
3932 return sym;
3933 }
3934 }
3935 //find a direct supertype that is a subtype of 'c'
3936 for (Type i : types.directSupertypes(env.enclClass.type)) {
3937 if (i.tsym.isSubClass(c, types) && i.tsym != c) {
3938 log.error(pos,
3939 Errors.IllegalDefaultSuperCall(c,
3940 Fragments.RedundantSupertype(c, i)));
3941 return syms.errSymbol;
3942 }
3943 }
3944 Assert.error();
3945 }
3946 log.error(pos, Errors.NotEnclClass(c));
3947 return syms.errSymbol;
3948 }
3949 //where
3950 private List<Type> pruneInterfaces(Type t) {
3951 ListBuffer<Type> result = new ListBuffer<>();
3952 for (Type t1 : types.interfaces(t)) {
3953 boolean shouldAdd = true;
3954 for (Type t2 : types.directSupertypes(t)) {
3955 if (t1 != t2 && !t2.hasTag(ERROR) && types.isSubtypeNoCapture(t2, t1)) {
3956 shouldAdd = false;
3957 }
3958 }
3959 if (shouldAdd) {
3960 result.append(t1);
3961 }
3962 }
3963 return result.toList();
3964 }
3965 private boolean isReceiverParameter(Env<AttrContext> env, JCFieldAccess tree) {
3966 if (env.tree.getTag() != METHODDEF)
3967 return false;
3968 JCMethodDecl method = (JCMethodDecl)env.tree;
3969 return method.recvparam != null && tree == method.recvparam.nameexpr;
3970 }
3971
3972 /**
3973 * Determine if an early instance field reference may appear in an early construction context of A.
3974 *
3975 * <p>
3976 * This is only allowed when:
3977 * - The field is not inherited from a superclass
3978 * - The access is not within a lambda or an inner class, because that would require
3979 * capturing 'this' which is not allowed prior to super().
3980 * - The field has no initializer or it is declared in a value class
3981 */
3982 private Symbol checkEarlyFieldRef(DiagnosticPosition pos, Env<AttrContext> env, JCTree base, VarSymbol field, boolean writeOnlyTarget) {
3983 EarlyConstructionContext context = env.info.earlyContext;
3984 Assert.check(context != EarlyConstructionContext.NONE);
3985 boolean earlyRefOk = base != null ?
3986 isQualifiedEarlyRefAllowed(pos, env, context, base, field, writeOnlyTarget) :
3987 isSimpleEarlyFieldRefAllowed(pos, env, context, field, writeOnlyTarget);
3988 if (earlyRefOk) {
3989 return field;
3990 } else {
3991 boolean isEarlyWrite = writeOnlyTarget &&
3992 field.owner == context.owner();
3993 return earlyRefResult(pos, context, field, isEarlyWrite);
3994 }
3995 }
3996
3997 /** Implements early access checks for qualified field references (15.8.3, 15.8.4) */
3998 private boolean isQualifiedEarlyRefAllowed(DiagnosticPosition pos,
3999 Env<AttrContext> env,
4000 EarlyConstructionContext context,
4001 JCTree base,
4002 VarSymbol field,
4003 boolean writeOnlyTarget) {
4004 if (!TreeInfo.isExplicitThisReference(types, (ClassType)context.owner().type, base)) {
4005 // Foo.this.x, where Foo is unrelated, ignore
4006 return true;
4007 }
4008 if (field.isStatic()) {
4009 // early this can only qualify instance field accesses
4010 return false;
4011 }
4012 return isSimpleEarlyFieldRefAllowed(pos, env, context, field, writeOnlyTarget);
4013 }
4014
4015 /** Implements early access checks for unqualified field references (6.5.6.1) */
4016 private boolean isSimpleEarlyFieldRefAllowed(DiagnosticPosition pos,
4017 Env<AttrContext> env,
4018 EarlyConstructionContext context,
4019 VarSymbol field,
4020 boolean writeOnlyTarget) {
4021 if (field.name == names._this || field.name == names._super) {
4022 // If unrelated this/super, ignore
4023 return field.owner != context.owner();
4024 }
4025 if (field.isStatic() ||
4026 !field.isMemberOf(context.owner(), types)) {
4027 // If unqualified static field, or unrelated instance field, ignore
4028 return true;
4029 }
4030 // We have now ruled out all cases where the check should not apply. Let's follow 6.5.6.1
4031 if (field.owner != context.owner()) {
4032 // The instance variable is declared by C, not a superclass of C
4033 return false;
4034 }
4035 if (context.restricted()) {
4036 // The expression name does not appear in a constructor of C whose body includes an
4037 // alternate constructor invocation, or a nested class or interface declaration
4038 // of C, or a lambda expression contained by C
4039 return false;
4040 }
4041 if ((field.flags_field & HASINIT) != 0 &&
4042 !field.isStrict() &&
4043 !context.onlyWarnings()) {
4044 // Either the declaration of the named variable has no initializer,
4045 // or C is a value class (8.1.1.5). Plus, if warnings are enabled, treat
4046 // the variable as strict -- as if it was declared in a value class.
4047 // To preserve legacy behavior, bad final field writes are never reported as early access.
4048 return writeOnlyTarget && field.isFinal();
4049 }
4050 // At this point we have seen a legal early ref
4051 if (!context.onlyWarnings()) {
4052 if (writeOnlyTarget) {
4053 // Write early ref, this is allowed with flexible constructor bodies
4054 preview.checkSourceLevel(pos, Feature.FLEXIBLE_CONSTRUCTORS);
4055 } else {
4056 // Read early ref, this is only allowed under JEP 401, and requires special codegen support
4057 preview.checkSourceLevel(pos, Feature.VALUE_CLASSES);
4058 if (context.ctorPrologue() && env.enclMethod != null) {
4059 // Track the early read for codegen
4060 localProxyVarsGen.addFieldReadInPrologue(env.enclMethod, field);
4061 }
4062 }
4063 }
4064 return true;
4065 }
4066
4067 /** Return a symbol modeling the early access, and warn if necessary */
4068 private Symbol earlyRefResult(DiagnosticPosition pos, EarlyConstructionContext context, Symbol sym,
4069 boolean isEarlyWrite) {
4070 if (context.onlyWarnings()) {
4071 log.warning(pos, LintWarnings.WouldNotBeAllowedInPrologue(sym));
4072 return sym;
4073 }
4074 return new RefBeforeCtorCalledError(sym, isEarlyWrite);
4075 }
4076
4077 /* ***************************************************************************
4078 * ResolveError classes, indicating error situations when accessing symbols
4079 ****************************************************************************/
4080
4081 //used by TransTypes when checking target type of synthetic cast
4082 public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) {
4083 AccessError error = new AccessError(env, env.enclClass.type, type.tsym);
4084 logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null);
4085 }
4086 //where
4087 private void logResolveError(ResolveError error,
4088 DiagnosticPosition pos,
4089 Symbol location,
4090 Type site,
4091 Name name,
4092 List<Type> argtypes,
4093 List<Type> typeargtypes) {
4094 JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
4390 List<Type> argtypes,
4391 List<Type> typeargtypes) {
4392 if (name == names.error)
4393 return null;
4394
4395 Pair<Symbol, JCDiagnostic> c = errCandidate();
4396 Symbol ws = c.fst.asMemberOf(site, types);
4397 UnaryOperator<JCDiagnostic> rewriter = compactMethodDiags ?
4398 d -> MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, c.snd) : null;
4399
4400 // If the problem is due to type arguments, then the method parameters aren't relevant,
4401 // so use the error message that omits them to avoid confusion.
4402 switch (c.snd.getCode()) {
4403 case "compiler.misc.wrong.number.type.args":
4404 case "compiler.misc.explicit.param.do.not.conform.to.bounds":
4405 return diags.create(dkind, log.currentSource(), pos,
4406 "cant.apply.symbol.noargs",
4407 rewriter,
4408 kindName(ws),
4409 ws.name == names.init ? ws.owner.name : ws.name,
4410 ws.owner.type,
4411 c.snd);
4412 default:
4413 // Avoid saying "constructor Array in class Array"
4414 if (ws.owner == syms.arrayClass && ws.name == names.init) {
4415 return diags.create(dkind, log.currentSource(), pos,
4416 "cant.apply.array.ctor",
4417 rewriter,
4418 methodArguments(ws.type.getParameterTypes()),
4419 methodArguments(argtypes),
4420 c.snd);
4421 }
4422 return diags.create(dkind, log.currentSource(), pos,
4423 "cant.apply.symbol",
4424 rewriter,
4425 kindName(ws),
4426 ws.name == names.init ? ws.owner.name : ws.name,
4427 methodArguments(ws.type.getParameterTypes()),
4428 methodArguments(argtypes),
4429 kindName(ws.owner),
4827 */
4828 class BadLocalClassCreation extends StaticError {
4829 BadLocalClassCreation(Symbol sym) {
4830 super(sym, "bad local class creation");
4831 }
4832
4833 @Override
4834 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4835 DiagnosticPosition pos,
4836 Symbol location,
4837 Type site,
4838 Name name,
4839 List<Type> argtypes,
4840 List<Type> typeargtypes) {
4841 return diags.create(dkind, log.currentSource(), pos,
4842 "local.cant.be.inst.static", kindName(sym), sym);
4843 }
4844 }
4845
4846 /**
4847 * Specialization of {@link StaticError} for illegal
4848 * early accesses within a constructor prologue.
4849 */
4850 class RefBeforeCtorCalledError extends StaticError {
4851
4852 final boolean isEarlyWrite;
4853
4854 RefBeforeCtorCalledError(Symbol sym, boolean isEarlyWrite) {
4855 super(sym, "prologue error");
4856 this.isEarlyWrite = isEarlyWrite;
4857 }
4858
4859 @Override
4860 JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4861 DiagnosticPosition pos,
4862 Symbol location,
4863 Type site,
4864 Name name,
4865 List<Type> argtypes,
4866 List<Type> typeargtypes) {
4867 Symbol errSym = ((sym.kind == TYP && sym.type.hasTag(CLASS))
4868 ? types.erasure(sym.type).tsym
4869 : sym);
4870 if (isEarlyWrite && (sym.flags() & HASINIT) != 0) {
4871 // Keep diagnostic compatibility with earlier versions
4872 return diags.create(dkind, log.currentSource(), pos,
4873 "cant.assign.initialized.before.ctor.called", errSym);
4874 }
4875 return diags.create(dkind, log.currentSource(), pos,
4876 "cant.ref.before.ctor.called", errSym);
4877 }
4878 }
4879
4880 /**
4881 * InvalidSymbolError error class indicating that a pair of symbols
4882 * (either methods, constructors or operands) are ambiguous
4883 * given an actual arguments/type argument list.
4884 */
4885 class AmbiguityError extends ResolveError {
4886
4887 /** The other maximally specific symbol */
4888 List<Symbol> ambiguousSyms = List.nil();
4889
4890 @Override
4891 public boolean exists() {
4892 return true;
4893 }
4894
5298 final MethodResolutionPhase step;
5299 final Symbol sym;
5300 final JCDiagnostic details;
5301 final Type mtype;
5302
5303 private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) {
5304 this.step = step;
5305 this.sym = sym;
5306 this.details = details;
5307 this.mtype = mtype;
5308 }
5309
5310 boolean isApplicable() {
5311 return mtype != null;
5312 }
5313 }
5314
5315 DeferredAttr.AttrMode attrMode() {
5316 return attrMode;
5317 }
5318 }
5319
5320 MethodResolutionContext currentResolutionContext = null;
5321 }
|