Add support of nullable serializers to UseSerializers annotation (#3898)

Fixes https://github.com/Kotlin/kotlinx.serialization/issues/984
This commit is contained in:
Sergey Shanshin
2020-11-10 19:42:02 +03:00
committed by GitHub
parent 66f5c98505
commit 202459531d
2 changed files with 9 additions and 6 deletions
@@ -46,11 +46,11 @@ abstract class AbstractSerialGenerator(val bindingContext: BindingContext, val c
).toSet() ).toSet()
} }
val additionalSerializersInScopeOfCurrentFile: Map<ClassDescriptor, ClassDescriptor> by lazy { val additionalSerializersInScopeOfCurrentFile: Map<KotlinType, ClassDescriptor> by lazy {
getKClassListFromFileAnnotation(SerializationAnnotations.additionalSerializersFqName, currentDeclaration) getKClassListFromFileAnnotation(SerializationAnnotations.additionalSerializersFqName, currentDeclaration)
.associateBy( .associateBy(
{ {
it.supertypes().find(::isKSerializer)?.arguments?.firstOrNull()?.type.toClassDescriptor it.supertypes().find(::isKSerializer)?.arguments?.firstOrNull()?.type
?: throw AssertionError("Argument for ${SerializationAnnotations.additionalSerializersFqName} does not implement KSerializer or does not provide serializer for concrete type") ?: throw AssertionError("Argument for ${SerializationAnnotations.additionalSerializersFqName} does not implement KSerializer or does not provide serializer for concrete type")
}, },
{ it.toClassDescriptor!! } { it.toClassDescriptor!! }
@@ -34,7 +34,7 @@ open class SerialTypeInfo(
) )
fun AbstractSerialGenerator.findAddOnSerializer(propertyType: KotlinType, module: ModuleDescriptor): ClassDescriptor? { fun AbstractSerialGenerator.findAddOnSerializer(propertyType: KotlinType, module: ModuleDescriptor): ClassDescriptor? {
additionalSerializersInScopeOfCurrentFile[propertyType.toClassDescriptor]?.let { return it } additionalSerializersInScopeOfCurrentFile[propertyType]?.let { return it }
if (propertyType in contextualKClassListInCurrentFile) if (propertyType in contextualKClassListInCurrentFile)
return module.getClassFromSerializationPackage(SpecialBuiltins.contextSerializer) return module.getClassFromSerializationPackage(SpecialBuiltins.contextSerializer)
if (propertyType.toClassDescriptor?.annotations?.hasAnnotation(SerializationAnnotations.polymorphicFqName) == true) if (propertyType.toClassDescriptor?.annotations?.hasAnnotation(SerializationAnnotations.polymorphicFqName) == true)
@@ -123,9 +123,12 @@ fun AbstractSerialGenerator.findTypeSerializerOrContextUnchecked(
): ClassDescriptor? { ): ClassDescriptor? {
val annotations = kType.annotations val annotations = kType.annotations
if (kType.isTypeParameter()) return null if (kType.isTypeParameter()) return null
if (kType.isMarkedNullable) return findTypeSerializerOrContextUnchecked(module, kType.makeNotNullable())
annotations.serializableWith(module)?.let { return it.toClassDescriptor } annotations.serializableWith(module)?.let { return it.toClassDescriptor }
additionalSerializersInScopeOfCurrentFile[kType.toClassDescriptor]?.let { return it } additionalSerializersInScopeOfCurrentFile[kType]?.let { return it }
if (!kType.isMarkedNullable) {
additionalSerializersInScopeOfCurrentFile[kType.makeNullable()]?.let { return it }
}
if (kType in contextualKClassListInCurrentFile) return module.getClassFromSerializationPackage(SpecialBuiltins.contextSerializer) if (kType in contextualKClassListInCurrentFile) return module.getClassFromSerializationPackage(SpecialBuiltins.contextSerializer)
return analyzeSpecialSerializers(module, annotations) ?: findTypeSerializer(module, kType) return analyzeSpecialSerializers(module, annotations) ?: findTypeSerializer(module, kType)
} }