From 34efee5474ac6bb56af53487b75a20e35d54399b Mon Sep 17 00:00:00 2001 From: Leonid Startsev Date: Tue, 18 Apr 2023 18:11:58 +0200 Subject: [PATCH] Don't fail if there is no serializer for type parameters of contextual serializer Return null instead. Such behaviour is needed to support cachedChildSerializers logic. Since this field creator doesn't provide genericGetter (because it's static), type param serializer can't be retrieved, and the whole contextual serializer shouldn't be cached. #KT-58067 Fixed (cherry picked from commit fa8f38c2c8bacac4281da683afdaec93cdba408e) --- .../compiler/backend/ir/BaseIrGenerator.kt | 2 +- .../boxIr/contextualWithTypeParameters.kt | 44 +++++++++++++++++++ ...SerializationFirBlackBoxTestGenerated.java | 6 +++ .../SerializationIrBoxTestGenerated.java | 6 +++ 4 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 plugins/kotlinx-serialization/testData/boxIr/contextualWithTypeParameters.kt diff --git a/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/BaseIrGenerator.kt b/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/BaseIrGenerator.kt index 5b6b49c9cbcde..7d4faf6bd4331 100644 --- a/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/BaseIrGenerator.kt +++ b/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/BaseIrGenerator.kt @@ -497,7 +497,7 @@ abstract class BaseIrGenerator(private val currentClass: IrClass, final override compilerContext, it ) - instantiate(argSer, it)!! + instantiate(argSer, it) ?: return null }) ) } diff --git a/plugins/kotlinx-serialization/testData/boxIr/contextualWithTypeParameters.kt b/plugins/kotlinx-serialization/testData/boxIr/contextualWithTypeParameters.kt new file mode 100644 index 0000000000000..77dfb1e83a0a0 --- /dev/null +++ b/plugins/kotlinx-serialization/testData/boxIr/contextualWithTypeParameters.kt @@ -0,0 +1,44 @@ +// TARGET_BACKEND: JVM_IR + +// WITH_STDLIB + +import kotlinx.serialization.* +import kotlinx.serialization.json.* +import kotlinx.serialization.descriptors.* +import kotlinx.serialization.modules.* +import kotlinx.serialization.encoding.* + +class SomeData(val t: T) + +@Serializable +class PagedData( + @Contextual val someData: SomeData, +) + +class SomeDataSerializer(val tSer: KSerializer) : KSerializer> { + override val descriptor: SerialDescriptor = buildClassSerialDescriptor("SomeData") + + override fun serialize(encoder: Encoder, value: SomeData) { + encoder as JsonEncoder + val data = encoder.json.encodeToJsonElement(tSer, value.t) + val obj = buildJsonObject { + put("innerType", tSer.descriptor.serialName) + put("data", data) + } + encoder.encodeJsonElement(obj) + } + + override fun deserialize(decoder: Decoder): SomeData { + TODO("Not yet implemented") + } +} + +fun box(): String { + val module = SerializersModule { + contextual(SomeData::class) { args -> SomeDataSerializer(args[0]) } + } + val json = Json { serializersModule = module } + val input = PagedData(SomeData("foo_bar")) + val enc = json.encodeToString(input) + return if (enc != """{"someData":{"innerType":"kotlin.String","data":"foo_bar"}}""") enc else "OK" +} diff --git a/plugins/kotlinx-serialization/tests-gen/org/jetbrains/kotlinx/serialization/runners/SerializationFirBlackBoxTestGenerated.java b/plugins/kotlinx-serialization/tests-gen/org/jetbrains/kotlinx/serialization/runners/SerializationFirBlackBoxTestGenerated.java index 642f8429ea245..706f5753dda28 100644 --- a/plugins/kotlinx-serialization/tests-gen/org/jetbrains/kotlinx/serialization/runners/SerializationFirBlackBoxTestGenerated.java +++ b/plugins/kotlinx-serialization/tests-gen/org/jetbrains/kotlinx/serialization/runners/SerializationFirBlackBoxTestGenerated.java @@ -57,6 +57,12 @@ public void testContextualFallback() throws Exception { runTest("plugins/kotlinx-serialization/testData/boxIr/contextualFallback.kt"); } + @Test + @TestMetadata("contextualWithTypeParameters.kt") + public void testContextualWithTypeParameters() throws Exception { + runTest("plugins/kotlinx-serialization/testData/boxIr/contextualWithTypeParameters.kt"); + } + @Test @TestMetadata("delegatedInterface.kt") public void testDelegatedInterface() throws Exception { diff --git a/plugins/kotlinx-serialization/tests-gen/org/jetbrains/kotlinx/serialization/runners/SerializationIrBoxTestGenerated.java b/plugins/kotlinx-serialization/tests-gen/org/jetbrains/kotlinx/serialization/runners/SerializationIrBoxTestGenerated.java index 334c0a3f3b7e4..94e07699f0674 100644 --- a/plugins/kotlinx-serialization/tests-gen/org/jetbrains/kotlinx/serialization/runners/SerializationIrBoxTestGenerated.java +++ b/plugins/kotlinx-serialization/tests-gen/org/jetbrains/kotlinx/serialization/runners/SerializationIrBoxTestGenerated.java @@ -55,6 +55,12 @@ public void testContextualFallback() throws Exception { runTest("plugins/kotlinx-serialization/testData/boxIr/contextualFallback.kt"); } + @Test + @TestMetadata("contextualWithTypeParameters.kt") + public void testContextualWithTypeParameters() throws Exception { + runTest("plugins/kotlinx-serialization/testData/boxIr/contextualWithTypeParameters.kt"); + } + @Test @TestMetadata("delegatedInterface.kt") public void testDelegatedInterface() throws Exception {