< prev index next >

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

Print this page

5389 
5390             // Next attribute owner, if it is a class.
5391             if (c.owner.kind == TYP && c.owner.type.hasTag(CLASS))
5392                 attribClass((ClassSymbol)c.owner);
5393 
5394             c.flags_field |= Flags.SUPER_OWNER_ATTRIBUTED;
5395         }
5396 
5397         // The previous operations might have attributed the current class
5398         // if there was a cycle. So we test first whether the class is still
5399         // UNATTRIBUTED.
5400         if ((c.flags_field & UNATTRIBUTED) != 0) {
5401             c.flags_field &= ~UNATTRIBUTED;
5402 
5403             // Get environment current at the point of class definition.
5404             Env<AttrContext> env = typeEnvs.get(c);
5405 
5406             if (c.isSealed() &&
5407                     !c.isEnum() &&
5408                     !c.isPermittedExplicit &&
5409                     c.permitted.isEmpty()) {
5410                 log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.SealedClassMustHaveSubclasses);
5411             }
5412 
5413             if (c.isSealed()) {
5414                 Set<Symbol> permittedTypes = new HashSet<>();
5415                 boolean sealedInUnnamed = c.packge().modle == syms.unnamedModule || c.packge().modle == syms.noModule;
5416                 for (Symbol subTypeSym : c.permitted) {
5417                     boolean isTypeVar = false;
5418                     if (subTypeSym.type.getTag() == TYPEVAR) {
5419                         isTypeVar = true; //error recovery
5420                         log.error(TreeInfo.diagnosticPositionFor(subTypeSym, env.tree),
5421                                 Errors.InvalidPermitsClause(Fragments.IsATypeVariable(subTypeSym.type)));
5422                     }
5423                     if (subTypeSym.isAnonymous() && !c.isEnum()) {
5424                         log.error(TreeInfo.diagnosticPositionFor(subTypeSym, env.tree),  Errors.LocalClassesCantExtendSealed(Fragments.Anonymous));
5425                     }
5426                     if (permittedTypes.contains(subTypeSym)) {
5427                         DiagnosticPosition pos =
5428                                 env.enclClass.permitting.stream()
5429                                         .filter(permittedExpr -> TreeInfo.diagnosticPositionFor(subTypeSym, permittedExpr, true) != null)
5430                                         .limit(2).collect(List.collector()).get(1);
5431                         log.error(pos, Errors.InvalidPermitsClause(Fragments.IsDuplicated(subTypeSym.type)));
5432                     } else {
5433                         permittedTypes.add(subTypeSym);
5434                     }
5435                     if (sealedInUnnamed) {
5436                         if (subTypeSym.packge() != c.packge()) {
5437                             log.error(TreeInfo.diagnosticPositionFor(subTypeSym, env.tree),
5438                                     Errors.ClassInUnnamedModuleCantExtendSealedInDiffPackage(c)
5439                             );
5440                         }
5441                     } else if (subTypeSym.packge().modle != c.packge().modle) {
5442                         log.error(TreeInfo.diagnosticPositionFor(subTypeSym, env.tree),
5443                                 Errors.ClassInModuleCantExtendSealedInDiffModule(c, c.packge().modle)
5444                         );
5445                     }
5446                     if (subTypeSym == c.type.tsym || types.isSuperType(subTypeSym.type, c.type)) {
5447                         log.error(TreeInfo.diagnosticPositionFor(subTypeSym, ((JCClassDecl)env.tree).permitting),
5448                                 Errors.InvalidPermitsClause(
5449                                         subTypeSym == c.type.tsym ?
5450                                                 Fragments.MustNotBeSameClass :
5451                                                 Fragments.MustNotBeSupertype(subTypeSym.type)
5452                                 )
5453                         );
5454                     } else if (!isTypeVar) {
5455                         boolean thisIsASuper = types.directSupertypes(subTypeSym.type)
5456                                                     .stream()
5457                                                     .anyMatch(d -> d.tsym == c);
5458                         if (!thisIsASuper) {
5459                             log.error(TreeInfo.diagnosticPositionFor(subTypeSym, env.tree),
5460                                     Errors.InvalidPermitsClause(Fragments.DoesntExtendSealed(subTypeSym.type)));
5461                         }
5462                     }
5463                 }
5464             }
5465 
5466             List<ClassSymbol> sealedSupers = types.directSupertypes(c.type)
5467                                                   .stream()
5468                                                   .filter(s -> s.tsym.isSealed())
5469                                                   .map(s -> (ClassSymbol) s.tsym)
5470                                                   .collect(List.collector());
5471 
5472             if (sealedSupers.isEmpty()) {
5473                 if ((c.flags_field & Flags.NON_SEALED) != 0) {
5474                     boolean hasErrorSuper = false;
5475 
5476                     hasErrorSuper |= types.directSupertypes(c.type)
5477                                           .stream()
5478                                           .anyMatch(s -> s.tsym.kind == Kind.ERR);
5479 
5480                     ClassType ct = (ClassType) c.type;
5481 
5482                     hasErrorSuper |= !ct.isCompound() && ct.interfaces_field != ct.all_interfaces_field;
5483 
5484                     if (!hasErrorSuper) {
5485                         log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.NonSealedWithNoSealedSupertype(c));
5486                     }
5487                 }
5488             } else {
5489                 if (c.isDirectlyOrIndirectlyLocal() && !c.isEnum()) {
5490                     log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.LocalClassesCantExtendSealed(c.isAnonymous() ? Fragments.Anonymous : Fragments.Local));
5491                 }
5492 
5493                 if (!c.type.isCompound()) {
5494                     for (ClassSymbol supertypeSym : sealedSupers) {
5495                         if (!supertypeSym.permitted.contains(c.type.tsym)) {
5496                             log.error(TreeInfo.diagnosticPositionFor(c.type.tsym, env.tree), Errors.CantInheritFromSealed(supertypeSym));
5497                         }
5498                     }
5499                     if (!c.isNonSealed() && !c.isFinal() && !c.isSealed()) {
5500                         log.error(TreeInfo.diagnosticPositionFor(c, env.tree),
5501                                 c.isInterface() ?
5502                                         Errors.NonSealedOrSealedExpected :
5503                                         Errors.NonSealedSealedOrFinalExpected);
5504                     }
5505                 }
5506             }
5507 
5508             // The info.lint field in the envs stored in typeEnvs is deliberately uninitialized,
5509             // because the annotations were not available at the time the env was created. Therefore,
5510             // we look up the environment chain for the first enclosing environment for which the
5511             // lint value is set. Typically, this is the parent env, but might be further if there
5512             // are any envs created as a result of TypeParameter nodes.
5513             Env<AttrContext> lintEnv = env;
5514             while (lintEnv.info.lint == null)
5515                 lintEnv = lintEnv.next;

5389 
5390             // Next attribute owner, if it is a class.
5391             if (c.owner.kind == TYP && c.owner.type.hasTag(CLASS))
5392                 attribClass((ClassSymbol)c.owner);
5393 
5394             c.flags_field |= Flags.SUPER_OWNER_ATTRIBUTED;
5395         }
5396 
5397         // The previous operations might have attributed the current class
5398         // if there was a cycle. So we test first whether the class is still
5399         // UNATTRIBUTED.
5400         if ((c.flags_field & UNATTRIBUTED) != 0) {
5401             c.flags_field &= ~UNATTRIBUTED;
5402 
5403             // Get environment current at the point of class definition.
5404             Env<AttrContext> env = typeEnvs.get(c);
5405 
5406             if (c.isSealed() &&
5407                     !c.isEnum() &&
5408                     !c.isPermittedExplicit &&
5409                     c.getPermittedSubclasses().isEmpty()) {
5410                 log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.SealedClassMustHaveSubclasses);
5411             }
5412 
5413             if (c.isSealed()) {
5414                 Set<Symbol> permittedTypes = new HashSet<>();
5415                 boolean sealedInUnnamed = c.packge().modle == syms.unnamedModule || c.packge().modle == syms.noModule;
5416                 for (Type subType : c.getPermittedSubclasses()) {
5417                     boolean isTypeVar = false;
5418                     if (subType.getTag() == TYPEVAR) {
5419                         isTypeVar = true; //error recovery
5420                         log.error(TreeInfo.diagnosticPositionFor(subType.tsym, env.tree),
5421                                 Errors.InvalidPermitsClause(Fragments.IsATypeVariable(subType)));
5422                     }
5423                     if (subType.tsym.isAnonymous() && !c.isEnum()) {
5424                         log.error(TreeInfo.diagnosticPositionFor(subType.tsym, env.tree),  Errors.LocalClassesCantExtendSealed(Fragments.Anonymous));
5425                     }
5426                     if (permittedTypes.contains(subType.tsym)) {
5427                         DiagnosticPosition pos =
5428                                 env.enclClass.permitting.stream()
5429                                         .filter(permittedExpr -> TreeInfo.diagnosticPositionFor(subType.tsym, permittedExpr, true) != null)
5430                                         .limit(2).collect(List.collector()).get(1);
5431                         log.error(pos, Errors.InvalidPermitsClause(Fragments.IsDuplicated(subType)));
5432                     } else {
5433                         permittedTypes.add(subType.tsym);
5434                     }
5435                     if (sealedInUnnamed) {
5436                         if (subType.tsym.packge() != c.packge()) {
5437                             log.error(TreeInfo.diagnosticPositionFor(subType.tsym, env.tree),
5438                                     Errors.ClassInUnnamedModuleCantExtendSealedInDiffPackage(c)
5439                             );
5440                         }
5441                     } else if (subType.tsym.packge().modle != c.packge().modle) {
5442                         log.error(TreeInfo.diagnosticPositionFor(subType.tsym, env.tree),
5443                                 Errors.ClassInModuleCantExtendSealedInDiffModule(c, c.packge().modle)
5444                         );
5445                     }
5446                     if (subType.tsym == c.type.tsym || types.isSuperType(subType, c.type)) {
5447                         log.error(TreeInfo.diagnosticPositionFor(subType.tsym, ((JCClassDecl)env.tree).permitting),
5448                                 Errors.InvalidPermitsClause(
5449                                         subType.tsym == c.type.tsym ?
5450                                                 Fragments.MustNotBeSameClass :
5451                                                 Fragments.MustNotBeSupertype(subType)
5452                                 )
5453                         );
5454                     } else if (!isTypeVar) {
5455                         boolean thisIsASuper = types.directSupertypes(subType)
5456                                                     .stream()
5457                                                     .anyMatch(d -> d.tsym == c);
5458                         if (!thisIsASuper) {
5459                             log.error(TreeInfo.diagnosticPositionFor(subType.tsym, env.tree),
5460                                     Errors.InvalidPermitsClause(Fragments.DoesntExtendSealed(subType)));
5461                         }
5462                     }
5463                 }
5464             }
5465 
5466             List<ClassSymbol> sealedSupers = types.directSupertypes(c.type)
5467                                                   .stream()
5468                                                   .filter(s -> s.tsym.isSealed())
5469                                                   .map(s -> (ClassSymbol) s.tsym)
5470                                                   .collect(List.collector());
5471 
5472             if (sealedSupers.isEmpty()) {
5473                 if ((c.flags_field & Flags.NON_SEALED) != 0) {
5474                     boolean hasErrorSuper = false;
5475 
5476                     hasErrorSuper |= types.directSupertypes(c.type)
5477                                           .stream()
5478                                           .anyMatch(s -> s.tsym.kind == Kind.ERR);
5479 
5480                     ClassType ct = (ClassType) c.type;
5481 
5482                     hasErrorSuper |= !ct.isCompound() && ct.interfaces_field != ct.all_interfaces_field;
5483 
5484                     if (!hasErrorSuper) {
5485                         log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.NonSealedWithNoSealedSupertype(c));
5486                     }
5487                 }
5488             } else {
5489                 if (c.isDirectlyOrIndirectlyLocal() && !c.isEnum()) {
5490                     log.error(TreeInfo.diagnosticPositionFor(c, env.tree), Errors.LocalClassesCantExtendSealed(c.isAnonymous() ? Fragments.Anonymous : Fragments.Local));
5491                 }
5492 
5493                 if (!c.type.isCompound()) {
5494                     for (ClassSymbol supertypeSym : sealedSupers) {
5495                         if (!supertypeSym.isPermittedSubclass(c.type.tsym)) {
5496                             log.error(TreeInfo.diagnosticPositionFor(c.type.tsym, env.tree), Errors.CantInheritFromSealed(supertypeSym));
5497                         }
5498                     }
5499                     if (!c.isNonSealed() && !c.isFinal() && !c.isSealed()) {
5500                         log.error(TreeInfo.diagnosticPositionFor(c, env.tree),
5501                                 c.isInterface() ?
5502                                         Errors.NonSealedOrSealedExpected :
5503                                         Errors.NonSealedSealedOrFinalExpected);
5504                     }
5505                 }
5506             }
5507 
5508             // The info.lint field in the envs stored in typeEnvs is deliberately uninitialized,
5509             // because the annotations were not available at the time the env was created. Therefore,
5510             // we look up the environment chain for the first enclosing environment for which the
5511             // lint value is set. Typically, this is the parent env, but might be further if there
5512             // are any envs created as a result of TypeParameter nodes.
5513             Env<AttrContext> lintEnv = env;
5514             while (lintEnv.info.lint == null)
5515                 lintEnv = lintEnv.next;
< prev index next >