[kxSerialization] Added diagnostic on useless Serializer annotation

Resolves Kotlin/kotlinx.serialization#2182

Merge-request: KT-MR-8718
Merged-by: Sergey Shanshin <Sergey.Shanshin@jetbrains.com>
This commit is contained in:
Sergey.Shanshin
2023-02-14 22:00:33 +00:00
committed by Space Team
parent 3124154aef
commit c9b8160f1e
10 changed files with 93 additions and 4 deletions
@@ -47,6 +47,7 @@ object FirSerializationErrors {
val INCONSISTENT_INHERITABLE_SERIALINFO by error2<PsiElement, ConeKotlinType, ConeKotlinType>()
val META_SERIALIZABLE_NOT_APPLICABLE by error0<PsiElement>()
val EXTERNAL_SERIALIZER_USELESS by warning1<PsiElement, FirClassSymbol<*>>()
val EXTERNAL_CLASS_NOT_SERIALIZABLE by error2<PsiElement, FirClassSymbol<*>, ConeKotlinType>()
val EXTERNAL_CLASS_IN_ANOTHER_MODULE by error2<PsiElement, FirClassSymbol<*>, ConeKotlinType>()
@@ -26,11 +26,13 @@ import org.jetbrains.kotlin.resolve.jvm.annotations.TRANSIENT_ANNOTATION_CLASS_I
import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlinx.serialization.compiler.diagnostic.RuntimeVersions
import org.jetbrains.kotlinx.serialization.compiler.fir.*
import org.jetbrains.kotlinx.serialization.compiler.fir.checkers.FirSerializationErrors.EXTERNAL_SERIALIZER_USELESS
import org.jetbrains.kotlinx.serialization.compiler.fir.getSerializerForClass
import org.jetbrains.kotlinx.serialization.compiler.fir.services.dependencySerializationInfoProvider
import org.jetbrains.kotlinx.serialization.compiler.fir.services.findTypeSerializerOrContextUnchecked
import org.jetbrains.kotlinx.serialization.compiler.fir.services.serializablePropertiesProvider
import org.jetbrains.kotlinx.serialization.compiler.fir.services.versionReader
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationAnnotations
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializersClassIds
@@ -74,6 +76,32 @@ object FirSerializationPluginClassChecker : FirClassChecker() {
private fun checkExternalSerializer(classSymbol: FirClassSymbol<*>, reporter: DiagnosticReporter) {
val serializableKType = classSymbol.getSerializerForClass(session) ?: return
val serializableClassSymbol = serializableKType.toRegularClassSymbol(session) ?: return
val declarations = classSymbol.declarationSymbols
val descriptorOverridden = declarations.filterIsInstance<FirPropertySymbol>().singleOrNull {
it.name == SerialEntityNames.SERIAL_DESC_FIELD_NAME
&& it.isOverride
&& it.origin == FirDeclarationOrigin.Source
} != null
val serializeOverridden = declarations.filterIsInstance<FirFunctionSymbol<*>>().singleOrNull {
it.name == SerialEntityNames.SAVE_NAME
&& it.valueParameterSymbols.size == 2
&& it.isOverride
&& it.origin == FirDeclarationOrigin.Source
} != null
val deserializeOverridden = declarations.filterIsInstance<FirFunctionSymbol<*>>().singleOrNull {
it.name == SerialEntityNames.LOAD_NAME
&& it.valueParameterSymbols.size == 1
&& it.isOverride
&& it.origin == FirDeclarationOrigin.Source
} != null
if (descriptorOverridden && serializeOverridden && deserializeOverridden) {
val source = classSymbol.getSerializerAnnotation(session)?.source ?: classSymbol.source
reporter.reportOn(source, EXTERNAL_SERIALIZER_USELESS, classSymbol)
return
}
val properties = session.serializablePropertiesProvider.getSerializablePropertiesForClass(serializableClassSymbol)
if (!properties.isExternallySerializable) {
val source = classSymbol.getSerializerAnnotation(session)?.source ?: classSymbol.source
@@ -156,6 +156,12 @@ object KtDefaultErrorMessagesSerialization : BaseDiagnosticRendererFactory() {
"@MetaSerializable annotation can be used only on top-level annotation classes."
)
put(
FirSerializationErrors.EXTERNAL_SERIALIZER_USELESS,
"@Serializer annotation has no effect on class ''{0}'', because all members of KSerializer are already overridden",
FirDiagnosticRenderers.SYMBOL,
)
put(
FirSerializationErrors.EXTERNAL_CLASS_NOT_SERIALIZABLE,
"Cannot generate external serializer ''{0}'': class ''{1}'' have constructor parameters which are not properties and therefore it is not serializable automatically",