< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java

Print this page

 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) {
< prev index next >