From dc0cd61b6f60b1272514cb6585e7b75974fe02a9 Mon Sep 17 00:00:00 2001 From: Leonid Startsev Date: Tue, 17 Jan 2023 17:04:20 +0100 Subject: [PATCH] Handle @Serializable classes that implement interfaces by delegation by filtering out delegated properties that end up in irClass.properties() list Fixes https://github.com/Kotlin/kotlinx.serialization/issues/2157 --- .../backend/ir/IrSerializableProperties.kt | 5 ++-- .../testData/boxIr/delegatedInterface.kt | 23 +++++++++++++++++++ ...SerializationFirBlackBoxTestGenerated.java | 6 +++++ .../SerializationIrBoxTestGenerated.java | 6 +++++ 4 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 plugins/kotlinx-serialization/testData/boxIr/delegatedInterface.kt diff --git a/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/IrSerializableProperties.kt b/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/IrSerializableProperties.kt index d5abb7f5c7f..92a5f11fd91 100644 --- a/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/IrSerializableProperties.kt +++ b/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/IrSerializableProperties.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -8,6 +8,7 @@ package org.jetbrains.kotlinx.serialization.compiler.backend.ir import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrProperty import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.util.* @@ -78,7 +79,7 @@ internal fun serializablePropertiesForIrBackend( val (primaryCtorSerializableProps, bodySerializableProps) = properties .asSequence() - .filter { !it.isFakeOverride && !it.isDelegated } + .filter { !it.isFakeOverride && !it.isDelegated && it.origin != IrDeclarationOrigin.DELEGATED_MEMBER } .filter(::isPropSerializable) .map { val isConstructorParameterWithDefault = primaryParamsAsProps[it] ?: false diff --git a/plugins/kotlinx-serialization/testData/boxIr/delegatedInterface.kt b/plugins/kotlinx-serialization/testData/boxIr/delegatedInterface.kt new file mode 100644 index 00000000000..8dcae4cb674 --- /dev/null +++ b/plugins/kotlinx-serialization/testData/boxIr/delegatedInterface.kt @@ -0,0 +1,23 @@ +// TARGET_BACKEND: JVM_IR + +// WITH_STDLIB + +import kotlinx.serialization.* +import kotlinx.serialization.descriptors.* +import kotlinx.serialization.encoding.* +import kotlinx.serialization.json.* + +@Serializable() +class Dto( + val data: Map +) : Map by data + +fun box(): String { + val dto = Dto(mapOf(1 to 2)) + val s = Json.encodeToString(dto) + if (s != """{"data":{"1":2}}""") return s + val d = Json.decodeFromString(s) + if (d.size != 1) return "Delegation to Map failed" + if (d.data != dto.data) return "Equals failed ${d.data}" + return "OK" +} \ No newline at end of file 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 e8be4b91a2e..ce5e787241f 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 class SerializationFirBlackBoxTestGenerated extends AbstractSerialization runTest("plugins/kotlinx-serialization/testData/boxIr/contextualFallback.kt"); } + @Test + @TestMetadata("delegatedInterface.kt") + public void testDelegatedInterface() throws Exception { + runTest("plugins/kotlinx-serialization/testData/boxIr/delegatedInterface.kt"); + } + @Test @TestMetadata("enumsAreCached.kt") public void testEnumsAreCached() 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 bce8b071d53..ee802f07f1b 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("delegatedInterface.kt") + public void testDelegatedInterface() throws Exception { + runTest("plugins/kotlinx-serialization/testData/boxIr/delegatedInterface.kt"); + } + @Test @TestMetadata("enumsAreCached.kt") public void testEnumsAreCached() throws Exception {