[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
@@ -79,6 +79,9 @@ internal fun IrClass.findEnumLegacySerializer(): IrClass? {
internal val IrClass.isSealedSerializableInterface: Boolean
get() = kind == ClassKind.INTERFACE && modality == Modality.SEALED && hasSerializableOrMetaAnnotation()
internal val IrClass.isSerializableInterfaceWithCustom: Boolean
get() = kind == ClassKind.INTERFACE && hasSerializableAnnotationWithArgs()
internal fun IrClass.isInternallySerializableEnum(): Boolean =
kind == ClassKind.ENUM_CLASS && hasSerializableOrMetaAnnotationWithoutArgs()
@@ -93,6 +96,11 @@ internal fun IrClass.hasSerializableOrMetaAnnotationWithoutArgs(): Boolean = che
fun IrClass.hasSerializableOrMetaAnnotation() = checkSerializableOrMetaAnnotationArgs(mustDoNotHaveArgs = false)
private fun IrClass.hasSerializableAnnotationWithArgs(): Boolean {
val annot = getAnnotation(SerializationAnnotations.serializableAnnotationFqName)
return annot?.getValueArgument(0) != null
}
private fun IrClass.checkSerializableOrMetaAnnotationArgs(mustDoNotHaveArgs: Boolean): Boolean {
val annot = getAnnotation(SerializationAnnotations.serializableAnnotationFqName)
if (annot != null) { // @Serializable have higher priority
@@ -118,7 +126,7 @@ internal fun IrClass.shouldHaveGeneratedSerializer(): Boolean =
|| isEnumWithLegacyGeneratedSerializer()
internal val IrClass.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
internal fun IrClass.isSerializableEnum(): Boolean = kind == ClassKind.ENUM_CLASS && hasSerializableOrMetaAnnotation()
@@ -193,6 +201,7 @@ internal fun IrClass.needSerializerFactory(compilerContext: SerializationPluginC
if (serializableClass.isSerializableEnum()) return true
if (serializableClass.isAbstractOrSealedSerializableClass) return true
if (serializableClass.isSealedSerializableInterface) return true
if (serializableClass.isSerializableInterfaceWithCustom) return true
if (serializableClass.typeParameters.isEmpty()) return false
return true
}