From fa8f38c2c8bacac4281da683afdaec93cdba408e 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 --- .../compiler/backend/ir/BaseIrGenerator.kt | 2 +- .../boxIr/contextualWithTypeParameters.kt | 44 +++++++++++++++++++ ...tionFirLightTreeBlackBoxTestGenerated.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 47b4fdb8821..e52ab68aa53 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 @@ -519,7 +519,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 00000000000..77dfb1e83a0 --- /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/SerializationFirLightTreeBlackBoxTestGenerated.java b/plugins/kotlinx-serialization/tests-gen/org/jetbrains/kotlinx/serialization/runners/SerializationFirLightTreeBlackBoxTestGenerated.java index b88db08cbca..0d9fe0da0a0 100644 --- a/plugins/kotlinx-serialization/tests-gen/org/jetbrains/kotlinx/serialization/runners/SerializationFirLightTreeBlackBoxTestGenerated.java +++ b/plugins/kotlinx-serialization/tests-gen/org/jetbrains/kotlinx/serialization/runners/SerializationFirLightTreeBlackBoxTestGenerated.java @@ -57,6 +57,12 @@ public class SerializationFirLightTreeBlackBoxTestGenerated extends AbstractSeri 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 5dd4777432a..2d2fa527aaf 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 class SerializationIrBoxTestGenerated extends AbstractSerializationIrBoxT 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 {