107 final DeferredAttr deferredAttr;
108 final Check chk;
109 final Flow flow;
110 final MemberEnter memberEnter;
111 final TypeEnter typeEnter;
112 final TreeMaker make;
113 final ConstFold cfolder;
114 final Enter enter;
115 final Target target;
116 final Types types;
117 final Preview preview;
118 final JCDiagnostic.Factory diags;
119 final TypeAnnotations typeAnnotations;
120 final DeferredLintHandler deferredLintHandler;
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
128 public static Attr instance(Context context) {
129 Attr instance = context.get(attrKey);
130 if (instance == null)
131 instance = new Attr(context);
132 return instance;
133 }
134
135 @SuppressWarnings("this-escape")
136 protected Attr(Context context) {
137 context.put(attrKey, this);
138
139 names = Names.instance(context);
140 log = Log.instance(context);
141 syms = Symtab.instance(context);
142 rs = Resolve.instance(context);
143 operators = Operators.instance(context);
144 chk = Check.instance(context);
145 flow = Flow.instance(context);
146 memberEnter = MemberEnter.instance(context);
147 typeEnter = TypeEnter.instance(context);
148 make = TreeMaker.instance(context);
149 enter = Enter.instance(context);
150 infer = Infer.instance(context);
151 analyzer = Analyzer.instance(context);
152 deferredAttr = DeferredAttr.instance(context);
153 cfolder = ConstFold.instance(context);
154 target = Target.instance(context);
155 types = Types.instance(context);
156 preview = Preview.instance(context);
157 diags = JCDiagnostic.Factory.instance(context);
158 annotate = Annotate.instance(context);
159 typeAnnotations = TypeAnnotations.instance(context);
160 deferredLintHandler = DeferredLintHandler.instance(context);
161 typeEnvs = TypeEnvs.instance(context);
162 dependencies = Dependencies.instance(context);
163 argumentAttr = ArgumentAttr.instance(context);
164 matchBindingsComputer = MatchBindingsComputer.instance(context);
165 attrRecover = AttrRecover.instance(context);
166
167 Options options = Options.instance(context);
168
169 Source source = Source.instance(context);
170 allowReifiableTypesInInstanceof = Feature.REIFIABLE_TYPES_INSTANCEOF.allowedInSource(source);
171 allowRecords = Feature.RECORDS.allowedInSource(source);
172 allowPatternSwitch = (preview.isEnabled() || !preview.isPreview(Feature.PATTERN_SWITCH)) &&
173 Feature.PATTERN_SWITCH.allowedInSource(source);
174 allowUnconditionalPatternsInstanceOf =
175 Feature.UNCONDITIONAL_PATTERN_IN_INSTANCEOF.allowedInSource(source);
176 sourceName = source.name;
177 useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning");
178
179 statInfo = new ResultInfo(KindSelector.NIL, Type.noType);
180 varAssignmentInfo = new ResultInfo(KindSelector.ASG, Type.noType);
181 unknownExprInfo = new ResultInfo(KindSelector.VAL, Type.noType);
182 methodAttrInfo = new MethodAttrInfo();
183 unknownTypeInfo = new ResultInfo(KindSelector.TYP, Type.noType);
184 unknownTypeExprInfo = new ResultInfo(KindSelector.VAL_TYP, Type.noType);
185 recoveryInfo = new RecoveryInfo(deferredAttr.emptyDeferredAttrContext);
186 initBlockType = new MethodType(List.nil(), syms.voidType, List.nil(), syms.methodClass);
187 }
188
189 /** Switch: reifiable types in instanceof enabled?
190 */
191 boolean allowReifiableTypesInInstanceof;
192
193 /** Are records allowed
194 */
195 private final boolean allowRecords;
196
197 /** Are patterns in switch allowed
198 */
199 private final boolean allowPatternSwitch;
200
201 /** Are unconditional patterns in instanceof allowed
202 */
203 private final boolean allowUnconditionalPatternsInstanceOf;
204
205 /**
206 * Switch: warn about use of variable before declaration?
207 * RFE: 6425594
208 */
209 boolean useBeforeDeclarationWarning;
210
211 /**
212 * Switch: name of source level; used for error reporting.
213 */
214 String sourceName;
215
216 /** Check kind and type of given tree against protokind and prototype.
217 * If check succeeds, store type in tree and return it.
218 * If check fails, store errType in tree and return it.
219 * No checks are performed if the prototype is a method type.
220 * It is not necessary in this case since we know that kind and type
221 * are correct.
222 *
223 * @param tree The tree whose kind and type is checked
224 * @param found The computed type of the tree
278 owner.kind == VAR || // i.e. we are in a variable initializer
279 (owner.flags() & BLOCK) != 0) // i.e. we are in an initializer block
280 &&
281 v.owner == owner.owner
282 &&
283 ((v.flags() & STATIC) != 0) == Resolve.isStatic(env));
284 boolean insideCompactConstructor = env.enclMethod != null && TreeInfo.isCompactConstructor(env.enclMethod);
285 return isAssignable & !insideCompactConstructor;
286 }
287
288 /** Check that variable can be assigned to.
289 * @param pos The current source code position.
290 * @param v The assigned variable
291 * @param base If the variable is referred to in a Select, the part
292 * to the left of the `.', null otherwise.
293 * @param env The current environment.
294 */
295 void checkAssignable(DiagnosticPosition pos, VarSymbol v, JCTree base, Env<AttrContext> env) {
296 if (v.name == names._this) {
297 log.error(pos, Errors.CantAssignValToThis);
298 return;
299 }
300 if ((v.flags() & FINAL) != 0 &&
301 ((v.flags() & HASINIT) != 0
302 ||
303 !((base == null ||
304 TreeInfo.isThisQualifier(base)) &&
305 isAssignableAsBlankFinal(v, env)))) {
306 if (v.isResourceVariable()) { //TWR resource
307 log.error(pos, Errors.TryResourceMayNotBeAssigned(v));
308 } else {
309 log.error(pos, Errors.CantAssignValToVar(Flags.toSource(v.flags() & (STATIC | FINAL)), v));
310 }
311 return;
312 }
313
314 // Check instance field assignments that appear in constructor prologues
315 if (rs.isEarlyReference(env, base, v)) {
316
317 // Field may not be inherited from a superclass
318 if (v.owner != env.enclClass.sym) {
319 log.error(pos, Errors.CantRefBeforeCtorCalled(v));
320 return;
321 }
322
323 // Field may not have an initializer
324 if ((v.flags() & HASINIT) != 0) {
325 log.error(pos, Errors.CantAssignInitializedBeforeCtorCalled(v));
326 return;
327 }
328 }
329 }
330
331 /** Does tree represent a static reference to an identifier?
332 * It is assumed that tree is either a SELECT or an IDENT.
333 * We have to weed out selects from non-type names here.
334 * @param tree The candidate tree.
335 */
336 boolean isStaticReference(JCTree tree) {
337 if (tree.hasTag(SELECT)) {
338 Symbol lsym = TreeInfo.symbol(((JCFieldAccess) tree).selected);
339 if (lsym == null || lsym.kind != TYP) {
340 return false;
341 }
342 }
343 return true;
344 }
345
346 /** Is this symbol a type?
347 */
1105 * - have an accessibility stricter than that of the record type
1106 * - explicitly invoke any other constructor
1107 */
1108 if ((tree.sym.flags_field & GENERATEDCONSTR) == 0) {
1109 if (Check.protection(m.flags()) > Check.protection(env.enclClass.sym.flags())) {
1110 log.error(tree,
1111 (env.enclClass.sym.flags() & AccessFlags) == 0 ?
1112 Errors.InvalidCanonicalConstructorInRecord(
1113 Fragments.Canonical,
1114 env.enclClass.sym.name,
1115 Fragments.CanonicalMustNotHaveStrongerAccess("package")
1116 ) :
1117 Errors.InvalidCanonicalConstructorInRecord(
1118 Fragments.Canonical,
1119 env.enclClass.sym.name,
1120 Fragments.CanonicalMustNotHaveStrongerAccess(asFlagSet(env.enclClass.sym.flags() & AccessFlags))
1121 )
1122 );
1123 }
1124
1125 if (TreeInfo.hasAnyConstructorCall(tree)) {
1126 log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1127 Fragments.Canonical, env.enclClass.sym.name,
1128 Fragments.CanonicalMustNotContainExplicitConstructorInvocation));
1129 }
1130 }
1131
1132 // also we want to check that no type variables have been defined
1133 if (!tree.typarams.isEmpty()) {
1134 log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1135 Fragments.Canonical, env.enclClass.sym.name, Fragments.CanonicalMustNotDeclareTypeVariables));
1136 }
1137
1138 /* and now we need to check that the constructor's arguments are exactly the same as those of the
1139 * record components
1140 */
1141 List<? extends RecordComponent> recordComponents = env.enclClass.sym.getRecordComponents();
1142 List<Type> recordFieldTypes = TreeInfo.recordFields(env.enclClass).map(vd -> vd.sym.type);
1143 for (JCVariableDecl param: tree.params) {
1144 boolean paramIsVarArgs = (param.sym.flags_field & VARARGS) != 0;
1145 if (!types.isSameType(param.type, recordFieldTypes.head) ||
1187 }
1188 if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0)
1189 log.error(tree.pos(), Errors.MissingMethBodyOrDeclAbstract);
1190 } else {
1191 if ((tree.sym.flags() & (ABSTRACT|DEFAULT|PRIVATE)) == ABSTRACT) {
1192 if ((owner.flags() & INTERFACE) != 0) {
1193 log.error(tree.body.pos(), Errors.IntfMethCantHaveBody);
1194 } else {
1195 log.error(tree.pos(), Errors.AbstractMethCantHaveBody);
1196 }
1197 } else if ((tree.mods.flags & NATIVE) != 0) {
1198 log.error(tree.pos(), Errors.NativeMethCantHaveBody);
1199 }
1200 // Add an implicit super() call unless an explicit call to
1201 // super(...) or this(...) is given
1202 // or we are compiling class java.lang.Object.
1203 if (isConstructor && owner.type != syms.objectType) {
1204 if (!TreeInfo.hasAnyConstructorCall(tree)) {
1205 JCStatement supCall = make.at(tree.body.pos).Exec(make.Apply(List.nil(),
1206 make.Ident(names._super), make.Idents(List.nil())));
1207 tree.body.stats = tree.body.stats.prepend(supCall);
1208 } else if ((env.enclClass.sym.flags() & ENUM) != 0 &&
1209 (tree.mods.flags & GENERATEDCONSTR) == 0 &&
1210 TreeInfo.hasConstructorCall(tree, names._super)) {
1211 // enum constructors are not allowed to call super
1212 // directly, so make sure there aren't any super calls
1213 // in enum constructors, except in the compiler
1214 // generated one.
1215 log.error(tree.body.stats.head.pos(),
1216 Errors.CallToSuperNotAllowedInEnumCtor(env.enclClass.sym));
1217 }
1218 if (env.enclClass.sym.isRecord() && (tree.sym.flags_field & RECORD) != 0) { // we are seeing the canonical constructor
1219 List<Name> recordComponentNames = TreeInfo.recordFields(env.enclClass).map(vd -> vd.sym.name);
1220 List<Name> initParamNames = tree.sym.params.map(p -> p.name);
1221 if (!initParamNames.equals(recordComponentNames)) {
1222 log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1223 Fragments.Canonical, env.enclClass.sym.name, Fragments.CanonicalWithNameMismatch));
1224 }
1225 if (tree.sym.type.asMethodType().thrown != null && !tree.sym.type.asMethodType().thrown.isEmpty()) {
1226 log.error(tree,
1227 Errors.InvalidCanonicalConstructorInRecord(
1228 TreeInfo.isCompactConstructor(tree) ? Fragments.Compact : Fragments.Canonical,
1229 env.enclClass.sym.name,
1230 Fragments.ThrowsClauseNotAllowedForCanonicalConstructor(
1231 TreeInfo.isCompactConstructor(tree) ? Fragments.Compact : Fragments.Canonical)));
1232 }
1233 }
1234 }
1235
1236 // Attribute all type annotations in the body
1237 annotate.queueScanTreeAndTypeAnnotate(tree.body, localEnv, m, null);
1238 annotate.flush();
1239
1240 // Start of constructor prologue
1241 localEnv.info.ctorPrologue = isConstructor;
1242
1243 // Attribute method body.
1244 attribStat(tree.body, localEnv);
1245 }
1246
1247 localEnv.info.scope.leave();
1248 result = tree.type = m.type;
1249 } finally {
1250 chk.setLint(prevLint);
1251 chk.setMethod(prevMethod);
1252 env.info.ctorPrologue = ctorProloguePrev;
1253 }
1254 }
1255
1256 public void visitVarDef(JCVariableDecl tree) {
1257 // Local variables have not been entered yet, so we need to do it now:
1258 if (env.info.scope.owner.kind == MTH || env.info.scope.owner.kind == VAR) {
1259 if (tree.sym != null) {
1260 // parameters have already been entered
1261 env.info.scope.enter(tree.sym);
1262 } else {
1263 if (tree.isImplicitlyTyped() && (tree.getModifiers().flags & PARAMETER) == 0) {
1264 if (tree.init == null) {
1265 //cannot use 'var' without initializer
1266 log.error(tree, Errors.CantInferLocalVarType(tree.name, Fragments.LocalMissingInit));
1267 tree.vartype = make.Erroneous();
1268 } else {
1269 Fragment msg = canInferLocalVarType(tree);
1270 if (msg != null) {
1271 //cannot use 'var' with initializer which require an explicit target
1272 //(e.g. lambda, method reference, array initializer).
1273 log.error(tree, Errors.CantInferLocalVarType(tree.name, msg));
1274 tree.vartype = make.Erroneous();
1275 }
1297 chk.validate(tree.vartype, env, !isImplicitLambdaParameter && !tree.isImplicitlyTyped());
1298
1299 try {
1300 v.getConstValue(); // ensure compile-time constant initializer is evaluated
1301 deferredLintHandler.flush(tree, lint);
1302 chk.checkDeprecatedAnnotation(tree.pos(), v);
1303
1304 if (tree.init != null) {
1305 if ((v.flags_field & FINAL) == 0 ||
1306 !memberEnter.needsLazyConstValue(tree.init)) {
1307 // Not a compile-time constant
1308 // Attribute initializer in a new environment
1309 // with the declared variable as owner.
1310 // Check that initializer conforms to variable's declared type.
1311 Env<AttrContext> initEnv = memberEnter.initEnv(tree, env);
1312 initEnv.info.lint = lint;
1313 // In order to catch self-references, we set the variable's
1314 // declaration position to maximal possible value, effectively
1315 // marking the variable as undefined.
1316 initEnv.info.enclVar = v;
1317 attribExpr(tree.init, initEnv, v.type);
1318 if (tree.isImplicitlyTyped()) {
1319 //fixup local variable type
1320 v.type = chk.checkLocalVarType(tree, tree.init.type, tree.name);
1321 }
1322 }
1323 if (tree.isImplicitlyTyped()) {
1324 setSyntheticVariableType(tree, v.type);
1325 }
1326 }
1327 result = tree.type = v.type;
1328 if (env.enclClass.sym.isRecord() && tree.sym.owner.kind == TYP && !v.isStatic()) {
1329 if (isNonArgsMethodInObject(v.name)) {
1330 log.error(tree, Errors.IllegalRecordComponentName(v));
1331 }
1332 }
1333 chk.checkRequiresIdentity(tree, env.info.lint);
1334 }
1335 finally {
1336 chk.setLint(prevLint);
1337 }
1338 }
1339
1340 private void doQueueScanTreeAndTypeAnnotateForVarInit(JCVariableDecl tree, Env<AttrContext> env) {
1421 }
1422 }
1423 }
1424
1425 public void visitSkip(JCSkip tree) {
1426 result = null;
1427 }
1428
1429 public void visitBlock(JCBlock tree) {
1430 if (env.info.scope.owner.kind == TYP || env.info.scope.owner.kind == ERR) {
1431 // Block is a static or instance initializer;
1432 // let the owner of the environment be a freshly
1433 // created BLOCK-method.
1434 Symbol fakeOwner =
1435 new MethodSymbol(tree.flags | BLOCK |
1436 env.info.scope.owner.flags() & STRICTFP, names.empty, initBlockType,
1437 env.info.scope.owner);
1438 final Env<AttrContext> localEnv =
1439 env.dup(tree, env.info.dup(env.info.scope.dupUnshared(fakeOwner)));
1440
1441 if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
1442 // Attribute all type annotations in the block
1443 annotate.queueScanTreeAndTypeAnnotate(tree, localEnv, localEnv.info.scope.owner, null);
1444 annotate.flush();
1445 attribStats(tree.stats, localEnv);
1446
1447 {
1448 // Store init and clinit type annotations with the ClassSymbol
1449 // to allow output in Gen.normalizeDefs.
1450 ClassSymbol cs = (ClassSymbol)env.info.scope.owner;
1451 List<Attribute.TypeCompound> tas = localEnv.info.scope.owner.getRawTypeAttributes();
1452 if ((tree.flags & STATIC) != 0) {
1453 cs.appendClassInitTypeAttributes(tas);
1454 } else {
1455 cs.appendInitTypeAttributes(tas);
1456 }
1457 }
1458 } else {
1459 // Create a new local environment with a local scope.
1460 Env<AttrContext> localEnv =
1461 env.dup(tree, env.info.dup(env.info.scope.dup()));
1934 // where
1935 /** Return the selected enumeration constant symbol, or null. */
1936 private Symbol enumConstant(JCTree tree, Type enumType) {
1937 if (tree.hasTag(IDENT)) {
1938 JCIdent ident = (JCIdent)tree;
1939 Name name = ident.name;
1940 for (Symbol sym : enumType.tsym.members().getSymbolsByName(name)) {
1941 if (sym.kind == VAR) {
1942 Symbol s = ident.sym = sym;
1943 ((VarSymbol)s).getConstValue(); // ensure initializer is evaluated
1944 ident.type = s.type;
1945 return ((s.flags_field & Flags.ENUM) == 0)
1946 ? null : s;
1947 }
1948 }
1949 }
1950 return null;
1951 }
1952
1953 public void visitSynchronized(JCSynchronized tree) {
1954 chk.checkRefType(tree.pos(), attribExpr(tree.lock, env));
1955 if (tree.lock.type != null && tree.lock.type.isValueBased()) {
1956 env.info.lint.logIfEnabled(tree.pos(), LintWarnings.AttemptToSynchronizeOnInstanceOfValueBasedClass);
1957 }
1958 attribStat(tree.body, env);
1959 result = null;
1960 }
1961
1962 public void visitTry(JCTry tree) {
1963 // Create a new local environment with a local
1964 Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
1965 try {
1966 boolean isTryWithResource = tree.resources.nonEmpty();
1967 // Create a nested environment for attributing the try block if needed
1968 Env<AttrContext> tryEnv = isTryWithResource ?
1969 env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) :
1970 localEnv;
1971 try {
1972 // Attribute resource declarations
1973 for (JCTree resource : tree.resources) {
1974 CheckContext twrContext = new Check.NestedCheckContext(resultInfo.checkContext) {
1975 @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);
5492 .filter(s -> s.tsym.isSealed())
5493 .map(s -> (ClassSymbol) s.tsym)
5494 .collect(List.collector());
5495
5496 if (sealedSupers.isEmpty()) {
5497 if ((c.flags_field & Flags.NON_SEALED) != 0) {
5498 boolean hasErrorSuper = false;
5499
5500 hasErrorSuper |= types.directSupertypes(c.type)
5501 .stream()
5502 .anyMatch(s -> s.tsym.kind == Kind.ERR);
5503
5504 ClassType ct = (ClassType) c.type;
5505
5506 hasErrorSuper |= !ct.isCompound() && ct.interfaces_field != ct.all_interfaces_field;
5507
5508 if (!hasErrorSuper) {
5509 log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.NonSealedWithNoSealedSupertype(c));
5510 }
5511 }
5512 } else {
5513 if (c.isDirectlyOrIndirectlyLocal() && !c.isEnum()) {
5514 log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.LocalClassesCantExtendSealed(c.isAnonymous() ? Fragments.Anonymous : Fragments.Local));
5515 }
5516
5517 if (!c.type.isCompound()) {
5518 for (ClassSymbol supertypeSym : sealedSupers) {
5519 if (!supertypeSym.isPermittedSubclass(c.type.tsym)) {
5520 log.error(TreeInfo.diagnosticPositionFor(c.type.tsym, env.tree), Errors.CantInheritFromSealed(supertypeSym));
5521 }
5522 }
5523 if (!c.isNonSealed() && !c.isFinal() && !c.isSealed()) {
5524 log.error(TreeInfo.diagnosticPositionFor(c, env.tree),
5525 c.isInterface() ?
5526 Errors.NonSealedOrSealedExpected :
5527 Errors.NonSealedSealedOrFinalExpected);
5528 }
5529 }
5530 }
5531
5532 deferredLintHandler.flush(env.tree, env.info.lint);
5533 env.info.returnResult = null;
5534 // java.lang.Enum may not be subclassed by a non-enum
5535 if (st.tsym == syms.enumSym &&
5536 ((c.flags_field & (Flags.ENUM|Flags.COMPOUND)) == 0))
5537 log.error(env.tree.pos(), Errors.EnumNoSubclassing);
5538
5539 // Enums may not be extended by source-level classes
5540 if (st.tsym != null &&
5541 ((st.tsym.flags_field & Flags.ENUM) != 0) &&
5542 ((c.flags_field & (Flags.ENUM | Flags.COMPOUND)) == 0)) {
5543 log.error(env.tree.pos(), Errors.EnumTypesNotExtensible);
5544 }
5545
5546 if (rs.isSerializable(c.type)) {
5547 env.info.isSerializable = true;
5548 }
5549
5550 attribClassBody(env, c);
5551
5552 chk.checkDeprecatedAnnotation(env.tree.pos(), c);
5553 chk.checkClassOverrideEqualsAndHashIfNeeded(env.tree.pos(), c);
5554 chk.checkFunctionalInterface((JCClassDecl) env.tree, c);
5555 chk.checkLeaksNotAccessible(env, (JCClassDecl) env.tree);
5556
5557 if (c.isImplicit()) {
5558 chk.checkHasMain(env.tree.pos(), c);
5559 }
5560 } finally {
5561 env.info.returnResult = prevReturnRes;
5562 log.useSource(prev);
5563 chk.setLint(prevLint);
5564 }
5565
5566 }
5567 }
5568
5569 public void visitImport(JCImport tree) {
5674 sym.kind != VAR ||
5675 sym.getConstValue() == null)
5676 log.error(l.head.pos(), Errors.IclsCantHaveStaticDecl(c));
5677 }
5678 }
5679
5680 // Check for proper placement of super()/this() calls.
5681 chk.checkSuperInitCalls(tree);
5682
5683 // Check for cycles among non-initial constructors.
5684 chk.checkCyclicConstructors(tree);
5685
5686 // Check for cycles among annotation elements.
5687 chk.checkNonCyclicElements(tree);
5688
5689 // Check for proper use of serialVersionUID and other
5690 // serialization-related fields and methods
5691 if (env.info.lint.isEnabled(LintCategory.SERIAL)
5692 && rs.isSerializable(c.type)
5693 && !c.isAnonymous()) {
5694 chk.checkSerialStructure(tree, c);
5695 }
5696 // Correctly organize the positions of the type annotations
5697 typeAnnotations.organizeTypeAnnotationsBodies(tree);
5698
5699 // Check type annotations applicability rules
5700 validateTypeAnnotations(tree, false);
5701 }
5702 // where
5703 /** get a diagnostic position for an attribute of Type t, or null if attribute missing */
5704 private DiagnosticPosition getDiagnosticPosition(JCClassDecl tree, Type t) {
5705 for(List<JCAnnotation> al = tree.mods.annotations; !al.isEmpty(); al = al.tail) {
5706 if (types.isSameType(al.head.annotationType.type, t))
5707 return al.head.pos();
5708 }
5709
5710 return null;
5711 }
5712
5713 private Type capture(Type type) {
5714 return types.capture(type);
|
107 final DeferredAttr deferredAttr;
108 final Check chk;
109 final Flow flow;
110 final MemberEnter memberEnter;
111 final TypeEnter typeEnter;
112 final TreeMaker make;
113 final ConstFold cfolder;
114 final Enter enter;
115 final Target target;
116 final Types types;
117 final Preview preview;
118 final JCDiagnostic.Factory diags;
119 final TypeAnnotations typeAnnotations;
120 final DeferredLintHandler deferredLintHandler;
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
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 syms = Symtab.instance(context);
143 rs = Resolve.instance(context);
144 operators = Operators.instance(context);
145 chk = Check.instance(context);
146 flow = Flow.instance(context);
147 memberEnter = MemberEnter.instance(context);
148 typeEnter = TypeEnter.instance(context);
149 make = TreeMaker.instance(context);
150 enter = Enter.instance(context);
151 infer = Infer.instance(context);
152 analyzer = Analyzer.instance(context);
153 deferredAttr = DeferredAttr.instance(context);
154 cfolder = ConstFold.instance(context);
155 target = Target.instance(context);
156 types = Types.instance(context);
157 preview = Preview.instance(context);
158 diags = JCDiagnostic.Factory.instance(context);
159 annotate = Annotate.instance(context);
160 typeAnnotations = TypeAnnotations.instance(context);
161 deferredLintHandler = DeferredLintHandler.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 localProxyVarsGen = LocalProxyVarsGen.instance(context);
168
169 Options options = Options.instance(context);
170
171 Source source = Source.instance(context);
172 allowReifiableTypesInInstanceof = Feature.REIFIABLE_TYPES_INSTANCEOF.allowedInSource(source);
173 allowRecords = Feature.RECORDS.allowedInSource(source);
174 allowPatternSwitch = (preview.isEnabled() || !preview.isPreview(Feature.PATTERN_SWITCH)) &&
175 Feature.PATTERN_SWITCH.allowedInSource(source);
176 allowUnconditionalPatternsInstanceOf =
177 Feature.UNCONDITIONAL_PATTERN_IN_INSTANCEOF.allowedInSource(source);
178 sourceName = source.name;
179 useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning");
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 allowValueClasses = (!preview.isPreview(Feature.VALUE_CLASSES) || preview.isEnabled()) &&
190 Feature.VALUE_CLASSES.allowedInSource(source);
191 }
192
193 /** Switch: reifiable types in instanceof enabled?
194 */
195 boolean allowReifiableTypesInInstanceof;
196
197 /** Are records allowed
198 */
199 private final boolean allowRecords;
200
201 /** Are patterns in switch allowed
202 */
203 private final boolean allowPatternSwitch;
204
205 /** Are unconditional patterns in instanceof allowed
206 */
207 private final boolean allowUnconditionalPatternsInstanceOf;
208
209 /** Are value classes allowed
210 */
211 private final boolean allowValueClasses;
212
213 /**
214 * Switch: warn about use of variable before declaration?
215 * RFE: 6425594
216 */
217 boolean useBeforeDeclarationWarning;
218
219 /**
220 * Switch: name of source level; used for error reporting.
221 */
222 String sourceName;
223
224 /** Check kind and type of given tree against protokind and prototype.
225 * If check succeeds, store type in tree and return it.
226 * If check fails, store errType in tree and return it.
227 * No checks are performed if the prototype is a method type.
228 * It is not necessary in this case since we know that kind and type
229 * are correct.
230 *
231 * @param tree The tree whose kind and type is checked
232 * @param found The computed type of the tree
286 owner.kind == VAR || // i.e. we are in a variable initializer
287 (owner.flags() & BLOCK) != 0) // i.e. we are in an initializer block
288 &&
289 v.owner == owner.owner
290 &&
291 ((v.flags() & STATIC) != 0) == Resolve.isStatic(env));
292 boolean insideCompactConstructor = env.enclMethod != null && TreeInfo.isCompactConstructor(env.enclMethod);
293 return isAssignable & !insideCompactConstructor;
294 }
295
296 /** Check that variable can be assigned to.
297 * @param pos The current source code position.
298 * @param v The assigned variable
299 * @param base If the variable is referred to in a Select, the part
300 * to the left of the `.', null otherwise.
301 * @param env The current environment.
302 */
303 void checkAssignable(DiagnosticPosition pos, VarSymbol v, JCTree base, Env<AttrContext> env) {
304 if (v.name == names._this) {
305 log.error(pos, Errors.CantAssignValToThis);
306 } else if ((v.flags() & FINAL) != 0 &&
307 ((v.flags() & HASINIT) != 0
308 ||
309 !((base == null ||
310 TreeInfo.isThisQualifier(base)) &&
311 isAssignableAsBlankFinal(v, env)))) {
312 if (v.isResourceVariable()) { //TWR resource
313 log.error(pos, Errors.TryResourceMayNotBeAssigned(v));
314 } else {
315 log.error(pos, Errors.CantAssignValToVar(Flags.toSource(v.flags() & (STATIC | FINAL)), v));
316 }
317 }
318 }
319
320 /** Does tree represent a static reference to an identifier?
321 * It is assumed that tree is either a SELECT or an IDENT.
322 * We have to weed out selects from non-type names here.
323 * @param tree The candidate tree.
324 */
325 boolean isStaticReference(JCTree tree) {
326 if (tree.hasTag(SELECT)) {
327 Symbol lsym = TreeInfo.symbol(((JCFieldAccess) tree).selected);
328 if (lsym == null || lsym.kind != TYP) {
329 return false;
330 }
331 }
332 return true;
333 }
334
335 /** Is this symbol a type?
336 */
1094 * - have an accessibility stricter than that of the record type
1095 * - explicitly invoke any other constructor
1096 */
1097 if ((tree.sym.flags_field & GENERATEDCONSTR) == 0) {
1098 if (Check.protection(m.flags()) > Check.protection(env.enclClass.sym.flags())) {
1099 log.error(tree,
1100 (env.enclClass.sym.flags() & AccessFlags) == 0 ?
1101 Errors.InvalidCanonicalConstructorInRecord(
1102 Fragments.Canonical,
1103 env.enclClass.sym.name,
1104 Fragments.CanonicalMustNotHaveStrongerAccess("package")
1105 ) :
1106 Errors.InvalidCanonicalConstructorInRecord(
1107 Fragments.Canonical,
1108 env.enclClass.sym.name,
1109 Fragments.CanonicalMustNotHaveStrongerAccess(asFlagSet(env.enclClass.sym.flags() & AccessFlags))
1110 )
1111 );
1112 }
1113
1114 if (!allowValueClasses && 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) ||
1176 }
1177 if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0)
1178 log.error(tree.pos(), Errors.MissingMethBodyOrDeclAbstract);
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 if (isConstructor && owner.type != syms.objectType) {
1193 if (!TreeInfo.hasAnyConstructorCall(tree)) {
1194 JCStatement supCall = make.at(tree.body.pos).Exec(make.Apply(List.nil(),
1195 make.Ident(names._super), make.Idents(List.nil())));
1196 if (allowValueClasses && (owner.isValueClass() || owner.hasStrict() || ((owner.flags_field & RECORD) != 0))) {
1197 tree.body.stats = tree.body.stats.append(supCall);
1198 } else {
1199 tree.body.stats = tree.body.stats.prepend(supCall);
1200 }
1201 } else if ((env.enclClass.sym.flags() & ENUM) != 0 &&
1202 (tree.mods.flags & GENERATEDCONSTR) == 0 &&
1203 TreeInfo.hasConstructorCall(tree, names._super)) {
1204 // enum constructors are not allowed to call super
1205 // directly, so make sure there aren't any super calls
1206 // in enum constructors, except in the compiler
1207 // generated one.
1208 log.error(tree.body.stats.head.pos(),
1209 Errors.CallToSuperNotAllowedInEnumCtor(env.enclClass.sym));
1210 }
1211 if (env.enclClass.sym.isRecord() && (tree.sym.flags_field & RECORD) != 0) { // we are seeing the canonical constructor
1212 List<Name> recordComponentNames = TreeInfo.recordFields(env.enclClass).map(vd -> vd.sym.name);
1213 List<Name> initParamNames = tree.sym.params.map(p -> p.name);
1214 if (!initParamNames.equals(recordComponentNames)) {
1215 log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1216 Fragments.Canonical, env.enclClass.sym.name, Fragments.CanonicalWithNameMismatch));
1217 }
1218 if (tree.sym.type.asMethodType().thrown != null && !tree.sym.type.asMethodType().thrown.isEmpty()) {
1219 log.error(tree,
1220 Errors.InvalidCanonicalConstructorInRecord(
1221 TreeInfo.isCompactConstructor(tree) ? Fragments.Compact : Fragments.Canonical,
1222 env.enclClass.sym.name,
1223 Fragments.ThrowsClauseNotAllowedForCanonicalConstructor(
1224 TreeInfo.isCompactConstructor(tree) ? Fragments.Compact : Fragments.Canonical)));
1225 }
1226 }
1227 }
1228
1229 // Attribute all type annotations in the body
1230 annotate.queueScanTreeAndTypeAnnotate(tree.body, localEnv, m, null);
1231 annotate.flush();
1232
1233 // Start of constructor prologue
1234 localEnv.info.ctorPrologue = isConstructor;
1235
1236 // Attribute method body.
1237 attribStat(tree.body, localEnv);
1238 if (isConstructor) {
1239 ListBuffer<JCTree> prologueCode = new ListBuffer<>();
1240 for (JCTree stat : tree.body.stats) {
1241 prologueCode.add(stat);
1242 /* gather all the stats in the body until a `super` or `this` constructor invocation is found,
1243 * including the constructor invocation, that way we don't need to worry in the visitor below if
1244 * if we are dealing or not with prologue code
1245 */
1246 if (stat instanceof JCExpressionStatement expStmt &&
1247 expStmt.expr instanceof JCMethodInvocation mi &&
1248 TreeInfo.isConstructorCall(mi)) {
1249 break;
1250 }
1251 }
1252 if (!prologueCode.isEmpty()) {
1253 CtorPrologueVisitor ctorPrologueVisitor = new CtorPrologueVisitor(localEnv);
1254 ctorPrologueVisitor.scan(prologueCode.toList());
1255 }
1256 }
1257 }
1258
1259 localEnv.info.scope.leave();
1260 result = tree.type = m.type;
1261 } finally {
1262 chk.setLint(prevLint);
1263 chk.setMethod(prevMethod);
1264 env.info.ctorPrologue = ctorProloguePrev;
1265 }
1266 }
1267
1268 class CtorPrologueVisitor extends TreeScanner {
1269 Env<AttrContext> localEnv;
1270 CtorPrologueVisitor(Env<AttrContext> localEnv) {
1271 this.localEnv = localEnv;
1272 currentClassSym = localEnv.enclClass.sym;
1273 }
1274
1275 boolean insideLambdaOrClassDef = false;
1276
1277 @Override
1278 public void visitLambda(JCLambda lambda) {
1279 boolean previousInsideLambdaOrClassDef = insideLambdaOrClassDef;
1280 try {
1281 insideLambdaOrClassDef = true;
1282 super.visitLambda(lambda);
1283 } finally {
1284 insideLambdaOrClassDef = previousInsideLambdaOrClassDef;
1285 }
1286 }
1287
1288 ClassSymbol currentClassSym;
1289
1290 @Override
1291 public void visitClassDef(JCClassDecl classDecl) {
1292 boolean previousInsideLambdaOrClassDef = insideLambdaOrClassDef;
1293 ClassSymbol previousClassSym = currentClassSym;
1294 try {
1295 insideLambdaOrClassDef = true;
1296 currentClassSym = classDecl.sym;
1297 super.visitClassDef(classDecl);
1298 } finally {
1299 insideLambdaOrClassDef = previousInsideLambdaOrClassDef;
1300 currentClassSym = previousClassSym;
1301 }
1302 }
1303
1304 private void reportPrologueError(JCTree tree, Symbol sym) {
1305 preview.checkSourceLevel(tree, Feature.FLEXIBLE_CONSTRUCTORS);
1306 log.error(tree, Errors.CantRefBeforeCtorCalled(sym));
1307 }
1308
1309 @Override
1310 public void visitApply(JCMethodInvocation tree) {
1311 super.visitApply(tree);
1312 Name name = TreeInfo.name(tree.meth);
1313 boolean isConstructorCall = name == names._this || name == names._super;
1314 Symbol msym = TreeInfo.symbolFor(tree.meth);
1315 // is this an instance method call or an illegal constructor invocation like: `this.super()`?
1316 if (msym != null && // for erroneous invocations msym can be null, ignore those
1317 (!isConstructorCall ||
1318 isConstructorCall && tree.meth.hasTag(SELECT))) {
1319 if (isEarlyReference(localEnv, tree.meth, msym))
1320 reportPrologueError(tree.meth, msym);
1321 }
1322 }
1323
1324 @Override
1325 public void visitIdent(JCIdent tree) {
1326 analyzeSymbol(tree);
1327 }
1328
1329 @Override
1330 public void visitSelect(JCFieldAccess tree) {
1331 SelectScanner ss = new SelectScanner();
1332 ss.scan(tree);
1333 if (ss.scanLater == null) {
1334 analyzeSymbol(tree);
1335 } else {
1336 boolean prevLhs = isInLHS;
1337 try {
1338 isInLHS = false;
1339 scan(ss.scanLater);
1340 } finally {
1341 isInLHS = prevLhs;
1342 }
1343 }
1344 }
1345
1346 @Override
1347 public void visitNewClass(JCNewClass tree) {
1348 super.visitNewClass(tree);
1349 checkNewClassAndMethRefs(tree, tree.type);
1350 }
1351
1352 @Override
1353 public void visitReference(JCMemberReference tree) {
1354 super.visitReference(tree);
1355 if (tree.getMode() == JCMemberReference.ReferenceMode.NEW) {
1356 checkNewClassAndMethRefs(tree, tree.expr.type);
1357 }
1358 }
1359
1360 void checkNewClassAndMethRefs(JCTree tree, Type t) {
1361 if (t.tsym.isEnclosedBy(localEnv.enclClass.sym) &&
1362 !t.tsym.isStatic() &&
1363 !t.tsym.isDirectlyOrIndirectlyLocal()) {
1364 reportPrologueError(tree, t.getEnclosingType().tsym);
1365 }
1366 }
1367
1368 /* if a symbol is in the LHS of an assignment expression we won't consider it as a candidate
1369 * for a proxy local variable later on
1370 */
1371 boolean isInLHS = false;
1372
1373 @Override
1374 public void visitAssign(JCAssign tree) {
1375 boolean previousIsInLHS = isInLHS;
1376 try {
1377 isInLHS = true;
1378 scan(tree.lhs);
1379 } finally {
1380 isInLHS = previousIsInLHS;
1381 }
1382 scan(tree.rhs);
1383 }
1384
1385 @Override
1386 public void visitMethodDef(JCMethodDecl tree) {
1387 // ignore any declarative part, mainly to avoid scanning receiver parameters
1388 scan(tree.body);
1389 }
1390
1391 void analyzeSymbol(JCTree tree) {
1392 Symbol sym = TreeInfo.symbolFor(tree);
1393 // make sure that there is a symbol and it is not static
1394 if (sym == null || sym.isStatic()) {
1395 return;
1396 }
1397 if (isInLHS && !insideLambdaOrClassDef) {
1398 // Check instance field assignments that appear in constructor prologues
1399 if (isEarlyReference(localEnv, tree, sym)) {
1400 // Field may not be inherited from a superclass
1401 if (sym.owner != localEnv.enclClass.sym) {
1402 log.error(tree, Errors.CantRefBeforeCtorCalled(sym));
1403 return;
1404 }
1405 // Field may not have an initializer
1406 if ((sym.flags() & HASINIT) != 0) {
1407 log.error(tree, Errors.CantAssignInitializedBeforeCtorCalled(sym));
1408 return;
1409 }
1410 }
1411 return;
1412 }
1413 tree = TreeInfo.skipParens(tree);
1414 if (sym.kind == VAR && sym.owner.kind == TYP) {
1415 if (sym.name == names._this || sym.name == names._super) {
1416 // are we seeing something like `this` or `CurrentClass.this` or `SuperClass.super::foo`?
1417 if (TreeInfo.isExplicitThisReference(
1418 types,
1419 (ClassType)localEnv.enclClass.sym.type,
1420 tree)) {
1421 reportPrologueError(tree, sym);
1422 }
1423 } else if (sym.kind == VAR && sym.owner.kind == TYP) { // now fields only
1424 if (sym.owner != localEnv.enclClass.sym) {
1425 if (localEnv.enclClass.sym.isSubClass(sym.owner, types) &&
1426 sym.isInheritedIn(localEnv.enclClass.sym, types)) {
1427 /* if we are dealing with a field that doesn't belong to the current class, but the
1428 * field is inherited, this is an error. Unless, the super class is also an outer
1429 * class and the field's qualifier refers to the outer class
1430 */
1431 if (tree.hasTag(IDENT) ||
1432 TreeInfo.isExplicitThisReference(
1433 types,
1434 (ClassType)localEnv.enclClass.sym.type,
1435 ((JCFieldAccess)tree).selected)) {
1436 reportPrologueError(tree, sym);
1437 }
1438 }
1439 } else if (isEarlyReference(localEnv, tree, sym)) {
1440 /* now this is a `proper` instance field of the current class
1441 * references to fields of identity classes which happen to have initializers are
1442 * not allowed in the prologue
1443 */
1444 if (insideLambdaOrClassDef ||
1445 (!localEnv.enclClass.sym.isValueClass() && (sym.flags_field & HASINIT) != 0))
1446 reportPrologueError(tree, sym);
1447 // we will need to generate a proxy for this field later on
1448 if (!isInLHS) {
1449 if (allowValueClasses) {
1450 localProxyVarsGen.addFieldReadInPrologue(localEnv.enclMethod, sym);
1451 } else {
1452 reportPrologueError(tree, sym);
1453 }
1454 }
1455 }
1456 }
1457 }
1458 }
1459
1460 /**
1461 * Determine if the symbol appearance constitutes an early reference to the current class.
1462 *
1463 * <p>
1464 * This means the symbol is an instance field, or method, of the current class and it appears
1465 * in an early initialization context of it (i.e., one of its constructor prologues).
1466 *
1467 * @param env The current environment
1468 * @param tree the AST referencing the variable
1469 * @param sym The symbol
1470 */
1471 private boolean isEarlyReference(Env<AttrContext> env, JCTree tree, Symbol sym) {
1472 if ((sym.flags() & STATIC) == 0 &&
1473 (sym.kind == VAR || sym.kind == MTH) &&
1474 sym.isMemberOf(env.enclClass.sym, types)) {
1475 // Allow "Foo.this.x" when "Foo" is (also) an outer class, as this refers to the outer instance
1476 if (tree instanceof JCFieldAccess fa) {
1477 return TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, fa.selected);
1478 } else if (currentClassSym != env.enclClass.sym) {
1479 /* so we are inside a class, CI, in the prologue of an outer class, CO, and the symbol being
1480 * analyzed has no qualifier. So if the symbol is a member of CI the reference is allowed,
1481 * otherwise it is not.
1482 * It could be that the reference to CI's member happens inside CI's own prologue, but that
1483 * will be checked separately, when CI's prologue is analyzed.
1484 */
1485 return !sym.isMemberOf(currentClassSym, types);
1486 }
1487 return true;
1488 }
1489 return false;
1490 }
1491
1492 /* scanner for a select expression, anything that is not a select or identifier
1493 * will be stored for further analysis
1494 */
1495 class SelectScanner extends DeferredAttr.FilterScanner {
1496 JCTree scanLater;
1497
1498 SelectScanner() {
1499 super(Set.of(IDENT, SELECT, PARENS));
1500 }
1501
1502 @Override
1503 void skip(JCTree tree) {
1504 scanLater = tree;
1505 }
1506 }
1507 }
1508
1509 public void visitVarDef(JCVariableDecl tree) {
1510 // Local variables have not been entered yet, so we need to do it now:
1511 if (env.info.scope.owner.kind == MTH || env.info.scope.owner.kind == VAR) {
1512 if (tree.sym != null) {
1513 // parameters have already been entered
1514 env.info.scope.enter(tree.sym);
1515 } else {
1516 if (tree.isImplicitlyTyped() && (tree.getModifiers().flags & PARAMETER) == 0) {
1517 if (tree.init == null) {
1518 //cannot use 'var' without initializer
1519 log.error(tree, Errors.CantInferLocalVarType(tree.name, Fragments.LocalMissingInit));
1520 tree.vartype = make.Erroneous();
1521 } else {
1522 Fragment msg = canInferLocalVarType(tree);
1523 if (msg != null) {
1524 //cannot use 'var' with initializer which require an explicit target
1525 //(e.g. lambda, method reference, array initializer).
1526 log.error(tree, Errors.CantInferLocalVarType(tree.name, msg));
1527 tree.vartype = make.Erroneous();
1528 }
1550 chk.validate(tree.vartype, env, !isImplicitLambdaParameter && !tree.isImplicitlyTyped());
1551
1552 try {
1553 v.getConstValue(); // ensure compile-time constant initializer is evaluated
1554 deferredLintHandler.flush(tree, lint);
1555 chk.checkDeprecatedAnnotation(tree.pos(), v);
1556
1557 if (tree.init != null) {
1558 if ((v.flags_field & FINAL) == 0 ||
1559 !memberEnter.needsLazyConstValue(tree.init)) {
1560 // Not a compile-time constant
1561 // Attribute initializer in a new environment
1562 // with the declared variable as owner.
1563 // Check that initializer conforms to variable's declared type.
1564 Env<AttrContext> initEnv = memberEnter.initEnv(tree, env);
1565 initEnv.info.lint = lint;
1566 // In order to catch self-references, we set the variable's
1567 // declaration position to maximal possible value, effectively
1568 // marking the variable as undefined.
1569 initEnv.info.enclVar = v;
1570 boolean previousCtorPrologue = initEnv.info.ctorPrologue;
1571 try {
1572 if (v.owner.kind == TYP && !v.isStatic() && v.isStrict()) {
1573 // strict instance initializer in a value class
1574 initEnv.info.ctorPrologue = true;
1575 }
1576 attribExpr(tree.init, initEnv, v.type);
1577 if (tree.isImplicitlyTyped()) {
1578 //fixup local variable type
1579 v.type = chk.checkLocalVarType(tree, tree.init.type, tree.name);
1580 }
1581 if (v.owner.kind == TYP && !v.isStatic() && v.isStrict()) {
1582 // strict field initializers are inlined in constructor's prologues
1583 CtorPrologueVisitor ctorPrologueVisitor = new CtorPrologueVisitor(initEnv);
1584 ctorPrologueVisitor.scan(tree.init);
1585 }
1586 } finally {
1587 initEnv.info.ctorPrologue = previousCtorPrologue;
1588 }
1589 }
1590 if (tree.isImplicitlyTyped()) {
1591 setSyntheticVariableType(tree, v.type);
1592 }
1593 }
1594 result = tree.type = v.type;
1595 if (env.enclClass.sym.isRecord() && tree.sym.owner.kind == TYP && !v.isStatic()) {
1596 if (isNonArgsMethodInObject(v.name)) {
1597 log.error(tree, Errors.IllegalRecordComponentName(v));
1598 }
1599 }
1600 chk.checkRequiresIdentity(tree, env.info.lint);
1601 }
1602 finally {
1603 chk.setLint(prevLint);
1604 }
1605 }
1606
1607 private void doQueueScanTreeAndTypeAnnotateForVarInit(JCVariableDecl tree, Env<AttrContext> env) {
1688 }
1689 }
1690 }
1691
1692 public void visitSkip(JCSkip tree) {
1693 result = null;
1694 }
1695
1696 public void visitBlock(JCBlock tree) {
1697 if (env.info.scope.owner.kind == TYP || env.info.scope.owner.kind == ERR) {
1698 // Block is a static or instance initializer;
1699 // let the owner of the environment be a freshly
1700 // created BLOCK-method.
1701 Symbol fakeOwner =
1702 new MethodSymbol(tree.flags | BLOCK |
1703 env.info.scope.owner.flags() & STRICTFP, names.empty, initBlockType,
1704 env.info.scope.owner);
1705 final Env<AttrContext> localEnv =
1706 env.dup(tree, env.info.dup(env.info.scope.dupUnshared(fakeOwner)));
1707
1708 if ((tree.flags & STATIC) != 0) {
1709 localEnv.info.staticLevel++;
1710 } else {
1711 localEnv.info.instanceInitializerBlock = true;
1712 }
1713 // Attribute all type annotations in the block
1714 annotate.queueScanTreeAndTypeAnnotate(tree, localEnv, localEnv.info.scope.owner, null);
1715 annotate.flush();
1716 attribStats(tree.stats, localEnv);
1717
1718 {
1719 // Store init and clinit type annotations with the ClassSymbol
1720 // to allow output in Gen.normalizeDefs.
1721 ClassSymbol cs = (ClassSymbol)env.info.scope.owner;
1722 List<Attribute.TypeCompound> tas = localEnv.info.scope.owner.getRawTypeAttributes();
1723 if ((tree.flags & STATIC) != 0) {
1724 cs.appendClassInitTypeAttributes(tas);
1725 } else {
1726 cs.appendInitTypeAttributes(tas);
1727 }
1728 }
1729 } else {
1730 // Create a new local environment with a local scope.
1731 Env<AttrContext> localEnv =
1732 env.dup(tree, env.info.dup(env.info.scope.dup()));
2205 // where
2206 /** Return the selected enumeration constant symbol, or null. */
2207 private Symbol enumConstant(JCTree tree, Type enumType) {
2208 if (tree.hasTag(IDENT)) {
2209 JCIdent ident = (JCIdent)tree;
2210 Name name = ident.name;
2211 for (Symbol sym : enumType.tsym.members().getSymbolsByName(name)) {
2212 if (sym.kind == VAR) {
2213 Symbol s = ident.sym = sym;
2214 ((VarSymbol)s).getConstValue(); // ensure initializer is evaluated
2215 ident.type = s.type;
2216 return ((s.flags_field & Flags.ENUM) == 0)
2217 ? null : s;
2218 }
2219 }
2220 }
2221 return null;
2222 }
2223
2224 public void visitSynchronized(JCSynchronized tree) {
2225 boolean identityType = chk.checkIdentityType(tree.pos(), attribExpr(tree.lock, env));
2226 if (identityType && tree.lock.type != null && tree.lock.type.isValueBased()) {
2227 env.info.lint.logIfEnabled(tree.pos(), LintWarnings.AttemptToSynchronizeOnInstanceOfValueBasedClass);
2228 }
2229 attribStat(tree.body, env);
2230 result = null;
2231 }
2232
2233 public void visitTry(JCTry tree) {
2234 // Create a new local environment with a local
2235 Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
2236 try {
2237 boolean isTryWithResource = tree.resources.nonEmpty();
2238 // Create a nested environment for attributing the try block if needed
2239 Env<AttrContext> tryEnv = isTryWithResource ?
2240 env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) :
2241 localEnv;
2242 try {
2243 // Attribute resource declarations
2244 for (JCTree resource : tree.resources) {
2245 CheckContext twrContext = new Check.NestedCheckContext(resultInfo.checkContext) {
2246 @Override
4660 }
4661
4662 public void visitSelect(JCFieldAccess tree) {
4663 // Determine the expected kind of the qualifier expression.
4664 KindSelector skind = KindSelector.NIL;
4665 if (tree.name == names._this || tree.name == names._super ||
4666 tree.name == names._class)
4667 {
4668 skind = KindSelector.TYP;
4669 } else {
4670 if (pkind().contains(KindSelector.PCK))
4671 skind = KindSelector.of(skind, KindSelector.PCK);
4672 if (pkind().contains(KindSelector.TYP))
4673 skind = KindSelector.of(skind, KindSelector.TYP, KindSelector.PCK);
4674 if (pkind().contains(KindSelector.VAL_MTH))
4675 skind = KindSelector.of(skind, KindSelector.VAL, KindSelector.TYP);
4676 }
4677
4678 // Attribute the qualifier expression, and determine its symbol (if any).
4679 Type site = attribTree(tree.selected, env, new ResultInfo(skind, Type.noType));
4680 Assert.check(site == tree.selected.type);
4681 if (!pkind().contains(KindSelector.TYP_PCK))
4682 site = capture(site); // Capture field access
4683
4684 // don't allow T.class T[].class, etc
4685 if (skind == KindSelector.TYP) {
4686 Type elt = site;
4687 while (elt.hasTag(ARRAY))
4688 elt = ((ArrayType)elt).elemtype;
4689 if (elt.hasTag(TYPEVAR)) {
4690 log.error(tree.pos(), Errors.TypeVarCantBeDeref);
4691 result = tree.type = types.createErrorType(tree.name, site.tsym, site);
4692 tree.sym = tree.type.tsym;
4693 return ;
4694 }
4695 }
4696
4697 // If qualifier symbol is a type or `super', assert `selectSuper'
4698 // for the selection. This is relevant for determining whether
4699 // protected symbols are accessible.
4700 Symbol sitesym = TreeInfo.symbol(tree.selected);
5764 .filter(s -> s.tsym.isSealed())
5765 .map(s -> (ClassSymbol) s.tsym)
5766 .collect(List.collector());
5767
5768 if (sealedSupers.isEmpty()) {
5769 if ((c.flags_field & Flags.NON_SEALED) != 0) {
5770 boolean hasErrorSuper = false;
5771
5772 hasErrorSuper |= types.directSupertypes(c.type)
5773 .stream()
5774 .anyMatch(s -> s.tsym.kind == Kind.ERR);
5775
5776 ClassType ct = (ClassType) c.type;
5777
5778 hasErrorSuper |= !ct.isCompound() && ct.interfaces_field != ct.all_interfaces_field;
5779
5780 if (!hasErrorSuper) {
5781 log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.NonSealedWithNoSealedSupertype(c));
5782 }
5783 }
5784 } else if ((c.flags_field & Flags.COMPOUND) == 0) {
5785 if (c.isDirectlyOrIndirectlyLocal() && !c.isEnum()) {
5786 log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.LocalClassesCantExtendSealed(c.isAnonymous() ? Fragments.Anonymous : Fragments.Local));
5787 }
5788
5789 if (!c.type.isCompound()) {
5790 for (ClassSymbol supertypeSym : sealedSupers) {
5791 if (!supertypeSym.isPermittedSubclass(c.type.tsym)) {
5792 log.error(TreeInfo.diagnosticPositionFor(c.type.tsym, env.tree), Errors.CantInheritFromSealed(supertypeSym));
5793 }
5794 }
5795 if (!c.isNonSealed() && !c.isFinal() && !c.isSealed()) {
5796 log.error(TreeInfo.diagnosticPositionFor(c, env.tree),
5797 c.isInterface() ?
5798 Errors.NonSealedOrSealedExpected :
5799 Errors.NonSealedSealedOrFinalExpected);
5800 }
5801 }
5802 }
5803
5804 deferredLintHandler.flush(env.tree, env.info.lint);
5805 env.info.returnResult = null;
5806 // java.lang.Enum may not be subclassed by a non-enum
5807 if (st.tsym == syms.enumSym &&
5808 ((c.flags_field & (Flags.ENUM|Flags.COMPOUND)) == 0))
5809 log.error(env.tree.pos(), Errors.EnumNoSubclassing);
5810
5811 // Enums may not be extended by source-level classes
5812 if (st.tsym != null &&
5813 ((st.tsym.flags_field & Flags.ENUM) != 0) &&
5814 ((c.flags_field & (Flags.ENUM | Flags.COMPOUND)) == 0)) {
5815 log.error(env.tree.pos(), Errors.EnumTypesNotExtensible);
5816 }
5817
5818 if (rs.isSerializable(c.type)) {
5819 env.info.isSerializable = true;
5820 }
5821
5822 if (c.isValueClass()) {
5823 Assert.check(env.tree.hasTag(CLASSDEF));
5824 chk.checkConstraintsOfValueClass((JCClassDecl) env.tree, c);
5825 }
5826
5827 attribClassBody(env, c);
5828
5829 chk.checkDeprecatedAnnotation(env.tree.pos(), c);
5830 chk.checkClassOverrideEqualsAndHashIfNeeded(env.tree.pos(), c);
5831 chk.checkFunctionalInterface((JCClassDecl) env.tree, c);
5832 chk.checkLeaksNotAccessible(env, (JCClassDecl) env.tree);
5833
5834 if (c.isImplicit()) {
5835 chk.checkHasMain(env.tree.pos(), c);
5836 }
5837 } finally {
5838 env.info.returnResult = prevReturnRes;
5839 log.useSource(prev);
5840 chk.setLint(prevLint);
5841 }
5842
5843 }
5844 }
5845
5846 public void visitImport(JCImport tree) {
5951 sym.kind != VAR ||
5952 sym.getConstValue() == null)
5953 log.error(l.head.pos(), Errors.IclsCantHaveStaticDecl(c));
5954 }
5955 }
5956
5957 // Check for proper placement of super()/this() calls.
5958 chk.checkSuperInitCalls(tree);
5959
5960 // Check for cycles among non-initial constructors.
5961 chk.checkCyclicConstructors(tree);
5962
5963 // Check for cycles among annotation elements.
5964 chk.checkNonCyclicElements(tree);
5965
5966 // Check for proper use of serialVersionUID and other
5967 // serialization-related fields and methods
5968 if (env.info.lint.isEnabled(LintCategory.SERIAL)
5969 && rs.isSerializable(c.type)
5970 && !c.isAnonymous()) {
5971 chk.checkSerialStructure(env, tree, c);
5972 }
5973 // Correctly organize the positions of the type annotations
5974 typeAnnotations.organizeTypeAnnotationsBodies(tree);
5975
5976 // Check type annotations applicability rules
5977 validateTypeAnnotations(tree, false);
5978 }
5979 // where
5980 /** get a diagnostic position for an attribute of Type t, or null if attribute missing */
5981 private DiagnosticPosition getDiagnosticPosition(JCClassDecl tree, Type t) {
5982 for(List<JCAnnotation> al = tree.mods.annotations; !al.isEmpty(); al = al.tail) {
5983 if (types.isSameType(al.head.annotationType.type, t))
5984 return al.head.pos();
5985 }
5986
5987 return null;
5988 }
5989
5990 private Type capture(Type type) {
5991 return types.capture(type);
|