Implement inspection about no-arg constructor in non-serializable supertype

This commit is contained in:
Leonid Startsev
2019-05-30 16:43:27 +03:00
parent 8f77b55ada
commit dc79b99dd2
3 changed files with 21 additions and 7 deletions
@@ -16,13 +16,16 @@ import static org.jetbrains.kotlin.diagnostics.Severity.ERROR;
import static org.jetbrains.kotlin.diagnostics.Severity.WARNING;
public interface SerializationErrors {
DiagnosticFactory0<KtAnnotationEntry> SERIALIZABLE_ANNOTATION_IGNORED = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> INLINE_CLASSES_NOT_SUPPORTED = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtAnnotationEntry> SERIALIZABLE_ANNOTATION_IGNORED = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtAnnotationEntry> NON_SERIALIZABLE_PARENT_MUST_HAVE_NOARG_CTOR = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtAnnotationEntry> PRIMARY_CONSTRUCTOR_PARAMETER_IS_NOT_A_PROPERTY = DiagnosticFactory0.create(ERROR);
DiagnosticFactory1<KtAnnotationEntry, String> DUPLICATE_SERIAL_NAME = DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<PsiElement> SERIALIZER_NOT_FOUND = DiagnosticFactory0.create(ERROR);
DiagnosticFactory1<PsiElement, KotlinType> SERIALIZER_NULLABILITY_INCOMPATIBLE = DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<PsiElement> TRANSIENT_MISSING_INITIALIZER = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> TRANSIENT_IS_REDUNDANT = DiagnosticFactory0.create(WARNING);
@SuppressWarnings("UnusedDeclaration")
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
import org.jetbrains.kotlin.resolve.hasBackingField
import org.jetbrains.kotlin.resolve.isInlineClassType
import org.jetbrains.kotlin.types.KotlinType
@@ -52,6 +53,12 @@ class SerializationPluginDeclarationChecker : DeclarationChecker {
if (!descriptor.isInternalSerializable && !descriptor.hasCompanionObjectAsSerializer) {
trace.reportOnSerializableAnnotation(descriptor, SerializationErrors.SERIALIZABLE_ANNOTATION_IGNORED)
}
// check that we can instantiate supertype
val superClass = descriptor.getSuperClassOrAny()
if (!superClass.isInternalSerializable && superClass.constructors.singleOrNull { it.valueParameters.size == 0 } == null) {
trace.reportOnSerializableAnnotation(descriptor, SerializationErrors.NON_SERIALIZABLE_PARENT_MUST_HAVE_NOARG_CTOR)
}
}
private fun buildSerializableProperties(descriptor: ClassDescriptor, trace: BindingTrace): SerializableProperties? {
@@ -14,18 +14,26 @@ object SerializationPluginErrorsRendering : DefaultErrorMessages.Extension {
override fun getMap() = MAP
init {
MAP.put(
SerializationErrors.INLINE_CLASSES_NOT_SUPPORTED,
"Inline classes are not supported by serialization framework yet."
)
MAP.put(
SerializationErrors.SERIALIZABLE_ANNOTATION_IGNORED,
"@Serializable annotation would be ignored because it is impossible to serialize automatically interfaces or enums. " +
"Provide serializer manually via e.g. companion object"
)
MAP.put(
SerializationErrors.NON_SERIALIZABLE_PARENT_MUST_HAVE_NOARG_CTOR,
"Impossible to make this class serializable because its parent is not serializable and does not have exactly one constructor without arguments"
)
MAP.put(
SerializationErrors.PRIMARY_CONSTRUCTOR_PARAMETER_IS_NOT_A_PROPERTY,
"This class is not serializable automatically because it has primary constructor parameters which are not properties."
)
MAP.put(
SerializationErrors.DUPLICATE_SERIAL_NAME,
"Serializable class has duplicate serial name of property ''{0}'', either in it or its parents.",
"Serializable class has duplicate serial name of property ''{0}'', either in it or its supertypes.",
Renderers.STRING
)
MAP.put(
@@ -35,7 +43,7 @@ object SerializationPluginErrorsRendering : DefaultErrorMessages.Extension {
)
MAP.put(
SerializationErrors.SERIALIZER_NULLABILITY_INCOMPATIBLE,
"This type is not-nullable and therefore can not be serialized with serializer for nullable type ''{0}''",
"This type is non-nullable and therefore can not be serialized with serializer for nullable type ''{0}''",
Renderers.RENDER_TYPE
)
MAP.put(
@@ -46,9 +54,5 @@ object SerializationPluginErrorsRendering : DefaultErrorMessages.Extension {
SerializationErrors.TRANSIENT_IS_REDUNDANT,
"This property does not have backing field which makes it non-serializable and therefore @Transient is redundant"
)
MAP.put(
SerializationErrors.INLINE_CLASSES_NOT_SUPPORTED,
"Inline classes are not supported by serialization framework yet."
)
}
}