[KxSerialization] Implemented generation of companions for interfaces

For interfaces with custom serializer (@Serializer(`SerializerType::class)`) now the `serializer()` function is generated in the companion so that user can get a serializer by type

Merge-request: KT-MR-11040
Merged-by: Sergey Shanshin <Sergey.Shanshin@jetbrains.com>
This commit is contained in:
Sergey.Shanshin
2023-07-17 19:44:01 +00:00
committed by Space Team
parent 38b55c659b
commit a45fe2d8a8
8 changed files with 157 additions and 2 deletions
@@ -113,7 +113,11 @@ val KotlinType?.toClassDescriptor: ClassDescriptor?
}
val ClassDescriptor.shouldHaveGeneratedMethodsInCompanion: Boolean
get() = this.isSerializableObject || this.isSerializableEnum() || (this.kind == ClassKind.CLASS && hasSerializableOrMetaAnnotation) || this.isSealedSerializableInterface
get() = this.isSerializableObject
|| this.isSerializableEnum()
|| (this.kind == ClassKind.CLASS && hasSerializableOrMetaAnnotation)
|| this.isSealedSerializableInterface
|| this.isSerializableInterfaceWithCustom
val ClassDescriptor.isSerializableObject: Boolean
get() = kind == ClassKind.OBJECT && hasSerializableOrMetaAnnotation
@@ -124,6 +128,9 @@ val ClassDescriptor.isInternallySerializableObject: Boolean
val ClassDescriptor.isSealedSerializableInterface: Boolean
get() = kind == ClassKind.INTERFACE && modality == Modality.SEALED && hasSerializableOrMetaAnnotation
val ClassDescriptor.isSerializableInterfaceWithCustom: Boolean
get() = kind == ClassKind.INTERFACE && hasSerializableAnnotationWithArgs
val ClassDescriptor.isAbstractOrSealedOrInterface: Boolean
get() = kind == ClassKind.INTERFACE || modality == Modality.SEALED || modality == Modality.ABSTRACT
@@ -196,6 +203,15 @@ private val ClassDescriptor.hasSerializableAnnotationWithoutArgs: Boolean
return psi.valueArguments.isEmpty()
}
private val ClassDescriptor.hasSerializableAnnotationWithArgs: Boolean
get() {
if (!hasSerializableAnnotation) return false
// If provided descriptor is lazy, carefully look at psi in order not to trigger full resolve which may be recursive.
// Otherwise, this descriptor is deserialized from another module, and it is OK to check value right away.
val psi = findSerializableAnnotationDeclaration() ?: return (serializableWith != null)
return psi.valueArguments.isNotEmpty()
}
private fun Annotated.findSerializableAnnotationDeclaration(): KtAnnotationEntry? {
val lazyDesc = annotations.findAnnotation(serializableAnnotationFqName) as? LazyAnnotationDescriptor
return lazyDesc?.annotationEntry
@@ -277,6 +293,7 @@ fun ClassDescriptor.needSerializerFactory(): Boolean {
if (serializableClass.isSerializableEnum()) return true
if (serializableClass.isAbstractOrSealedSerializableClass()) return true
if (serializableClass.isSealedSerializableInterface) return true
if (serializableClass.isSerializableInterfaceWithCustom) return true
if (serializableClass.declaredTypeParameters.isEmpty()) return false
return true
}