From 8d25c20169ebf869cb1ed66cfd0ad0c434777d8c Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Tue, 12 May 2015 18:07:17 +0300 Subject: [PATCH] Introduction of sealed classes Sealed classes can be derived only by their own inner classes or objects. Their constructors cannot be called explicitly, so compiler knows all their descendants. Incompatible modifier checks (final, abstract). Impossible with interface, object, enum. A pack of tests provided. --- .../jetbrains/kotlin/diagnostics/Errors.java | 14 ++++ .../diagnostics/PositioningStrategies.kt | 2 + .../rendering/DefaultErrorMessages.java | 8 +++ .../org/jetbrains/kotlin/lexer/JetTokens.java | 5 +- .../kotlin/resolve/BodyResolver.java | 39 +++++++++-- .../kotlin/resolve/DeclarationsChecker.java | 21 ++++++ .../kotlin/resolve/ModifiersChecker.java | 5 +- .../resolve/calls/CallExpressionResolver.java | 9 ++- .../diagnostics/tests/sealed/DoubleInner.kt | 9 +++ .../diagnostics/tests/sealed/DoubleInner.txt | 52 ++++++++++++++ .../diagnostics/tests/sealed/Local.kt | 13 ++++ .../diagnostics/tests/sealed/Local.txt | 44 ++++++++++++ .../tests/sealed/NeverConstructed.kt | 3 + .../tests/sealed/NeverConstructed.txt | 9 +++ .../diagnostics/tests/sealed/NeverDerived.kt | 7 ++ .../diagnostics/tests/sealed/NeverDerived.txt | 15 ++++ .../diagnostics/tests/sealed/NeverEnum.kt | 6 ++ .../diagnostics/tests/sealed/NeverEnum.txt | 45 ++++++++++++ .../diagnostics/tests/sealed/NeverFinal.kt | 3 + .../diagnostics/tests/sealed/NeverFinal.txt | 8 +++ .../tests/sealed/NeverInterface.kt | 3 + .../tests/sealed/NeverInterface.txt | 7 ++ .../diagnostics/tests/sealed/NeverObject.kt | 3 + .../diagnostics/tests/sealed/NeverObject.txt | 8 +++ .../diagnostics/tests/sealed/NeverOpen.kt | 3 + .../diagnostics/tests/sealed/NeverOpen.txt | 8 +++ .../tests/sealed/RedundantAbstract.kt | 3 + .../tests/sealed/RedundantAbstract.txt | 8 +++ .../checkers/JetDiagnosticsTestGenerated.java | 69 +++++++++++++++++++ .../kotlin/descriptors/Modality.java | 3 +- .../testData/keywords/AfterClassProperty.kt | 1 + .../testData/keywords/AfterClasses.kt | 1 + .../testData/keywords/AfterFuns.kt | 1 + .../testData/keywords/FileKeyword.kt | 1 + .../keywords/GlobalPropertyAccessors.kt | 1 + .../testData/keywords/InClassBeforeFun.kt | 1 + .../testData/keywords/InClassScope.kt | 1 + .../keywords/InTopScopeAfterPackage.kt | 1 + .../testData/keywords/PropertyAccessors.kt | 1 + .../testData/keywords/PropertyAccessors2.kt | 1 + .../testData/keywords/PropertySetter.kt | 1 + .../testData/keywords/TopScope.kt | 1 + 42 files changed, 432 insertions(+), 12 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/sealed/DoubleInner.kt create mode 100644 compiler/testData/diagnostics/tests/sealed/DoubleInner.txt create mode 100644 compiler/testData/diagnostics/tests/sealed/Local.kt create mode 100644 compiler/testData/diagnostics/tests/sealed/Local.txt create mode 100644 compiler/testData/diagnostics/tests/sealed/NeverConstructed.kt create mode 100644 compiler/testData/diagnostics/tests/sealed/NeverConstructed.txt create mode 100644 compiler/testData/diagnostics/tests/sealed/NeverDerived.kt create mode 100644 compiler/testData/diagnostics/tests/sealed/NeverDerived.txt create mode 100644 compiler/testData/diagnostics/tests/sealed/NeverEnum.kt create mode 100644 compiler/testData/diagnostics/tests/sealed/NeverEnum.txt create mode 100644 compiler/testData/diagnostics/tests/sealed/NeverFinal.kt create mode 100644 compiler/testData/diagnostics/tests/sealed/NeverFinal.txt create mode 100644 compiler/testData/diagnostics/tests/sealed/NeverInterface.kt create mode 100644 compiler/testData/diagnostics/tests/sealed/NeverInterface.txt create mode 100644 compiler/testData/diagnostics/tests/sealed/NeverObject.kt create mode 100644 compiler/testData/diagnostics/tests/sealed/NeverObject.txt create mode 100644 compiler/testData/diagnostics/tests/sealed/NeverOpen.kt create mode 100644 compiler/testData/diagnostics/tests/sealed/NeverOpen.txt create mode 100644 compiler/testData/diagnostics/tests/sealed/RedundantAbstract.kt create mode 100644 compiler/testData/diagnostics/tests/sealed/RedundantAbstract.txt 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