kotlinx.serialization: Support @Serializable on sealed interfaces.

Interfaces (regular and sealed) are by default polymorphic. To benefit
from sealing (i.e. knowledge of all inheritors in compile-time), @Serializable
annotation may be added on sealed interface, generating the same serializer
that can be used for sealed classes.

Synthetic nested classes are not generated in DEFAULT_IMPLS mode because
it causes problems when adding a synthetic companion to an interface.

Fixes https://github.com/Kotlin/kotlinx.serialization/issues/1576
This commit is contained in:
Leonid Startsev
2021-12-01 14:14:47 +00:00
committed by Space
parent e6a5614321
commit de128a5406
12 changed files with 295 additions and 76 deletions
@@ -105,12 +105,14 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
}
// Generate synthetic nested classes
Collection<DeclarationDescriptor> classifiers = descriptor
.getUnsubstitutedMemberScope()
.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS, MemberScope.Companion.getALL_NAME_FILTER());
for (DeclarationDescriptor memberDescriptor : classifiers) {
if (memberDescriptor instanceof SyntheticClassOrObjectDescriptor) {
genSyntheticClassOrObject((SyntheticClassOrObjectDescriptor) memberDescriptor);
if (kind != OwnerKind.DEFAULT_IMPLS) {
Collection<DeclarationDescriptor> classifiers = descriptor
.getUnsubstitutedMemberScope()
.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS, MemberScope.Companion.getALL_NAME_FILTER());
for (DeclarationDescriptor memberDescriptor : classifiers) {
if (memberDescriptor instanceof SyntheticClassOrObjectDescriptor) {
genSyntheticClassOrObject((SyntheticClassOrObjectDescriptor) memberDescriptor);
}
}
}
@@ -81,7 +81,7 @@ fun AbstractSerialGenerator.allSealedSerializableSubclassesFor(
klass: ClassDescriptor,
module: ModuleDescriptor
): Pair<List<KotlinType>, List<ClassDescriptor>> {
assert(klass.kind == ClassKind.CLASS && klass.modality == Modality.SEALED)
assert(klass.modality == Modality.SEALED)
fun recursiveSealed(klass: ClassDescriptor): Collection<ClassDescriptor> {
return klass.sealedSubclasses.flatMap { if (it.modality == Modality.SEALED) recursiveSealed(it) else setOf(it) }
}
@@ -155,7 +155,7 @@ fun findTypeSerializer(module: ModuleDescriptor, kType: KotlinType): ClassDescri
val stdSer = findStandardKotlinTypeSerializer(module, kType) // see if there is a standard serializer
?: findEnumTypeSerializer(module, kType)
if (stdSer != null) return stdSer
if (kType.isInterface()) return module.getClassFromSerializationPackage(SpecialBuiltins.polymorphicSerializer)
if (kType.isInterface() && kType.toClassDescriptor?.isSealedSerializableInterface == false) return module.getClassFromSerializationPackage(SpecialBuiltins.polymorphicSerializer)
return kType.toClassDescriptor?.classSerializer // check for serializer defined on the type
}
@@ -420,4 +420,4 @@ open class SerializationPluginDeclarationChecker : DeclarationChecker {
}
internal val ClassDescriptor.serializableAnnotationIsUseless: Boolean
get() = hasSerializableAnnotationWithoutArgs && !isInternalSerializable && !hasCompanionObjectAsSerializer && !isSerializableEnum()
get() = hasSerializableAnnotationWithoutArgs && !isInternalSerializable && !hasCompanionObjectAsSerializer && !isSerializableEnum() && !isSealedSerializableInterface
@@ -40,8 +40,8 @@ object SerializationPluginErrorsRendering : DefaultErrorMessages.Extension {
)
MAP.put(
SerializationErrors.SERIALIZABLE_ANNOTATION_IGNORED,
"@Serializable annotation is ignored because it is impossible to serialize automatically interfaces or enums. " +
"Provide serializer manually via e.g. companion object"
"@Serializable annotation without arguments can be used only on sealed interfaces." +
"Non-sealed interfaces are polymorphically serializable by default."
)
MAP.put(
SerializationErrors.NON_SERIALIZABLE_PARENT_MUST_HAVE_NOARG_CTOR,
@@ -101,7 +101,7 @@ val KotlinType?.toClassDescriptor: ClassDescriptor?
}
internal val ClassDescriptor.shouldHaveGeneratedMethodsInCompanion: Boolean
get() = this.isSerializableObject || this.isSerializableEnum() || this.kind == ClassKind.CLASS && hasSerializableAnnotation
get() = this.isSerializableObject || this.isSerializableEnum() || this.kind == ClassKind.CLASS && hasSerializableAnnotation || this.isSealedSerializableInterface
internal val ClassDescriptor.isSerializableObject: Boolean
get() = kind == ClassKind.OBJECT && hasSerializableAnnotation
@@ -109,6 +109,9 @@ internal val ClassDescriptor.isSerializableObject: Boolean
internal val ClassDescriptor.isInternallySerializableObject: Boolean
get() = kind == ClassKind.OBJECT && hasSerializableAnnotationWithoutArgs
internal val ClassDescriptor.isSealedSerializableInterface: Boolean
get() = kind == ClassKind.INTERFACE && modality == Modality.SEALED && hasSerializableAnnotation
internal val ClassDescriptor.isInternalSerializable: Boolean //todo normal checking
get() {
if (kind != ClassKind.CLASS) return false
@@ -158,6 +161,7 @@ internal fun ClassDescriptor.isAbstractOrSealedSerializableClass(): Boolean =
internal fun ClassDescriptor.polymorphicSerializerIfApplicableAutomatically(): ClassDescriptor? {
val serializer = when {
kind == ClassKind.INTERFACE && modality == Modality.SEALED -> SpecialBuiltins.sealedSerializer
kind == ClassKind.INTERFACE -> SpecialBuiltins.polymorphicSerializer
isInternalSerializable && modality == Modality.ABSTRACT -> SpecialBuiltins.polymorphicSerializer
isInternalSerializable && modality == Modality.SEALED -> SpecialBuiltins.sealedSerializer
@@ -212,6 +216,7 @@ internal fun ClassDescriptor.needSerializerFactory(): Boolean {
val serializableClass = getSerializableClassDescriptorByCompanion(this) ?: return false
if (serializableClass.isSerializableObject) return true
if (serializableClass.isAbstractOrSealedSerializableClass()) return true
if (serializableClass.isSealedSerializableInterface) return true
if (serializableClass.declaredTypeParameters.isEmpty()) return false
return true
}
@@ -30,4 +30,10 @@ public class SerializationIrBoxTestGenerated extends AbstractSerializationIrBoxT
public void testMultimoduleInheritance() throws Exception {
runTest("plugins/kotlin-serialization/kotlin-serialization-compiler/testData/boxIr/multimoduleInheritance.kt");
}
@Test
@TestMetadata("sealedInterfaces.kt")
public void testSealedInterfaces() throws Exception {
runTest("plugins/kotlin-serialization/kotlin-serialization-compiler/testData/boxIr/sealedInterfaces.kt");
}
}
@@ -0,0 +1,37 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM_IR
// WITH_RUNTIME
package a
import kotlinx.serialization.*
import kotlinx.serialization.descriptors.*
import kotlin.test.assertEquals
interface I
sealed interface SI
@Serializable
sealed interface SSI
@Serializable
class Holder(
val i: I,
val si: SI,
val ssi: SSI
)
fun SerialDescriptor.checkKind(index: Int, kind: String) {
assertEquals(kind, getElementDescriptor(index).kind.toString())
}
fun box(): String {
val desc = Holder.serializer().descriptor
desc.checkKind(0, "OPEN")
desc.checkKind(1, "OPEN")
desc.checkKind(2, "SEALED")
return "OK"
}
@@ -9,7 +9,7 @@ public final class Container$$serializer : java/lang/Object, kotlinx/serializati
INVOKESPECIAL (Container$$serializer, <init>, ()V)
PUTSTATIC (Container$$serializer, INSTANCE, LContainer$$serializer;)
LABEL (L0)
LINENUMBER (13)
LINENUMBER (18)
NEW (kotlinx/serialization/internal/PluginGeneratedSerialDescriptor)
DUP
LDC (Container)
@@ -26,13 +26,13 @@ public final class Container$$serializer : java/lang/Object, kotlinx/serializati
CHECKCAST (kotlinx/serialization/descriptors/SerialDescriptor)
PUTSTATIC (Container$$serializer, descriptor, Lkotlinx/serialization/descriptors/SerialDescriptor;)
LABEL (L1)
LINENUMBER (14)
LINENUMBER (19)
RETURN
}
private void <init>() {
LABEL (L0)
LINENUMBER (13)
LINENUMBER (18)
ALOAD (0)
INVOKESPECIAL (java/lang/Object, <init>, ()V)
RETURN
@@ -41,7 +41,7 @@ public final class Container$$serializer : java/lang/Object, kotlinx/serializati
public kotlinx.serialization.KSerializer[] childSerializers() {
LABEL (L0)
LINENUMBER (13)
LINENUMBER (18)
ICONST_1
ANEWARRAY (kotlinx/serialization/KSerializer)
ASTORE (1)
@@ -61,7 +61,7 @@ public final class Container$$serializer : java/lang/Object, kotlinx/serializati
LDC (decoder)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNullParameter, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L1)
LINENUMBER (13)
LINENUMBER (18)
ALOAD (0)
INVOKEVIRTUAL (Container$$serializer, getDescriptor, ()Lkotlinx/serialization/descriptors/SerialDescriptor;)
ASTORE (2)
@@ -146,7 +146,7 @@ public final class Container$$serializer : java/lang/Object, kotlinx/serializati
public java.lang.Object deserialize(kotlinx.serialization.encoding.Decoder decoder) {
LABEL (L0)
LINENUMBER (13)
LINENUMBER (18)
ALOAD (0)
ALOAD (1)
INVOKEVIRTUAL (Container$$serializer, deserialize, (Lkotlinx/serialization/encoding/Decoder;)LContainer;)
@@ -166,7 +166,7 @@ public final class Container$$serializer : java/lang/Object, kotlinx/serializati
public final class Container$Companion : java/lang/Object {
private void <init>() {
LABEL (L0)
LINENUMBER (13)
LINENUMBER (18)
ALOAD (0)
INVOKESPECIAL (java/lang/Object, <init>, ()V)
RETURN
@@ -183,7 +183,7 @@ public final class Container$Companion : java/lang/Object {
public final kotlinx.serialization.KSerializer serializer() {
LABEL (L0)
LINENUMBER (13)
LINENUMBER (18)
GETSTATIC (Container$$serializer, INSTANCE, LContainer$$serializer;)
CHECKCAST (kotlinx/serialization/KSerializer)
ARETURN
@@ -211,11 +211,11 @@ public final class Container : java/lang/Object {
LDC (r)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNullParameter, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L1)
LINENUMBER (13)
LINENUMBER (18)
ALOAD (0)
INVOKESPECIAL (java/lang/Object, <init>, ()V)
LABEL (L2)
LINENUMBER (14)
LINENUMBER (19)
ALOAD (0)
ALOAD (1)
PUTFIELD (Container, r, LResult;)
@@ -225,7 +225,7 @@ public final class Container : java/lang/Object {
public void <init>(int seen1, Result r, kotlinx.serialization.internal.SerializationConstructorMarker serializationConstructorMarker) {
LABEL (L0)
LINENUMBER (13)
LINENUMBER (18)
ICONST_1
ICONST_1
ILOAD (1)
@@ -260,7 +260,7 @@ public final class Container : java/lang/Object {
LDC (serialDesc)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNullParameter, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L1)
LINENUMBER (13)
LINENUMBER (18)
ALOAD (1)
ALOAD (2)
ICONST_0
@@ -297,7 +297,7 @@ final class Result$Companion$$cachedSerializer$delegate$1 : kotlin/jvm/internal/
public final kotlinx.serialization.KSerializer invoke() {
LABEL (L0)
LINENUMBER (7)
LINENUMBER (12)
NEW (kotlinx/serialization/SealedClassSerializer)
DUP
LDC (Result)
@@ -343,7 +343,7 @@ final class Result$Companion$$cachedSerializer$delegate$1 : kotlin/jvm/internal/
public java.lang.Object invoke() {
LABEL (L0)
LINENUMBER (7)
LINENUMBER (12)
ALOAD (0)
INVOKEVIRTUAL (Result$Companion$$cachedSerializer$delegate$1, invoke, ()Lkotlinx/serialization/KSerializer;)
ARETURN
@@ -354,7 +354,7 @@ final class Result$Companion$$cachedSerializer$delegate$1 : kotlin/jvm/internal/
public final class Result$Companion : java/lang/Object {
private void <init>() {
LABEL (L0)
LINENUMBER (7)
LINENUMBER (12)
ALOAD (0)
INVOKESPECIAL (java/lang/Object, <init>, ()V)
RETURN
@@ -373,7 +373,7 @@ public final class Result$Companion : java/lang/Object {
public final kotlinx.serialization.KSerializer serializer() {
LABEL (L0)
LINENUMBER (7)
LINENUMBER (12)
ALOAD (0)
INVOKESPECIAL (Result$Companion, get$cachedSerializer$delegate, ()Lkotlin/Lazy;)
INVOKEINTERFACE (kotlin/Lazy, getValue, ()Ljava/lang/Object;)
@@ -405,7 +405,7 @@ final class Result$Err$$cachedSerializer$delegate$1 : kotlin/jvm/internal/Lambda
public final kotlinx.serialization.KSerializer invoke() {
LABEL (L0)
LINENUMBER (10)
LINENUMBER (15)
NEW (kotlinx/serialization/internal/ObjectSerializer)
DUP
LDC (Result.Err)
@@ -418,7 +418,7 @@ final class Result$Err$$cachedSerializer$delegate$1 : kotlin/jvm/internal/Lambda
public java.lang.Object invoke() {
LABEL (L0)
LINENUMBER (10)
LINENUMBER (15)
ALOAD (0)
INVOKEVIRTUAL (Result$Err$$cachedSerializer$delegate$1, invoke, ()Lkotlinx/serialization/KSerializer;)
ARETURN
@@ -437,7 +437,7 @@ public final class Result$Err : Result {
INVOKESPECIAL (Result$Err, <init>, ()V)
PUTSTATIC (Result$Err, INSTANCE, LResult$Err;)
LABEL (L0)
LINENUMBER (10)
LINENUMBER (15)
GETSTATIC (kotlin/LazyThreadSafetyMode, PUBLICATION, Lkotlin/LazyThreadSafetyMode;)
GETSTATIC (Result$Err$$cachedSerializer$delegate$1, INSTANCE, LResult$Err$$cachedSerializer$delegate$1;)
CHECKCAST (kotlin/jvm/functions/Function0)
@@ -448,7 +448,7 @@ public final class Result$Err : Result {
private void <init>() {
LABEL (L0)
LINENUMBER (10)
LINENUMBER (15)
ALOAD (0)
ACONST_NULL
INVOKESPECIAL (Result, <init>, (Lkotlin/jvm/internal/DefaultConstructorMarker;)V)
@@ -460,7 +460,7 @@ public final class Result$Err : Result {
public final kotlinx.serialization.KSerializer serializer() {
LABEL (L0)
LINENUMBER (10)
LINENUMBER (15)
ALOAD (0)
INVOKESPECIAL (Result$Err, get$cachedSerializer$delegate, ()Lkotlin/Lazy;)
INVOKEINTERFACE (kotlin/Lazy, getValue, ()Ljava/lang/Object;)
@@ -481,7 +481,7 @@ public final class Result$OK$$serializer : java/lang/Object, kotlinx/serializati
INVOKESPECIAL (Result$OK$$serializer, <init>, ()V)
PUTSTATIC (Result$OK$$serializer, INSTANCE, LResult$OK$$serializer;)
LABEL (L0)
LINENUMBER (9)
LINENUMBER (14)
NEW (kotlinx/serialization/internal/PluginGeneratedSerialDescriptor)
DUP
LDC (Result.OK)
@@ -502,7 +502,7 @@ public final class Result$OK$$serializer : java/lang/Object, kotlinx/serializati
private void <init>() {
LABEL (L0)
LINENUMBER (9)
LINENUMBER (14)
ALOAD (0)
INVOKESPECIAL (java/lang/Object, <init>, ()V)
RETURN
@@ -511,7 +511,7 @@ public final class Result$OK$$serializer : java/lang/Object, kotlinx/serializati
public kotlinx.serialization.KSerializer[] childSerializers() {
LABEL (L0)
LINENUMBER (9)
LINENUMBER (14)
ICONST_1
ANEWARRAY (kotlinx/serialization/KSerializer)
ASTORE (1)
@@ -531,7 +531,7 @@ public final class Result$OK$$serializer : java/lang/Object, kotlinx/serializati
LDC (decoder)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNullParameter, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L1)
LINENUMBER (9)
LINENUMBER (14)
ALOAD (0)
INVOKEVIRTUAL (Result$OK$$serializer, getDescriptor, ()Lkotlinx/serialization/descriptors/SerialDescriptor;)
ASTORE (2)
@@ -607,7 +607,7 @@ public final class Result$OK$$serializer : java/lang/Object, kotlinx/serializati
public java.lang.Object deserialize(kotlinx.serialization.encoding.Decoder decoder) {
LABEL (L0)
LINENUMBER (9)
LINENUMBER (14)
ALOAD (0)
ALOAD (1)
INVOKEVIRTUAL (Result$OK$$serializer, deserialize, (Lkotlinx/serialization/encoding/Decoder;)LResult$OK;)
@@ -627,7 +627,7 @@ public final class Result$OK$$serializer : java/lang/Object, kotlinx/serializati
public final class Result$OK$Companion : java/lang/Object {
private void <init>() {
LABEL (L0)
LINENUMBER (9)
LINENUMBER (14)
ALOAD (0)
INVOKESPECIAL (java/lang/Object, <init>, ()V)
RETURN
@@ -644,7 +644,7 @@ public final class Result$OK$Companion : java/lang/Object {
public final kotlinx.serialization.KSerializer serializer() {
LABEL (L0)
LINENUMBER (9)
LINENUMBER (14)
GETSTATIC (Result$OK$$serializer, INSTANCE, LResult$OK$$serializer;)
CHECKCAST (kotlinx/serialization/KSerializer)
ARETURN
@@ -672,7 +672,7 @@ public final class Result$OK : Result {
LDC (s)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNullParameter, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L1)
LINENUMBER (9)
LINENUMBER (14)
ALOAD (0)
ACONST_NULL
INVOKESPECIAL (Result, <init>, (Lkotlin/jvm/internal/DefaultConstructorMarker;)V)
@@ -685,7 +685,7 @@ public final class Result$OK : Result {
public void <init>(int seen1, java.lang.String s, kotlinx.serialization.internal.SerializationConstructorMarker serializationConstructorMarker) {
LABEL (L0)
LINENUMBER (9)
LINENUMBER (14)
ICONST_1
ICONST_1
ILOAD (1)
@@ -722,7 +722,7 @@ public final class Result$OK : Result {
LDC (serialDesc)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNullParameter, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L1)
LINENUMBER (9)
LINENUMBER (14)
ALOAD (0)
CHECKCAST (Result)
ALOAD (1)
@@ -739,7 +739,7 @@ public final class Result$OK : Result {
}
}
public abstract class Result : java/lang/Object {
public abstract class Result : java/lang/Object, X {
private final static kotlin.Lazy $cachedSerializer$delegate
public final static Result$Companion Companion
@@ -751,7 +751,7 @@ public abstract class Result : java/lang/Object {
INVOKESPECIAL (Result$Companion, <init>, (Lkotlin/jvm/internal/DefaultConstructorMarker;)V)
PUTSTATIC (Result, Companion, LResult$Companion;)
LABEL (L0)
LINENUMBER (7)
LINENUMBER (12)
GETSTATIC (kotlin/LazyThreadSafetyMode, PUBLICATION, Lkotlin/LazyThreadSafetyMode;)
GETSTATIC (Result$Companion$$cachedSerializer$delegate$1, INSTANCE, LResult$Companion$$cachedSerializer$delegate$1;)
CHECKCAST (kotlin/jvm/functions/Function0)
@@ -762,18 +762,18 @@ public abstract class Result : java/lang/Object {
private void <init>() {
LABEL (L0)
LINENUMBER (7)
LINENUMBER (12)
ALOAD (0)
INVOKESPECIAL (java/lang/Object, <init>, ()V)
LABEL (L1)
LINENUMBER (8)
LINENUMBER (13)
RETURN
LABEL (L2)
}
public void <init>(int seen1, kotlinx.serialization.internal.SerializationConstructorMarker serializationConstructorMarker) {
LABEL (L0)
LINENUMBER (7)
LINENUMBER (12)
ALOAD (0)
INVOKESPECIAL (java/lang/Object, <init>, ()V)
RETURN
@@ -790,6 +790,8 @@ public abstract class Result : java/lang/Object {
public final static kotlin.Lazy access$get$cachedSerializer$delegate$cp()
public void def()
public final static void write$Self(Result self, kotlinx.serialization.encoding.CompositeEncoder output, kotlinx.serialization.descriptors.SerialDescriptor serialDesc) {
LABEL (L0)
ALOAD (0)
@@ -805,3 +807,86 @@ public abstract class Result : java/lang/Object {
LABEL (L1)
}
}
public final class X$Companion : java/lang/Object {
final static X$Companion $$INSTANCE
static void <clinit>() {
NEW (X$Companion)
DUP
INVOKESPECIAL (X$Companion, <init>, ()V)
PUTSTATIC (X$Companion, $$INSTANCE, LX$Companion;)
RETURN
}
private void <init>() {
LABEL (L0)
LINENUMBER (6)
ALOAD (0)
INVOKESPECIAL (java/lang/Object, <init>, ()V)
RETURN
LABEL (L1)
}
public final kotlinx.serialization.KSerializer serializer() {
LABEL (L0)
LINENUMBER (6)
NEW (kotlinx/serialization/SealedClassSerializer)
DUP
LDC (X)
LDC (LX;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, getOrCreateKotlinClass, (Ljava/lang/Class;)Lkotlin/reflect/KClass;)
ICONST_2
ANEWARRAY (kotlin/reflect/KClass)
ASTORE (1)
ALOAD (1)
ICONST_0
LDC (LResult$OK;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, getOrCreateKotlinClass, (Ljava/lang/Class;)Lkotlin/reflect/KClass;)
AASTORE
ALOAD (1)
ICONST_1
LDC (LResult$Err;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, getOrCreateKotlinClass, (Ljava/lang/Class;)Lkotlin/reflect/KClass;)
AASTORE
ALOAD (1)
ICONST_2
ANEWARRAY (kotlinx/serialization/KSerializer)
ASTORE (1)
ALOAD (1)
ICONST_0
GETSTATIC (Result$OK$$serializer, INSTANCE, LResult$OK$$serializer;)
CHECKCAST (kotlinx/serialization/KSerializer)
AASTORE
ALOAD (1)
ICONST_1
NEW (kotlinx/serialization/internal/ObjectSerializer)
DUP
LDC (Result.Err)
GETSTATIC (Result$Err, INSTANCE, LResult$Err;)
INVOKESPECIAL (kotlinx/serialization/internal/ObjectSerializer, <init>, (Ljava/lang/String;Ljava/lang/Object;)V)
CHECKCAST (kotlinx/serialization/KSerializer)
AASTORE
ALOAD (1)
INVOKESPECIAL (kotlinx/serialization/SealedClassSerializer, <init>, (Ljava/lang/String;Lkotlin/reflect/KClass;[Lkotlin/reflect/KClass;[Lkotlinx/serialization/KSerializer;)V)
CHECKCAST (kotlinx/serialization/KSerializer)
ARETURN
LABEL (L1)
}
}
public final class X$DefaultImpls : java/lang/Object {
public static void def(X this)
}
public abstract interface X : java/lang/Object {
public final static X$Companion Companion
static void <clinit>() {
GETSTATIC (X$Companion, $$INSTANCE, LX$Companion;)
PUTSTATIC (X, Companion, LX$Companion;)
RETURN
}
public abstract void def()
}
@@ -3,9 +3,14 @@
import kotlinx.serialization.*
@Serializable
sealed interface X {
fun def() {}
}
// do not forget to update this test with custom serialinfo annotation when serialization 1.3.0 is released
@Serializable
sealed class Result {
sealed class Result: X {
@Serializable class OK(val s: String): Result()
@Serializable object Err: Result()
}
@@ -5,7 +5,7 @@ public final class Container$$serializer : java/lang/Object, kotlinx/serializati
static void <clinit>() {
LABEL (L0)
LINENUMBER (14)
LINENUMBER (19)
NEW (Container$$serializer)
DUP
INVOKESPECIAL (Container$$serializer, <init>, ()V)
@@ -31,7 +31,7 @@ public final class Container$$serializer : java/lang/Object, kotlinx/serializati
private void <init>() {
LABEL (L0)
LINENUMBER (14)
LINENUMBER (19)
ALOAD (0)
INVOKESPECIAL (java/lang/Object, <init>, ()V)
RETURN
@@ -222,7 +222,7 @@ public final class Container$$serializer : java/lang/Object, kotlinx/serializati
public java.lang.Object deserialize(kotlinx.serialization.encoding.Decoder p0) {
LABEL (L0)
LINENUMBER (14)
LINENUMBER (19)
ALOAD (0)
ALOAD (1)
INVOKEVIRTUAL (Container$$serializer, deserialize, (Lkotlinx/serialization/encoding/Decoder;)LContainer;)
@@ -241,7 +241,7 @@ public final class Container$$serializer : java/lang/Object, kotlinx/serializati
public final class Container$Companion : java/lang/Object {
private void <init>() {
LABEL (L0)
LINENUMBER (14)
LINENUMBER (19)
ALOAD (0)
INVOKESPECIAL (java/lang/Object, <init>, ()V)
RETURN
@@ -250,7 +250,7 @@ public final class Container$Companion : java/lang/Object {
public void <init>(kotlin.jvm.internal.DefaultConstructorMarker $constructor_marker) {
LABEL (L0)
LINENUMBER (14)
LINENUMBER (19)
ALOAD (0)
INVOKESPECIAL (Container$Companion, <init>, ()V)
RETURN
@@ -286,7 +286,7 @@ public final class Container : java/lang/Object {
LDC (r)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNullParameter, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L1)
LINENUMBER (14)
LINENUMBER (19)
ALOAD (0)
INVOKESPECIAL (java/lang/Object, <init>, ()V)
ALOAD (0)
@@ -458,7 +458,7 @@ public final class Result$Companion : java/lang/Object {
private void <init>() {
LABEL (L0)
LINENUMBER (8)
LINENUMBER (13)
ALOAD (0)
INVOKESPECIAL (java/lang/Object, <init>, ()V)
RETURN
@@ -467,7 +467,7 @@ public final class Result$Companion : java/lang/Object {
public void <init>(kotlin.jvm.internal.DefaultConstructorMarker $constructor_marker) {
LABEL (L0)
LINENUMBER (8)
LINENUMBER (13)
ALOAD (0)
INVOKESPECIAL (Result$Companion, <init>, ()V)
RETURN
@@ -531,7 +531,7 @@ public final class Result$Err : Result {
static void <clinit>() {
LABEL (L0)
LINENUMBER (10)
LINENUMBER (15)
NEW (Result$Err)
DUP
INVOKESPECIAL (Result$Err, <init>, ()V)
@@ -548,11 +548,11 @@ public final class Result$Err : Result {
private void <init>() {
LABEL (L0)
LINENUMBER (10)
LINENUMBER (15)
ALOAD (0)
ACONST_NULL
LABEL (L1)
LINENUMBER (10)
LINENUMBER (15)
INVOKESPECIAL (Result, <init>, (Lkotlin/jvm/internal/DefaultConstructorMarker;)V)
RETURN
LABEL (L2)
@@ -575,7 +575,7 @@ public final class Result$OK$$serializer : java/lang/Object, kotlinx/serializati
static void <clinit>() {
LABEL (L0)
LINENUMBER (9)
LINENUMBER (14)
NEW (Result$OK$$serializer)
DUP
INVOKESPECIAL (Result$OK$$serializer, <init>, ()V)
@@ -601,7 +601,7 @@ public final class Result$OK$$serializer : java/lang/Object, kotlinx/serializati
private void <init>() {
LABEL (L0)
LINENUMBER (9)
LINENUMBER (14)
ALOAD (0)
INVOKESPECIAL (java/lang/Object, <init>, ()V)
RETURN
@@ -691,7 +691,7 @@ public final class Result$OK$$serializer : java/lang/Object, kotlinx/serializati
public java.lang.Object deserialize(kotlinx.serialization.encoding.Decoder p0) {
LABEL (L0)
LINENUMBER (9)
LINENUMBER (14)
ALOAD (0)
ALOAD (1)
INVOKEVIRTUAL (Result$OK$$serializer, deserialize, (Lkotlinx/serialization/encoding/Decoder;)LResult$OK;)
@@ -710,7 +710,7 @@ public final class Result$OK$$serializer : java/lang/Object, kotlinx/serializati
public final class Result$OK$Companion : java/lang/Object {
private void <init>() {
LABEL (L0)
LINENUMBER (9)
LINENUMBER (14)
ALOAD (0)
INVOKESPECIAL (java/lang/Object, <init>, ()V)
RETURN
@@ -719,7 +719,7 @@ public final class Result$OK$Companion : java/lang/Object {
public void <init>(kotlin.jvm.internal.DefaultConstructorMarker $constructor_marker) {
LABEL (L0)
LINENUMBER (9)
LINENUMBER (14)
ALOAD (0)
INVOKESPECIAL (Result$OK$Companion, <init>, ()V)
RETURN
@@ -755,7 +755,7 @@ public final class Result$OK : Result {
LDC (s)
INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNullParameter, (Ljava/lang/Object;Ljava/lang/String;)V)
LABEL (L1)
LINENUMBER (9)
LINENUMBER (14)
ALOAD (0)
ACONST_NULL
INVOKESPECIAL (Result, <init>, (Lkotlin/jvm/internal/DefaultConstructorMarker;)V)
@@ -819,7 +819,7 @@ public final class Result$OK : Result {
}
}
public abstract class Result : java/lang/Object {
public abstract class Result : java/lang/Object, X {
public final static Result$Companion Companion
static void <clinit>() {
@@ -833,7 +833,7 @@ public abstract class Result : java/lang/Object {
private void <init>() {
LABEL (L0)
LINENUMBER (8)
LINENUMBER (13)
ALOAD (0)
INVOKESPECIAL (java/lang/Object, <init>, ()V)
RETURN
@@ -842,7 +842,7 @@ public abstract class Result : java/lang/Object {
public void <init>(kotlin.jvm.internal.DefaultConstructorMarker $constructor_marker) {
LABEL (L0)
LINENUMBER (8)
LINENUMBER (13)
ALOAD (0)
INVOKESPECIAL (Result, <init>, ()V)
RETURN
@@ -857,6 +857,8 @@ public abstract class Result : java/lang/Object {
LABEL (L1)
}
public void def()
public final static void write$Self(Result self, kotlinx.serialization.encoding.CompositeEncoder output, kotlinx.serialization.descriptors.SerialDescriptor serialDesc) {
LABEL (L0)
ALOAD (0)
@@ -872,3 +874,83 @@ public abstract class Result : java/lang/Object {
LABEL (L1)
}
}
public final class X$Companion : java/lang/Object {
final static X$Companion $$INSTANCE
static void <clinit>() {
LABEL (L0)
LINENUMBER (7)
NEW (X$Companion)
DUP
INVOKESPECIAL (X$Companion, <init>, ()V)
ASTORE (0)
ALOAD (0)
PUTSTATIC (X$Companion, $$INSTANCE, LX$Companion;)
RETURN
}
private void <init>() {
LABEL (L0)
LINENUMBER (7)
ALOAD (0)
INVOKESPECIAL (java/lang/Object, <init>, ()V)
RETURN
LABEL (L1)
}
public final kotlinx.serialization.KSerializer serializer() {
LABEL (L0)
NEW (kotlinx/serialization/SealedClassSerializer)
DUP
LDC (X)
LDC (LX;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, getOrCreateKotlinClass, (Ljava/lang/Class;)Lkotlin/reflect/KClass;)
ICONST_2
ANEWARRAY (kotlin/reflect/KClass)
DUP
ICONST_0
LDC (LResult$OK;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, getOrCreateKotlinClass, (Ljava/lang/Class;)Lkotlin/reflect/KClass;)
AASTORE
DUP
ICONST_1
LDC (LResult$Err;)
INVOKESTATIC (kotlin/jvm/internal/Reflection, getOrCreateKotlinClass, (Ljava/lang/Class;)Lkotlin/reflect/KClass;)
AASTORE
ICONST_2
ANEWARRAY (kotlinx/serialization/KSerializer)
DUP
ICONST_0
GETSTATIC (Result$OK$$serializer, INSTANCE, LResult$OK$$serializer;)
CHECKCAST (kotlinx/serialization/KSerializer)
AASTORE
DUP
ICONST_1
NEW (kotlinx/serialization/internal/ObjectSerializer)
DUP
LDC (Result.Err)
GETSTATIC (Result$Err, INSTANCE, LResult$Err;)
INVOKESPECIAL (kotlinx/serialization/internal/ObjectSerializer, <init>, (Ljava/lang/String;Ljava/lang/Object;)V)
AASTORE
INVOKESPECIAL (kotlinx/serialization/SealedClassSerializer, <init>, (Ljava/lang/String;Lkotlin/reflect/KClass;[Lkotlin/reflect/KClass;[Lkotlinx/serialization/KSerializer;)V)
ARETURN
LABEL (L1)
}
}
public final class X$DefaultImpls : java/lang/Object {
public static void def(X $this)
}
public abstract interface X : java/lang/Object {
public final static X$Companion Companion
static void <clinit>() {
GETSTATIC (X$Companion, $$INSTANCE, LX$Companion;)
PUTSTATIC (X, Companion, LX$Companion;)
RETURN
}
public abstract void def()
}
@@ -1,7 +1,11 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER,-UNUSED_VARIABLE
// SKIP_TXT
// FILE: test.kt
import kotlinx.serialization.*
<!SERIALIZABLE_ANNOTATION_IGNORED!>@Serializable<!>
interface INonSerializable
@Serializable
sealed interface SealedSerializable
@@ -1,7 +0,0 @@
package
@kotlinx.serialization.Serializable public interface INonSerializable {
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
}