diff options
author | Sergey Shanshin <sergey.shanshin@jetbrains.com> | 2023-06-13 16:13:29 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-13 15:13:29 +0200 |
commit | 881e7a91e722fdaad180db298df807c597bb065c (patch) | |
tree | 651463b56aa6bcb423a504984fc93586bff23a53 | |
parent | 780f43ebb307bfc0bd7b3cc2ffaa8f91dd7a7f1f (diff) | |
download | kotlinx.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.kt | 8 | ||||
-rw-r--r-- | formats/json-tests/commonTest/src/kotlinx/serialization/SerializersLookupTest.kt | 38 |
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?>>>() |