diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 0cd7e590779..14e09bad62e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -185,6 +185,7 @@ public interface Errors { DiagnosticFactory0 OPEN_MODIFIER_IN_TRAIT = DiagnosticFactory0 .create(WARNING, modifierSetPosition(JetTokens.OPEN_KEYWORD)); DiagnosticFactory0 TRAIT_CAN_NOT_BE_FINAL = DiagnosticFactory0.create(ERROR, FINAL_MODIFIER); + DiagnosticFactory0 TRAIT_CAN_NOT_BE_SEALED = DiagnosticFactory0.create(ERROR, SEALED_MODIFIER); DiagnosticFactory0 CONSTRUCTOR_IN_TRAIT = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); @@ -203,6 +204,8 @@ public interface Errors { .create(ERROR, modifierSetPosition(JetTokens.OPEN_KEYWORD)); DiagnosticFactory0 ABSTRACT_MODIFIER_IN_ENUM = DiagnosticFactory0 .create(ERROR, modifierSetPosition(JetTokens.ABSTRACT_KEYWORD)); + DiagnosticFactory0 SEALED_MODIFIER_IN_ENUM = DiagnosticFactory0 + .create(ERROR, modifierSetPosition(JetTokens.SEALED_KEYWORD)); DiagnosticFactory0 CLASS_IN_SUPERTYPE_FOR_ENUM = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 TYPE_PARAMETERS_IN_ENUM = DiagnosticFactory0.create(ERROR); @@ -214,6 +217,17 @@ public interface Errors { DiagnosticFactory1 ENUM_ENTRY_AFTER_ENUM_MEMBER = DiagnosticFactory1.create(WARNING, DECLARATION_NAME); DiagnosticFactory0 ENUM_CLASS_CONSTRUCTOR_CALL = DiagnosticFactory0.create(ERROR); + // Sealed-specific + DiagnosticFactory0 OPEN_MODIFIER_IN_SEALED = DiagnosticFactory0 + .create(ERROR, modifierSetPosition(JetTokens.OPEN_KEYWORD)); + DiagnosticFactory0 FINAL_MODIFIER_IN_SEALED = DiagnosticFactory0 + .create(ERROR, modifierSetPosition(JetTokens.FINAL_KEYWORD)); + DiagnosticFactory0 ABSTRACT_MODIFIER_IN_SEALED = DiagnosticFactory0 + .create(WARNING, modifierSetPosition(JetTokens.ABSTRACT_KEYWORD)); + DiagnosticFactory0 SEALED_CLASS_CONSTRUCTOR_CALL = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 SEALED_SUPERTYPE = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 SEALED_SUPERTYPE_IN_LOCAL_CLASS = DiagnosticFactory0.create(ERROR); + // Companion objects DiagnosticFactory0 MANY_COMPANION_OBJECTS = DiagnosticFactory0.create(ERROR, COMPANION_OBJECT); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt index 740cd33e581..a57d3d38272 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt @@ -208,6 +208,8 @@ public object PositioningStrategies { public val FINAL_MODIFIER: PositioningStrategy = modifierSetPosition(JetTokens.FINAL_KEYWORD) + public val SEALED_MODIFIER: PositioningStrategy = modifierSetPosition(JetTokens.SEALED_KEYWORD) + public val VARIANCE_MODIFIER: PositioningStrategy = modifierSetPosition(JetTokens.IN_KEYWORD, JetTokens.OUT_KEYWORD) public val FOR_REDECLARATION: PositioningStrategy = object : PositioningStrategy() { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 060bd066846..2fa4ca6bf72 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -141,11 +141,16 @@ public class DefaultErrorMessages { MAP.put(REDUNDANT_MODIFIER, "Modifier ''{0}'' is redundant because ''{1}'' is present", TO_STRING, TO_STRING); MAP.put(ABSTRACT_MODIFIER_IN_TRAIT, "Modifier ''abstract'' is redundant in interface"); MAP.put(OPEN_MODIFIER_IN_TRAIT, "Modifier ''open'' is redundant in interface"); + MAP.put(OPEN_MODIFIER_IN_SEALED, "Modifier ''open'' is not applicable for sealed class"); MAP.put(OPEN_MODIFIER_IN_ENUM, "Modifier ''open'' is not applicable for enum class"); MAP.put(ABSTRACT_MODIFIER_IN_ENUM, "Modifier ''abstract'' is not applicable for enum class"); + MAP.put(ABSTRACT_MODIFIER_IN_SEALED, "Modifier ''abstract'' is redundant for sealed class"); + MAP.put(SEALED_MODIFIER_IN_ENUM, "Modifier ''sealed'' is not applicable for enum class"); + MAP.put(FINAL_MODIFIER_IN_SEALED, "Modifier ''final'' is not applicable for sealed class"); MAP.put(ILLEGAL_ENUM_ANNOTATION, "Annotation ''enum'' is only applicable for class"); MAP.put(REDUNDANT_MODIFIER_IN_GETTER, "Visibility modifiers are redundant in getter"); MAP.put(TRAIT_CAN_NOT_BE_FINAL, "Interface cannot be final"); + MAP.put(TRAIT_CAN_NOT_BE_SEALED, "Interface cannot be sealed"); MAP.put(TYPE_PARAMETERS_IN_ENUM, "Enum class cannot have type parameters"); MAP.put(TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM, "Type checking has run into a recursive problem. Easiest workaround: specify types of your declarations explicitly"); // TODO: message @@ -292,6 +297,7 @@ public class DefaultErrorMessages { MAP.put(ENUM_ENTRY_USES_DEPRECATED_SUPER_CONSTRUCTOR, "Enum entry ''{0}'' uses deprecated super constructor syntax, use ENTRY(arguments) instead", NAME); MAP.put(ENUM_ENTRY_AFTER_ENUM_MEMBER, "Enum entry ''{0}'' is not allowed after a member", NAME); MAP.put(ENUM_CLASS_CONSTRUCTOR_CALL, "Enum types cannot be instantiated"); + MAP.put(SEALED_CLASS_CONSTRUCTOR_CALL, "Sealed types cannot be instantiated"); MAP.put(DELEGATION_IN_TRAIT, "Interfaces cannot use delegation"); MAP.put(DELEGATION_NOT_TO_TRAIT, "Only interfaces can be delegated to"); @@ -430,6 +436,8 @@ public class DefaultErrorMessages { MAP.put(TRAIT_WITH_SUPERCLASS, "An interface cannot inherit from a class"); MAP.put(SUPERTYPE_APPEARS_TWICE, "A supertype appears twice"); MAP.put(FINAL_SUPERTYPE, "This type is final, so it cannot be inherited from"); + MAP.put(SEALED_SUPERTYPE, "This type is sealed, so it can be inherited by only its own nested classes or objects"); + MAP.put(SEALED_SUPERTYPE_IN_LOCAL_CLASS, "Local class cannot extend a sealed class"); MAP.put(SINGLETON_IN_SUPERTYPE, "Cannot inherit from a singleton"); MAP.put(CYCLIC_CONSTRUCTOR_DELEGATION_CALL, "There's a cycle in the delegation calls chain"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/lexer/JetTokens.java b/compiler/frontend/src/org/jetbrains/kotlin/lexer/JetTokens.java index c6bcc8899a2..30d77adfab9 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/lexer/JetTokens.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/lexer/JetTokens.java @@ -157,6 +157,7 @@ public interface JetTokens { JetModifierKeywordToken REIFIED_KEYWORD = JetModifierKeywordToken.softKeywordModifier("reified"); JetModifierKeywordToken DYNAMIC_KEYWORD = JetModifierKeywordToken.softKeywordModifier("dynamic"); JetModifierKeywordToken COMPANION_KEYWORD = JetModifierKeywordToken.softKeywordModifier("companion"); + JetModifierKeywordToken SEALED_KEYWORD = JetModifierKeywordToken.softKeywordModifier("sealed"); JetKeywordToken FINALLY_KEYWORD = JetKeywordToken.softKeyword("finally"); JetModifierKeywordToken FINAL_KEYWORD = JetModifierKeywordToken.softKeywordModifier("final"); @@ -174,7 +175,7 @@ public interface JetTokens { SET_KEYWORD, ABSTRACT_KEYWORD, ENUM_KEYWORD, OPEN_KEYWORD, INNER_KEYWORD, ANNOTATION_KEYWORD, OVERRIDE_KEYWORD, PRIVATE_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD, PROTECTED_KEYWORD, CATCH_KEYWORD, FINALLY_KEYWORD, OUT_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD, REIFIED_KEYWORD, - DYNAMIC_KEYWORD, COMPANION_KEYWORD, CONSTRUCTOR_KEYWORD, INIT_KEYWORD + DYNAMIC_KEYWORD, COMPANION_KEYWORD, CONSTRUCTOR_KEYWORD, INIT_KEYWORD, SEALED_KEYWORD ); /* @@ -186,7 +187,7 @@ public interface JetTokens { new JetModifierKeywordToken[] { ABSTRACT_KEYWORD, ENUM_KEYWORD, OPEN_KEYWORD, INNER_KEYWORD, ANNOTATION_KEYWORD, OVERRIDE_KEYWORD, PRIVATE_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD, PROTECTED_KEYWORD, OUT_KEYWORD, IN_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD, - REIFIED_KEYWORD, COMPANION_KEYWORD + REIFIED_KEYWORD, COMPANION_KEYWORD, SEALED_KEYWORD }; TokenSet MODIFIER_KEYWORDS = TokenSet.create(MODIFIER_KEYWORDS_ARRAY); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java index 09526f89e17..897aee133ff 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java @@ -394,15 +394,28 @@ public class BodyResolver { trace.report(SUPERTYPES_FOR_ANNOTATION_CLASS.on(jetClass.getDelegationSpecifierList())); } - Set parentEnum = - jetClass instanceof JetEnumEntry - ? Collections.singleton(((ClassDescriptor) descriptor.getContainingDeclaration()).getTypeConstructor()) - : Collections.emptySet(); + Set parentEnumOrSealed; + if (jetClass instanceof JetEnumEntry) { + parentEnumOrSealed = Collections.singleton(((ClassDescriptor) descriptor.getContainingDeclaration()).getTypeConstructor()); + } + else { + parentEnumOrSealed = Collections.emptySet(); + ClassDescriptor currentDescriptor = descriptor; + while (currentDescriptor.getContainingDeclaration() instanceof ClassDescriptor) { + currentDescriptor = (ClassDescriptor) currentDescriptor.getContainingDeclaration(); + if (currentDescriptor.getModality() == Modality.SEALED) { + if (parentEnumOrSealed.isEmpty()) { + parentEnumOrSealed = new HashSet(); + } + parentEnumOrSealed.add(currentDescriptor.getTypeConstructor()); + } + } + } if (primaryConstructorDelegationCall[0] != null && primaryConstructor != null) { recordConstructorDelegationCall(trace, primaryConstructor, primaryConstructorDelegationCall[0]); } - checkSupertypeList(descriptor, supertypes, parentEnum); + checkSupertypeList(descriptor, supertypes, parentEnumOrSealed); } private static void recordConstructorDelegationCall( @@ -464,7 +477,21 @@ public class BodyResolver { trace.report(SINGLETON_IN_SUPERTYPE.on(typeReference)); } else if (constructor.isFinal() && !allowedFinalSupertypes.contains(constructor)) { - trace.report(FINAL_SUPERTYPE.on(typeReference)); + if (classDescriptor.getModality() == Modality.SEALED) { + DeclarationDescriptor containingDescriptor = supertypeOwner.getContainingDeclaration(); + while (containingDescriptor != null && containingDescriptor != classDescriptor) { + containingDescriptor = containingDescriptor.getContainingDeclaration(); + } + if (containingDescriptor == null) { + trace.report(SEALED_SUPERTYPE.on(typeReference)); + } + else { + trace.report(SEALED_SUPERTYPE_IN_LOCAL_CLASS.on(typeReference)); + } + } + else { + trace.report(FINAL_SUPERTYPE.on(typeReference)); + } } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java index 74016b5c8af..f84e64e8f68 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java @@ -265,6 +265,9 @@ public class DeclarationsChecker { trace.report(LOCAL_ENUM_NOT_ALLOWED.on(aClass, classDescriptor)); } } + else if (aClass.hasModifier(JetTokens.SEALED_KEYWORD)) { + checkSealedModifiers(aClass); + } else if (aClass instanceof JetEnumEntry) { checkEnumEntry((JetEnumEntry) aClass, classDescriptor); } @@ -319,6 +322,9 @@ public class DeclarationsChecker { if (modifierList.hasModifier(JetTokens.FINAL_KEYWORD)) { trace.report(Errors.TRAIT_CAN_NOT_BE_FINAL.on(aClass)); } + if (modifierList.hasModifier(JetTokens.SEALED_KEYWORD)) { + trace.report(Errors.TRAIT_CAN_NOT_BE_SEALED.on(aClass)); + } if (modifierList.hasModifier(JetTokens.ABSTRACT_KEYWORD)) { trace.report(Errors.ABSTRACT_MODIFIER_IN_TRAIT.on(aClass)); } @@ -550,6 +556,21 @@ public class DeclarationsChecker { if (aClass.hasModifier(JetTokens.ABSTRACT_KEYWORD)) { trace.report(ABSTRACT_MODIFIER_IN_ENUM.on(aClass)); } + if (aClass.hasModifier(JetTokens.SEALED_KEYWORD)) { + trace.report(SEALED_MODIFIER_IN_ENUM.on(aClass)); + } + } + + private void checkSealedModifiers(JetClass aClass) { + if (aClass.hasModifier(JetTokens.OPEN_KEYWORD)) { + trace.report(OPEN_MODIFIER_IN_SEALED.on(aClass)); + } + if (aClass.hasModifier(JetTokens.FINAL_KEYWORD)) { + trace.report(FINAL_MODIFIER_IN_SEALED.on(aClass)); + } + if (aClass.hasModifier(JetTokens.ABSTRACT_KEYWORD)) { + trace.report(ABSTRACT_MODIFIER_IN_SEALED.on(aClass)); + } } // Temporary diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.java index 0a8c7ed7d98..18154c9e66c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.java @@ -45,7 +45,7 @@ import static org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry; public class ModifiersChecker { private static final Collection MODALITY_MODIFIERS = - Lists.newArrayList(ABSTRACT_KEYWORD, OPEN_KEYWORD, FINAL_KEYWORD, OVERRIDE_KEYWORD); + Lists.newArrayList(ABSTRACT_KEYWORD, OPEN_KEYWORD, FINAL_KEYWORD, OVERRIDE_KEYWORD, SEALED_KEYWORD); private static final Collection VISIBILITY_MODIFIERS = Lists.newArrayList(PRIVATE_KEYWORD, PROTECTED_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD); @@ -370,6 +370,9 @@ public class ModifiersChecker { boolean hasAbstractModifier = modifierList.hasModifier(ABSTRACT_KEYWORD); boolean hasOverrideModifier = modifierList.hasModifier(OVERRIDE_KEYWORD); + if (modifierList.hasModifier(SEALED_KEYWORD)) { + return Modality.SEALED; + } if (modifierList.hasModifier(OPEN_KEYWORD)) { if (hasAbstractModifier || defaultModality == Modality.ABSTRACT) { return Modality.ABSTRACT; diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.java index 3fb4273bdc3..c8018e605c4 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.java @@ -211,13 +211,18 @@ public class CallExpressionResolver { return TypeInfoFactoryPackage.noTypeInfo(context); } if (functionDescriptor instanceof ConstructorDescriptor) { - if (DescriptorUtils.isAnnotationClass(functionDescriptor.getContainingDeclaration()) + DeclarationDescriptor containingDescriptor = functionDescriptor.getContainingDeclaration(); + if (DescriptorUtils.isAnnotationClass(containingDescriptor) && !canInstantiateAnnotationClass(callExpression)) { context.trace.report(ANNOTATION_CLASS_CONSTRUCTOR_CALL.on(callExpression)); } - if (DescriptorUtils.isEnumClass(functionDescriptor.getContainingDeclaration())) { + if (DescriptorUtils.isEnumClass(containingDescriptor)) { context.trace.report(ENUM_CLASS_CONSTRUCTOR_CALL.on(callExpression)); } + if (containingDescriptor instanceof ClassDescriptor + && ((ClassDescriptor) containingDescriptor).getModality() == Modality.SEALED) { + context.trace.report(SEALED_CLASS_CONSTRUCTOR_CALL.on(callExpression)); + } } JetType type = functionDescriptor.getReturnType(); diff --git a/compiler/testData/diagnostics/tests/sealed/DoubleInner.kt b/compiler/testData/diagnostics/tests/sealed/DoubleInner.kt new file mode 100644 index 00000000000..a4be675f925 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/DoubleInner.kt @@ -0,0 +1,9 @@ +sealed class Sealed(val x: Int) { + object First: Sealed(12) + open class NonFirst(x: Int, val y: Int): Sealed(x) { + object Second: NonFirst(34, 2) + object Third: NonFirst(56, 3) + // It's ALLOWED to inherit Sealed also here + object Fourth: Sealed(78) + } +} diff --git a/compiler/testData/diagnostics/tests/sealed/DoubleInner.txt b/compiler/testData/diagnostics/tests/sealed/DoubleInner.txt new file mode 100644 index 00000000000..6140d4eeba9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/DoubleInner.txt @@ -0,0 +1,52 @@ +package + +internal sealed class Sealed { + public constructor Sealed(/*0*/ x: kotlin.Int) + internal final val x: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + internal object First : Sealed { + private constructor First() + internal final override /*1*/ /*fake_override*/ val x: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + internal open class NonFirst : Sealed { + public constructor NonFirst(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int) + internal final override /*1*/ /*fake_override*/ val x: kotlin.Int + internal final val y: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + internal object Fourth : Sealed { + private constructor Fourth() + internal final override /*1*/ /*fake_override*/ val x: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + internal object Second : Sealed.NonFirst { + private constructor Second() + internal final override /*1*/ /*fake_override*/ val x: kotlin.Int + internal final override /*1*/ /*fake_override*/ val y: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + internal object Third : Sealed.NonFirst { + private constructor Third() + internal final override /*1*/ /*fake_override*/ val x: kotlin.Int + internal final override /*1*/ /*fake_override*/ val y: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + } +} diff --git a/compiler/testData/diagnostics/tests/sealed/Local.kt b/compiler/testData/diagnostics/tests/sealed/Local.kt new file mode 100644 index 00000000000..ea19a4e8a59 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/Local.kt @@ -0,0 +1,13 @@ +sealed class Sealed { + object First: Sealed() + open class NonFirst: Sealed() { + object Second: NonFirst() + object Third: NonFirst() + fun foo(): Int { + val s = object: Sealed() {} + class Local: Sealed() {} + return s.hashCode() + } + } + val p: Sealed = object: Sealed() {} +} diff --git a/compiler/testData/diagnostics/tests/sealed/Local.txt b/compiler/testData/diagnostics/tests/sealed/Local.txt new file mode 100644 index 00000000000..2951c987fe6 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/Local.txt @@ -0,0 +1,44 @@ +package + +internal sealed class Sealed { + public constructor Sealed() + internal final val p: Sealed + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + internal object First : Sealed { + private constructor First() + internal final override /*1*/ /*fake_override*/ val p: Sealed + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + internal open class NonFirst : Sealed { + public constructor NonFirst() + internal final override /*1*/ /*fake_override*/ val p: Sealed + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + internal final fun foo(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + internal object Second : Sealed.NonFirst { + private constructor Second() + internal final override /*1*/ /*fake_override*/ val p: Sealed + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + internal final override /*1*/ /*fake_override*/ fun foo(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + internal object Third : Sealed.NonFirst { + private constructor Third() + internal final override /*1*/ /*fake_override*/ val p: Sealed + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + internal final override /*1*/ /*fake_override*/ fun foo(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + } +} diff --git a/compiler/testData/diagnostics/tests/sealed/NeverConstructed.kt b/compiler/testData/diagnostics/tests/sealed/NeverConstructed.kt new file mode 100644 index 00000000000..bdbc1591b04 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/NeverConstructed.kt @@ -0,0 +1,3 @@ +sealed class Base { + fun foo() = Base() +} diff --git a/compiler/testData/diagnostics/tests/sealed/NeverConstructed.txt b/compiler/testData/diagnostics/tests/sealed/NeverConstructed.txt new file mode 100644 index 00000000000..bbe109ea8e2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/NeverConstructed.txt @@ -0,0 +1,9 @@ +package + +internal sealed class Base { + public constructor Base() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + internal final fun foo(): Base + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/sealed/NeverDerived.kt b/compiler/testData/diagnostics/tests/sealed/NeverDerived.kt new file mode 100644 index 00000000000..2a4224d3593 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/NeverDerived.kt @@ -0,0 +1,7 @@ +sealed class Base { + +} + +class Derived: Base() { + +} diff --git a/compiler/testData/diagnostics/tests/sealed/NeverDerived.txt b/compiler/testData/diagnostics/tests/sealed/NeverDerived.txt new file mode 100644 index 00000000000..efda7b37829 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/NeverDerived.txt @@ -0,0 +1,15 @@ +package + +internal sealed class Base { + public constructor Base() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +internal final class Derived : Base { + public constructor Derived() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/sealed/NeverEnum.kt b/compiler/testData/diagnostics/tests/sealed/NeverEnum.kt new file mode 100644 index 00000000000..bac4bed5130 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/NeverEnum.kt @@ -0,0 +1,6 @@ +sealed enum class SealedEnum { + FIRST, + SECOND; + + class Derived: SealedEnum() +} diff --git a/compiler/testData/diagnostics/tests/sealed/NeverEnum.txt b/compiler/testData/diagnostics/tests/sealed/NeverEnum.txt new file mode 100644 index 00000000000..d55aa959cba --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/NeverEnum.txt @@ -0,0 +1,45 @@ +package + +internal sealed enum class SealedEnum : kotlin.Enum { + public enum entry FIRST : SealedEnum { + private constructor FIRST() + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: SealedEnum): kotlin.Int + public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final override /*1*/ /*fake_override*/ fun name(): kotlin.String + public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + public enum entry SECOND : SealedEnum { + private constructor SECOND() + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: SealedEnum): kotlin.Int + public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final override /*1*/ /*fake_override*/ fun name(): kotlin.String + public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + private constructor SealedEnum() + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: SealedEnum): kotlin.Int + public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final override /*1*/ /*fake_override*/ fun name(): kotlin.String + public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + internal final class Derived : SealedEnum { + public constructor Derived() + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: SealedEnum): kotlin.Int + public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final override /*1*/ /*fake_override*/ fun name(): kotlin.String + public final override /*1*/ /*fake_override*/ fun ordinal(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): SealedEnum + public final /*synthesized*/ fun values(): kotlin.Array +} diff --git a/compiler/testData/diagnostics/tests/sealed/NeverFinal.kt b/compiler/testData/diagnostics/tests/sealed/NeverFinal.kt new file mode 100644 index 00000000000..f1fe4036d56 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/NeverFinal.kt @@ -0,0 +1,3 @@ +final sealed class Base { + +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/sealed/NeverFinal.txt b/compiler/testData/diagnostics/tests/sealed/NeverFinal.txt new file mode 100644 index 00000000000..a91a691fa48 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/NeverFinal.txt @@ -0,0 +1,8 @@ +package + +internal sealed class Base { + public constructor Base() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/sealed/NeverInterface.kt b/compiler/testData/diagnostics/tests/sealed/NeverInterface.kt new file mode 100644 index 00000000000..146bff3e649 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/NeverInterface.kt @@ -0,0 +1,3 @@ +sealed interface Base { + +} diff --git a/compiler/testData/diagnostics/tests/sealed/NeverInterface.txt b/compiler/testData/diagnostics/tests/sealed/NeverInterface.txt new file mode 100644 index 00000000000..11958c17cd5 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/NeverInterface.txt @@ -0,0 +1,7 @@ +package + +internal sealed interface Base { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/sealed/NeverObject.kt b/compiler/testData/diagnostics/tests/sealed/NeverObject.kt new file mode 100644 index 00000000000..8cde5f8bbb6 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/NeverObject.kt @@ -0,0 +1,3 @@ +sealed object Sealed { + +} diff --git a/compiler/testData/diagnostics/tests/sealed/NeverObject.txt b/compiler/testData/diagnostics/tests/sealed/NeverObject.txt new file mode 100644 index 00000000000..8f078612c67 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/NeverObject.txt @@ -0,0 +1,8 @@ +package + +internal object Sealed { + private constructor Sealed() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/sealed/NeverOpen.kt b/compiler/testData/diagnostics/tests/sealed/NeverOpen.kt new file mode 100644 index 00000000000..ee1ec2d1347 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/NeverOpen.kt @@ -0,0 +1,3 @@ +open sealed class Base { + +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/sealed/NeverOpen.txt b/compiler/testData/diagnostics/tests/sealed/NeverOpen.txt new file mode 100644 index 00000000000..a91a691fa48 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/NeverOpen.txt @@ -0,0 +1,8 @@ +package + +internal sealed class Base { + public constructor Base() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/sealed/RedundantAbstract.kt b/compiler/testData/diagnostics/tests/sealed/RedundantAbstract.kt new file mode 100644 index 00000000000..d4bf9e9848f --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/RedundantAbstract.kt @@ -0,0 +1,3 @@ +abstract sealed class Base { + +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/sealed/RedundantAbstract.txt b/compiler/testData/diagnostics/tests/sealed/RedundantAbstract.txt new file mode 100644 index 00000000000..a91a691fa48 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/RedundantAbstract.txt @@ -0,0 +1,8 @@ +package + +internal sealed class Base { + public constructor Base() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 0c5514a0981..9640b8a8b48 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -11425,6 +11425,75 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { } } + @TestMetadata("compiler/testData/diagnostics/tests/sealed") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Sealed extends AbstractJetDiagnosticsTest { + public void testAllFilesPresentInSealed() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/sealed"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("DoubleInner.kt") + public void testDoubleInner() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/DoubleInner.kt"); + doTest(fileName); + } + + @TestMetadata("Local.kt") + public void testLocal() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/Local.kt"); + doTest(fileName); + } + + @TestMetadata("NeverConstructed.kt") + public void testNeverConstructed() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/NeverConstructed.kt"); + doTest(fileName); + } + + @TestMetadata("NeverDerived.kt") + public void testNeverDerived() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/NeverDerived.kt"); + doTest(fileName); + } + + @TestMetadata("NeverEnum.kt") + public void testNeverEnum() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/NeverEnum.kt"); + doTest(fileName); + } + + @TestMetadata("NeverFinal.kt") + public void testNeverFinal() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/NeverFinal.kt"); + doTest(fileName); + } + + @TestMetadata("NeverInterface.kt") + public void testNeverInterface() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/NeverInterface.kt"); + doTest(fileName); + } + + @TestMetadata("NeverObject.kt") + public void testNeverObject() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/NeverObject.kt"); + doTest(fileName); + } + + @TestMetadata("NeverOpen.kt") + public void testNeverOpen() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/NeverOpen.kt"); + doTest(fileName); + } + + @TestMetadata("RedundantAbstract.kt") + public void testRedundantAbstract() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/sealed/RedundantAbstract.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/diagnostics/tests/secondaryConstructors") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/Modality.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/Modality.java index dc61a08cbe1..52505a68b91 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/Modality.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/Modality.java @@ -21,12 +21,13 @@ import org.jetbrains.annotations.NotNull; public enum Modality { // THE ORDER OF ENTRIES MATTERS HERE FINAL(false), + SEALED(false), OPEN(true), ABSTRACT(true); private final boolean overridable; - private Modality(boolean overridable) { + Modality(boolean overridable) { this.overridable = overridable; } diff --git a/idea/idea-completion/testData/keywords/AfterClassProperty.kt b/idea/idea-completion/testData/keywords/AfterClassProperty.kt index 2649721eb78..e1c48a3f01b 100644 --- a/idea/idea-completion/testData/keywords/AfterClassProperty.kt +++ b/idea/idea-completion/testData/keywords/AfterClassProperty.kt @@ -35,4 +35,5 @@ class MouseMovedEventArgs // EXIST: init /*why?*/ // EXIST: companion object +// EXIST: sealed // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/AfterClasses.kt b/idea/idea-completion/testData/keywords/AfterClasses.kt index 436af4fd543..40c822bde0e 100644 --- a/idea/idea-completion/testData/keywords/AfterClasses.kt +++ b/idea/idea-completion/testData/keywords/AfterClasses.kt @@ -38,5 +38,6 @@ class B { // EXIST: vararg /*why?*/ // EXIST: companion object +// EXIST: sealed /*TODO*/ // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/AfterFuns.kt b/idea/idea-completion/testData/keywords/AfterFuns.kt index 013df371df9..3cb320a7ab4 100644 --- a/idea/idea-completion/testData/keywords/AfterFuns.kt +++ b/idea/idea-completion/testData/keywords/AfterFuns.kt @@ -38,4 +38,5 @@ class A { // EXIST: init /*why?*/ // EXIST: companion object +// EXIST: sealed // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/FileKeyword.kt b/idea/idea-completion/testData/keywords/FileKeyword.kt index 141cc26dd37..d7163b48ad8 100644 --- a/idea/idea-completion/testData/keywords/FileKeyword.kt +++ b/idea/idea-completion/testData/keywords/FileKeyword.kt @@ -20,6 +20,7 @@ // EXIST: {"lookupString":"protected","itemText":"protected","attributes":"bold"} // EXIST: {"lookupString":"public","itemText":"public","attributes":"bold"} // EXIST: {"lookupString":"reified","itemText":"reified","attributes":"bold"} +// EXIST: {"lookupString":"sealed","itemText":"sealed","attributes":"bold"} // EXIST: {"lookupString":"val","itemText":"val","attributes":"bold"} // EXIST: {"lookupString":"var","itemText":"var","attributes":"bold"} // EXIST: {"lookupString":"vararg","itemText":"vararg","attributes":"bold"} diff --git a/idea/idea-completion/testData/keywords/GlobalPropertyAccessors.kt b/idea/idea-completion/testData/keywords/GlobalPropertyAccessors.kt index aaf2001f13d..1071377222e 100644 --- a/idea/idea-completion/testData/keywords/GlobalPropertyAccessors.kt +++ b/idea/idea-completion/testData/keywords/GlobalPropertyAccessors.kt @@ -38,5 +38,6 @@ var a : Int // EXIST: vararg /*why?*/ // EXIST: companion object +// EXIST: sealed /*TODO*/ // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/InClassBeforeFun.kt b/idea/idea-completion/testData/keywords/InClassBeforeFun.kt index 89e978abc6a..7a59f949c52 100644 --- a/idea/idea-completion/testData/keywords/InClassBeforeFun.kt +++ b/idea/idea-completion/testData/keywords/InClassBeforeFun.kt @@ -36,4 +36,5 @@ public class Test { // EXIST: init /*why?*/ // EXIST: companion object +// EXIST: sealed // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/InClassScope.kt b/idea/idea-completion/testData/keywords/InClassScope.kt index fd9d78ab9bb..9158b047cf0 100644 --- a/idea/idea-completion/testData/keywords/InClassScope.kt +++ b/idea/idea-completion/testData/keywords/InClassScope.kt @@ -30,4 +30,5 @@ class TestClass { // EXIST: constructor // EXIST: init // EXIST: companion object +// EXIST: sealed // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/InTopScopeAfterPackage.kt b/idea/idea-completion/testData/keywords/InTopScopeAfterPackage.kt index 9aace37ee78..cfd2c497048 100644 --- a/idea/idea-completion/testData/keywords/InTopScopeAfterPackage.kt +++ b/idea/idea-completion/testData/keywords/InTopScopeAfterPackage.kt @@ -29,5 +29,6 @@ package Test // EXIST: vararg /*why?*/ // EXIST: companion object +// EXIST: sealed /*TODO*/ // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/PropertyAccessors.kt b/idea/idea-completion/testData/keywords/PropertyAccessors.kt index 289dc9fdc89..97fed3ffa6c 100644 --- a/idea/idea-completion/testData/keywords/PropertyAccessors.kt +++ b/idea/idea-completion/testData/keywords/PropertyAccessors.kt @@ -34,4 +34,5 @@ class Some { // EXIST: constructor // EXIST: init // EXIST: companion object +// EXIST: sealed // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/PropertyAccessors2.kt b/idea/idea-completion/testData/keywords/PropertyAccessors2.kt index 7e1b324789b..d0f18e763f3 100644 --- a/idea/idea-completion/testData/keywords/PropertyAccessors2.kt +++ b/idea/idea-completion/testData/keywords/PropertyAccessors2.kt @@ -34,4 +34,5 @@ class Some { // EXIST: constructor // EXIST: init // EXIST: companion object +// EXIST: sealed // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/PropertySetter.kt b/idea/idea-completion/testData/keywords/PropertySetter.kt index 78ada27bc57..d1c3ac16d2e 100644 --- a/idea/idea-completion/testData/keywords/PropertySetter.kt +++ b/idea/idea-completion/testData/keywords/PropertySetter.kt @@ -36,4 +36,5 @@ class Some { // EXIST: constructor // EXIST: init // EXIST: companion object +// EXIST: sealed // NOTHING_ELSE diff --git a/idea/idea-completion/testData/keywords/TopScope.kt b/idea/idea-completion/testData/keywords/TopScope.kt index a77cad63424..df2f8c318ca 100644 --- a/idea/idea-completion/testData/keywords/TopScope.kt +++ b/idea/idea-completion/testData/keywords/TopScope.kt @@ -28,5 +28,6 @@ // EXIST: vararg /*why?*/ // EXIST: companion object +// EXIST: sealed /*TODO*/ // NOTHING_ELSE