1 /*
2 * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
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 */
1104 * - have an accessibility stricter than that of the record type
1105 * - explicitly invoke any other constructor
1106 */
1107 if ((tree.sym.flags_field & GENERATEDCONSTR) == 0) {
1108 if (Check.protection(m.flags()) > Check.protection(env.enclClass.sym.flags())) {
1109 log.error(tree,
1110 (env.enclClass.sym.flags() & AccessFlags) == 0 ?
1111 Errors.InvalidCanonicalConstructorInRecord(
1112 Fragments.Canonical,
1113 env.enclClass.sym.name,
1114 Fragments.CanonicalMustNotHaveStrongerAccess("package")
1115 ) :
1116 Errors.InvalidCanonicalConstructorInRecord(
1117 Fragments.Canonical,
1118 env.enclClass.sym.name,
1119 Fragments.CanonicalMustNotHaveStrongerAccess(asFlagSet(env.enclClass.sym.flags() & AccessFlags))
1120 )
1121 );
1122 }
1123
1124 if (TreeInfo.hasAnyConstructorCall(tree)) {
1125 log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1126 Fragments.Canonical, env.enclClass.sym.name,
1127 Fragments.CanonicalMustNotContainExplicitConstructorInvocation));
1128 }
1129 }
1130
1131 // also we want to check that no type variables have been defined
1132 if (!tree.typarams.isEmpty()) {
1133 log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1134 Fragments.Canonical, env.enclClass.sym.name, Fragments.CanonicalMustNotDeclareTypeVariables));
1135 }
1136
1137 /* and now we need to check that the constructor's arguments are exactly the same as those of the
1138 * record components
1139 */
1140 List<? extends RecordComponent> recordComponents = env.enclClass.sym.getRecordComponents();
1141 List<Type> recordFieldTypes = TreeInfo.recordFields(env.enclClass).map(vd -> vd.sym.type);
1142 for (JCVariableDecl param: tree.params) {
1143 boolean paramIsVarArgs = (param.sym.flags_field & VARARGS) != 0;
1144 if (!types.isSameType(param.type, recordFieldTypes.head) ||
1182 if (tree.defaultValue != null) {
1183 if ((owner.flags() & ANNOTATION) == 0)
1184 log.error(tree.pos(),
1185 Errors.DefaultAllowedInIntfAnnotationMember);
1186 }
1187 if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0)
1188 log.error(tree.pos(), Errors.MissingMethBodyOrDeclAbstract(tree.sym, owner));
1189 } else {
1190 if ((tree.sym.flags() & (ABSTRACT|DEFAULT|PRIVATE)) == ABSTRACT) {
1191 if ((owner.flags() & INTERFACE) != 0) {
1192 log.error(tree.body.pos(), Errors.IntfMethCantHaveBody);
1193 } else {
1194 log.error(tree.pos(), Errors.AbstractMethCantHaveBody);
1195 }
1196 } else if ((tree.mods.flags & NATIVE) != 0) {
1197 log.error(tree.pos(), Errors.NativeMethCantHaveBody);
1198 }
1199 // Add an implicit super() call unless an explicit call to
1200 // super(...) or this(...) is given
1201 // or we are compiling class java.lang.Object.
1202 if (isConstructor && owner.type != syms.objectType) {
1203 if (!TreeInfo.hasAnyConstructorCall(tree)) {
1204 JCStatement supCall = make.at(tree.body.pos).Exec(make.Apply(List.nil(),
1205 make.Ident(names._super), make.Idents(List.nil())));
1206 tree.body.stats = tree.body.stats.prepend(supCall);
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 }
1245
1246 localEnv.info.scope.leave();
1247 result = tree.type = m.type;
1248 } finally {
1249 chk.setLint(prevLint);
1250 chk.setMethod(prevMethod);
1251 env.info.ctorPrologue = ctorProloguePrev;
1252 }
1253 }
1254
1255 public void visitVarDef(JCVariableDecl tree) {
1256 // Local variables have not been entered yet, so we need to do it now:
1257 if (env.info.scope.owner.kind == MTH || env.info.scope.owner.kind == VAR) {
1258 if (tree.sym != null) {
1259 // parameters have already been entered
1260 env.info.scope.enter(tree.sym);
1261 } else {
1262 if (tree.isImplicitlyTyped() && (tree.getModifiers().flags & PARAMETER) == 0) {
1263 if (tree.init == null) {
1264 //cannot use 'var' without initializer
1265 log.error(tree, Errors.CantInferLocalVarType(tree.name, Fragments.LocalMissingInit));
1266 tree.vartype = make.at(tree.pos()).Erroneous();
1267 } else {
1268 Fragment msg = canInferLocalVarType(tree);
1269 if (msg != null) {
1270 //cannot use 'var' with initializer which require an explicit target
1271 //(e.g. lambda, method reference, array initializer).
1272 log.error(tree, Errors.CantInferLocalVarType(tree.name, msg));
1273 tree.vartype = make.at(tree.pos()).Erroneous();
1274 }
1283 }
1284 } else {
1285 doQueueScanTreeAndTypeAnnotateForVarInit(tree, env);
1286 }
1287
1288 VarSymbol v = tree.sym;
1289 Lint lint = env.info.lint.augment(v);
1290 Lint prevLint = chk.setLint(lint);
1291
1292 // Check that the variable's declared type is well-formed.
1293 boolean isImplicitLambdaParameter = env.tree.hasTag(LAMBDA) &&
1294 ((JCLambda)env.tree).paramKind == JCLambda.ParameterKind.IMPLICIT &&
1295 (tree.sym.flags() & PARAMETER) != 0;
1296 chk.validate(tree.vartype, env, !isImplicitLambdaParameter && !tree.isImplicitlyTyped());
1297
1298 try {
1299 v.getConstValue(); // ensure compile-time constant initializer is evaluated
1300 chk.checkDeprecatedAnnotation(tree.pos(), v);
1301
1302 if (tree.init != null) {
1303 if ((v.flags_field & FINAL) == 0 ||
1304 !memberEnter.needsLazyConstValue(tree.init)) {
1305 // Not a compile-time constant
1306 // Attribute initializer in a new environment
1307 // with the declared variable as owner.
1308 // Check that initializer conforms to variable's declared type.
1309 Env<AttrContext> initEnv = memberEnter.initEnv(tree, env);
1310 initEnv.info.lint = lint;
1311 // In order to catch self-references, we set the variable's
1312 // declaration position to maximal possible value, effectively
1313 // marking the variable as undefined.
1314 initEnv.info.enclVar = v;
1315 attribExpr(tree.init, initEnv, v.type);
1316 if (tree.isImplicitlyTyped()) {
1317 //fixup local variable type
1318 v.type = chk.checkLocalVarType(tree, tree.init.type, tree.name);
1319 }
1320 }
1321 if (tree.isImplicitlyTyped()) {
1322 setSyntheticVariableType(tree, v.type);
1323 }
1324 }
1325 result = tree.type = v.type;
1326 if (env.enclClass.sym.isRecord() && tree.sym.owner.kind == TYP && !v.isStatic()) {
1327 if (isNonArgsMethodInObject(v.name)) {
1328 log.error(tree, Errors.IllegalRecordComponentName(v));
1329 }
1330 }
1331 chk.checkRequiresIdentity(tree, env.info.lint);
1332 }
1333 finally {
1334 chk.setLint(prevLint);
1335 }
1336 }
1337
1338 private void doQueueScanTreeAndTypeAnnotateForVarInit(JCVariableDecl tree, Env<AttrContext> env) {
1339 if (tree.init != null &&
1340 (tree.mods.flags & Flags.FIELD_INIT_TYPE_ANNOTATIONS_QUEUED) == 0 &&
1419 }
1420 }
1421 }
1422
1423 public void visitSkip(JCSkip tree) {
1424 result = null;
1425 }
1426
1427 public void visitBlock(JCBlock tree) {
1428 if (env.info.scope.owner.kind == TYP || env.info.scope.owner.kind == ERR) {
1429 // Block is a static or instance initializer;
1430 // let the owner of the environment be a freshly
1431 // created BLOCK-method.
1432 Symbol fakeOwner =
1433 new MethodSymbol(tree.flags | BLOCK |
1434 env.info.scope.owner.flags() & STRICTFP, names.empty, initBlockType,
1435 env.info.scope.owner);
1436 final Env<AttrContext> localEnv =
1437 env.dup(tree, env.info.dup(env.info.scope.dupUnshared(fakeOwner)));
1438
1439 if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
1440 // Attribute all type annotations in the block
1441 annotate.queueScanTreeAndTypeAnnotate(tree, localEnv, localEnv.info.scope.owner);
1442 annotate.flush();
1443 attribStats(tree.stats, localEnv);
1444
1445 {
1446 // Store init and clinit type annotations with the ClassSymbol
1447 // to allow output in Gen.normalizeDefs.
1448 ClassSymbol cs = (ClassSymbol)env.info.scope.owner;
1449 List<Attribute.TypeCompound> tas = localEnv.info.scope.owner.getRawTypeAttributes();
1450 if ((tree.flags & STATIC) != 0) {
1451 cs.appendClassInitTypeAttributes(tas);
1452 } else {
1453 cs.appendInitTypeAttributes(tas);
1454 }
1455 }
1456 } else {
1457 // Create a new local environment with a local scope.
1458 Env<AttrContext> localEnv =
1459 env.dup(tree, env.info.dup(env.info.scope.dup()));
1932 // where
1933 /** Return the selected enumeration constant symbol, or null. */
1934 private Symbol enumConstant(JCTree tree, Type enumType) {
1935 if (tree.hasTag(IDENT)) {
1936 JCIdent ident = (JCIdent)tree;
1937 Name name = ident.name;
1938 for (Symbol sym : enumType.tsym.members().getSymbolsByName(name)) {
1939 if (sym.kind == VAR) {
1940 Symbol s = ident.sym = sym;
1941 ((VarSymbol)s).getConstValue(); // ensure initializer is evaluated
1942 ident.type = s.type;
1943 return ((s.flags_field & Flags.ENUM) == 0)
1944 ? null : s;
1945 }
1946 }
1947 }
1948 return null;
1949 }
1950
1951 public void visitSynchronized(JCSynchronized tree) {
1952 chk.checkRefType(tree.pos(), attribExpr(tree.lock, env));
1953 if (tree.lock.type != null && tree.lock.type.isValueBased()) {
1954 log.warning(tree.pos(), LintWarnings.AttemptToSynchronizeOnInstanceOfValueBasedClass);
1955 }
1956 attribStat(tree.body, env);
1957 result = null;
1958 }
1959
1960 public void visitTry(JCTry tree) {
1961 // Create a new local environment with a local
1962 Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
1963 try {
1964 boolean isTryWithResource = tree.resources.nonEmpty();
1965 // Create a nested environment for attributing the try block if needed
1966 Env<AttrContext> tryEnv = isTryWithResource ?
1967 env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) :
1968 localEnv;
1969 try {
1970 // Attribute resource declarations
1971 for (JCTree resource : tree.resources) {
1972 CheckContext twrContext = new Check.NestedCheckContext(resultInfo.checkContext) {
1973 @Override
4389 }
4390
4391 public void visitSelect(JCFieldAccess tree) {
4392 // Determine the expected kind of the qualifier expression.
4393 KindSelector skind = KindSelector.NIL;
4394 if (tree.name == names._this || tree.name == names._super ||
4395 tree.name == names._class)
4396 {
4397 skind = KindSelector.TYP;
4398 } else {
4399 if (pkind().contains(KindSelector.PCK))
4400 skind = KindSelector.of(skind, KindSelector.PCK);
4401 if (pkind().contains(KindSelector.TYP))
4402 skind = KindSelector.of(skind, KindSelector.TYP, KindSelector.PCK);
4403 if (pkind().contains(KindSelector.VAL_MTH))
4404 skind = KindSelector.of(skind, KindSelector.VAL, KindSelector.TYP);
4405 }
4406
4407 // Attribute the qualifier expression, and determine its symbol (if any).
4408 Type site = attribTree(tree.selected, env, new ResultInfo(skind, Type.noType));
4409 if (!pkind().contains(KindSelector.TYP_PCK))
4410 site = capture(site); // Capture field access
4411
4412 // don't allow T.class T[].class, etc
4413 if (skind == KindSelector.TYP) {
4414 Type elt = site;
4415 while (elt.hasTag(ARRAY))
4416 elt = ((ArrayType)elt).elemtype;
4417 if (elt.hasTag(TYPEVAR)) {
4418 log.error(tree.pos(), Errors.TypeVarCantBeDeref);
4419 result = tree.type = types.createErrorType(tree.name, site.tsym, site);
4420 tree.sym = tree.type.tsym;
4421 return ;
4422 }
4423 }
4424
4425 // If qualifier symbol is a type or `super', assert `selectSuper'
4426 // for the selection. This is relevant for determining whether
4427 // protected symbols are accessible.
4428 Symbol sitesym = TreeInfo.symbol(tree.selected);
5500 .filter(s -> s.tsym.isSealed())
5501 .map(s -> (ClassSymbol) s.tsym)
5502 .collect(List.collector());
5503
5504 if (sealedSupers.isEmpty()) {
5505 if ((c.flags_field & Flags.NON_SEALED) != 0) {
5506 boolean hasErrorSuper = false;
5507
5508 hasErrorSuper |= types.directSupertypes(c.type)
5509 .stream()
5510 .anyMatch(s -> s.tsym.kind == Kind.ERR);
5511
5512 ClassType ct = (ClassType) c.type;
5513
5514 hasErrorSuper |= !ct.isCompound() && ct.interfaces_field != ct.all_interfaces_field;
5515
5516 if (!hasErrorSuper) {
5517 log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.NonSealedWithNoSealedSupertype(c));
5518 }
5519 }
5520 } else {
5521 if (c.isDirectlyOrIndirectlyLocal() && !c.isEnum()) {
5522 log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.LocalClassesCantExtendSealed(c.isAnonymous() ? Fragments.Anonymous : Fragments.Local));
5523 }
5524
5525 if (!c.type.isCompound()) {
5526 for (ClassSymbol supertypeSym : sealedSupers) {
5527 if (!supertypeSym.isPermittedSubclass(c.type.tsym)) {
5528 log.error(TreeInfo.diagnosticPositionFor(c.type.tsym, env.tree), Errors.CantInheritFromSealed(supertypeSym));
5529 }
5530 }
5531 if (!c.isNonSealed() && !c.isFinal() && !c.isSealed()) {
5532 log.error(TreeInfo.diagnosticPositionFor(c, env.tree),
5533 c.isInterface() ?
5534 Errors.NonSealedOrSealedExpected :
5535 Errors.NonSealedSealedOrFinalExpected);
5536 }
5537 }
5538 }
5539
5540 env.info.returnResult = null;
5541 // java.lang.Enum may not be subclassed by a non-enum
5542 if (st.tsym == syms.enumSym &&
5543 ((c.flags_field & (Flags.ENUM|Flags.COMPOUND)) == 0))
5544 log.error(env.tree.pos(), Errors.EnumNoSubclassing);
5545
5546 // Enums may not be extended by source-level classes
5547 if (st.tsym != null &&
5548 ((st.tsym.flags_field & Flags.ENUM) != 0) &&
5549 ((c.flags_field & (Flags.ENUM | Flags.COMPOUND)) == 0)) {
5550 log.error(env.tree.pos(), Errors.EnumTypesNotExtensible);
5551 }
5552
5553 if (rs.isSerializable(c.type)) {
5554 env.info.isSerializable = true;
5555 }
5556
5557 attribClassBody(env, c);
5558
5559 chk.checkDeprecatedAnnotation(env.tree.pos(), c);
5560 chk.checkClassOverrideEqualsAndHashIfNeeded(env.tree.pos(), c);
5561 chk.checkFunctionalInterface((JCClassDecl) env.tree, c);
5562 chk.checkLeaksNotAccessible(env, (JCClassDecl) env.tree);
5563
5564 if (c.isImplicit()) {
5565 chk.checkHasMain(env.tree.pos(), c);
5566 }
5567 } finally {
5568 env.info.returnResult = prevReturnRes;
5569 log.useSource(prev);
5570 chk.setLint(prevLint);
5571 }
5572
5573 }
5574 }
5575
5576 public void visitImport(JCImport tree) {
5683 sym.kind != VAR ||
5684 sym.getConstValue() == null)
5685 log.error(l.head.pos(), Errors.IclsCantHaveStaticDecl(c));
5686 }
5687 }
5688
5689 // Check for proper placement of super()/this() calls.
5690 chk.checkSuperInitCalls(tree);
5691
5692 // Check for cycles among non-initial constructors.
5693 chk.checkCyclicConstructors(tree);
5694
5695 // Check for cycles among annotation elements.
5696 chk.checkNonCyclicElements(tree);
5697
5698 // Check for proper use of serialVersionUID and other
5699 // serialization-related fields and methods
5700 if (env.info.lint.isEnabled(LintCategory.SERIAL)
5701 && rs.isSerializable(c.type)
5702 && !c.isAnonymous()) {
5703 chk.checkSerialStructure(tree, c);
5704 }
5705 // Correctly organize the positions of the type annotations
5706 typeAnnotations.organizeTypeAnnotationsBodies(tree);
5707
5708 // Check type annotations applicability rules
5709 validateTypeAnnotations(tree, false);
5710 }
5711 // where
5712 /** get a diagnostic position for an attribute of Type t, or null if attribute missing */
5713 private DiagnosticPosition getDiagnosticPosition(JCClassDecl tree, Type t) {
5714 for(List<JCAnnotation> al = tree.mods.annotations; !al.isEmpty(); al = al.tail) {
5715 if (types.isSameType(al.head.annotationType.type, t))
5716 return al.head.pos();
5717 }
5718
5719 return null;
5720 }
5721
5722 private Type capture(Type type) {
5723 return types.capture(type);
|
1 /*
2 * Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
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 */
1093 * - have an accessibility stricter than that of the record type
1094 * - explicitly invoke any other constructor
1095 */
1096 if ((tree.sym.flags_field & GENERATEDCONSTR) == 0) {
1097 if (Check.protection(m.flags()) > Check.protection(env.enclClass.sym.flags())) {
1098 log.error(tree,
1099 (env.enclClass.sym.flags() & AccessFlags) == 0 ?
1100 Errors.InvalidCanonicalConstructorInRecord(
1101 Fragments.Canonical,
1102 env.enclClass.sym.name,
1103 Fragments.CanonicalMustNotHaveStrongerAccess("package")
1104 ) :
1105 Errors.InvalidCanonicalConstructorInRecord(
1106 Fragments.Canonical,
1107 env.enclClass.sym.name,
1108 Fragments.CanonicalMustNotHaveStrongerAccess(asFlagSet(env.enclClass.sym.flags() & AccessFlags))
1109 )
1110 );
1111 }
1112
1113 if ((!allowValueClasses || TreeInfo.isCompactConstructor(tree)) &&
1114 TreeInfo.hasAnyConstructorCall(tree)) {
1115 log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1116 Fragments.Canonical, env.enclClass.sym.name,
1117 Fragments.CanonicalMustNotContainExplicitConstructorInvocation));
1118 }
1119 }
1120
1121 // also we want to check that no type variables have been defined
1122 if (!tree.typarams.isEmpty()) {
1123 log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1124 Fragments.Canonical, env.enclClass.sym.name, Fragments.CanonicalMustNotDeclareTypeVariables));
1125 }
1126
1127 /* and now we need to check that the constructor's arguments are exactly the same as those of the
1128 * record components
1129 */
1130 List<? extends RecordComponent> recordComponents = env.enclClass.sym.getRecordComponents();
1131 List<Type> recordFieldTypes = TreeInfo.recordFields(env.enclClass).map(vd -> vd.sym.type);
1132 for (JCVariableDecl param: tree.params) {
1133 boolean paramIsVarArgs = (param.sym.flags_field & VARARGS) != 0;
1134 if (!types.isSameType(param.type, recordFieldTypes.head) ||
1172 if (tree.defaultValue != null) {
1173 if ((owner.flags() & ANNOTATION) == 0)
1174 log.error(tree.pos(),
1175 Errors.DefaultAllowedInIntfAnnotationMember);
1176 }
1177 if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0)
1178 log.error(tree.pos(), Errors.MissingMethBodyOrDeclAbstract(tree.sym, owner));
1179 } else {
1180 if ((tree.sym.flags() & (ABSTRACT|DEFAULT|PRIVATE)) == ABSTRACT) {
1181 if ((owner.flags() & INTERFACE) != 0) {
1182 log.error(tree.body.pos(), Errors.IntfMethCantHaveBody);
1183 } else {
1184 log.error(tree.pos(), Errors.AbstractMethCantHaveBody);
1185 }
1186 } else if ((tree.mods.flags & NATIVE) != 0) {
1187 log.error(tree.pos(), Errors.NativeMethCantHaveBody);
1188 }
1189 // Add an implicit super() call unless an explicit call to
1190 // super(...) or this(...) is given
1191 // or we are compiling class java.lang.Object.
1192 boolean addedSuperInIdentityClass = false;
1193 if (isConstructor && owner.type != syms.objectType) {
1194 if (!TreeInfo.hasAnyConstructorCall(tree)) {
1195 JCStatement supCall = make.at(tree.body.pos).Exec(make.Apply(List.nil(),
1196 make.Ident(names._super), make.Idents(List.nil())));
1197 if (allowValueClasses && (owner.isValueClass() || ((owner.flags_field & RECORD) != 0))) {
1198 tree.body.stats = tree.body.stats.append(supCall);
1199 } else {
1200 tree.body.stats = tree.body.stats.prepend(supCall);
1201 addedSuperInIdentityClass = true;
1202 }
1203 } else if ((env.enclClass.sym.flags() & ENUM) != 0 &&
1204 (tree.mods.flags & GENERATEDCONSTR) == 0 &&
1205 TreeInfo.hasConstructorCall(tree, names._super)) {
1206 // enum constructors are not allowed to call super
1207 // directly, so make sure there aren't any super calls
1208 // in enum constructors, except in the compiler
1209 // generated one.
1210 log.error(tree.body.stats.head.pos(),
1211 Errors.CallToSuperNotAllowedInEnumCtor(env.enclClass.sym));
1212 }
1213 if (env.enclClass.sym.isRecord() && (tree.sym.flags_field & RECORD) != 0) { // we are seeing the canonical constructor
1214 List<Name> recordComponentNames = TreeInfo.recordFields(env.enclClass).map(vd -> vd.sym.name);
1215 List<Name> initParamNames = tree.sym.params.map(p -> p.name);
1216 if (!initParamNames.equals(recordComponentNames)) {
1217 log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1218 Fragments.Canonical, env.enclClass.sym.name, Fragments.CanonicalWithNameMismatch));
1219 }
1220 if (tree.sym.type.asMethodType().thrown != null && !tree.sym.type.asMethodType().thrown.isEmpty()) {
1221 log.error(tree,
1222 Errors.InvalidCanonicalConstructorInRecord(
1223 TreeInfo.isCompactConstructor(tree) ? Fragments.Compact : Fragments.Canonical,
1224 env.enclClass.sym.name,
1225 Fragments.ThrowsClauseNotAllowedForCanonicalConstructor(
1226 TreeInfo.isCompactConstructor(tree) ? Fragments.Compact : Fragments.Canonical)));
1227 }
1228 }
1229 }
1230
1231 // Attribute all type annotations in the body
1232 annotate.queueScanTreeAndTypeAnnotate(tree.body, localEnv, m);
1233 annotate.flush();
1234
1235 // Start of constructor prologue (if not in java.lang.Object constructor)
1236 localEnv.info.ctorPrologue = isConstructor && owner.type != syms.objectType;
1237
1238 // Attribute method body.
1239 attribStat(tree.body, localEnv);
1240 if (localEnv.info.ctorPrologue) {
1241 boolean thisInvocation = false;
1242 ListBuffer<JCTree> prologueCode = new ListBuffer<>();
1243 for (JCTree stat : tree.body.stats) {
1244 prologueCode.add(stat);
1245 /* gather all the stats in the body until a `super` or `this` constructor invocation is found,
1246 * including the constructor invocation, that way we don't need to worry in the visitor below if
1247 * if we are dealing or not with prologue code
1248 */
1249 if (stat instanceof JCExpressionStatement expStmt &&
1250 expStmt.expr instanceof JCMethodInvocation mi &&
1251 TreeInfo.isConstructorCall(mi)) {
1252 thisInvocation = TreeInfo.name(mi.meth) == names._this;
1253 if (!addedSuperInIdentityClass || !allowValueClasses) {
1254 break;
1255 }
1256 }
1257 }
1258 if (!prologueCode.isEmpty()) {
1259 CtorPrologueVisitor ctorPrologueVisitor = new CtorPrologueVisitor(localEnv,
1260 addedSuperInIdentityClass && allowValueClasses ?
1261 PrologueVisitorMode.WARNINGS_ONLY :
1262 thisInvocation ?
1263 PrologueVisitorMode.THIS_CONSTRUCTOR :
1264 PrologueVisitorMode.SUPER_CONSTRUCTOR,
1265 false);
1266 ctorPrologueVisitor.scan(prologueCode.toList());
1267 }
1268 }
1269 }
1270
1271 localEnv.info.scope.leave();
1272 result = tree.type = m.type;
1273 } finally {
1274 chk.setLint(prevLint);
1275 chk.setMethod(prevMethod);
1276 env.info.ctorPrologue = ctorProloguePrev;
1277 }
1278 }
1279
1280 enum PrologueVisitorMode {
1281 WARNINGS_ONLY,
1282 SUPER_CONSTRUCTOR,
1283 THIS_CONSTRUCTOR
1284 }
1285
1286 class CtorPrologueVisitor extends TreeScanner {
1287 Env<AttrContext> localEnv;
1288 PrologueVisitorMode mode;
1289 boolean isInitializer;
1290
1291 CtorPrologueVisitor(Env<AttrContext> localEnv, PrologueVisitorMode mode, boolean isInitializer) {
1292 this.localEnv = localEnv;
1293 currentClassSym = localEnv.enclClass.sym;
1294 this.mode = mode;
1295 this.isInitializer = isInitializer;
1296 }
1297
1298 boolean insideLambdaOrClassDef = false;
1299
1300 @Override
1301 public void visitLambda(JCLambda lambda) {
1302 boolean previousInsideLambdaOrClassDef = insideLambdaOrClassDef;
1303 try {
1304 insideLambdaOrClassDef = true;
1305 super.visitLambda(lambda);
1306 } finally {
1307 insideLambdaOrClassDef = previousInsideLambdaOrClassDef;
1308 }
1309 }
1310
1311 ClassSymbol currentClassSym;
1312
1313 @Override
1314 public void visitClassDef(JCClassDecl classDecl) {
1315 boolean previousInsideLambdaOrClassDef = insideLambdaOrClassDef;
1316 ClassSymbol previousClassSym = currentClassSym;
1317 try {
1318 insideLambdaOrClassDef = true;
1319 currentClassSym = classDecl.sym;
1320 super.visitClassDef(classDecl);
1321 } finally {
1322 insideLambdaOrClassDef = previousInsideLambdaOrClassDef;
1323 currentClassSym = previousClassSym;
1324 }
1325 }
1326
1327 private void reportPrologueError(JCTree tree, Symbol sym) {
1328 reportPrologueError(tree, sym, false);
1329 }
1330
1331 private void reportPrologueError(JCTree tree, Symbol sym, boolean hasInit) {
1332 preview.checkSourceLevel(tree, Feature.FLEXIBLE_CONSTRUCTORS);
1333 if (mode != PrologueVisitorMode.WARNINGS_ONLY) {
1334 if (hasInit) {
1335 log.error(tree, Errors.CantAssignInitializedBeforeCtorCalled(sym));
1336 } else {
1337 log.error(tree, Errors.CantRefBeforeCtorCalled(sym));
1338 }
1339 } else if (allowValueClasses) {
1340 // issue lint warning
1341 log.warning(tree, LintWarnings.WouldNotBeAllowedInPrologue(sym));
1342 }
1343 }
1344
1345 @Override
1346 public void visitApply(JCMethodInvocation tree) {
1347 super.visitApply(tree);
1348 Name name = TreeInfo.name(tree.meth);
1349 boolean isConstructorCall = name == names._this || name == names._super;
1350 Symbol msym = TreeInfo.symbolFor(tree.meth);
1351 // is this an instance method call or an illegal constructor invocation like: `this.super()`?
1352 if (msym != null && // for erroneous invocations msym can be null, ignore those
1353 (!isConstructorCall ||
1354 isConstructorCall && tree.meth.hasTag(SELECT))) {
1355 if (isEarlyReference(localEnv, tree.meth, msym))
1356 reportPrologueError(tree.meth, msym);
1357 }
1358 }
1359
1360 @Override
1361 public void visitIdent(JCIdent tree) {
1362 analyzeSymbol(tree);
1363 }
1364
1365 boolean isIndexed = false;
1366
1367 @Override
1368 public void visitIndexed(JCArrayAccess tree) {
1369 boolean previousIsIndexed = isIndexed;
1370 try {
1371 isIndexed = true;
1372 scan(tree.indexed);
1373 } finally {
1374 isIndexed = previousIsIndexed;
1375 }
1376 scan(tree.index);
1377 if (mode == PrologueVisitorMode.SUPER_CONSTRUCTOR && isInstanceField(tree.indexed)) {
1378 localProxyVarsGen.addFieldReadInPrologue(localEnv.enclMethod, TreeInfo.symbolFor(tree.indexed));
1379 }
1380 }
1381
1382 @Override
1383 public void visitSelect(JCFieldAccess tree) {
1384 SelectScanner ss = new SelectScanner();
1385 ss.scan(tree);
1386 if (ss.scanLater == null) {
1387 Symbol sym = TreeInfo.symbolFor(tree);
1388 // if this is a field access
1389 if (sym.kind == VAR && sym.owner.kind == TYP) {
1390 // Type.super.field or super.field expressions are forbidden in early construction contexts
1391 for (JCTree subtree : ss.selectorTrees) {
1392 if (TreeInfo.isSuperOrSelectorDotSuper(subtree)) {
1393 reportPrologueError(tree, sym);
1394 return;
1395 } else if (mode == PrologueVisitorMode.THIS_CONSTRUCTOR &&
1396 TreeInfo.isThisOrSelectorDotThis(subtree) &&
1397 TreeInfo.isExplicitThisReference(
1398 types,
1399 (ClassType)localEnv.enclClass.sym.type,
1400 subtree)) {
1401 reportPrologueError(tree, sym);
1402 return;
1403 }
1404 }
1405 }
1406 analyzeSymbol(tree);
1407 } else {
1408 boolean prevLhs = isInLHS;
1409 try {
1410 isInLHS = false;
1411 scan(ss.scanLater);
1412 } finally {
1413 isInLHS = prevLhs;
1414 }
1415 }
1416 if (mode == PrologueVisitorMode.SUPER_CONSTRUCTOR) {
1417 for (JCTree subtree : ss.selectorTrees) {
1418 if (isInstanceField(subtree)) {
1419 // we need to add a proxy for this one
1420 localProxyVarsGen.addFieldReadInPrologue(localEnv.enclMethod, TreeInfo.symbolFor(subtree));
1421 }
1422 }
1423 }
1424 }
1425
1426 private boolean isInstanceField(JCTree tree) {
1427 Symbol sym = TreeInfo.symbolFor(tree);
1428 return (sym != null &&
1429 !sym.isStatic() &&
1430 sym.kind == VAR &&
1431 sym.owner.kind == TYP &&
1432 sym.name != names._this &&
1433 sym.name != names._super &&
1434 isEarlyReference(localEnv, tree, sym));
1435 }
1436
1437 @Override
1438 public void visitNewClass(JCNewClass tree) {
1439 super.visitNewClass(tree);
1440 checkNewClassAndMethRefs(tree, tree.type);
1441 }
1442
1443 @Override
1444 public void visitReference(JCMemberReference tree) {
1445 super.visitReference(tree);
1446 if (tree.getMode() == JCMemberReference.ReferenceMode.NEW) {
1447 checkNewClassAndMethRefs(tree, tree.expr.type);
1448 }
1449 }
1450
1451 void checkNewClassAndMethRefs(JCTree tree, Type t) {
1452 if (t.tsym.isEnclosedBy(localEnv.enclClass.sym) &&
1453 !t.tsym.isStatic() &&
1454 !t.tsym.isDirectlyOrIndirectlyLocal()) {
1455 reportPrologueError(tree, t.getEnclosingType().tsym);
1456 }
1457 }
1458
1459 /* if a symbol is in the LHS of an assignment expression we won't consider it as a candidate
1460 * for a proxy local variable later on
1461 */
1462 boolean isInLHS = false;
1463
1464 @Override
1465 public void visitAssign(JCAssign tree) {
1466 boolean previousIsInLHS = isInLHS;
1467 try {
1468 isInLHS = true;
1469 scan(tree.lhs);
1470 } finally {
1471 isInLHS = previousIsInLHS;
1472 }
1473 scan(tree.rhs);
1474 }
1475
1476 @Override
1477 public void visitMethodDef(JCMethodDecl tree) {
1478 // ignore any declarative part, mainly to avoid scanning receiver parameters
1479 scan(tree.body);
1480 }
1481
1482 void analyzeSymbol(JCTree tree) {
1483 Symbol sym = TreeInfo.symbolFor(tree);
1484 // make sure that there is a symbol and it is not static
1485 if (sym == null || sym.isStatic()) {
1486 return;
1487 }
1488 if (isInLHS && !insideLambdaOrClassDef) {
1489 // Check instance field assignments that appear in constructor prologues
1490 if (isEarlyReference(localEnv, tree, sym)) {
1491 // Field may not be inherited from a superclass
1492 if (sym.owner != localEnv.enclClass.sym) {
1493 reportPrologueError(tree, sym);
1494 return;
1495 }
1496 // Field may not have an initializer
1497 if ((sym.flags() & HASINIT) != 0) {
1498 if (!localEnv.enclClass.sym.isValueClass() || !sym.type.hasTag(ARRAY) || !isIndexed) {
1499 reportPrologueError(tree, sym, true);
1500 }
1501 return;
1502 }
1503 // cant reference an instance field before a this constructor
1504 if (allowValueClasses && mode == PrologueVisitorMode.THIS_CONSTRUCTOR) {
1505 reportPrologueError(tree, sym);
1506 return;
1507 }
1508 }
1509 return;
1510 }
1511 tree = TreeInfo.skipParens(tree);
1512 if (sym.kind == VAR && sym.owner.kind == TYP) {
1513 if (sym.name == names._this || sym.name == names._super) {
1514 // are we seeing something like `this` or `CurrentClass.this` or `SuperClass.super::foo`?
1515 if (TreeInfo.isExplicitThisReference(
1516 types,
1517 (ClassType)localEnv.enclClass.sym.type,
1518 tree)) {
1519 reportPrologueError(tree, sym);
1520 }
1521 } else if (sym.kind == VAR && sym.owner.kind == TYP) { // now fields only
1522 if (sym.owner != localEnv.enclClass.sym) {
1523 if (localEnv.enclClass.sym.isSubClass(sym.owner, types) &&
1524 sym.isInheritedIn(localEnv.enclClass.sym, types)) {
1525 /* if we are dealing with a field that doesn't belong to the current class, but the
1526 * field is inherited, this is an error. Unless, the super class is also an outer
1527 * class and the field's qualifier refers to the outer class
1528 */
1529 if (tree.hasTag(IDENT) ||
1530 TreeInfo.isExplicitThisReference(
1531 types,
1532 (ClassType)localEnv.enclClass.sym.type,
1533 ((JCFieldAccess)tree).selected)) {
1534 reportPrologueError(tree, sym);
1535 }
1536 }
1537 } else if (isEarlyReference(localEnv, tree, sym)) {
1538 /* now this is a `proper` instance field of the current class
1539 * references to fields of identity classes which happen to have initializers are
1540 * not allowed in the prologue.
1541 * But it is OK for a field with initializer to refer to another field with initializer,
1542 * so no warning or error if we are analyzing a field initializer.
1543 */
1544 if (insideLambdaOrClassDef ||
1545 (!localEnv.enclClass.sym.isValueClass() &&
1546 (sym.flags_field & HASINIT) != 0 &&
1547 !isInitializer))
1548 reportPrologueError(tree, sym);
1549 // we will need to generate a proxy for this field later on
1550 if (!isInLHS) {
1551 if (!allowValueClasses) {
1552 reportPrologueError(tree, sym);
1553 } else {
1554 if (mode == PrologueVisitorMode.THIS_CONSTRUCTOR) {
1555 reportPrologueError(tree, sym);
1556 } else if (mode == PrologueVisitorMode.SUPER_CONSTRUCTOR && isInstanceField(tree)) {
1557 localProxyVarsGen.addFieldReadInPrologue(localEnv.enclMethod, sym);
1558 }
1559 /* we do nothing in warnings only mode, as in that mode we are simulating what
1560 * the compiler would do in case the constructor code would be in the prologue
1561 * phase
1562 */
1563 }
1564 }
1565 }
1566 }
1567 }
1568 }
1569
1570 /**
1571 * Determine if the symbol appearance constitutes an early reference to the current class.
1572 *
1573 * <p>
1574 * This means the symbol is an instance field, or method, of the current class and it appears
1575 * in an early initialization context of it (i.e., one of its constructor prologues).
1576 *
1577 * @param env The current environment
1578 * @param tree the AST referencing the variable
1579 * @param sym The symbol
1580 */
1581 private boolean isEarlyReference(Env<AttrContext> env, JCTree tree, Symbol sym) {
1582 if ((sym.kind == VAR || sym.kind == MTH) &&
1583 sym.isMemberOf(env.enclClass.sym, types) &&
1584 ((sym.flags() & STATIC) == 0 ||
1585 (sym.kind == MTH && tree instanceof JCFieldAccess))) {
1586 // Allow "Foo.this.x" when "Foo" is (also) an outer class, as this refers to the outer instance
1587 if (tree instanceof JCFieldAccess fa) {
1588 return TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, fa.selected);
1589 } else if (currentClassSym != env.enclClass.sym) {
1590 /* so we are inside a class, CI, in the prologue of an outer class, CO, and the symbol being
1591 * analyzed has no qualifier. So if the symbol is a member of CI the reference is allowed,
1592 * otherwise it is not.
1593 * It could be that the reference to CI's member happens inside CI's own prologue, but that
1594 * will be checked separately, when CI's prologue is analyzed.
1595 */
1596 return !sym.isMemberOf(currentClassSym, types);
1597 }
1598 return true;
1599 }
1600 return false;
1601 }
1602
1603 /* scanner for a select expression, anything that is not a select or identifier
1604 * will be stored for further analysis
1605 */
1606 class SelectScanner extends DeferredAttr.FilterScanner {
1607 JCTree scanLater;
1608 java.util.List<JCTree> selectorTrees = new ArrayList<>();
1609
1610 SelectScanner() {
1611 super(Set.of(IDENT, SELECT, PARENS));
1612 }
1613
1614 @Override
1615 public void visitSelect(JCFieldAccess tree) {
1616 super.visitSelect(tree);
1617 selectorTrees.add(tree.selected);
1618 }
1619
1620 @Override
1621 void skip(JCTree tree) {
1622 scanLater = tree;
1623 }
1624 }
1625 }
1626
1627 public void visitVarDef(JCVariableDecl tree) {
1628 // Local variables have not been entered yet, so we need to do it now:
1629 if (env.info.scope.owner.kind == MTH || env.info.scope.owner.kind == VAR) {
1630 if (tree.sym != null) {
1631 // parameters have already been entered
1632 env.info.scope.enter(tree.sym);
1633 } else {
1634 if (tree.isImplicitlyTyped() && (tree.getModifiers().flags & PARAMETER) == 0) {
1635 if (tree.init == null) {
1636 //cannot use 'var' without initializer
1637 log.error(tree, Errors.CantInferLocalVarType(tree.name, Fragments.LocalMissingInit));
1638 tree.vartype = make.at(tree.pos()).Erroneous();
1639 } else {
1640 Fragment msg = canInferLocalVarType(tree);
1641 if (msg != null) {
1642 //cannot use 'var' with initializer which require an explicit target
1643 //(e.g. lambda, method reference, array initializer).
1644 log.error(tree, Errors.CantInferLocalVarType(tree.name, msg));
1645 tree.vartype = make.at(tree.pos()).Erroneous();
1646 }
1655 }
1656 } else {
1657 doQueueScanTreeAndTypeAnnotateForVarInit(tree, env);
1658 }
1659
1660 VarSymbol v = tree.sym;
1661 Lint lint = env.info.lint.augment(v);
1662 Lint prevLint = chk.setLint(lint);
1663
1664 // Check that the variable's declared type is well-formed.
1665 boolean isImplicitLambdaParameter = env.tree.hasTag(LAMBDA) &&
1666 ((JCLambda)env.tree).paramKind == JCLambda.ParameterKind.IMPLICIT &&
1667 (tree.sym.flags() & PARAMETER) != 0;
1668 chk.validate(tree.vartype, env, !isImplicitLambdaParameter && !tree.isImplicitlyTyped());
1669
1670 try {
1671 v.getConstValue(); // ensure compile-time constant initializer is evaluated
1672 chk.checkDeprecatedAnnotation(tree.pos(), v);
1673
1674 if (tree.init != null) {
1675 Env<AttrContext> initEnv = memberEnter.initEnv(tree, env);
1676 if ((v.flags_field & FINAL) == 0 ||
1677 !memberEnter.needsLazyConstValue(tree.init)) {
1678 // Not a compile-time constant
1679 // Attribute initializer in a new environment
1680 // with the declared variable as owner.
1681 // Check that initializer conforms to variable's declared type.
1682 initEnv.info.lint = lint;
1683 // In order to catch self-references, we set the variable's
1684 // declaration position to maximal possible value, effectively
1685 // marking the variable as undefined.
1686 initEnv.info.enclVar = v;
1687 boolean previousCtorPrologue = initEnv.info.ctorPrologue;
1688 try {
1689 if (v.owner.kind == TYP && !v.isStatic() && v.isStrict()) {
1690 // strict instance initializer in a value class
1691 initEnv.info.ctorPrologue = true;
1692 }
1693 attribExpr(tree.init, initEnv, v.type);
1694 if (tree.isImplicitlyTyped()) {
1695 //fixup local variable type
1696 v.type = chk.checkLocalVarType(tree, tree.init.type, tree.name);
1697 }
1698 } finally {
1699 initEnv.info.ctorPrologue = previousCtorPrologue;
1700 }
1701 }
1702 if (allowValueClasses && v.owner.kind == TYP && !v.isStatic()) {
1703 // strict field initializers are inlined in constructor's prologues
1704 CtorPrologueVisitor ctorPrologueVisitor = new CtorPrologueVisitor(initEnv,
1705 !v.isStrict() ? PrologueVisitorMode.WARNINGS_ONLY : PrologueVisitorMode.SUPER_CONSTRUCTOR,
1706 true);
1707 ctorPrologueVisitor.scan(tree.init);
1708 }
1709 if (tree.isImplicitlyTyped()) {
1710 setSyntheticVariableType(tree, v.type);
1711 }
1712 }
1713 result = tree.type = v.type;
1714 if (env.enclClass.sym.isRecord() && tree.sym.owner.kind == TYP && !v.isStatic()) {
1715 if (isNonArgsMethodInObject(v.name)) {
1716 log.error(tree, Errors.IllegalRecordComponentName(v));
1717 }
1718 }
1719 chk.checkRequiresIdentity(tree, env.info.lint);
1720 }
1721 finally {
1722 chk.setLint(prevLint);
1723 }
1724 }
1725
1726 private void doQueueScanTreeAndTypeAnnotateForVarInit(JCVariableDecl tree, Env<AttrContext> env) {
1727 if (tree.init != null &&
1728 (tree.mods.flags & Flags.FIELD_INIT_TYPE_ANNOTATIONS_QUEUED) == 0 &&
1807 }
1808 }
1809 }
1810
1811 public void visitSkip(JCSkip tree) {
1812 result = null;
1813 }
1814
1815 public void visitBlock(JCBlock tree) {
1816 if (env.info.scope.owner.kind == TYP || env.info.scope.owner.kind == ERR) {
1817 // Block is a static or instance initializer;
1818 // let the owner of the environment be a freshly
1819 // created BLOCK-method.
1820 Symbol fakeOwner =
1821 new MethodSymbol(tree.flags | BLOCK |
1822 env.info.scope.owner.flags() & STRICTFP, names.empty, initBlockType,
1823 env.info.scope.owner);
1824 final Env<AttrContext> localEnv =
1825 env.dup(tree, env.info.dup(env.info.scope.dupUnshared(fakeOwner)));
1826
1827 if ((tree.flags & STATIC) != 0) {
1828 localEnv.info.staticLevel++;
1829 } else {
1830 localEnv.info.instanceInitializerBlock = true;
1831 }
1832 // Attribute all type annotations in the block
1833 annotate.queueScanTreeAndTypeAnnotate(tree, localEnv, localEnv.info.scope.owner);
1834 annotate.flush();
1835 attribStats(tree.stats, localEnv);
1836
1837 {
1838 // Store init and clinit type annotations with the ClassSymbol
1839 // to allow output in Gen.normalizeDefs.
1840 ClassSymbol cs = (ClassSymbol)env.info.scope.owner;
1841 List<Attribute.TypeCompound> tas = localEnv.info.scope.owner.getRawTypeAttributes();
1842 if ((tree.flags & STATIC) != 0) {
1843 cs.appendClassInitTypeAttributes(tas);
1844 } else {
1845 cs.appendInitTypeAttributes(tas);
1846 }
1847 }
1848 } else {
1849 // Create a new local environment with a local scope.
1850 Env<AttrContext> localEnv =
1851 env.dup(tree, env.info.dup(env.info.scope.dup()));
2324 // where
2325 /** Return the selected enumeration constant symbol, or null. */
2326 private Symbol enumConstant(JCTree tree, Type enumType) {
2327 if (tree.hasTag(IDENT)) {
2328 JCIdent ident = (JCIdent)tree;
2329 Name name = ident.name;
2330 for (Symbol sym : enumType.tsym.members().getSymbolsByName(name)) {
2331 if (sym.kind == VAR) {
2332 Symbol s = ident.sym = sym;
2333 ((VarSymbol)s).getConstValue(); // ensure initializer is evaluated
2334 ident.type = s.type;
2335 return ((s.flags_field & Flags.ENUM) == 0)
2336 ? null : s;
2337 }
2338 }
2339 }
2340 return null;
2341 }
2342
2343 public void visitSynchronized(JCSynchronized tree) {
2344 boolean identityType = chk.checkIdentityType(tree.pos(), attribExpr(tree.lock, env));
2345 if (identityType && tree.lock.type != null && tree.lock.type.isValueBased()) {
2346 log.warning(tree.pos(), LintWarnings.AttemptToSynchronizeOnInstanceOfValueBasedClass);
2347 }
2348 attribStat(tree.body, env);
2349 result = null;
2350 }
2351
2352 public void visitTry(JCTry tree) {
2353 // Create a new local environment with a local
2354 Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
2355 try {
2356 boolean isTryWithResource = tree.resources.nonEmpty();
2357 // Create a nested environment for attributing the try block if needed
2358 Env<AttrContext> tryEnv = isTryWithResource ?
2359 env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) :
2360 localEnv;
2361 try {
2362 // Attribute resource declarations
2363 for (JCTree resource : tree.resources) {
2364 CheckContext twrContext = new Check.NestedCheckContext(resultInfo.checkContext) {
2365 @Override
4781 }
4782
4783 public void visitSelect(JCFieldAccess tree) {
4784 // Determine the expected kind of the qualifier expression.
4785 KindSelector skind = KindSelector.NIL;
4786 if (tree.name == names._this || tree.name == names._super ||
4787 tree.name == names._class)
4788 {
4789 skind = KindSelector.TYP;
4790 } else {
4791 if (pkind().contains(KindSelector.PCK))
4792 skind = KindSelector.of(skind, KindSelector.PCK);
4793 if (pkind().contains(KindSelector.TYP))
4794 skind = KindSelector.of(skind, KindSelector.TYP, KindSelector.PCK);
4795 if (pkind().contains(KindSelector.VAL_MTH))
4796 skind = KindSelector.of(skind, KindSelector.VAL, KindSelector.TYP);
4797 }
4798
4799 // Attribute the qualifier expression, and determine its symbol (if any).
4800 Type site = attribTree(tree.selected, env, new ResultInfo(skind, Type.noType));
4801 Assert.check(site == tree.selected.type);
4802 if (!pkind().contains(KindSelector.TYP_PCK))
4803 site = capture(site); // Capture field access
4804
4805 // don't allow T.class T[].class, etc
4806 if (skind == KindSelector.TYP) {
4807 Type elt = site;
4808 while (elt.hasTag(ARRAY))
4809 elt = ((ArrayType)elt).elemtype;
4810 if (elt.hasTag(TYPEVAR)) {
4811 log.error(tree.pos(), Errors.TypeVarCantBeDeref);
4812 result = tree.type = types.createErrorType(tree.name, site.tsym, site);
4813 tree.sym = tree.type.tsym;
4814 return ;
4815 }
4816 }
4817
4818 // If qualifier symbol is a type or `super', assert `selectSuper'
4819 // for the selection. This is relevant for determining whether
4820 // protected symbols are accessible.
4821 Symbol sitesym = TreeInfo.symbol(tree.selected);
5893 .filter(s -> s.tsym.isSealed())
5894 .map(s -> (ClassSymbol) s.tsym)
5895 .collect(List.collector());
5896
5897 if (sealedSupers.isEmpty()) {
5898 if ((c.flags_field & Flags.NON_SEALED) != 0) {
5899 boolean hasErrorSuper = false;
5900
5901 hasErrorSuper |= types.directSupertypes(c.type)
5902 .stream()
5903 .anyMatch(s -> s.tsym.kind == Kind.ERR);
5904
5905 ClassType ct = (ClassType) c.type;
5906
5907 hasErrorSuper |= !ct.isCompound() && ct.interfaces_field != ct.all_interfaces_field;
5908
5909 if (!hasErrorSuper) {
5910 log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.NonSealedWithNoSealedSupertype(c));
5911 }
5912 }
5913 } else if ((c.flags_field & Flags.COMPOUND) == 0) {
5914 if (c.isDirectlyOrIndirectlyLocal() && !c.isEnum()) {
5915 log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.LocalClassesCantExtendSealed(c.isAnonymous() ? Fragments.Anonymous : Fragments.Local));
5916 }
5917
5918 if (!c.type.isCompound()) {
5919 for (ClassSymbol supertypeSym : sealedSupers) {
5920 if (!supertypeSym.isPermittedSubclass(c.type.tsym)) {
5921 log.error(TreeInfo.diagnosticPositionFor(c.type.tsym, env.tree), Errors.CantInheritFromSealed(supertypeSym));
5922 }
5923 }
5924 if (!c.isNonSealed() && !c.isFinal() && !c.isSealed()) {
5925 log.error(TreeInfo.diagnosticPositionFor(c, env.tree),
5926 c.isInterface() ?
5927 Errors.NonSealedOrSealedExpected :
5928 Errors.NonSealedSealedOrFinalExpected);
5929 }
5930 }
5931 }
5932
5933 env.info.returnResult = null;
5934 // java.lang.Enum may not be subclassed by a non-enum
5935 if (st.tsym == syms.enumSym &&
5936 ((c.flags_field & (Flags.ENUM|Flags.COMPOUND)) == 0))
5937 log.error(env.tree.pos(), Errors.EnumNoSubclassing);
5938
5939 // Enums may not be extended by source-level classes
5940 if (st.tsym != null &&
5941 ((st.tsym.flags_field & Flags.ENUM) != 0) &&
5942 ((c.flags_field & (Flags.ENUM | Flags.COMPOUND)) == 0)) {
5943 log.error(env.tree.pos(), Errors.EnumTypesNotExtensible);
5944 }
5945
5946 if (rs.isSerializable(c.type)) {
5947 env.info.isSerializable = true;
5948 }
5949
5950 if (c.isValueClass()) {
5951 Assert.check(env.tree.hasTag(CLASSDEF));
5952 chk.checkConstraintsOfValueClass((JCClassDecl) env.tree, c);
5953 }
5954
5955 attribClassBody(env, c);
5956
5957 chk.checkDeprecatedAnnotation(env.tree.pos(), c);
5958 chk.checkClassOverrideEqualsAndHashIfNeeded(env.tree.pos(), c);
5959 chk.checkFunctionalInterface((JCClassDecl) env.tree, c);
5960 chk.checkLeaksNotAccessible(env, (JCClassDecl) env.tree);
5961
5962 if (c.isImplicit()) {
5963 chk.checkHasMain(env.tree.pos(), c);
5964 }
5965 } finally {
5966 env.info.returnResult = prevReturnRes;
5967 log.useSource(prev);
5968 chk.setLint(prevLint);
5969 }
5970
5971 }
5972 }
5973
5974 public void visitImport(JCImport tree) {
6081 sym.kind != VAR ||
6082 sym.getConstValue() == null)
6083 log.error(l.head.pos(), Errors.IclsCantHaveStaticDecl(c));
6084 }
6085 }
6086
6087 // Check for proper placement of super()/this() calls.
6088 chk.checkSuperInitCalls(tree);
6089
6090 // Check for cycles among non-initial constructors.
6091 chk.checkCyclicConstructors(tree);
6092
6093 // Check for cycles among annotation elements.
6094 chk.checkNonCyclicElements(tree);
6095
6096 // Check for proper use of serialVersionUID and other
6097 // serialization-related fields and methods
6098 if (env.info.lint.isEnabled(LintCategory.SERIAL)
6099 && rs.isSerializable(c.type)
6100 && !c.isAnonymous()) {
6101 chk.checkSerialStructure(env, tree, c);
6102 }
6103 // Correctly organize the positions of the type annotations
6104 typeAnnotations.organizeTypeAnnotationsBodies(tree);
6105
6106 // Check type annotations applicability rules
6107 validateTypeAnnotations(tree, false);
6108 }
6109 // where
6110 /** get a diagnostic position for an attribute of Type t, or null if attribute missing */
6111 private DiagnosticPosition getDiagnosticPosition(JCClassDecl tree, Type t) {
6112 for(List<JCAnnotation> al = tree.mods.annotations; !al.isEmpty(); al = al.tail) {
6113 if (types.isSameType(al.head.annotationType.type, t))
6114 return al.head.pos();
6115 }
6116
6117 return null;
6118 }
6119
6120 private Type capture(Type type) {
6121 return types.capture(type);
|