288 * @param v The assigned variable
289 * @param base If the variable is referred to in a Select, the part
290 * to the left of the `.', null otherwise.
291 * @param env The current environment.
292 */
293 void checkAssignable(DiagnosticPosition pos, VarSymbol v, JCTree base, Env<AttrContext> env) {
294 if (v.name == names._this) {
295 log.error(pos, Errors.CantAssignValToThis);
296 } else if ((v.flags() & FINAL) != 0 &&
297 ((v.flags() & HASINIT) != 0
298 ||
299 !((base == null ||
300 TreeInfo.isThisQualifier(base)) &&
301 isAssignableAsBlankFinal(v, env)))) {
302 if (v.isResourceVariable()) { //TWR resource
303 log.error(pos, Errors.TryResourceMayNotBeAssigned(v));
304 } else {
305 log.error(pos, Errors.CantAssignValToVar(Flags.toSource(v.flags() & (STATIC | FINAL)), v));
306 }
307 }
308 }
309
310 /** Does tree represent a static reference to an identifier?
311 * It is assumed that tree is either a SELECT or an IDENT.
312 * We have to weed out selects from non-type names here.
313 * @param tree The candidate tree.
314 */
315 boolean isStaticReference(JCTree tree) {
316 if (tree.hasTag(SELECT)) {
317 Symbol lsym = TreeInfo.symbol(((JCFieldAccess) tree).selected);
318 if (lsym == null || lsym.kind != TYP) {
319 return false;
320 }
321 }
322 return true;
323 }
324
325 /** Is this symbol a type?
326 */
327 static boolean isType(Symbol sym) {
1172 }
1173 if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0)
1174 log.error(tree.pos(), Errors.MissingMethBodyOrDeclAbstract);
1175 } else {
1176 if ((tree.sym.flags() & (ABSTRACT|DEFAULT|PRIVATE)) == ABSTRACT) {
1177 if ((owner.flags() & INTERFACE) != 0) {
1178 log.error(tree.body.pos(), Errors.IntfMethCantHaveBody);
1179 } else {
1180 log.error(tree.pos(), Errors.AbstractMethCantHaveBody);
1181 }
1182 } else if ((tree.mods.flags & NATIVE) != 0) {
1183 log.error(tree.pos(), Errors.NativeMethCantHaveBody);
1184 }
1185 // Add an implicit super() call unless an explicit call to
1186 // super(...) or this(...) is given
1187 // or we are compiling class java.lang.Object.
1188 if (isConstructor && owner.type != syms.objectType) {
1189 if (!TreeInfo.hasAnyConstructorCall(tree)) {
1190 JCStatement supCall = make.at(tree.body.pos).Exec(make.Apply(List.nil(),
1191 make.Ident(names._super), make.Idents(List.nil())));
1192 tree.body.stats = tree.body.stats.prepend(supCall);
1193 } else if ((env.enclClass.sym.flags() & ENUM) != 0 &&
1194 (tree.mods.flags & GENERATEDCONSTR) == 0 &&
1195 TreeInfo.hasConstructorCall(tree, names._super)) {
1196 // enum constructors are not allowed to call super
1197 // directly, so make sure there aren't any super calls
1198 // in enum constructors, except in the compiler
1199 // generated one.
1200 log.error(tree.body.stats.head.pos(),
1201 Errors.CallToSuperNotAllowedInEnumCtor(env.enclClass.sym));
1202 }
1203 if (env.enclClass.sym.isRecord() && (tree.sym.flags_field & RECORD) != 0) { // we are seeing the canonical constructor
1204 List<Name> recordComponentNames = TreeInfo.recordFields(env.enclClass).map(vd -> vd.sym.name);
1205 List<Name> initParamNames = tree.sym.params.map(p -> p.name);
1206 if (!initParamNames.equals(recordComponentNames)) {
1207 log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
1208 Fragments.Canonical, env.enclClass.sym.name, Fragments.CanonicalWithNameMismatch));
1209 }
1210 if (tree.sym.type.asMethodType().thrown != null && !tree.sym.type.asMethodType().thrown.isEmpty()) {
1211 log.error(tree,
1212 Errors.InvalidCanonicalConstructorInRecord(
1314 }
1315 }
1316 result = tree.type = v.type;
1317 if (env.enclClass.sym.isRecord() && tree.sym.owner.kind == TYP && !v.isStatic()) {
1318 if (isNonArgsMethodInObject(v.name)) {
1319 log.error(tree, Errors.IllegalRecordComponentName(v));
1320 }
1321 }
1322 }
1323 finally {
1324 chk.setLint(prevLint);
1325 }
1326 }
1327
1328 private boolean isNonArgsMethodInObject(Name name) {
1329 for (Symbol s : syms.objectType.tsym.members().getSymbolsByName(name, s -> s.kind == MTH)) {
1330 if (s.type.getParameterTypes().isEmpty()) {
1331 return true;
1332 }
1333 }
1334 return false;
1335 }
1336
1337 Fragment canInferLocalVarType(JCVariableDecl tree) {
1338 LocalInitScanner lis = new LocalInitScanner();
1339 lis.scan(tree.init);
1340 return lis.badInferenceMsg;
1341 }
1342
1343 static class LocalInitScanner extends TreeScanner {
1344 Fragment badInferenceMsg = null;
1345 boolean needsTarget = true;
1346
1347 @Override
1348 public void visitNewArray(JCNewArray tree) {
1349 if (tree.elemtype == null && needsTarget) {
1350 badInferenceMsg = Fragments.LocalArrayMissingTarget;
1351 }
1352 }
1353
1354 @Override
1398 }
1399 }
1400 }
1401
1402 public void visitSkip(JCSkip tree) {
1403 result = null;
1404 }
1405
1406 public void visitBlock(JCBlock tree) {
1407 if (env.info.scope.owner.kind == TYP || env.info.scope.owner.kind == ERR) {
1408 // Block is a static or instance initializer;
1409 // let the owner of the environment be a freshly
1410 // created BLOCK-method.
1411 Symbol fakeOwner =
1412 new MethodSymbol(tree.flags | BLOCK |
1413 env.info.scope.owner.flags() & STRICTFP, names.empty, null,
1414 env.info.scope.owner);
1415 final Env<AttrContext> localEnv =
1416 env.dup(tree, env.info.dup(env.info.scope.dupUnshared(fakeOwner)));
1417
1418 if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
1419 // Attribute all type annotations in the block
1420 annotate.queueScanTreeAndTypeAnnotate(tree, localEnv, localEnv.info.scope.owner, null);
1421 annotate.flush();
1422 attribStats(tree.stats, localEnv);
1423
1424 {
1425 // Store init and clinit type annotations with the ClassSymbol
1426 // to allow output in Gen.normalizeDefs.
1427 ClassSymbol cs = (ClassSymbol)env.info.scope.owner;
1428 List<Attribute.TypeCompound> tas = localEnv.info.scope.owner.getRawTypeAttributes();
1429 if ((tree.flags & STATIC) != 0) {
1430 cs.appendClassInitTypeAttributes(tas);
1431 } else {
1432 cs.appendInitTypeAttributes(tas);
1433 }
1434 }
1435 } else {
1436 // Create a new local environment with a local scope.
1437 Env<AttrContext> localEnv =
1438 env.dup(tree, env.info.dup(env.info.scope.dup()));
1893 // where
1894 /** Return the selected enumeration constant symbol, or null. */
1895 private Symbol enumConstant(JCTree tree, Type enumType) {
1896 if (tree.hasTag(IDENT)) {
1897 JCIdent ident = (JCIdent)tree;
1898 Name name = ident.name;
1899 for (Symbol sym : enumType.tsym.members().getSymbolsByName(name)) {
1900 if (sym.kind == VAR) {
1901 Symbol s = ident.sym = sym;
1902 ((VarSymbol)s).getConstValue(); // ensure initializer is evaluated
1903 ident.type = s.type;
1904 return ((s.flags_field & Flags.ENUM) == 0)
1905 ? null : s;
1906 }
1907 }
1908 }
1909 return null;
1910 }
1911
1912 public void visitSynchronized(JCSynchronized tree) {
1913 chk.checkRefType(tree.pos(), attribExpr(tree.lock, env));
1914 if (env.info.lint.isEnabled(LintCategory.SYNCHRONIZATION) && isValueBased(tree.lock.type)) {
1915 log.warning(LintCategory.SYNCHRONIZATION, tree.pos(), Warnings.AttemptToSynchronizeOnInstanceOfValueBasedClass);
1916 }
1917 attribStat(tree.body, env);
1918 result = null;
1919 }
1920 // where
1921 private boolean isValueBased(Type t) {
1922 return t != null && t.tsym != null && (t.tsym.flags() & VALUE_BASED) != 0;
1923 }
1924
1925
1926 public void visitTry(JCTry tree) {
1927 // Create a new local environment with a local
1928 Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
1929 try {
1930 boolean isTryWithResource = tree.resources.nonEmpty();
1931 // Create a nested environment for attributing the try block if needed
1932 Env<AttrContext> tryEnv = isTryWithResource ?
1933 env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) :
4346 }
4347
4348 public void visitSelect(JCFieldAccess tree) {
4349 // Determine the expected kind of the qualifier expression.
4350 KindSelector skind = KindSelector.NIL;
4351 if (tree.name == names._this || tree.name == names._super ||
4352 tree.name == names._class)
4353 {
4354 skind = KindSelector.TYP;
4355 } else {
4356 if (pkind().contains(KindSelector.PCK))
4357 skind = KindSelector.of(skind, KindSelector.PCK);
4358 if (pkind().contains(KindSelector.TYP))
4359 skind = KindSelector.of(skind, KindSelector.TYP, KindSelector.PCK);
4360 if (pkind().contains(KindSelector.VAL_MTH))
4361 skind = KindSelector.of(skind, KindSelector.VAL, KindSelector.TYP);
4362 }
4363
4364 // Attribute the qualifier expression, and determine its symbol (if any).
4365 Type site = attribTree(tree.selected, env, new ResultInfo(skind, Type.noType));
4366 if (!pkind().contains(KindSelector.TYP_PCK))
4367 site = capture(site); // Capture field access
4368
4369 // don't allow T.class T[].class, etc
4370 if (skind == KindSelector.TYP) {
4371 Type elt = site;
4372 while (elt.hasTag(ARRAY))
4373 elt = ((ArrayType)elt).elemtype;
4374 if (elt.hasTag(TYPEVAR)) {
4375 log.error(tree.pos(), Errors.TypeVarCantBeDeref);
4376 result = tree.type = types.createErrorType(tree.name, site.tsym, site);
4377 tree.sym = tree.type.tsym;
4378 return ;
4379 }
4380 }
4381
4382 // If qualifier symbol is a type or `super', assert `selectSuper'
4383 // for the selection. This is relevant for determining whether
4384 // protected symbols are accessible.
4385 Symbol sitesym = TreeInfo.symbol(tree.selected);
5445 .filter(s -> s.tsym.isSealed())
5446 .map(s -> (ClassSymbol) s.tsym)
5447 .collect(List.collector());
5448
5449 if (sealedSupers.isEmpty()) {
5450 if ((c.flags_field & Flags.NON_SEALED) != 0) {
5451 boolean hasErrorSuper = false;
5452
5453 hasErrorSuper |= types.directSupertypes(c.type)
5454 .stream()
5455 .anyMatch(s -> s.tsym.kind == Kind.ERR);
5456
5457 ClassType ct = (ClassType) c.type;
5458
5459 hasErrorSuper |= !ct.isCompound() && ct.interfaces_field != ct.all_interfaces_field;
5460
5461 if (!hasErrorSuper) {
5462 log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.NonSealedWithNoSealedSupertype(c));
5463 }
5464 }
5465 } else {
5466 if (c.isDirectlyOrIndirectlyLocal() && !c.isEnum()) {
5467 log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.LocalClassesCantExtendSealed(c.isAnonymous() ? Fragments.Anonymous : Fragments.Local));
5468 }
5469
5470 if (!c.type.isCompound()) {
5471 for (ClassSymbol supertypeSym : sealedSupers) {
5472 if (!supertypeSym.permitted.contains(c.type.tsym)) {
5473 log.error(TreeInfo.diagnosticPositionFor(c.type.tsym, env.tree), Errors.CantInheritFromSealed(supertypeSym));
5474 }
5475 }
5476 if (!c.isNonSealed() && !c.isFinal() && !c.isSealed()) {
5477 log.error(TreeInfo.diagnosticPositionFor(c, env.tree),
5478 c.isInterface() ?
5479 Errors.NonSealedOrSealedExpected :
5480 Errors.NonSealedSealedOrFinalExpected);
5481 }
5482 }
5483 }
5484
5485 deferredLintHandler.flush(env.tree);
5486 env.info.returnResult = null;
5487 // java.lang.Enum may not be subclassed by a non-enum
5488 if (st.tsym == syms.enumSym &&
5489 ((c.flags_field & (Flags.ENUM|Flags.COMPOUND)) == 0))
5490 log.error(env.tree.pos(), Errors.EnumNoSubclassing);
5491
5492 // Enums may not be extended by source-level classes
5493 if (st.tsym != null &&
5494 ((st.tsym.flags_field & Flags.ENUM) != 0) &&
5495 ((c.flags_field & (Flags.ENUM | Flags.COMPOUND)) == 0)) {
5496 log.error(env.tree.pos(), Errors.EnumTypesNotExtensible);
5497 }
5498
5499 if (rs.isSerializable(c.type)) {
5500 env.info.isSerializable = true;
5501 }
5502
5503 attribClassBody(env, c);
5504
5505 chk.checkDeprecatedAnnotation(env.tree.pos(), c);
5506 chk.checkClassOverrideEqualsAndHashIfNeeded(env.tree.pos(), c);
5507 chk.checkFunctionalInterface((JCClassDecl) env.tree, c);
5508 chk.checkLeaksNotAccessible(env, (JCClassDecl) env.tree);
5509
5510 if (c.isImplicit()) {
5511 chk.checkHasMain(env.tree.pos(), c);
5512 }
5513 } finally {
5514 env.info.returnResult = prevReturnRes;
5515 log.useSource(prev);
5516 chk.setLint(prevLint);
5517 }
5518
5519 }
5520 }
5521
5522 public void visitImport(JCImport tree) {
|
288 * @param v The assigned variable
289 * @param base If the variable is referred to in a Select, the part
290 * to the left of the `.', null otherwise.
291 * @param env The current environment.
292 */
293 void checkAssignable(DiagnosticPosition pos, VarSymbol v, JCTree base, Env<AttrContext> env) {
294 if (v.name == names._this) {
295 log.error(pos, Errors.CantAssignValToThis);
296 } else if ((v.flags() & FINAL) != 0 &&
297 ((v.flags() & HASINIT) != 0
298 ||
299 !((base == null ||
300 TreeInfo.isThisQualifier(base)) &&
301 isAssignableAsBlankFinal(v, env)))) {
302 if (v.isResourceVariable()) { //TWR resource
303 log.error(pos, Errors.TryResourceMayNotBeAssigned(v));
304 } else {
305 log.error(pos, Errors.CantAssignValToVar(Flags.toSource(v.flags() & (STATIC | FINAL)), v));
306 }
307 }
308
309 if (!env.info.ctorPrologue &&
310 v.owner.isValueClass() &&
311 !env.info.instanceInitializerBlock && // it is OK instance initializer blocks will go after super() anyways
312 v.owner.kind == TYP &&
313 v.owner == env.enclClass.sym &&
314 (v.flags() & STATIC) == 0 &&
315 (base == null ||
316 TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, base))) {
317 log.error(pos, Errors.CantRefAfterCtorCalled(v));
318 }
319 }
320
321 /** Does tree represent a static reference to an identifier?
322 * It is assumed that tree is either a SELECT or an IDENT.
323 * We have to weed out selects from non-type names here.
324 * @param tree The candidate tree.
325 */
326 boolean isStaticReference(JCTree tree) {
327 if (tree.hasTag(SELECT)) {
328 Symbol lsym = TreeInfo.symbol(((JCFieldAccess) tree).selected);
329 if (lsym == null || lsym.kind != TYP) {
330 return false;
331 }
332 }
333 return true;
334 }
335
336 /** Is this symbol a type?
337 */
338 static boolean isType(Symbol sym) {
1183 }
1184 if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0)
1185 log.error(tree.pos(), Errors.MissingMethBodyOrDeclAbstract);
1186 } else {
1187 if ((tree.sym.flags() & (ABSTRACT|DEFAULT|PRIVATE)) == ABSTRACT) {
1188 if ((owner.flags() & INTERFACE) != 0) {
1189 log.error(tree.body.pos(), Errors.IntfMethCantHaveBody);
1190 } else {
1191 log.error(tree.pos(), Errors.AbstractMethCantHaveBody);
1192 }
1193 } else if ((tree.mods.flags & NATIVE) != 0) {
1194 log.error(tree.pos(), Errors.NativeMethCantHaveBody);
1195 }
1196 // Add an implicit super() call unless an explicit call to
1197 // super(...) or this(...) is given
1198 // or we are compiling class java.lang.Object.
1199 if (isConstructor && owner.type != syms.objectType) {
1200 if (!TreeInfo.hasAnyConstructorCall(tree)) {
1201 JCStatement supCall = make.at(tree.body.pos).Exec(make.Apply(List.nil(),
1202 make.Ident(names._super), make.Idents(List.nil())));
1203 if (owner.isValueClass()) {
1204 tree.body.stats = tree.body.stats.append(supCall);
1205 } else {
1206 tree.body.stats = tree.body.stats.prepend(supCall);
1207 }
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(
1329 }
1330 }
1331 result = tree.type = v.type;
1332 if (env.enclClass.sym.isRecord() && tree.sym.owner.kind == TYP && !v.isStatic()) {
1333 if (isNonArgsMethodInObject(v.name)) {
1334 log.error(tree, Errors.IllegalRecordComponentName(v));
1335 }
1336 }
1337 }
1338 finally {
1339 chk.setLint(prevLint);
1340 }
1341 }
1342
1343 private boolean isNonArgsMethodInObject(Name name) {
1344 for (Symbol s : syms.objectType.tsym.members().getSymbolsByName(name, s -> s.kind == MTH)) {
1345 if (s.type.getParameterTypes().isEmpty()) {
1346 return true;
1347 }
1348 }
1349 // isValueObject is not included in Object yet so we need a work around
1350 return name == names.isValueObject;
1351 }
1352
1353 Fragment canInferLocalVarType(JCVariableDecl tree) {
1354 LocalInitScanner lis = new LocalInitScanner();
1355 lis.scan(tree.init);
1356 return lis.badInferenceMsg;
1357 }
1358
1359 static class LocalInitScanner extends TreeScanner {
1360 Fragment badInferenceMsg = null;
1361 boolean needsTarget = true;
1362
1363 @Override
1364 public void visitNewArray(JCNewArray tree) {
1365 if (tree.elemtype == null && needsTarget) {
1366 badInferenceMsg = Fragments.LocalArrayMissingTarget;
1367 }
1368 }
1369
1370 @Override
1414 }
1415 }
1416 }
1417
1418 public void visitSkip(JCSkip tree) {
1419 result = null;
1420 }
1421
1422 public void visitBlock(JCBlock tree) {
1423 if (env.info.scope.owner.kind == TYP || env.info.scope.owner.kind == ERR) {
1424 // Block is a static or instance initializer;
1425 // let the owner of the environment be a freshly
1426 // created BLOCK-method.
1427 Symbol fakeOwner =
1428 new MethodSymbol(tree.flags | BLOCK |
1429 env.info.scope.owner.flags() & STRICTFP, names.empty, null,
1430 env.info.scope.owner);
1431 final Env<AttrContext> localEnv =
1432 env.dup(tree, env.info.dup(env.info.scope.dupUnshared(fakeOwner)));
1433
1434 if ((tree.flags & STATIC) != 0) {
1435 localEnv.info.staticLevel++;
1436 } else {
1437 localEnv.info.instanceInitializerBlock = true;
1438 }
1439 // Attribute all type annotations in the block
1440 annotate.queueScanTreeAndTypeAnnotate(tree, localEnv, localEnv.info.scope.owner, null);
1441 annotate.flush();
1442 attribStats(tree.stats, localEnv);
1443
1444 {
1445 // Store init and clinit type annotations with the ClassSymbol
1446 // to allow output in Gen.normalizeDefs.
1447 ClassSymbol cs = (ClassSymbol)env.info.scope.owner;
1448 List<Attribute.TypeCompound> tas = localEnv.info.scope.owner.getRawTypeAttributes();
1449 if ((tree.flags & STATIC) != 0) {
1450 cs.appendClassInitTypeAttributes(tas);
1451 } else {
1452 cs.appendInitTypeAttributes(tas);
1453 }
1454 }
1455 } else {
1456 // Create a new local environment with a local scope.
1457 Env<AttrContext> localEnv =
1458 env.dup(tree, env.info.dup(env.info.scope.dup()));
1913 // where
1914 /** Return the selected enumeration constant symbol, or null. */
1915 private Symbol enumConstant(JCTree tree, Type enumType) {
1916 if (tree.hasTag(IDENT)) {
1917 JCIdent ident = (JCIdent)tree;
1918 Name name = ident.name;
1919 for (Symbol sym : enumType.tsym.members().getSymbolsByName(name)) {
1920 if (sym.kind == VAR) {
1921 Symbol s = ident.sym = sym;
1922 ((VarSymbol)s).getConstValue(); // ensure initializer is evaluated
1923 ident.type = s.type;
1924 return ((s.flags_field & Flags.ENUM) == 0)
1925 ? null : s;
1926 }
1927 }
1928 }
1929 return null;
1930 }
1931
1932 public void visitSynchronized(JCSynchronized tree) {
1933 chk.checkIdentityType(tree.pos(), attribExpr(tree.lock, env));
1934 if (env.info.lint.isEnabled(LintCategory.SYNCHRONIZATION) && isValueBased(tree.lock.type)) {
1935 log.warning(LintCategory.SYNCHRONIZATION, tree.pos(), Warnings.AttemptToSynchronizeOnInstanceOfValueBasedClass);
1936 }
1937 attribStat(tree.body, env);
1938 result = null;
1939 }
1940 // where
1941 private boolean isValueBased(Type t) {
1942 return t != null && t.tsym != null && (t.tsym.flags() & VALUE_BASED) != 0;
1943 }
1944
1945
1946 public void visitTry(JCTry tree) {
1947 // Create a new local environment with a local
1948 Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
1949 try {
1950 boolean isTryWithResource = tree.resources.nonEmpty();
1951 // Create a nested environment for attributing the try block if needed
1952 Env<AttrContext> tryEnv = isTryWithResource ?
1953 env.dup(tree, localEnv.info.dup(localEnv.info.scope.dup())) :
4366 }
4367
4368 public void visitSelect(JCFieldAccess tree) {
4369 // Determine the expected kind of the qualifier expression.
4370 KindSelector skind = KindSelector.NIL;
4371 if (tree.name == names._this || tree.name == names._super ||
4372 tree.name == names._class)
4373 {
4374 skind = KindSelector.TYP;
4375 } else {
4376 if (pkind().contains(KindSelector.PCK))
4377 skind = KindSelector.of(skind, KindSelector.PCK);
4378 if (pkind().contains(KindSelector.TYP))
4379 skind = KindSelector.of(skind, KindSelector.TYP, KindSelector.PCK);
4380 if (pkind().contains(KindSelector.VAL_MTH))
4381 skind = KindSelector.of(skind, KindSelector.VAL, KindSelector.TYP);
4382 }
4383
4384 // Attribute the qualifier expression, and determine its symbol (if any).
4385 Type site = attribTree(tree.selected, env, new ResultInfo(skind, Type.noType));
4386 Assert.check(site == tree.selected.type);
4387 if (!pkind().contains(KindSelector.TYP_PCK))
4388 site = capture(site); // Capture field access
4389
4390 // don't allow T.class T[].class, etc
4391 if (skind == KindSelector.TYP) {
4392 Type elt = site;
4393 while (elt.hasTag(ARRAY))
4394 elt = ((ArrayType)elt).elemtype;
4395 if (elt.hasTag(TYPEVAR)) {
4396 log.error(tree.pos(), Errors.TypeVarCantBeDeref);
4397 result = tree.type = types.createErrorType(tree.name, site.tsym, site);
4398 tree.sym = tree.type.tsym;
4399 return ;
4400 }
4401 }
4402
4403 // If qualifier symbol is a type or `super', assert `selectSuper'
4404 // for the selection. This is relevant for determining whether
4405 // protected symbols are accessible.
4406 Symbol sitesym = TreeInfo.symbol(tree.selected);
5466 .filter(s -> s.tsym.isSealed())
5467 .map(s -> (ClassSymbol) s.tsym)
5468 .collect(List.collector());
5469
5470 if (sealedSupers.isEmpty()) {
5471 if ((c.flags_field & Flags.NON_SEALED) != 0) {
5472 boolean hasErrorSuper = false;
5473
5474 hasErrorSuper |= types.directSupertypes(c.type)
5475 .stream()
5476 .anyMatch(s -> s.tsym.kind == Kind.ERR);
5477
5478 ClassType ct = (ClassType) c.type;
5479
5480 hasErrorSuper |= !ct.isCompound() && ct.interfaces_field != ct.all_interfaces_field;
5481
5482 if (!hasErrorSuper) {
5483 log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.NonSealedWithNoSealedSupertype(c));
5484 }
5485 }
5486 } else if ((c.flags_field & Flags.COMPOUND) == 0) {
5487 if (c.isDirectlyOrIndirectlyLocal() && !c.isEnum()) {
5488 log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.LocalClassesCantExtendSealed(c.isAnonymous() ? Fragments.Anonymous : Fragments.Local));
5489 }
5490
5491 if (!c.type.isCompound()) {
5492 for (ClassSymbol supertypeSym : sealedSupers) {
5493 if (!supertypeSym.permitted.contains(c.type.tsym)) {
5494 log.error(TreeInfo.diagnosticPositionFor(c.type.tsym, env.tree), Errors.CantInheritFromSealed(supertypeSym));
5495 }
5496 }
5497 if (!c.isNonSealed() && !c.isFinal() && !c.isSealed()) {
5498 log.error(TreeInfo.diagnosticPositionFor(c, env.tree),
5499 c.isInterface() ?
5500 Errors.NonSealedOrSealedExpected :
5501 Errors.NonSealedSealedOrFinalExpected);
5502 }
5503 }
5504 }
5505
5506 deferredLintHandler.flush(env.tree);
5507 env.info.returnResult = null;
5508 // java.lang.Enum may not be subclassed by a non-enum
5509 if (st.tsym == syms.enumSym &&
5510 ((c.flags_field & (Flags.ENUM|Flags.COMPOUND)) == 0))
5511 log.error(env.tree.pos(), Errors.EnumNoSubclassing);
5512
5513 // Enums may not be extended by source-level classes
5514 if (st.tsym != null &&
5515 ((st.tsym.flags_field & Flags.ENUM) != 0) &&
5516 ((c.flags_field & (Flags.ENUM | Flags.COMPOUND)) == 0)) {
5517 log.error(env.tree.pos(), Errors.EnumTypesNotExtensible);
5518 }
5519
5520 if (rs.isSerializable(c.type)) {
5521 env.info.isSerializable = true;
5522 }
5523
5524 if (c.isValueClass()) {
5525 Assert.check(env.tree.hasTag(CLASSDEF));
5526 chk.checkConstraintsOfValueClass((JCClassDecl) env.tree, c);
5527 }
5528
5529 attribClassBody(env, c);
5530
5531 chk.checkDeprecatedAnnotation(env.tree.pos(), c);
5532 chk.checkClassOverrideEqualsAndHashIfNeeded(env.tree.pos(), c);
5533 chk.checkFunctionalInterface((JCClassDecl) env.tree, c);
5534 chk.checkLeaksNotAccessible(env, (JCClassDecl) env.tree);
5535
5536 if (c.isImplicit()) {
5537 chk.checkHasMain(env.tree.pos(), c);
5538 }
5539 } finally {
5540 env.info.returnResult = prevReturnRes;
5541 log.useSource(prev);
5542 chk.setLint(prevLint);
5543 }
5544
5545 }
5546 }
5547
5548 public void visitImport(JCImport tree) {
|