Added support of named companion in serializable class to the FIR

Merge-request: KT-MR-7472
This commit is contained in:
Sergey.Shanshin
2022-10-27 12:48:29 +00:00
committed by Space Team
parent 8d8d0d9922
commit d4cfb002d0
10 changed files with 237 additions and 55 deletions
@@ -61,7 +61,7 @@ class SerializationFirResolveExtension(session: FirSession) : FirDeclarationGene
with(session) {
if (classSymbol.shouldHaveGeneratedMethodsInCompanion && !classSymbol.isSerializableObject)
result += SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT
if (classSymbol.shouldHaveGeneratedSerializer && !classSymbol.hasCompanionObjectAsSerializer)
if (classSymbol.shouldHaveGeneratedSerializer && !classSymbol.isInternallySerializableObject)
result += SerialEntityNames.SERIALIZER_CLASS_NAME
}
@@ -85,12 +85,14 @@ class SerializationFirResolveExtension(session: FirSession) : FirDeclarationGene
val classId = classSymbol.classId
val result = mutableSetOf<Name>()
val origin = classSymbol.origin as? FirDeclarationOrigin.Plugin
val isExternalSerializer = classSymbol.isExternalSerializer
when {
classSymbol.isCompanion && origin?.key == SerializationPluginKey -> {
result += SpecialNames.INIT
classSymbol.isCompanion && !isExternalSerializer -> {
result += SerialEntityNames.SERIALIZER_PROVIDER_NAME
val origin = classSymbol.origin as? FirDeclarationOrigin.Plugin
if (origin?.key == SerializationPluginKey) {
result += SpecialNames.INIT
}
}
classId.shortClassName == SerialEntityNames.SERIALIZER_CLASS_NAME -> {
@@ -110,7 +112,7 @@ class SerializationFirResolveExtension(session: FirSession) : FirDeclarationGene
}
}
classSymbol.isExternalSerializer -> {
isExternalSerializer -> {
if (classSymbol.declarationSymbols.filterIsInstance<FirPropertySymbol>()
.none { it.name == SerialEntityNames.SERIAL_DESC_FIELD_NAME }
) {
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlinx.serialization.compiler.fir.services.dependencySerializationInfoProvider
@@ -99,11 +98,6 @@ internal val FirClassSymbol<*>.serializerForClass: ConeKotlinType?
.getAnnotationByClassId(SerializationAnnotations.serializerAnnotationClassId)
?.getKClassArgument(AnnotationParameterNames.FOR_CLASS)
internal val FirClassSymbol<*>.serializerFor: FirGetClassCall?
get() = resolvedAnnotationsWithArguments
.getAnnotationByClassId(SerializationAnnotations.serializerAnnotationClassId)
?.getGetKClassArgument(AnnotationParameterNames.FOR_CLASS)
internal val FirClassLikeDeclaration.serializerFor: FirGetClassCall?
get() = getAnnotationByClassId(SerializationAnnotations.serializerAnnotationClassId)
?.getGetKClassArgument(AnnotationParameterNames.FOR_CLASS)
@@ -164,31 +158,12 @@ context(FirSession)
internal val FirClassSymbol<*>.isSerializableEnum: Boolean
get() = classKind.isEnumClass && hasSerializableOrMetaAnnotation
/**
* Check that class is enum and marked by `Serializable` annotation without serializer argument or meta-serializable annotation.
*/
context(FirSession)
@Suppress("IncorrectFormatting") // KTIJ-22227
internal val FirClassSymbol<*>.isSerializableEnumWithoutArgs: Boolean
get() = classKind.isEnumClass && hasSerializableOrMetaAnnotationWithoutArgs
internal fun FirClassSymbol<*>.isFinalOrOpen(): Boolean {
val modality = rawStatus.modality
// null means default modality, final
return (modality == null || modality == Modality.FINAL || modality == Modality.OPEN)
}
context(FirSession)
@Suppress("IncorrectFormatting") // KTIJ-22227
val FirClassSymbol<*>.hasCompanionObjectAsSerializer: Boolean
get() = isInternallySerializableObject || hasCustomSerializerOnCompanion
context(FirSession)
@Suppress("IncorrectFormatting") // KTIJ-22227
val FirClassSymbol<*>.hasCustomSerializerOnCompanion: Boolean
// TODO It was accepted that the annotation on the companion can take only the current class as an argument. Before the release of FIR, we need to add a new annotation and check gere for its presence
get() = (this as? FirRegularClassSymbol)?.companionObjectSymbol?.serializerFor != null
context(FirSession)
val FirClassSymbol<*>.isEnumWithLegacyGeneratedSerializer: Boolean
get() = classKind.isEnumClass && dependencySerializationInfoProvider.useGeneratedEnumSerializer && hasSerializableOrMetaAnnotationWithoutArgs
@@ -197,12 +172,6 @@ context(FirSession)
val FirClassSymbol<*>.shouldHaveGeneratedSerializer: Boolean
get() = (isInternalSerializable && isFinalOrOpen()) || isEnumWithLegacyGeneratedSerializer
context(FirSession)
@Suppress("IncorrectFormatting") // KTIJ-22227
internal fun FirClassSymbol<*>.shouldHaveGeneratedSerializer(useGeneratedEnumSerializer: Boolean): Boolean {
return (isInternalSerializable && isFinalOrOpen()) || (useGeneratedEnumSerializer && isSerializableEnumWithoutArgs)
}
// ---------------------- type utils ----------------------
val ConeKotlinType.isKSerializer: Boolean
@@ -352,7 +352,7 @@ object FirSerializationPluginClassChecker : FirClassChecker() {
with(session) {
if (!classSymbol.hasSerializableOrMetaAnnotation) return null
if (!classSymbol.isInternalSerializable) return null
if (classSymbol.hasCompanionObjectAsSerializer) return null
if (classSymbol.isInternallySerializableObject) return null
}
val properties = session.serializablePropertiesProvider.getSerializablePropertiesForClass(classSymbol)
@@ -48,7 +48,7 @@ internal val FirClassSymbol<*>?.classSerializer: FirClassSymbol<*>?
// serializer annotation on class?
serializableWith?.let { return it.toRegularClassSymbol(session) }
// companion object serializer?
if (this is FirRegularClassSymbol && with(session) { hasCompanionObjectAsSerializer }) return companionObjectSymbol
if (this is FirRegularClassSymbol && with(session) { isInternallySerializableObject }) return companionObjectSymbol
// can infer @Poly?
polymorphicSerializerIfApplicableAutomatically?.let { return it }
// default serializable?
@@ -147,7 +147,7 @@ internal val FirClassSymbol<*>.serializableAnnotationIsUseless: Boolean
get() = !classKind.isEnumClass &&
hasSerializableOrMetaAnnotationWithoutArgs &&
!isInternalSerializable &&
!hasCompanionObjectAsSerializer &&
!isInternallySerializableObject &&
!isSealedSerializableInterface
// ---------------------- type utils ----------------------