diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java index 1d7643197a4..547b58b0836 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java @@ -132,7 +132,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (myClass instanceof JetClass) { JetClass jetClass = (JetClass) myClass; - if (jetClass.hasModifier(JetTokens.ABSTRACT_KEYWORD)) { + if (jetClass.hasModifier(JetTokens.ABSTRACT_KEYWORD) || jetClass.isSealed()) { isAbstract = true; } if (jetClass.isInterface()) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetClass.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetClass.kt index dd914c11797..803db5ea1d8 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetClass.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetClass.kt @@ -64,6 +64,7 @@ public open class JetClass : JetClassOrObject { ?: (findChildByType(JetTokens.TRAIT_KEYWORD) != null || findChildByType(JetTokens.INTERFACE_KEYWORD) != null) public fun isEnum(): Boolean = hasModifier(JetTokens.ENUM_KEYWORD) + public fun isSealed(): Boolean = hasModifier(JetTokens.SEALED_KEYWORD) public fun isInner(): Boolean = hasModifier(JetTokens.INNER_KEYWORD) override fun isEquivalentTo(another: PsiElement?): Boolean { diff --git a/compiler/testData/codegen/box/sealed/objects.kt b/compiler/testData/codegen/box/sealed/objects.kt new file mode 100644 index 00000000000..c33a71d498f --- /dev/null +++ b/compiler/testData/codegen/box/sealed/objects.kt @@ -0,0 +1,11 @@ +sealed class Season { + object Warm: Season() + object Cold: Season() +} + +fun foo(): Season = Season.Warm + +fun box() = when(foo()) { + Season.Warm -> "OK" + Season.Cold -> "Fail: Cold, should be Warm" +} diff --git a/compiler/testData/codegen/box/sealed/simple.kt b/compiler/testData/codegen/box/sealed/simple.kt new file mode 100644 index 00000000000..01ae3af2c95 --- /dev/null +++ b/compiler/testData/codegen/box/sealed/simple.kt @@ -0,0 +1,11 @@ +sealed class Season { + class Warm: Season() + class Cold: Season() +} + +fun foo(): Season = Season.Warm() + +fun box() = when(foo()) { + is Season.Warm -> "OK" + is Season.Cold -> "Fail: Cold, should be Warm" +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java index 5be3da6ada1..908f62af7a2 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -6581,6 +6581,27 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { } } + @TestMetadata("compiler/testData/codegen/box/sealed") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Sealed extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInSealed() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/sealed"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("objects.kt") + public void testObjects() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/sealed/objects.kt"); + doTest(fileName); + } + + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/sealed/simple.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/box/secondaryConstructors") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/serialization/DebugProtoBuf.java b/compiler/tests/org/jetbrains/kotlin/serialization/DebugProtoBuf.java index 2ea2486072d..a5d2c1021e2 100644 --- a/compiler/tests/org/jetbrains/kotlin/serialization/DebugProtoBuf.java +++ b/compiler/tests/org/jetbrains/kotlin/serialization/DebugProtoBuf.java @@ -29,6 +29,10 @@ public final class DebugProtoBuf { * ABSTRACT = 2; */ ABSTRACT(2, 2), + /** + * SEALED = 3; + */ + SEALED(3, 3), ; /** @@ -47,6 +51,10 @@ public final class DebugProtoBuf { * ABSTRACT = 2; */ public static final int ABSTRACT_VALUE = 2; + /** + * SEALED = 3; + */ + public static final int SEALED_VALUE = 3; public final int getNumber() { return value; } @@ -56,6 +64,7 @@ public final class DebugProtoBuf { case 0: return FINAL; case 1: return OPEN; case 2: return ABSTRACT; + case 3: return SEALED; default: return null; } } @@ -17092,11 +17101,11 @@ public final class DebugProtoBuf { "ION\020\000\022\021\n\rFAKE_OVERRIDE\020\001\022\016\n\nDELEGATION\020\002" + "\022\017\n\013SYNTHESIZED\020\003\":\n\014CallableKind\022\007\n\003FUN" + "\020\000\022\007\n\003VAL\020\001\022\007\n\003VAR\020\002\022\017\n\013CONSTRUCTOR\020\003*\005\010" + - "d\020\310\001*-\n\010Modality\022\t\n\005FINAL\020\000\022\010\n\004OPEN\020\001\022\014\n", - "\010ABSTRACT\020\002*b\n\nVisibility\022\014\n\010INTERNAL\020\000\022" + - "\013\n\007PRIVATE\020\001\022\r\n\tPROTECTED\020\002\022\n\n\006PUBLIC\020\003\022" + - "\023\n\017PRIVATE_TO_THIS\020\004\022\t\n\005LOCAL\020\005B\022B\rDebug" + - "ProtoBuf\210\001\000" + "d\020\310\001*9\n\010Modality\022\t\n\005FINAL\020\000\022\010\n\004OPEN\020\001\022\014\n", + "\010ABSTRACT\020\002\022\n\n\006SEALED\020\003*b\n\nVisibility\022\014\n" + + "\010INTERNAL\020\000\022\013\n\007PRIVATE\020\001\022\r\n\tPROTECTED\020\002\022" + + "\n\n\006PUBLIC\020\003\022\023\n\017PRIVATE_TO_THIS\020\004\022\t\n\005LOCA" + + "L\020\005B\022B\rDebugProtoBuf\210\001\000" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { diff --git a/core/deserialization/src/descriptors.proto b/core/deserialization/src/descriptors.proto index 06fd2915a1f..65056d72d46 100644 --- a/core/deserialization/src/descriptors.proto +++ b/core/deserialization/src/descriptors.proto @@ -288,6 +288,7 @@ enum Modality { FINAL = 0x00; OPEN = 0x01; ABSTRACT = 0x02; + SEALED = 0x03; } enum Visibility { diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/Flags.java b/core/deserialization/src/org/jetbrains/kotlin/serialization/Flags.java index e5d13c2f064..ef6d4069da5 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/Flags.java +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/Flags.java @@ -170,6 +170,8 @@ public class Flags { return ProtoBuf.Modality.OPEN; case ABSTRACT: return ProtoBuf.Modality.ABSTRACT; + case SEALED: + return ProtoBuf.Modality.SEALED; } throw new IllegalArgumentException("Unknown modality: " + modality); } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/ProtoBuf.java b/core/deserialization/src/org/jetbrains/kotlin/serialization/ProtoBuf.java index b26eef19689..8caaf42eb3d 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/ProtoBuf.java +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/ProtoBuf.java @@ -29,6 +29,10 @@ public final class ProtoBuf { * ABSTRACT = 2; */ ABSTRACT(2, 2), + /** + * SEALED = 3; + */ + SEALED(3, 3), ; /** @@ -47,6 +51,10 @@ public final class ProtoBuf { * ABSTRACT = 2; */ public static final int ABSTRACT_VALUE = 2; + /** + * SEALED = 3; + */ + public static final int SEALED_VALUE = 3; public final int getNumber() { return value; } @@ -56,6 +64,7 @@ public final class ProtoBuf { case 0: return FINAL; case 1: return OPEN; case 2: return ABSTRACT; + case 3: return SEALED; default: return null; } } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/protoEnumMapping.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/protoEnumMapping.kt index 3eedccd2fa3..57a43deddb2 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/protoEnumMapping.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/protoEnumMapping.kt @@ -35,6 +35,7 @@ fun modality(modality: ProtoBuf.Modality) = when (modality) { ProtoBuf.Modality.FINAL -> Modality.FINAL ProtoBuf.Modality.OPEN -> Modality.OPEN ProtoBuf.Modality.ABSTRACT -> Modality.ABSTRACT + ProtoBuf.Modality.SEALED -> Modality.SEALED } fun visibility(visibility: ProtoBuf.Visibility) = when (visibility) {