[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:
committed by
Space Team
parent
3124154aef
commit
c9b8160f1e
+2
@@ -54,6 +54,8 @@ public interface SerializationErrors {
|
||||
DiagnosticFactory2<PsiElement, KotlinType, KotlinType> INCONSISTENT_INHERITABLE_SERIALINFO = DiagnosticFactory2.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> META_SERIALIZABLE_NOT_APPLICABLE = DiagnosticFactory0.create(WARNING);
|
||||
|
||||
DiagnosticFactory1<PsiElement, KotlinType> EXTERNAL_SERIALIZER_USELESS = DiagnosticFactory1.create(WARNING);
|
||||
|
||||
DiagnosticFactory2<PsiElement, KotlinType, KotlinType> EXTERNAL_CLASS_NOT_SERIALIZABLE = DiagnosticFactory2.create(ERROR);
|
||||
DiagnosticFactory2<PsiElement, KotlinType, KotlinType> EXTERNAL_CLASS_IN_ANOTHER_MODULE = DiagnosticFactory2.create(ERROR);
|
||||
|
||||
|
||||
+30
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.JvmNames.TRANSIENT_ANNOTATION_FQ_NAME
|
||||
@@ -30,7 +31,11 @@ import org.jetbrains.kotlin.util.slicedMap.WritableSlice
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.*
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.bodyPropertiesDescriptorsMap
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.primaryConstructorPropertiesDescriptorsMap
|
||||
import org.jetbrains.kotlinx.serialization.compiler.diagnostic.SerializationErrors.EXTERNAL_SERIALIZER_USELESS
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.LOAD_NAME
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.SAVE_NAME
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.SERIAL_DESC_FIELD_NAME
|
||||
|
||||
val SERIALIZABLE_PROPERTIES: WritableSlice<ClassDescriptor, SerializableProperties> = Slices.createSimpleSlice()
|
||||
|
||||
@@ -73,6 +78,31 @@ open class SerializationPluginDeclarationChecker : DeclarationChecker {
|
||||
val serializableDescriptor = serializableKType.toClassDescriptor ?: return
|
||||
val props = SerializableProperties(serializableDescriptor, trace.bindingContext)
|
||||
|
||||
val descriptorOverridden = classDescriptor.unsubstitutedMemberScope
|
||||
.getContributedVariables(SERIAL_DESC_FIELD_NAME, NoLookupLocation.FROM_BACKEND).singleOrNull {
|
||||
it.kind != CallableMemberDescriptor.Kind.SYNTHESIZED
|
||||
} != null
|
||||
|
||||
val serializeOverridden = classDescriptor.unsubstitutedMemberScope
|
||||
.getContributedFunctions(SAVE_NAME, NoLookupLocation.FROM_BACKEND).singleOrNull {
|
||||
it.valueParameters.size == 2
|
||||
&& it.overriddenDescriptors.isNotEmpty()
|
||||
&& it.kind != CallableMemberDescriptor.Kind.SYNTHESIZED
|
||||
} != null
|
||||
|
||||
val deserializeOverridden = classDescriptor.unsubstitutedMemberScope
|
||||
.getContributedFunctions(LOAD_NAME, NoLookupLocation.FROM_BACKEND).singleOrNull {
|
||||
it.valueParameters.size == 1
|
||||
&& it.overriddenDescriptors.isNotEmpty()
|
||||
&& it.kind != CallableMemberDescriptor.Kind.SYNTHESIZED
|
||||
} != null
|
||||
|
||||
if (descriptorOverridden && serializeOverridden && deserializeOverridden) {
|
||||
val entry = classDescriptor.findAnnotationDeclaration(SerializationAnnotations.serializerAnnotationFqName)
|
||||
trace.report(EXTERNAL_SERIALIZER_USELESS.on(entry ?: declaration, classDescriptor.defaultType))
|
||||
return
|
||||
}
|
||||
|
||||
if (!props.isExternallySerializable) {
|
||||
val entry = classDescriptor.findAnnotationDeclaration(SerializationAnnotations.serializerAnnotationFqName)
|
||||
val inSameModule =
|
||||
|
||||
+6
@@ -165,6 +165,12 @@ object SerializationPluginErrorsRendering : DefaultErrorMessages.Extension {
|
||||
"@MetaSerializable annotation should be used only on top-level annotation classes. Usage on nested annotation classes is deprecated and will yield errors in the future."
|
||||
)
|
||||
|
||||
MAP.put(
|
||||
SerializationErrors.EXTERNAL_SERIALIZER_USELESS,
|
||||
"@Serializer annotation has no effect on class ''{0}'', because all members of KSerializer are already overridden",
|
||||
Renderers.RENDER_TYPE
|
||||
)
|
||||
|
||||
MAP.put(
|
||||
SerializationErrors.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",
|
||||
|
||||
Reference in New Issue
Block a user