[FIR] Don't lose non-serializable properties during metadata deserialization

^KT-57941 Fixed
This commit is contained in:
Dmitriy Novozhilov
2023-04-12 13:37:07 +03:00
committed by Space Team
parent 37bbf447a3
commit b253a3a47e
4 changed files with 22 additions and 3 deletions
@@ -327,10 +327,15 @@ private fun ProtoBuf.ClassOrBuilder.propertiesInOrder(context: FirDeserializatio
if (versionRequirements.any { it.version.major >= 2 }) return properties
val order = getExtension(SerializationPluginMetadataExtensions.propertiesNamesInProgramOrder)
.takeIf { it.isNotEmpty() }
?.toSet()
?: return properties
val propertiesByName = properties.groupBy { it.name }
return order.flatMap { propertiesByName[it] ?: emptyList() }.also {
assert(it.size == properties.size)
val orderedProperties = order.flatMap { propertiesByName[it] ?: emptyList() }
// non-serializable properties are not saved in SerializationPluginMetadataExtensions, so we need to pick up them if any
return if (orderedProperties.size == properties.size) {
orderedProperties
} else {
orderedProperties + properties.filter { it.name !in order }
}
}
@@ -23,7 +23,7 @@ class K2KotlinxSerializationIT : KGPBaseTest() {
}
}
@DisplayName("Compile code with kotlinx.serialization with K2 against K1")
@DisplayName("Compile code with kotlinx.serialization with K2 against K1. KT-57941")
@GradleTest
fun `test kotlinx serialization K2 against K1`() {
project("kotlinxSerializationK2AgainstK1", gradleVersion) {
@@ -19,6 +19,12 @@ class Derived(val d: Long = 1000000000000) : Base(2, "world", listOf("b", "c"))
}
}
fun processAbstractBase(abstractBase: AbstractBase) {
println(abstractBase.x)
println(abstractBase.y)
println(abstractBase.nonSerializableProp)
}
fun main() {
val expected = Derived(12)
val result = Json.encodeToString(Derived.serializer(), expected)
@@ -12,3 +12,11 @@ open class Base(
val b: String = "hello",
val a: List<String> = listOf("a")
)
@Serializable
abstract class AbstractBase(
val x: Int = 1,
val y: Int = 2
) {
abstract val nonSerializableProp: String
}