summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Shanshin <sergey.shanshin@jetbrains.com>2023-06-13 16:13:29 +0300
committerGitHub <noreply@github.com>2023-06-13 15:13:29 +0200
commit881e7a91e722fdaad180db298df807c597bb065c (patch)
tree651463b56aa6bcb423a504984fc93586bff23a53
parent780f43ebb307bfc0bd7b3cc2ffaa8f91dd7a7f1f (diff)
downloadkotlinx.serialization-881e7a91e722fdaad180db298df807c597bb065c.tar.gz
Fixed regression with serialization using list parametrized with contextual types (#2331)
Fixes #2323 In the current implementation of serializer lookup caching, if the serializer for the parameter was not found, the `serializerOrNull` function always returned null, without further searching for contextual serializers in the current SerializersModule.
-rw-r--r--core/commonMain/src/kotlinx/serialization/Serializers.kt8
-rw-r--r--formats/json-tests/commonTest/src/kotlinx/serialization/SerializersLookupTest.kt38
2 files changed, 39 insertions, 7 deletions
diff --git a/core/commonMain/src/kotlinx/serialization/Serializers.kt b/core/commonMain/src/kotlinx/serialization/Serializers.kt
index 2880dd58..6def5304 100644
--- a/core/commonMain/src/kotlinx/serialization/Serializers.kt
+++ b/core/commonMain/src/kotlinx/serialization/Serializers.kt
@@ -193,13 +193,7 @@ private fun SerializersModule.serializerByKTypeImpl(
val cachedSerializer = if (typeArguments.isEmpty()) {
findCachedSerializer(rootClass, isNullable)
} else {
- val cachedResult = findParametrizedCachedSerializer(rootClass, typeArguments, isNullable)
- if (failOnMissingTypeArgSerializer) {
- cachedResult.getOrNull()
- } else {
- // return null if error occurred - serializer for parameter(s) was not found
- cachedResult.getOrElse { return null }
- }
+ findParametrizedCachedSerializer(rootClass, typeArguments, isNullable).getOrNull()
}
cachedSerializer?.let { return it }
diff --git a/formats/json-tests/commonTest/src/kotlinx/serialization/SerializersLookupTest.kt b/formats/json-tests/commonTest/src/kotlinx/serialization/SerializersLookupTest.kt
index 89e53a7a..3d95019f 100644
--- a/formats/json-tests/commonTest/src/kotlinx/serialization/SerializersLookupTest.kt
+++ b/formats/json-tests/commonTest/src/kotlinx/serialization/SerializersLookupTest.kt
@@ -59,6 +59,7 @@ class SerializersLookupTest : JsonTestBase() {
assertSame(UInt.serializer(), serializer<UInt>())
assertSame(ULong.serializer(), serializer<ULong>())
}
+
@Test
@OptIn(ExperimentalUnsignedTypes::class)
fun testUnsignedArrays() {
@@ -210,6 +211,24 @@ class SerializersLookupTest : JsonTestBase() {
}
}
+ class GenericHolder<T>(value: T)
+
+ class GenericSerializer<T>(typeSerializer: KSerializer<T>) : KSerializer<GenericHolder<T>> {
+ override val descriptor: SerialDescriptor =
+ PrimitiveSerialDescriptor(
+ "Generic Serializer parametrized by ${typeSerializer.descriptor}",
+ PrimitiveKind.STRING
+ )
+
+ override fun deserialize(decoder: Decoder): GenericHolder<T> {
+ TODO()
+ }
+
+ override fun serialize(encoder: Encoder, value: GenericHolder<T>) {
+ TODO()
+ }
+ }
+
@Test
fun testContextualLookup() {
val module = SerializersModule { contextual(CustomIntSerializer(false).cast<IntBox>()) }
@@ -219,6 +238,25 @@ class SerializersLookupTest : JsonTestBase() {
}
@Test
+ fun testGenericOfContextual() {
+ val module = SerializersModule {
+ contextual(CustomIntSerializer(false).cast<IntBox>())
+ contextual(GenericHolder::class) { args -> GenericSerializer(args[0]) }
+ }
+
+ val listSerializer = module.serializerOrNull(typeOf<List<IntBox>>())
+ assertNotNull(listSerializer)
+ assertEquals("kotlin.collections.ArrayList(PrimitiveDescriptor(CIS))", listSerializer.descriptor.toString())
+
+ val genericSerializer = module.serializerOrNull(typeOf<GenericHolder<IntBox>>())
+ assertNotNull(genericSerializer)
+ assertEquals(
+ "PrimitiveDescriptor(Generic Serializer parametrized by PrimitiveDescriptor(CIS))",
+ genericSerializer.descriptor.toString()
+ )
+ }
+
+ @Test
fun testContextualLookupNullable() {
val module = SerializersModule { contextual(CustomIntSerializer(true).cast<IntBox>()) }
val serializer = module.serializer<List<List<IntBox?>>>()