107 final Analyzer analyzer;
108 final DeferredAttr deferredAttr;
109 final Check chk;
110 final Flow flow;
111 final MemberEnter memberEnter;
112 final TypeEnter typeEnter;
113 final TreeMaker make;
114 final ConstFold cfolder;
115 final Enter enter;
116 final Target target;
117 final Types types;
118 final Preview preview;
119 final JCDiagnostic.Factory diags;
120 final TypeAnnotations typeAnnotations;
121 final TypeEnvs typeEnvs;
122 final Dependencies dependencies;
123 final Annotate annotate;
124 final ArgumentAttr argumentAttr;
125 final MatchBindingsComputer matchBindingsComputer;
126 final AttrRecover attrRecover;
127 final boolean captureMRefReturnType;
128
129 public static Attr instance(Context context) {
130 Attr instance = context.get(attrKey);
131 if (instance == null)
132 instance = new Attr(context);
133 return instance;
134 }
135
136 @SuppressWarnings("this-escape")
137 protected Attr(Context context) {
138 context.put(attrKey, this);
139
140 names = Names.instance(context);
141 log = Log.instance(context);
142 lintMapper = LintMapper.instance(context);
143 syms = Symtab.instance(context);
144 rs = Resolve.instance(context);
145 operators = Operators.instance(context);
146 chk = Check.instance(context);
147 flow = Flow.instance(context);
148 memberEnter = MemberEnter.instance(context);
149 typeEnter = TypeEnter.instance(context);
150 make = TreeMaker.instance(context);
151 enter = Enter.instance(context);
152 infer = Infer.instance(context);
153 analyzer = Analyzer.instance(context);
154 deferredAttr = DeferredAttr.instance(context);
155 cfolder = ConstFold.instance(context);
156 target = Target.instance(context);
157 types = Types.instance(context);
158 preview = Preview.instance(context);
159 diags = JCDiagnostic.Factory.instance(context);
160 annotate = Annotate.instance(context);
161 typeAnnotations = TypeAnnotations.instance(context);
162 typeEnvs = TypeEnvs.instance(context);
163 dependencies = Dependencies.instance(context);
164 argumentAttr = ArgumentAttr.instance(context);
165 matchBindingsComputer = MatchBindingsComputer.instance(context);
166 attrRecover = AttrRecover.instance(context);
167
168 Options options = Options.instance(context);
169
170 Source source = Source.instance(context);
171 allowReifiableTypesInInstanceof = Feature.REIFIABLE_TYPES_INSTANCEOF.allowedInSource(source);
172 allowRecords = Feature.RECORDS.allowedInSource(source);
173 allowPatternSwitch = (preview.isEnabled() || !preview.isPreview(Feature.PATTERN_SWITCH)) &&
174 Feature.PATTERN_SWITCH.allowedInSource(source);
175 allowUnconditionalPatternsInstanceOf =
176 Feature.UNCONDITIONAL_PATTERN_IN_INSTANCEOF.allowedInSource(source);
177 sourceName = source.name;
178 useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning");
179 captureMRefReturnType = Source.Feature.CAPTURE_MREF_RETURN_TYPE.allowedInSource(source);
180
181 statInfo = new ResultInfo(KindSelector.NIL, Type.noType);
182 varAssignmentInfo = new ResultInfo(KindSelector.ASG, Type.noType);
183 unknownExprInfo = new ResultInfo(KindSelector.VAL, Type.noType);
184 methodAttrInfo = new MethodAttrInfo();
185 unknownTypeInfo = new ResultInfo(KindSelector.TYP, Type.noType);
186 unknownTypeExprInfo = new ResultInfo(KindSelector.VAL_TYP, Type.noType);
187 recoveryInfo = new RecoveryInfo(deferredAttr.emptyDeferredAttrContext);
188 initBlockType = new MethodType(List.nil(), syms.voidType, List.nil(), syms.methodClass);
189 }
190
191 /** Switch: reifiable types in instanceof enabled?
192 */
193 boolean allowReifiableTypesInInstanceof;
194
195 /** Are records allowed
196 */
197 private final boolean allowRecords;
198
199 /** Are patterns in switch allowed
200 */
201 private final boolean allowPatternSwitch;
202
203 /** Are unconditional patterns in instanceof allowed
204 */
205 private final boolean allowUnconditionalPatternsInstanceOf;
206
207 /**
208 * Switch: warn about use of variable before declaration?
209 * RFE: 6425594
210 */
211 boolean useBeforeDeclarationWarning;
212
213 /**
214 * Switch: name of source level; used for error reporting.
215 */
216 String sourceName;
217
218 /** Check kind and type of given tree against protokind and prototype.
219 * If check succeeds, store type in tree and return it.
220 * If check fails, store errType in tree and return it.
221 * No checks are performed if the prototype is a method type.
222 * It is not necessary in this case since we know that kind and type
223 * are correct.
224 *
225 * @param tree The tree whose kind and type is checked
226 * @param found The computed type of the tree
280 owner.kind == VAR || // i.e. we are in a variable initializer
281 (owner.flags() & BLOCK) != 0) // i.e. we are in an initializer block
282 &&
283 v.owner == owner.owner
284 &&
285 ((v.flags() & STATIC) != 0) == Resolve.isStatic(env));
286 boolean insideCompactConstructor = env.enclMethod != null && TreeInfo.isCompactConstructor(env.enclMethod);
287 return isAssignable & !insideCompactConstructor;
288 }
289
290 /** Check that variable can be assigned to.
291 * @param pos The current source code position.
292 * @param v The assigned variable
293 * @param base If the variable is referred to in a Select, the part
294 * to the left of the `.', null otherwise.
295 * @param env The current environment.
296 */
297 void checkAssignable(DiagnosticPosition pos, VarSymbol v, JCTree base, Env<AttrContext> env) {
298 if (v.name == names._this) {
299 log.error(pos, Errors.CantAssignValToThis);
300 return;
301 }
302 if ((v.flags() & FINAL) != 0 &&
303 ((v.flags() & HASINIT) != 0
304 ||
305 !((base == null ||
306 TreeInfo.isThisQualifier(base)) &&
307 isAssignableAsBlankFinal(v, env)))) {
308 if (v.isResourceVariable()) { //TWR resource
309 log.error(pos, Errors.TryResourceMayNotBeAssigned(v));
310 } else {
311 log.error(pos, Errors.CantAssignValToVar(Flags.toSource(v.flags() & (STATIC | FINAL)), v));
312 }
313 return;
314 }
315
316 // Check instance field assignments that appear in constructor prologues
317 if (rs.isEarlyReference(env, base, v)) {
318
319 // Field may not be inherited from a superclass
320 if (v.owner != env.enclClass.sym) {
321 log.error(pos, Errors.CantRefBeforeCtorCalled(v));
322 return;
323 }
324
325 // Field may not have an initializer
326 if ((v.flags() & HASINIT) != 0) {
327 log.error(pos, Errors.CantAssignInitializedBeforeCtorCalled(v));
328 return;
329 }
330 }
331 }
332
333 /** Does tree represent a static reference to an identifier?
334 * It is assumed that tree is either a SELECT or an IDENT.
335 * We have to weed out selects from non-type names here.
336 * @param tree The candidate tree.
337 */
338 boolean isStaticReference(JCTree tree) {
339 if (tree.hasTag(SELECT)) {
340 Symbol lsym = TreeInfo.symbol(((JCFieldAccess) tree).selected);
341 if (lsym == null || lsym.kind != TYP) {
342 return false;
343 }
344 }
345 return true;
346 }
347
348 /** Is this symbol a type?
349 */
1108 * - have an accessibility stricter than that of the record type
1109 * - explicitly invoke any other constructor
1110 */
1111 if ((tree.sym.flags_field & GENERATEDCONSTR) == 0) {
1112 if (Check.protection(m.flags()) > Check.protection(env.enclClass.sym.flags())) {
1113 log.error(tree,
1114 (env.enclClass.sym.flags() & AccessFlags) == 0 ?
1115 Errors.InvalidCanonicalConstructorInRecord(
1116 Fragments.Canonical,
1117 env.enclClass.sym.name,
1118 Fragments.CanonicalMustNotHaveStrongerAccess("package")
1119 ) :
1120 Errors.InvalidCanonicalConstructorInRecord(
1121 Fragments.Canonical,
1122 env.enclClass.sym.name,
1123 Fragments.CanonicalMustNotHaveStrongerAccess(asFlagSet(env.enclClass.sym.flags() & AccessFlags))
1124 )
1125 );
1126 }
1127
1128 if (TreeInfo.hasAnyConstructorCall(tree)) {
1129 log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1130 Fragments.Canonical, env.enclClass.sym.name,
1131 Fragments.CanonicalMustNotContainExplicitConstructorInvocation));
1132 }
1133 }
1134
1135 // also we want to check that no type variables have been defined
1136 if (!tree.typarams.isEmpty()) {
1137 log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1138 Fragments.Canonical, env.enclClass.sym.name, Fragments.CanonicalMustNotDeclareTypeVariables));
1139 }
1140
1141 /* and now we need to check that the constructor's arguments are exactly the same as those of the
1142 * record components
1143 */
1144 List<? extends RecordComponent> recordComponents = env.enclClass.sym.getRecordComponents();
1145 List<Type> recordFieldTypes = TreeInfo.recordFields(env.enclClass).map(vd -> vd.sym.type);
1146 for (JCVariableDecl param: tree.params) {
1147 boolean paramIsVarArgs = (param.sym.flags_field & VARARGS) != 0;
1148 if (!types.isSameType(param.type, recordFieldTypes.head) ||
1186 if (tree.defaultValue != null) {
1187 if ((owner.flags() & ANNOTATION) == 0)
1188 log.error(tree.pos(),
1189 Errors.DefaultAllowedInIntfAnnotationMember);
1190 }
1191 if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0)
1192 log.error(tree.pos(), Errors.MissingMethBodyOrDeclAbstract(tree.sym, owner));
1193 } else {
1194 if ((tree.sym.flags() & (ABSTRACT|DEFAULT|PRIVATE)) == ABSTRACT) {
1195 if ((owner.flags() & INTERFACE) != 0) {
1196 log.error(tree.body.pos(), Errors.IntfMethCantHaveBody);
1197 } else {
1198 log.error(tree.pos(), Errors.AbstractMethCantHaveBody);
1199 }
1200 } else if ((tree.mods.flags & NATIVE) != 0) {
1201 log.error(tree.pos(), Errors.NativeMethCantHaveBody);
1202 }
1203 // Add an implicit super() call unless an explicit call to
1204 // super(...) or this(...) is given
1205 // or we are compiling class java.lang.Object.
1206 if (isConstructor && owner.type != syms.objectType) {
1207 if (!TreeInfo.hasAnyConstructorCall(tree)) {
1208 JCStatement supCall = make.at(tree.body.pos).Exec(make.Apply(List.nil(),
1209 make.Ident(names._super), make.Idents(List.nil())));
1210 tree.body.stats = tree.body.stats.prepend(supCall);
1211 } else if ((env.enclClass.sym.flags() & ENUM) != 0 &&
1212 (tree.mods.flags & GENERATEDCONSTR) == 0 &&
1213 TreeInfo.hasConstructorCall(tree, names._super)) {
1214 // enum constructors are not allowed to call super
1215 // directly, so make sure there aren't any super calls
1216 // in enum constructors, except in the compiler
1217 // generated one.
1218 log.error(tree.body.stats.head.pos(),
1219 Errors.CallToSuperNotAllowedInEnumCtor(env.enclClass.sym));
1220 }
1221 if (env.enclClass.sym.isRecord() && (tree.sym.flags_field & RECORD) != 0) { // we are seeing the canonical constructor
1222 List<Name> recordComponentNames = TreeInfo.recordFields(env.enclClass).map(vd -> vd.sym.name);
1223 List<Name> initParamNames = tree.sym.params.map(p -> p.name);
1224 if (!initParamNames.equals(recordComponentNames)) {
1225 log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1226 Fragments.Canonical, env.enclClass.sym.name, Fragments.CanonicalWithNameMismatch));
1227 }
1228 if (tree.sym.type.asMethodType().thrown != null && !tree.sym.type.asMethodType().thrown.isEmpty()) {
1229 log.error(tree,
1230 Errors.InvalidCanonicalConstructorInRecord(
1231 TreeInfo.isCompactConstructor(tree) ? Fragments.Compact : Fragments.Canonical,
1232 env.enclClass.sym.name,
1233 Fragments.ThrowsClauseNotAllowedForCanonicalConstructor(
1234 TreeInfo.isCompactConstructor(tree) ? Fragments.Compact : Fragments.Canonical)));
1235 }
1236 }
1237 }
1238
1239 // Attribute all type annotations in the body
1240 annotate.queueScanTreeAndTypeAnnotate(tree.body, localEnv, m);
1241 annotate.flush();
1242
1243 // Start of constructor prologue (if not in java.lang.Object constructor)
1244 localEnv.info.ctorPrologue = isConstructor && owner.type != syms.objectType;
1245
1246 // Attribute method body.
1247 attribStat(tree.body, localEnv);
1248 }
1249
1250 localEnv.info.scope.leave();
1251 result = tree.type = m.type;
1252 } finally {
1253 chk.setLint(prevLint);
1254 chk.setMethod(prevMethod);
1255 env.info.ctorPrologue = ctorProloguePrev;
1256 }
1257 }
1258
1259 public void visitVarDef(JCVariableDecl tree) {
1260 // Local variables have not been entered yet, so we need to do it now:
1261 if (env.info.scope.owner.kind == MTH || env.info.scope.owner.kind == VAR) {
1262 if (tree.sym != null) {
1263 // parameters have already been entered
1264 env.info.scope.enter(tree.sym);
1265 } else {
1266 if (tree.isImplicitlyTyped() && (tree.getModifiers().flags & PARAMETER) == 0 && tree.type == null) {
1267 if (tree.init == null) {
1268 //cannot use 'var' without initializer
1269 log.error(tree, Errors.CantInferLocalVarType(tree.name, Fragments.LocalMissingInit));
1270 tree.type = syms.errType;
1271 } else {
1272 Fragment msg = canInferLocalVarType(tree);
1273 if (msg != null) {
1274 //cannot use 'var' with initializer which require an explicit target
1275 //(e.g. lambda, method reference, array initializer).
1276 log.error(tree, Errors.CantInferLocalVarType(tree.name, msg));
1277 tree.type = syms.errType;
1278 }
1288 }
1289 } else {
1290 doQueueScanTreeAndTypeAnnotateForVarInit(tree, env);
1291 }
1292
1293 VarSymbol v = tree.sym;
1294 Lint lint = env.info.lint.augment(v);
1295 Lint prevLint = chk.setLint(lint);
1296
1297 // Check that the variable's declared type is well-formed.
1298 boolean isImplicitLambdaParameter = env.tree.hasTag(LAMBDA) &&
1299 ((JCLambda)env.tree).paramKind == JCLambda.ParameterKind.IMPLICIT &&
1300 (tree.sym.flags() & PARAMETER) != 0;
1301 chk.validate(tree.vartype, env, !isImplicitLambdaParameter && !tree.isImplicitlyTyped());
1302
1303 try {
1304 v.getConstValue(); // ensure compile-time constant initializer is evaluated
1305 chk.checkDeprecatedAnnotation(tree.pos(), v);
1306
1307 if (tree.init != null) {
1308 if ((v.flags_field & FINAL) == 0 ||
1309 !memberEnter.needsLazyConstValue(tree.init)) {
1310 // Not a compile-time constant
1311 // Attribute initializer in a new environment
1312 // with the declared variable as owner.
1313 // Check that initializer conforms to variable's declared type.
1314 Env<AttrContext> initEnv = memberEnter.initEnv(tree, env);
1315 initEnv.info.lint = lint;
1316 // In order to catch self-references, we set the variable's
1317 // declaration position to maximal possible value, effectively
1318 // marking the variable as undefined.
1319 initEnv.info.enclVar = v;
1320 attribExpr(tree.init, initEnv, v.type);
1321 if (tree.isImplicitlyTyped()) {
1322 //fixup local variable type
1323 v.type = chk.checkLocalVarType(tree, tree.init.type, tree.name);
1324 }
1325 }
1326 if (tree.isImplicitlyTyped()) {
1327 setupImplicitlyTypedVariable(tree, v.type);
1328 }
1329 }
1330 result = tree.type = v.type;
1331 if (env.enclClass.sym.isRecord() && tree.sym.owner.kind == TYP && !v.isStatic()) {
1332 if (isNonArgsMethodInObject(v.name)) {
1333 log.error(tree, Errors.IllegalRecordComponentName(v));
1334 }
1335 }
1336 chk.checkRequiresIdentity(tree, env.info.lint);
1337 }
1338 finally {
1339 chk.setLint(prevLint);
1340 }
1341 }
1342
1343 private void doQueueScanTreeAndTypeAnnotateForVarInit(JCVariableDecl tree, Env<AttrContext> env) {
1344 if (tree.init != null &&
1345 (tree.mods.flags & Flags.FIELD_INIT_TYPE_ANNOTATIONS_QUEUED) == 0 &&
1424 }
1425 }
1426 }
1427
1428 public void visitSkip(JCSkip tree) {
1429 result = null;
1430 }
1431
1432 public void visitBlock(JCBlock tree) {
1433 if (env.info.scope.owner.kind == TYP || env.info.scope.owner.kind == ERR) {
1434 // Block is a static or instance initializer;
1435 // let the owner of the environment be a freshly
1436 // created BLOCK-method.
1437 Symbol fakeOwner =
1438 new MethodSymbol(tree.flags | BLOCK |
1439 env.info.scope.owner.flags() & STRICTFP, names.empty, initBlockType,
1440 env.info.scope.owner);
1441 final Env<AttrContext> localEnv =
1442 env.dup(tree, env.info.dup(env.info.scope.dupUnshared(fakeOwner)));
1443
1444 if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
1445 // Attribute all type annotations in the block
1446 annotate.queueScanTreeAndTypeAnnotate(tree, localEnv, localEnv.info.scope.owner);
1447 annotate.flush();
1448 attribStats(tree.stats, localEnv);
1449
1450 {
1451 // Store init and clinit type annotations with the ClassSymbol
1452 // to allow output in Gen.normalizeDefs.
1453 ClassSymbol cs = (ClassSymbol)env.info.scope.owner;
1454 List<Attribute.TypeCompound> tas = localEnv.info.scope.owner.getRawTypeAttributes();
1455 if ((tree.flags & STATIC) != 0) {
1456 cs.appendClassInitTypeAttributes(tas);
1457 } else {
1458 cs.appendInitTypeAttributes(tas);
1459 }
1460 }
1461 } else {
1462 // Create a new local environment with a local scope.
1463 Env<AttrContext> localEnv =
1464 env.dup(tree, env.info.dup(env.info.scope.dup()));
1938 // where
1939 /** Return the selected enumeration constant symbol, or null. */
1940 private Symbol enumConstant(JCTree tree, Type enumType) {
1941 if (tree.hasTag(IDENT)) {
1942 JCIdent ident = (JCIdent)tree;
1943 Name name = ident.name;
1944 for (Symbol sym : enumType.tsym.members().getSymbolsByName(name)) {
1945 if (sym.kind == VAR) {
1946 Symbol s = ident.sym = sym;
1947 ((VarSymbol)s).getConstValue(); // ensure initializer is evaluated
1948 ident.type = s.type;
1949 return ((s.flags_field & Flags.ENUM) == 0)
1950 ? null : s;
1951 }
1952 }
1953 }
1954 return null;
1955 }
1956
1957 public void visitSynchronized(JCSynchronized tree) {
1958 chk.checkRefType(tree.pos(), attribExpr(tree.lock, env));
1959 if (tree.lock.type != null && tree.lock.type.isValueBased()) {
1960 log.warning(tree.pos(), LintWarnings.AttemptToSynchronizeOnInstanceOfValueBasedClass);
1961 }
1962 attribStat(tree.body, env);
1963 result = null;
1964 }
1965
1966 public void visitTry(JCTry tree) {
1967 // Create a new local environment with a local
1968 Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
1969 try {
1970 boolean isTryWithResource = tree.resources.nonEmpty();
1971 // Create a nested environment for attributing the try block if needed
1972 Env<AttrContext> tryEnv = isTryWithResource ?
1973 env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) :
1974 localEnv;
1975 try {
1976 // Attribute resource declarations
1977 for (JCTree resource : tree.resources) {
1978 CheckContext twrContext = new Check.NestedCheckContext(resultInfo.checkContext) {
1979 @Override
4400 }
4401
4402 public void visitSelect(JCFieldAccess tree) {
4403 // Determine the expected kind of the qualifier expression.
4404 KindSelector skind = KindSelector.NIL;
4405 if (tree.name == names._this || tree.name == names._super ||
4406 tree.name == names._class)
4407 {
4408 skind = KindSelector.TYP;
4409 } else {
4410 if (pkind().contains(KindSelector.PCK))
4411 skind = KindSelector.of(skind, KindSelector.PCK);
4412 if (pkind().contains(KindSelector.TYP))
4413 skind = KindSelector.of(skind, KindSelector.TYP, KindSelector.PCK);
4414 if (pkind().contains(KindSelector.VAL_MTH))
4415 skind = KindSelector.of(skind, KindSelector.VAL, KindSelector.TYP);
4416 }
4417
4418 // Attribute the qualifier expression, and determine its symbol (if any).
4419 Type site = attribTree(tree.selected, env, new ResultInfo(skind, Type.noType));
4420 if (!pkind().contains(KindSelector.TYP_PCK))
4421 site = capture(site); // Capture field access
4422
4423 // don't allow T.class T[].class, etc
4424 if (skind == KindSelector.TYP) {
4425 Type elt = site;
4426 while (elt.hasTag(ARRAY))
4427 elt = ((ArrayType)elt).elemtype;
4428 if (elt.hasTag(TYPEVAR)) {
4429 log.error(tree.pos(), Errors.TypeVarCantBeDeref);
4430 result = tree.type = types.createErrorType(tree.name, site.tsym, site);
4431 tree.sym = tree.type.tsym;
4432 return ;
4433 }
4434 }
4435
4436 // If qualifier symbol is a type or `super', assert `selectSuper'
4437 // for the selection. This is relevant for determining whether
4438 // protected symbols are accessible.
4439 Symbol sitesym = TreeInfo.symbol(tree.selected);
5512 .filter(s -> s.tsym.isSealed())
5513 .map(s -> (ClassSymbol) s.tsym)
5514 .collect(List.collector());
5515
5516 if (sealedSupers.isEmpty()) {
5517 if ((c.flags_field & Flags.NON_SEALED) != 0) {
5518 boolean hasErrorSuper = false;
5519
5520 hasErrorSuper |= types.directSupertypes(c.type)
5521 .stream()
5522 .anyMatch(s -> s.tsym.kind == Kind.ERR);
5523
5524 ClassType ct = (ClassType) c.type;
5525
5526 hasErrorSuper |= !ct.isCompound() && ct.interfaces_field != ct.all_interfaces_field;
5527
5528 if (!hasErrorSuper) {
5529 log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.NonSealedWithNoSealedSupertype(c));
5530 }
5531 }
5532 } else {
5533 if (c.isDirectlyOrIndirectlyLocal() && !c.isEnum()) {
5534 log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.LocalClassesCantExtendSealed(c.isAnonymous() ? Fragments.Anonymous : Fragments.Local));
5535 }
5536
5537 if (!c.type.isCompound()) {
5538 for (ClassSymbol supertypeSym : sealedSupers) {
5539 if (!supertypeSym.isPermittedSubclass(c.type.tsym)) {
5540 log.error(TreeInfo.diagnosticPositionFor(c.type.tsym, env.tree), Errors.CantInheritFromSealed(supertypeSym));
5541 }
5542 }
5543 if (!c.isNonSealed() && !c.isFinal() && !c.isSealed()) {
5544 log.error(TreeInfo.diagnosticPositionFor(c, env.tree),
5545 c.isInterface() ?
5546 Errors.NonSealedOrSealedExpected :
5547 Errors.NonSealedSealedOrFinalExpected);
5548 }
5549 }
5550 }
5551
5552 env.info.returnResult = null;
5553 // java.lang.Enum may not be subclassed by a non-enum
5554 if (st.tsym == syms.enumSym &&
5555 ((c.flags_field & (Flags.ENUM|Flags.COMPOUND)) == 0))
5556 log.error(env.tree.pos(), Errors.EnumNoSubclassing);
5557
5558 // Enums may not be extended by source-level classes
5559 if (st.tsym != null &&
5560 ((st.tsym.flags_field & Flags.ENUM) != 0) &&
5561 ((c.flags_field & (Flags.ENUM | Flags.COMPOUND)) == 0)) {
5562 log.error(env.tree.pos(), Errors.EnumTypesNotExtensible);
5563 }
5564
5565 if (rs.isSerializable(c.type)) {
5566 env.info.isSerializable = true;
5567 }
5568
5569 attribClassBody(env, c);
5570
5571 chk.checkDeprecatedAnnotation(env.tree.pos(), c);
5572 chk.checkClassOverrideEqualsAndHashIfNeeded(env.tree.pos(), c);
5573 chk.checkFunctionalInterface((JCClassDecl) env.tree, c);
5574 chk.checkLeaksNotAccessible(env, (JCClassDecl) env.tree);
5575
5576 if (c.isImplicit()) {
5577 chk.checkHasMain(env.tree.pos(), c);
5578 }
5579 } finally {
5580 env.info.returnResult = prevReturnRes;
5581 log.useSource(prev);
5582 chk.setLint(prevLint);
5583 }
5584
5585 }
5586 }
5587
5588 public void visitImport(JCImport tree) {
5695 sym.kind != VAR ||
5696 sym.getConstValue() == null)
5697 log.error(l.head.pos(), Errors.IclsCantHaveStaticDecl(c));
5698 }
5699 }
5700
5701 // Check for proper placement of super()/this() calls.
5702 chk.checkSuperInitCalls(tree);
5703
5704 // Check for cycles among non-initial constructors.
5705 chk.checkCyclicConstructors(tree);
5706
5707 // Check for cycles among annotation elements.
5708 chk.checkNonCyclicElements(tree);
5709
5710 // Check for proper use of serialVersionUID and other
5711 // serialization-related fields and methods
5712 if (env.info.lint.isEnabled(LintCategory.SERIAL)
5713 && rs.isSerializable(c.type)
5714 && !c.isAnonymous()) {
5715 chk.checkSerialStructure(tree, c);
5716 }
5717 // Correctly organize the positions of the type annotations
5718 typeAnnotations.organizeTypeAnnotationsBodies(tree);
5719
5720 // Check type annotations applicability rules
5721 validateTypeAnnotations(tree, false);
5722 }
5723 // where
5724 /** get a diagnostic position for an attribute of Type t, or null if attribute missing */
5725 private DiagnosticPosition getDiagnosticPosition(JCClassDecl tree, Type t) {
5726 for(List<JCAnnotation> al = tree.mods.annotations; !al.isEmpty(); al = al.tail) {
5727 if (types.isSameType(al.head.annotationType.type, t))
5728 return al.head.pos();
5729 }
5730
5731 return null;
5732 }
5733
5734 private Type capture(Type type) {
5735 return types.capture(type);
|
107 final Analyzer analyzer;
108 final DeferredAttr deferredAttr;
109 final Check chk;
110 final Flow flow;
111 final MemberEnter memberEnter;
112 final TypeEnter typeEnter;
113 final TreeMaker make;
114 final ConstFold cfolder;
115 final Enter enter;
116 final Target target;
117 final Types types;
118 final Preview preview;
119 final JCDiagnostic.Factory diags;
120 final TypeAnnotations typeAnnotations;
121 final TypeEnvs typeEnvs;
122 final Dependencies dependencies;
123 final Annotate annotate;
124 final ArgumentAttr argumentAttr;
125 final MatchBindingsComputer matchBindingsComputer;
126 final AttrRecover attrRecover;
127 final LocalProxyVarsGen localProxyVarsGen;
128 final boolean captureMRefReturnType;
129
130 public static Attr instance(Context context) {
131 Attr instance = context.get(attrKey);
132 if (instance == null)
133 instance = new Attr(context);
134 return instance;
135 }
136
137 @SuppressWarnings("this-escape")
138 protected Attr(Context context) {
139 context.put(attrKey, this);
140
141 names = Names.instance(context);
142 log = Log.instance(context);
143 lintMapper = LintMapper.instance(context);
144 syms = Symtab.instance(context);
145 rs = Resolve.instance(context);
146 operators = Operators.instance(context);
147 chk = Check.instance(context);
148 flow = Flow.instance(context);
149 memberEnter = MemberEnter.instance(context);
150 typeEnter = TypeEnter.instance(context);
151 make = TreeMaker.instance(context);
152 enter = Enter.instance(context);
153 infer = Infer.instance(context);
154 analyzer = Analyzer.instance(context);
155 deferredAttr = DeferredAttr.instance(context);
156 cfolder = ConstFold.instance(context);
157 target = Target.instance(context);
158 types = Types.instance(context);
159 preview = Preview.instance(context);
160 diags = JCDiagnostic.Factory.instance(context);
161 annotate = Annotate.instance(context);
162 typeAnnotations = TypeAnnotations.instance(context);
163 typeEnvs = TypeEnvs.instance(context);
164 dependencies = Dependencies.instance(context);
165 argumentAttr = ArgumentAttr.instance(context);
166 matchBindingsComputer = MatchBindingsComputer.instance(context);
167 attrRecover = AttrRecover.instance(context);
168 localProxyVarsGen = LocalProxyVarsGen.instance(context);
169
170 Options options = Options.instance(context);
171
172 Source source = Source.instance(context);
173 allowReifiableTypesInInstanceof = Feature.REIFIABLE_TYPES_INSTANCEOF.allowedInSource(source);
174 allowRecords = Feature.RECORDS.allowedInSource(source);
175 allowPatternSwitch = (preview.isEnabled() || !preview.isPreview(Feature.PATTERN_SWITCH)) &&
176 Feature.PATTERN_SWITCH.allowedInSource(source);
177 allowUnconditionalPatternsInstanceOf =
178 Feature.UNCONDITIONAL_PATTERN_IN_INSTANCEOF.allowedInSource(source);
179 sourceName = source.name;
180 useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning");
181 captureMRefReturnType = Source.Feature.CAPTURE_MREF_RETURN_TYPE.allowedInSource(source);
182
183 statInfo = new ResultInfo(KindSelector.NIL, Type.noType);
184 varAssignmentInfo = new ResultInfo(KindSelector.ASG, Type.noType);
185 unknownExprInfo = new ResultInfo(KindSelector.VAL, Type.noType);
186 methodAttrInfo = new MethodAttrInfo();
187 unknownTypeInfo = new ResultInfo(KindSelector.TYP, Type.noType);
188 unknownTypeExprInfo = new ResultInfo(KindSelector.VAL_TYP, Type.noType);
189 recoveryInfo = new RecoveryInfo(deferredAttr.emptyDeferredAttrContext);
190 initBlockType = new MethodType(List.nil(), syms.voidType, List.nil(), syms.methodClass);
191 allowValueClasses = (!preview.isPreview(Feature.VALUE_CLASSES) || preview.isEnabled()) &&
192 Feature.VALUE_CLASSES.allowedInSource(source);
193 }
194
195 /** Switch: reifiable types in instanceof enabled?
196 */
197 boolean allowReifiableTypesInInstanceof;
198
199 /** Are records allowed
200 */
201 private final boolean allowRecords;
202
203 /** Are patterns in switch allowed
204 */
205 private final boolean allowPatternSwitch;
206
207 /** Are unconditional patterns in instanceof allowed
208 */
209 private final boolean allowUnconditionalPatternsInstanceOf;
210
211 /** Are value classes allowed
212 */
213 private final boolean allowValueClasses;
214
215 /**
216 * Switch: warn about use of variable before declaration?
217 * RFE: 6425594
218 */
219 boolean useBeforeDeclarationWarning;
220
221 /**
222 * Switch: name of source level; used for error reporting.
223 */
224 String sourceName;
225
226 /** Check kind and type of given tree against protokind and prototype.
227 * If check succeeds, store type in tree and return it.
228 * If check fails, store errType in tree and return it.
229 * No checks are performed if the prototype is a method type.
230 * It is not necessary in this case since we know that kind and type
231 * are correct.
232 *
233 * @param tree The tree whose kind and type is checked
234 * @param found The computed type of the tree
288 owner.kind == VAR || // i.e. we are in a variable initializer
289 (owner.flags() & BLOCK) != 0) // i.e. we are in an initializer block
290 &&
291 v.owner == owner.owner
292 &&
293 ((v.flags() & STATIC) != 0) == Resolve.isStatic(env));
294 boolean insideCompactConstructor = env.enclMethod != null && TreeInfo.isCompactConstructor(env.enclMethod);
295 return isAssignable & !insideCompactConstructor;
296 }
297
298 /** Check that variable can be assigned to.
299 * @param pos The current source code position.
300 * @param v The assigned variable
301 * @param base If the variable is referred to in a Select, the part
302 * to the left of the `.', null otherwise.
303 * @param env The current environment.
304 */
305 void checkAssignable(DiagnosticPosition pos, VarSymbol v, JCTree base, Env<AttrContext> env) {
306 if (v.name == names._this) {
307 log.error(pos, Errors.CantAssignValToThis);
308 } else if ((v.flags() & FINAL) != 0 &&
309 ((v.flags() & HASINIT) != 0
310 ||
311 !((base == null ||
312 TreeInfo.isThisQualifier(base)) &&
313 isAssignableAsBlankFinal(v, env)))) {
314 if (v.isResourceVariable()) { //TWR resource
315 log.error(pos, Errors.TryResourceMayNotBeAssigned(v));
316 } else {
317 log.error(pos, Errors.CantAssignValToVar(Flags.toSource(v.flags() & (STATIC | FINAL)), v));
318 }
319 }
320 }
321
322 /** Does tree represent a static reference to an identifier?
323 * It is assumed that tree is either a SELECT or an IDENT.
324 * We have to weed out selects from non-type names here.
325 * @param tree The candidate tree.
326 */
327 boolean isStaticReference(JCTree tree) {
328 if (tree.hasTag(SELECT)) {
329 Symbol lsym = TreeInfo.symbol(((JCFieldAccess) tree).selected);
330 if (lsym == null || lsym.kind != TYP) {
331 return false;
332 }
333 }
334 return true;
335 }
336
337 /** Is this symbol a type?
338 */
1097 * - have an accessibility stricter than that of the record type
1098 * - explicitly invoke any other constructor
1099 */
1100 if ((tree.sym.flags_field & GENERATEDCONSTR) == 0) {
1101 if (Check.protection(m.flags()) > Check.protection(env.enclClass.sym.flags())) {
1102 log.error(tree,
1103 (env.enclClass.sym.flags() & AccessFlags) == 0 ?
1104 Errors.InvalidCanonicalConstructorInRecord(
1105 Fragments.Canonical,
1106 env.enclClass.sym.name,
1107 Fragments.CanonicalMustNotHaveStrongerAccess("package")
1108 ) :
1109 Errors.InvalidCanonicalConstructorInRecord(
1110 Fragments.Canonical,
1111 env.enclClass.sym.name,
1112 Fragments.CanonicalMustNotHaveStrongerAccess(asFlagSet(env.enclClass.sym.flags() & AccessFlags))
1113 )
1114 );
1115 }
1116
1117 if ((!allowValueClasses || TreeInfo.isCompactConstructor(tree)) &&
1118 TreeInfo.hasAnyConstructorCall(tree)) {
1119 log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1120 Fragments.Canonical, env.enclClass.sym.name,
1121 Fragments.CanonicalMustNotContainExplicitConstructorInvocation));
1122 }
1123 }
1124
1125 // also we want to check that no type variables have been defined
1126 if (!tree.typarams.isEmpty()) {
1127 log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1128 Fragments.Canonical, env.enclClass.sym.name, Fragments.CanonicalMustNotDeclareTypeVariables));
1129 }
1130
1131 /* and now we need to check that the constructor's arguments are exactly the same as those of the
1132 * record components
1133 */
1134 List<? extends RecordComponent> recordComponents = env.enclClass.sym.getRecordComponents();
1135 List<Type> recordFieldTypes = TreeInfo.recordFields(env.enclClass).map(vd -> vd.sym.type);
1136 for (JCVariableDecl param: tree.params) {
1137 boolean paramIsVarArgs = (param.sym.flags_field & VARARGS) != 0;
1138 if (!types.isSameType(param.type, recordFieldTypes.head) ||
1176 if (tree.defaultValue != null) {
1177 if ((owner.flags() & ANNOTATION) == 0)
1178 log.error(tree.pos(),
1179 Errors.DefaultAllowedInIntfAnnotationMember);
1180 }
1181 if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0)
1182 log.error(tree.pos(), Errors.MissingMethBodyOrDeclAbstract(tree.sym, owner));
1183 } else {
1184 if ((tree.sym.flags() & (ABSTRACT|DEFAULT|PRIVATE)) == ABSTRACT) {
1185 if ((owner.flags() & INTERFACE) != 0) {
1186 log.error(tree.body.pos(), Errors.IntfMethCantHaveBody);
1187 } else {
1188 log.error(tree.pos(), Errors.AbstractMethCantHaveBody);
1189 }
1190 } else if ((tree.mods.flags & NATIVE) != 0) {
1191 log.error(tree.pos(), Errors.NativeMethCantHaveBody);
1192 }
1193 // Add an implicit super() call unless an explicit call to
1194 // super(...) or this(...) is given
1195 // or we are compiling class java.lang.Object.
1196 boolean addedSuperInIdentityClass = false;
1197 if (isConstructor && owner.type != syms.objectType) {
1198 if (!TreeInfo.hasAnyConstructorCall(tree)) {
1199 JCStatement supCall = make.at(tree.body.pos).Exec(make.Apply(List.nil(),
1200 make.Ident(names._super), make.Idents(List.nil())));
1201 if (allowValueClasses && (owner.isValueClass() || ((owner.flags_field & RECORD) != 0))) {
1202 tree.body.stats = tree.body.stats.append(supCall);
1203 } else {
1204 tree.body.stats = tree.body.stats.prepend(supCall);
1205 addedSuperInIdentityClass = true;
1206 }
1207 } else if ((env.enclClass.sym.flags() & ENUM) != 0 &&
1208 (tree.mods.flags & GENERATEDCONSTR) == 0 &&
1209 TreeInfo.hasConstructorCall(tree, names._super)) {
1210 // enum constructors are not allowed to call super
1211 // directly, so make sure there aren't any super calls
1212 // in enum constructors, except in the compiler
1213 // generated one.
1214 log.error(tree.body.stats.head.pos(),
1215 Errors.CallToSuperNotAllowedInEnumCtor(env.enclClass.sym));
1216 }
1217 if (env.enclClass.sym.isRecord() && (tree.sym.flags_field & RECORD) != 0) { // we are seeing the canonical constructor
1218 List<Name> recordComponentNames = TreeInfo.recordFields(env.enclClass).map(vd -> vd.sym.name);
1219 List<Name> initParamNames = tree.sym.params.map(p -> p.name);
1220 if (!initParamNames.equals(recordComponentNames)) {
1221 log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1222 Fragments.Canonical, env.enclClass.sym.name, Fragments.CanonicalWithNameMismatch));
1223 }
1224 if (tree.sym.type.asMethodType().thrown != null && !tree.sym.type.asMethodType().thrown.isEmpty()) {
1225 log.error(tree,
1226 Errors.InvalidCanonicalConstructorInRecord(
1227 TreeInfo.isCompactConstructor(tree) ? Fragments.Compact : Fragments.Canonical,
1228 env.enclClass.sym.name,
1229 Fragments.ThrowsClauseNotAllowedForCanonicalConstructor(
1230 TreeInfo.isCompactConstructor(tree) ? Fragments.Compact : Fragments.Canonical)));
1231 }
1232 }
1233 }
1234
1235 // Attribute all type annotations in the body
1236 annotate.queueScanTreeAndTypeAnnotate(tree.body, localEnv, m);
1237 annotate.flush();
1238
1239 // Start of constructor prologue (if not in java.lang.Object constructor)
1240 localEnv.info.ctorPrologue = isConstructor && owner.type != syms.objectType;
1241
1242 // Attribute method body.
1243 attribStat(tree.body, localEnv);
1244 if (localEnv.info.ctorPrologue) {
1245 boolean thisInvocation = false;
1246 ListBuffer<JCTree> prologueCode = new ListBuffer<>();
1247 for (JCTree stat : tree.body.stats) {
1248 prologueCode.add(stat);
1249 /* gather all the stats in the body until a `super` or `this` constructor invocation is found,
1250 * including the constructor invocation, that way we don't need to worry in the visitor below if
1251 * if we are dealing or not with prologue code
1252 */
1253 if (stat instanceof JCExpressionStatement expStmt &&
1254 expStmt.expr instanceof JCMethodInvocation mi &&
1255 TreeInfo.isConstructorCall(mi)) {
1256 thisInvocation = TreeInfo.name(mi.meth) == names._this;
1257 if (!addedSuperInIdentityClass || !allowValueClasses) {
1258 break;
1259 }
1260 }
1261 }
1262 if (!prologueCode.isEmpty()) {
1263 CtorPrologueVisitor ctorPrologueVisitor = new CtorPrologueVisitor(localEnv,
1264 addedSuperInIdentityClass && allowValueClasses ?
1265 PrologueVisitorMode.WARNINGS_ONLY :
1266 thisInvocation ?
1267 PrologueVisitorMode.THIS_CONSTRUCTOR :
1268 PrologueVisitorMode.SUPER_CONSTRUCTOR,
1269 false);
1270 ctorPrologueVisitor.scan(prologueCode.toList());
1271 }
1272 }
1273 }
1274
1275 localEnv.info.scope.leave();
1276 result = tree.type = m.type;
1277 } finally {
1278 chk.setLint(prevLint);
1279 chk.setMethod(prevMethod);
1280 env.info.ctorPrologue = ctorProloguePrev;
1281 }
1282 }
1283
1284 enum PrologueVisitorMode {
1285 WARNINGS_ONLY,
1286 SUPER_CONSTRUCTOR,
1287 THIS_CONSTRUCTOR
1288 }
1289
1290 class CtorPrologueVisitor extends TreeScanner {
1291 Env<AttrContext> localEnv;
1292 PrologueVisitorMode mode;
1293 boolean isInitializer;
1294
1295 CtorPrologueVisitor(Env<AttrContext> localEnv, PrologueVisitorMode mode, boolean isInitializer) {
1296 this.localEnv = localEnv;
1297 currentClassSym = localEnv.enclClass.sym;
1298 this.mode = mode;
1299 this.isInitializer = isInitializer;
1300 }
1301
1302 boolean insideLambdaOrClassDef = false;
1303
1304 @Override
1305 public void visitLambda(JCLambda lambda) {
1306 boolean previousInsideLambdaOrClassDef = insideLambdaOrClassDef;
1307 try {
1308 insideLambdaOrClassDef = true;
1309 super.visitLambda(lambda);
1310 } finally {
1311 insideLambdaOrClassDef = previousInsideLambdaOrClassDef;
1312 }
1313 }
1314
1315 ClassSymbol currentClassSym;
1316
1317 @Override
1318 public void visitClassDef(JCClassDecl classDecl) {
1319 boolean previousInsideLambdaOrClassDef = insideLambdaOrClassDef;
1320 ClassSymbol previousClassSym = currentClassSym;
1321 try {
1322 insideLambdaOrClassDef = true;
1323 currentClassSym = classDecl.sym;
1324 super.visitClassDef(classDecl);
1325 } finally {
1326 insideLambdaOrClassDef = previousInsideLambdaOrClassDef;
1327 currentClassSym = previousClassSym;
1328 }
1329 }
1330
1331 private void reportPrologueError(JCTree tree, Symbol sym) {
1332 reportPrologueError(tree, sym, false);
1333 }
1334
1335 private void reportPrologueError(JCTree tree, Symbol sym, boolean hasInit) {
1336 preview.checkSourceLevel(tree, Feature.FLEXIBLE_CONSTRUCTORS);
1337 if (mode != PrologueVisitorMode.WARNINGS_ONLY) {
1338 if (hasInit) {
1339 log.error(tree, Errors.CantAssignInitializedBeforeCtorCalled(sym));
1340 } else {
1341 log.error(tree, Errors.CantRefBeforeCtorCalled(sym));
1342 }
1343 } else if (allowValueClasses) {
1344 // issue lint warning
1345 log.warning(tree, LintWarnings.WouldNotBeAllowedInPrologue(sym));
1346 }
1347 }
1348
1349 @Override
1350 public void visitApply(JCMethodInvocation tree) {
1351 super.visitApply(tree);
1352 Name name = TreeInfo.name(tree.meth);
1353 boolean isConstructorCall = name == names._this || name == names._super;
1354 Symbol msym = TreeInfo.symbolFor(tree.meth);
1355 // is this an instance method call or an illegal constructor invocation like: `this.super()`?
1356 if (msym != null && // for erroneous invocations msym can be null, ignore those
1357 (!isConstructorCall ||
1358 isConstructorCall && tree.meth.hasTag(SELECT))) {
1359 if (isEarlyReference(localEnv, tree.meth, msym))
1360 reportPrologueError(tree.meth, msym);
1361 }
1362 }
1363
1364 @Override
1365 public void visitIdent(JCIdent tree) {
1366 analyzeSymbol(tree);
1367 }
1368
1369 boolean isIndexed = false;
1370
1371 @Override
1372 public void visitIndexed(JCArrayAccess tree) {
1373 boolean previousIsIndexed = isIndexed;
1374 try {
1375 isIndexed = true;
1376 scan(tree.indexed);
1377 } finally {
1378 isIndexed = previousIsIndexed;
1379 }
1380 scan(tree.index);
1381 if (mode == PrologueVisitorMode.SUPER_CONSTRUCTOR && isInstanceField(tree.indexed)) {
1382 localProxyVarsGen.addFieldReadInPrologue(localEnv.enclMethod, TreeInfo.symbolFor(tree.indexed));
1383 }
1384 }
1385
1386 @Override
1387 public void visitSelect(JCFieldAccess tree) {
1388 SelectScanner ss = new SelectScanner();
1389 ss.scan(tree);
1390 if (ss.scanLater == null) {
1391 Symbol sym = TreeInfo.symbolFor(tree);
1392 // if this is a field access
1393 if (sym.kind == VAR && sym.owner.kind == TYP) {
1394 // Type.super.field or super.field expressions are forbidden in early construction contexts
1395 for (JCTree subtree : ss.selectorTrees) {
1396 if (TreeInfo.isSuperOrSelectorDotSuper(subtree)) {
1397 reportPrologueError(tree, sym);
1398 return;
1399 } else if (mode == PrologueVisitorMode.THIS_CONSTRUCTOR &&
1400 TreeInfo.isThisOrSelectorDotThis(subtree) &&
1401 TreeInfo.isExplicitThisReference(
1402 types,
1403 (ClassType)localEnv.enclClass.sym.type,
1404 subtree)) {
1405 reportPrologueError(tree, sym);
1406 return;
1407 }
1408 }
1409 }
1410 analyzeSymbol(tree);
1411 } else {
1412 boolean prevLhs = isInLHS;
1413 try {
1414 isInLHS = false;
1415 scan(ss.scanLater);
1416 } finally {
1417 isInLHS = prevLhs;
1418 }
1419 }
1420 if (mode == PrologueVisitorMode.SUPER_CONSTRUCTOR) {
1421 for (JCTree subtree : ss.selectorTrees) {
1422 if (isInstanceField(subtree)) {
1423 // we need to add a proxy for this one
1424 localProxyVarsGen.addFieldReadInPrologue(localEnv.enclMethod, TreeInfo.symbolFor(subtree));
1425 }
1426 }
1427 }
1428 }
1429
1430 private boolean isInstanceField(JCTree tree) {
1431 Symbol sym = TreeInfo.symbolFor(tree);
1432 return (sym != null &&
1433 !sym.isStatic() &&
1434 sym.kind == VAR &&
1435 sym.owner.kind == TYP &&
1436 sym.name != names._this &&
1437 sym.name != names._super &&
1438 isEarlyReference(localEnv, tree, sym));
1439 }
1440
1441 @Override
1442 public void visitNewClass(JCNewClass tree) {
1443 super.visitNewClass(tree);
1444 checkNewClassAndMethRefs(tree, tree.type);
1445 }
1446
1447 @Override
1448 public void visitReference(JCMemberReference tree) {
1449 super.visitReference(tree);
1450 if (tree.getMode() == JCMemberReference.ReferenceMode.NEW) {
1451 checkNewClassAndMethRefs(tree, tree.expr.type);
1452 }
1453 }
1454
1455 void checkNewClassAndMethRefs(JCTree tree, Type t) {
1456 if (t.tsym.isInner() &&
1457 t.tsym.isEnclosedBy(localEnv.enclClass.sym) &&
1458 !t.tsym.isDirectlyOrIndirectlyLocal()) {
1459 reportPrologueError(tree, t.getEnclosingType().tsym);
1460 }
1461 }
1462
1463 /* if a symbol is in the LHS of an assignment expression we won't consider it as a candidate
1464 * for a proxy local variable later on
1465 */
1466 boolean isInLHS = false;
1467
1468 @Override
1469 public void visitAssign(JCAssign tree) {
1470 boolean previousIsInLHS = isInLHS;
1471 try {
1472 isInLHS = true;
1473 scan(tree.lhs);
1474 } finally {
1475 isInLHS = previousIsInLHS;
1476 }
1477 scan(tree.rhs);
1478 }
1479
1480 @Override
1481 public void visitMethodDef(JCMethodDecl tree) {
1482 // ignore any declarative part, mainly to avoid scanning receiver parameters
1483 scan(tree.body);
1484 }
1485
1486 void analyzeSymbol(JCTree tree) {
1487 Symbol sym = TreeInfo.symbolFor(tree);
1488 // make sure that there is a symbol and it is not static
1489 if (sym == null || sym.isStatic()) {
1490 return;
1491 }
1492 if (isInLHS && !insideLambdaOrClassDef) {
1493 // Check instance field assignments that appear in constructor prologues
1494 if (isEarlyReference(localEnv, tree, sym)) {
1495 // Field may not be inherited from a superclass
1496 if (sym.owner != localEnv.enclClass.sym) {
1497 reportPrologueError(tree, sym);
1498 return;
1499 }
1500 // Field may not have an initializer
1501 if ((sym.flags() & HASINIT) != 0) {
1502 if (!localEnv.enclClass.sym.isValueClass() || !sym.type.hasTag(ARRAY) || !isIndexed) {
1503 reportPrologueError(tree, sym, true);
1504 }
1505 return;
1506 }
1507 // cant reference an instance field before a this constructor
1508 if (allowValueClasses && mode == PrologueVisitorMode.THIS_CONSTRUCTOR) {
1509 reportPrologueError(tree, sym);
1510 return;
1511 }
1512 }
1513 return;
1514 }
1515 tree = TreeInfo.skipParens(tree);
1516 if (sym.kind == VAR && sym.owner.kind == TYP) {
1517 if (sym.name == names._this || sym.name == names._super) {
1518 // are we seeing something like `this` or `CurrentClass.this` or `SuperClass.super::foo`?
1519 if (TreeInfo.isExplicitThisReference(
1520 types,
1521 (ClassType)localEnv.enclClass.sym.type,
1522 tree)) {
1523 reportPrologueError(tree, sym);
1524 }
1525 } else if (sym.kind == VAR && sym.owner.kind == TYP) { // now fields only
1526 if (sym.owner != localEnv.enclClass.sym) {
1527 if (localEnv.enclClass.sym.isSubClass(sym.owner, types) &&
1528 sym.isInheritedIn(localEnv.enclClass.sym, types)) {
1529 /* if we are dealing with a field that doesn't belong to the current class, but the
1530 * field is inherited, this is an error. Unless, the super class is also an outer
1531 * class and the field's qualifier refers to the outer class
1532 */
1533 if (tree.hasTag(IDENT) ||
1534 TreeInfo.isExplicitThisReference(
1535 types,
1536 (ClassType)localEnv.enclClass.sym.type,
1537 ((JCFieldAccess)tree).selected)) {
1538 reportPrologueError(tree, sym);
1539 }
1540 }
1541 } else if (isEarlyReference(localEnv, tree, sym)) {
1542 /* now this is a `proper` instance field of the current class
1543 * references to fields of identity classes which happen to have initializers are
1544 * not allowed in the prologue.
1545 * But it is OK for a field with initializer to refer to another field with initializer,
1546 * so no warning or error if we are analyzing a field initializer.
1547 */
1548 if (insideLambdaOrClassDef ||
1549 (!localEnv.enclClass.sym.isValueClass() &&
1550 (sym.flags_field & HASINIT) != 0 &&
1551 !isInitializer))
1552 reportPrologueError(tree, sym);
1553 // we will need to generate a proxy for this field later on
1554 if (!isInLHS) {
1555 if (!allowValueClasses) {
1556 reportPrologueError(tree, sym);
1557 } else {
1558 if (mode == PrologueVisitorMode.THIS_CONSTRUCTOR) {
1559 reportPrologueError(tree, sym);
1560 } else if (mode == PrologueVisitorMode.SUPER_CONSTRUCTOR && isInstanceField(tree)) {
1561 localProxyVarsGen.addFieldReadInPrologue(localEnv.enclMethod, sym);
1562 }
1563 /* we do nothing in warnings only mode, as in that mode we are simulating what
1564 * the compiler would do in case the constructor code would be in the prologue
1565 * phase
1566 */
1567 }
1568 }
1569 }
1570 }
1571 }
1572 }
1573
1574 /**
1575 * Determine if the symbol appearance constitutes an early reference to the current class.
1576 *
1577 * <p>
1578 * This means the symbol is an instance field, or method, of the current class and it appears
1579 * in an early initialization context of it (i.e., one of its constructor prologues).
1580 *
1581 * @param env The current environment
1582 * @param tree the AST referencing the variable
1583 * @param sym The symbol
1584 */
1585 private boolean isEarlyReference(Env<AttrContext> env, JCTree tree, Symbol sym) {
1586 if ((sym.kind == VAR || sym.kind == MTH) &&
1587 sym.isMemberOf(env.enclClass.sym, types) &&
1588 ((sym.flags() & STATIC) == 0 ||
1589 (sym.kind == MTH && tree instanceof JCFieldAccess))) {
1590 // Allow "Foo.this.x" when "Foo" is (also) an outer class, as this refers to the outer instance
1591 if (tree instanceof JCFieldAccess fa) {
1592 return TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, fa.selected);
1593 } else if (currentClassSym != env.enclClass.sym) {
1594 /* so we are inside a class, CI, in the prologue of an outer class, CO, and the symbol being
1595 * analyzed has no qualifier. So if the symbol is a member of CI the reference is allowed,
1596 * otherwise it is not.
1597 * It could be that the reference to CI's member happens inside CI's own prologue, but that
1598 * will be checked separately, when CI's prologue is analyzed.
1599 */
1600 return !sym.isMemberOf(currentClassSym, types);
1601 }
1602 return true;
1603 }
1604 return false;
1605 }
1606
1607 /* scanner for a select expression, anything that is not a select or identifier
1608 * will be stored for further analysis
1609 */
1610 class SelectScanner extends DeferredAttr.FilterScanner {
1611 JCTree scanLater;
1612 java.util.List<JCTree> selectorTrees = new ArrayList<>();
1613
1614 SelectScanner() {
1615 super(Set.of(IDENT, SELECT, PARENS));
1616 }
1617
1618 @Override
1619 public void visitSelect(JCFieldAccess tree) {
1620 super.visitSelect(tree);
1621 selectorTrees.add(tree.selected);
1622 }
1623
1624 @Override
1625 void skip(JCTree tree) {
1626 scanLater = tree;
1627 }
1628 }
1629 }
1630
1631 public void visitVarDef(JCVariableDecl tree) {
1632 // Local variables have not been entered yet, so we need to do it now:
1633 if (env.info.scope.owner.kind == MTH || env.info.scope.owner.kind == VAR) {
1634 if (tree.sym != null) {
1635 // parameters have already been entered
1636 env.info.scope.enter(tree.sym);
1637 } else {
1638 if (tree.isImplicitlyTyped() && (tree.getModifiers().flags & PARAMETER) == 0 && tree.type == null) {
1639 if (tree.init == null) {
1640 //cannot use 'var' without initializer
1641 log.error(tree, Errors.CantInferLocalVarType(tree.name, Fragments.LocalMissingInit));
1642 tree.type = syms.errType;
1643 } else {
1644 Fragment msg = canInferLocalVarType(tree);
1645 if (msg != null) {
1646 //cannot use 'var' with initializer which require an explicit target
1647 //(e.g. lambda, method reference, array initializer).
1648 log.error(tree, Errors.CantInferLocalVarType(tree.name, msg));
1649 tree.type = syms.errType;
1650 }
1660 }
1661 } else {
1662 doQueueScanTreeAndTypeAnnotateForVarInit(tree, env);
1663 }
1664
1665 VarSymbol v = tree.sym;
1666 Lint lint = env.info.lint.augment(v);
1667 Lint prevLint = chk.setLint(lint);
1668
1669 // Check that the variable's declared type is well-formed.
1670 boolean isImplicitLambdaParameter = env.tree.hasTag(LAMBDA) &&
1671 ((JCLambda)env.tree).paramKind == JCLambda.ParameterKind.IMPLICIT &&
1672 (tree.sym.flags() & PARAMETER) != 0;
1673 chk.validate(tree.vartype, env, !isImplicitLambdaParameter && !tree.isImplicitlyTyped());
1674
1675 try {
1676 v.getConstValue(); // ensure compile-time constant initializer is evaluated
1677 chk.checkDeprecatedAnnotation(tree.pos(), v);
1678
1679 if (tree.init != null) {
1680 Env<AttrContext> initEnv = memberEnter.initEnv(tree, env);
1681 if ((v.flags_field & FINAL) == 0 ||
1682 !memberEnter.needsLazyConstValue(tree.init)) {
1683 // Not a compile-time constant
1684 // Attribute initializer in a new environment
1685 // with the declared variable as owner.
1686 // Check that initializer conforms to variable's declared type.
1687 initEnv.info.lint = lint;
1688 // In order to catch self-references, we set the variable's
1689 // declaration position to maximal possible value, effectively
1690 // marking the variable as undefined.
1691 initEnv.info.enclVar = v;
1692 boolean previousCtorPrologue = initEnv.info.ctorPrologue;
1693 try {
1694 if (v.owner.kind == TYP && !v.isStatic() && v.isStrict()) {
1695 // strict instance initializer in a value class
1696 initEnv.info.ctorPrologue = true;
1697 }
1698 attribExpr(tree.init, initEnv, v.type);
1699 if (tree.isImplicitlyTyped()) {
1700 //fixup local variable type
1701 v.type = chk.checkLocalVarType(tree, tree.init.type, tree.name);
1702 }
1703 } finally {
1704 initEnv.info.ctorPrologue = previousCtorPrologue;
1705 }
1706 }
1707 if (allowValueClasses && v.owner.kind == TYP && !v.isStatic()) {
1708 // strict field initializers are inlined in constructor's prologues
1709 CtorPrologueVisitor ctorPrologueVisitor = new CtorPrologueVisitor(initEnv,
1710 !v.isStrict() ? PrologueVisitorMode.WARNINGS_ONLY : PrologueVisitorMode.SUPER_CONSTRUCTOR,
1711 true);
1712 ctorPrologueVisitor.scan(tree.init);
1713 }
1714 if (tree.isImplicitlyTyped()) {
1715 setupImplicitlyTypedVariable(tree, v.type);
1716 }
1717 }
1718 result = tree.type = v.type;
1719 if (env.enclClass.sym.isRecord() && tree.sym.owner.kind == TYP && !v.isStatic()) {
1720 if (isNonArgsMethodInObject(v.name)) {
1721 log.error(tree, Errors.IllegalRecordComponentName(v));
1722 }
1723 }
1724 chk.checkRequiresIdentity(tree, env.info.lint);
1725 }
1726 finally {
1727 chk.setLint(prevLint);
1728 }
1729 }
1730
1731 private void doQueueScanTreeAndTypeAnnotateForVarInit(JCVariableDecl tree, Env<AttrContext> env) {
1732 if (tree.init != null &&
1733 (tree.mods.flags & Flags.FIELD_INIT_TYPE_ANNOTATIONS_QUEUED) == 0 &&
1812 }
1813 }
1814 }
1815
1816 public void visitSkip(JCSkip tree) {
1817 result = null;
1818 }
1819
1820 public void visitBlock(JCBlock tree) {
1821 if (env.info.scope.owner.kind == TYP || env.info.scope.owner.kind == ERR) {
1822 // Block is a static or instance initializer;
1823 // let the owner of the environment be a freshly
1824 // created BLOCK-method.
1825 Symbol fakeOwner =
1826 new MethodSymbol(tree.flags | BLOCK |
1827 env.info.scope.owner.flags() & STRICTFP, names.empty, initBlockType,
1828 env.info.scope.owner);
1829 final Env<AttrContext> localEnv =
1830 env.dup(tree, env.info.dup(env.info.scope.dupUnshared(fakeOwner)));
1831
1832 if ((tree.flags & STATIC) != 0) {
1833 localEnv.info.staticLevel++;
1834 } else {
1835 localEnv.info.instanceInitializerBlock = true;
1836 }
1837 // Attribute all type annotations in the block
1838 annotate.queueScanTreeAndTypeAnnotate(tree, localEnv, localEnv.info.scope.owner);
1839 annotate.flush();
1840 attribStats(tree.stats, localEnv);
1841
1842 {
1843 // Store init and clinit type annotations with the ClassSymbol
1844 // to allow output in Gen.normalizeDefs.
1845 ClassSymbol cs = (ClassSymbol)env.info.scope.owner;
1846 List<Attribute.TypeCompound> tas = localEnv.info.scope.owner.getRawTypeAttributes();
1847 if ((tree.flags & STATIC) != 0) {
1848 cs.appendClassInitTypeAttributes(tas);
1849 } else {
1850 cs.appendInitTypeAttributes(tas);
1851 }
1852 }
1853 } else {
1854 // Create a new local environment with a local scope.
1855 Env<AttrContext> localEnv =
1856 env.dup(tree, env.info.dup(env.info.scope.dup()));
2330 // where
2331 /** Return the selected enumeration constant symbol, or null. */
2332 private Symbol enumConstant(JCTree tree, Type enumType) {
2333 if (tree.hasTag(IDENT)) {
2334 JCIdent ident = (JCIdent)tree;
2335 Name name = ident.name;
2336 for (Symbol sym : enumType.tsym.members().getSymbolsByName(name)) {
2337 if (sym.kind == VAR) {
2338 Symbol s = ident.sym = sym;
2339 ((VarSymbol)s).getConstValue(); // ensure initializer is evaluated
2340 ident.type = s.type;
2341 return ((s.flags_field & Flags.ENUM) == 0)
2342 ? null : s;
2343 }
2344 }
2345 }
2346 return null;
2347 }
2348
2349 public void visitSynchronized(JCSynchronized tree) {
2350 boolean identityType = chk.checkIdentityType(tree.pos(), attribExpr(tree.lock, env));
2351 if (identityType && tree.lock.type != null && tree.lock.type.isValueBased()) {
2352 log.warning(tree.pos(), LintWarnings.AttemptToSynchronizeOnInstanceOfValueBasedClass);
2353 }
2354 attribStat(tree.body, env);
2355 result = null;
2356 }
2357
2358 public void visitTry(JCTry tree) {
2359 // Create a new local environment with a local
2360 Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
2361 try {
2362 boolean isTryWithResource = tree.resources.nonEmpty();
2363 // Create a nested environment for attributing the try block if needed
2364 Env<AttrContext> tryEnv = isTryWithResource ?
2365 env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) :
2366 localEnv;
2367 try {
2368 // Attribute resource declarations
2369 for (JCTree resource : tree.resources) {
2370 CheckContext twrContext = new Check.NestedCheckContext(resultInfo.checkContext) {
2371 @Override
4792 }
4793
4794 public void visitSelect(JCFieldAccess tree) {
4795 // Determine the expected kind of the qualifier expression.
4796 KindSelector skind = KindSelector.NIL;
4797 if (tree.name == names._this || tree.name == names._super ||
4798 tree.name == names._class)
4799 {
4800 skind = KindSelector.TYP;
4801 } else {
4802 if (pkind().contains(KindSelector.PCK))
4803 skind = KindSelector.of(skind, KindSelector.PCK);
4804 if (pkind().contains(KindSelector.TYP))
4805 skind = KindSelector.of(skind, KindSelector.TYP, KindSelector.PCK);
4806 if (pkind().contains(KindSelector.VAL_MTH))
4807 skind = KindSelector.of(skind, KindSelector.VAL, KindSelector.TYP);
4808 }
4809
4810 // Attribute the qualifier expression, and determine its symbol (if any).
4811 Type site = attribTree(tree.selected, env, new ResultInfo(skind, Type.noType));
4812 Assert.check(site == tree.selected.type);
4813 if (!pkind().contains(KindSelector.TYP_PCK))
4814 site = capture(site); // Capture field access
4815
4816 // don't allow T.class T[].class, etc
4817 if (skind == KindSelector.TYP) {
4818 Type elt = site;
4819 while (elt.hasTag(ARRAY))
4820 elt = ((ArrayType)elt).elemtype;
4821 if (elt.hasTag(TYPEVAR)) {
4822 log.error(tree.pos(), Errors.TypeVarCantBeDeref);
4823 result = tree.type = types.createErrorType(tree.name, site.tsym, site);
4824 tree.sym = tree.type.tsym;
4825 return ;
4826 }
4827 }
4828
4829 // If qualifier symbol is a type or `super', assert `selectSuper'
4830 // for the selection. This is relevant for determining whether
4831 // protected symbols are accessible.
4832 Symbol sitesym = TreeInfo.symbol(tree.selected);
5905 .filter(s -> s.tsym.isSealed())
5906 .map(s -> (ClassSymbol) s.tsym)
5907 .collect(List.collector());
5908
5909 if (sealedSupers.isEmpty()) {
5910 if ((c.flags_field & Flags.NON_SEALED) != 0) {
5911 boolean hasErrorSuper = false;
5912
5913 hasErrorSuper |= types.directSupertypes(c.type)
5914 .stream()
5915 .anyMatch(s -> s.tsym.kind == Kind.ERR);
5916
5917 ClassType ct = (ClassType) c.type;
5918
5919 hasErrorSuper |= !ct.isCompound() && ct.interfaces_field != ct.all_interfaces_field;
5920
5921 if (!hasErrorSuper) {
5922 log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.NonSealedWithNoSealedSupertype(c));
5923 }
5924 }
5925 } else if ((c.flags_field & Flags.COMPOUND) == 0) {
5926 if (c.isDirectlyOrIndirectlyLocal() && !c.isEnum()) {
5927 log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.LocalClassesCantExtendSealed(c.isAnonymous() ? Fragments.Anonymous : Fragments.Local));
5928 }
5929
5930 if (!c.type.isCompound()) {
5931 for (ClassSymbol supertypeSym : sealedSupers) {
5932 if (!supertypeSym.isPermittedSubclass(c.type.tsym)) {
5933 log.error(TreeInfo.diagnosticPositionFor(c.type.tsym, env.tree), Errors.CantInheritFromSealed(supertypeSym));
5934 }
5935 }
5936 if (!c.isNonSealed() && !c.isFinal() && !c.isSealed()) {
5937 log.error(TreeInfo.diagnosticPositionFor(c, env.tree),
5938 c.isInterface() ?
5939 Errors.NonSealedOrSealedExpected :
5940 Errors.NonSealedSealedOrFinalExpected);
5941 }
5942 }
5943 }
5944
5945 env.info.returnResult = null;
5946 // java.lang.Enum may not be subclassed by a non-enum
5947 if (st.tsym == syms.enumSym &&
5948 ((c.flags_field & (Flags.ENUM|Flags.COMPOUND)) == 0))
5949 log.error(env.tree.pos(), Errors.EnumNoSubclassing);
5950
5951 // Enums may not be extended by source-level classes
5952 if (st.tsym != null &&
5953 ((st.tsym.flags_field & Flags.ENUM) != 0) &&
5954 ((c.flags_field & (Flags.ENUM | Flags.COMPOUND)) == 0)) {
5955 log.error(env.tree.pos(), Errors.EnumTypesNotExtensible);
5956 }
5957
5958 if (rs.isSerializable(c.type)) {
5959 env.info.isSerializable = true;
5960 }
5961
5962 if (c.isValueClass()) {
5963 Assert.check(env.tree.hasTag(CLASSDEF));
5964 chk.checkConstraintsOfValueClass((JCClassDecl) env.tree, c);
5965 }
5966
5967 attribClassBody(env, c);
5968
5969 chk.checkDeprecatedAnnotation(env.tree.pos(), c);
5970 chk.checkClassOverrideEqualsAndHashIfNeeded(env.tree.pos(), c);
5971 chk.checkFunctionalInterface((JCClassDecl) env.tree, c);
5972 chk.checkLeaksNotAccessible(env, (JCClassDecl) env.tree);
5973
5974 if (c.isImplicit()) {
5975 chk.checkHasMain(env.tree.pos(), c);
5976 }
5977 } finally {
5978 env.info.returnResult = prevReturnRes;
5979 log.useSource(prev);
5980 chk.setLint(prevLint);
5981 }
5982
5983 }
5984 }
5985
5986 public void visitImport(JCImport tree) {
6093 sym.kind != VAR ||
6094 sym.getConstValue() == null)
6095 log.error(l.head.pos(), Errors.IclsCantHaveStaticDecl(c));
6096 }
6097 }
6098
6099 // Check for proper placement of super()/this() calls.
6100 chk.checkSuperInitCalls(tree);
6101
6102 // Check for cycles among non-initial constructors.
6103 chk.checkCyclicConstructors(tree);
6104
6105 // Check for cycles among annotation elements.
6106 chk.checkNonCyclicElements(tree);
6107
6108 // Check for proper use of serialVersionUID and other
6109 // serialization-related fields and methods
6110 if (env.info.lint.isEnabled(LintCategory.SERIAL)
6111 && rs.isSerializable(c.type)
6112 && !c.isAnonymous()) {
6113 chk.checkSerialStructure(env, tree, c);
6114 }
6115 // Correctly organize the positions of the type annotations
6116 typeAnnotations.organizeTypeAnnotationsBodies(tree);
6117
6118 // Check type annotations applicability rules
6119 validateTypeAnnotations(tree, false);
6120 }
6121 // where
6122 /** get a diagnostic position for an attribute of Type t, or null if attribute missing */
6123 private DiagnosticPosition getDiagnosticPosition(JCClassDecl tree, Type t) {
6124 for(List<JCAnnotation> al = tree.mods.annotations; !al.isEmpty(); al = al.tail) {
6125 if (types.isSameType(al.head.annotationType.type, t))
6126 return al.head.pos();
6127 }
6128
6129 return null;
6130 }
6131
6132 private Type capture(Type type) {
6133 return types.capture(type);
|