Support situation when argument for serializer<T>() function has SerialInfo annotations.

Because SerializationJvmIrIntrinsicSupport does not instantiate annotations yet,
this info could be lost. As a workaround, it is possible to call Companion.serializer()
functions instead of direct serializer instantiation, as they are plugin-generated
and correctly handle annotations.

Note that for some cases (enums & interfaces) this WA is not enough, so additional work
is needed later.

Fixes https://github.com/Kotlin/kotlinx.serialization/issues/2179
This commit is contained in:
Leonid Startsev
2023-02-03 15:19:28 +01:00
committed by Space Team
parent 363330f904
commit e0dce31cde
6 changed files with 73 additions and 13 deletions
@@ -0,0 +1,40 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM_IR
// WITH_STDLIB
import kotlinx.serialization.*
import kotlinx.serialization.json.*
import kotlinx.serialization.internal.*
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.modules.*
import kotlin.test.*
@Serializable
@JsonClassDiscriminator("sealed")
sealed class Sealed
@Serializable
@JsonClassDiscriminator("abstract")
abstract class Abstract
@Serializable
@JsonClassDiscriminator("object")
object Object
fun test(descriptor: SerialDescriptor, value: String, name: String = descriptor.serialName) {
val anno = descriptor.annotations.filterIsInstance<JsonClassDiscriminator>().singleOrNull()
requireNotNull(anno) { "Annotation value not found for $name" }
assertEquals(anno.discriminator, value, "Annotation value incorrect for $name")
}
fun box(): String {
test(serializer<Sealed>().descriptor, "sealed")
test(serializer<Abstract>().descriptor, "abstract")
test(serializer<Object>().descriptor, "object")
test(serializer<List<Sealed>>().descriptor.getElementDescriptor(0), "sealed", "List<Sealed>")
test(serializer<List<Abstract>>().descriptor.getElementDescriptor(0), "abstract", "List<Abstract>")
test(serializer<List<Object>>().descriptor.getElementDescriptor(0), "object", "List<Object>")
test(serializer<Array<Sealed>>().descriptor.getElementDescriptor(0), "sealed", "Array<Sealed>")
return "OK"
}
@@ -127,7 +127,8 @@ public final class IntrinsicsKt : java/lang/Object {
GETSTATIC (Box, Companion, LBox$Companion;)
NEW (kotlinx/serialization/internal/ArrayListSerializer)
DUP
GETSTATIC (Simple$$serializer, INSTANCE, LSimple$$serializer;)
GETSTATIC (Simple, Companion, LSimple$Companion;)
INVOKEVIRTUAL (Simple$Companion, serializer, ()Lkotlinx/serialization/KSerializer;)
INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
INVOKEVIRTUAL (Box$Companion, serializer, (Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer;)
POP
@@ -142,7 +143,8 @@ public final class IntrinsicsKt : java/lang/Object {
GETSTATIC (Box, Companion, LBox$Companion;)
NEW (kotlinx/serialization/internal/ArrayListSerializer)
DUP
GETSTATIC (Simple$$serializer, INSTANCE, LSimple$$serializer;)
GETSTATIC (Simple, Companion, LSimple$Companion;)
INVOKEVIRTUAL (Simple$Companion, serializer, ()Lkotlinx/serialization/KSerializer;)
INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
INVOKEVIRTUAL (Box$Companion, serializer, (Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer;)
INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
@@ -167,10 +169,9 @@ public final class IntrinsicsKt : java/lang/Object {
DUP
NEW (kotlinx/serialization/internal/ArrayListSerializer)
DUP
NEW (Box$$serializer)
DUP
GETSTATIC (Box, Companion, LBox$Companion;)
GETSTATIC (kotlinx/serialization/internal/IntSerializer, INSTANCE, Lkotlinx/serialization/internal/IntSerializer;)
INVOKESPECIAL (Box$$serializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
INVOKEVIRTUAL (Box$Companion, serializer, (Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer;)
INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
LABEL (L21)
@@ -50,7 +50,8 @@ public final class IntrinsicsAdvancedKt : java/lang/Object {
POP
NEW (kotlinx/serialization/internal/ArrayListSerializer)
DUP
GETSTATIC (Simple$$serializer, INSTANCE, LSimple$$serializer;)
GETSTATIC (Simple, Companion, LSimple$Companion;)
INVOKEVIRTUAL (Simple$Companion, serializer, ()Lkotlinx/serialization/KSerializer;)
INVOKESPECIAL (kotlinx/serialization/internal/ArrayListSerializer, <init>, (Lkotlinx/serialization/KSerializer;)V)
POP
LABEL (L3)
@@ -109,7 +110,8 @@ public final class IntrinsicsAdvancedKt : java/lang/Object {
ANEWARRAY (kotlinx/serialization/KSerializer)
DUP
ICONST_0
GETSTATIC (Simple$$serializer, INSTANCE, LSimple$$serializer;)
GETSTATIC (Simple, Companion, LSimple$Companion;)
INVOKEVIRTUAL (Simple$Companion, serializer, ()Lkotlinx/serialization/KSerializer;)
AASTORE
INVOKESTATIC (kotlinx/serialization/SerializersKt, noCompiledSerializer, (Lkotlinx/serialization/modules/SerializersModule;Lkotlin/reflect/KClass;[Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer;)
LABEL (L15)