Add IDE diagnostic on @Serializable classes for non-applied serialization plugin
This commit is contained in:
+1
@@ -18,6 +18,7 @@ import static org.jetbrains.kotlin.diagnostics.Severity.WARNING;
|
|||||||
|
|
||||||
public interface SerializationErrors {
|
public interface SerializationErrors {
|
||||||
DiagnosticFactory0<PsiElement> INLINE_CLASSES_NOT_SUPPORTED = DiagnosticFactory0.create(ERROR);
|
DiagnosticFactory0<PsiElement> INLINE_CLASSES_NOT_SUPPORTED = DiagnosticFactory0.create(ERROR);
|
||||||
|
DiagnosticFactory0<PsiElement> PLUGIN_IS_NOT_ENABLED = DiagnosticFactory0.create(WARNING);
|
||||||
|
|
||||||
DiagnosticFactory0<KtAnnotationEntry> SERIALIZABLE_ANNOTATION_IGNORED = 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> NON_SERIALIZABLE_PARENT_MUST_HAVE_NOARG_CTOR = DiagnosticFactory0.create(ERROR);
|
||||||
|
|||||||
+14
-2
@@ -33,8 +33,8 @@ import org.jetbrains.kotlinx.serialization.compiler.resolve.*
|
|||||||
|
|
||||||
internal val SERIALIZABLE_PROPERTIES: WritableSlice<ClassDescriptor, SerializableProperties> = Slices.createSimpleSlice()
|
internal val SERIALIZABLE_PROPERTIES: WritableSlice<ClassDescriptor, SerializableProperties> = Slices.createSimpleSlice()
|
||||||
|
|
||||||
class SerializationPluginDeclarationChecker : DeclarationChecker {
|
open class SerializationPluginDeclarationChecker : DeclarationChecker {
|
||||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
final override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||||
if (descriptor !is ClassDescriptor) return
|
if (descriptor !is ClassDescriptor) return
|
||||||
|
|
||||||
if (!canBeSerializedInternally(descriptor, context.trace)) return
|
if (!canBeSerializedInternally(descriptor, context.trace)) return
|
||||||
@@ -47,6 +47,11 @@ class SerializationPluginDeclarationChecker : DeclarationChecker {
|
|||||||
private fun canBeSerializedInternally(descriptor: ClassDescriptor, trace: BindingTrace): Boolean {
|
private fun canBeSerializedInternally(descriptor: ClassDescriptor, trace: BindingTrace): Boolean {
|
||||||
if (!descriptor.annotations.hasAnnotation(SerializationAnnotations.serializableAnnotationFqName)) return false
|
if (!descriptor.annotations.hasAnnotation(SerializationAnnotations.serializableAnnotationFqName)) return false
|
||||||
|
|
||||||
|
if (!serializationPluginEnabledOn(descriptor)) {
|
||||||
|
trace.reportOnSerializableAnnotation(descriptor, SerializationErrors.PLUGIN_IS_NOT_ENABLED)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if (descriptor.isInline) {
|
if (descriptor.isInline) {
|
||||||
trace.reportOnSerializableAnnotation(descriptor, SerializationErrors.INLINE_CLASSES_NOT_SUPPORTED)
|
trace.reportOnSerializableAnnotation(descriptor, SerializationErrors.INLINE_CLASSES_NOT_SUPPORTED)
|
||||||
return false
|
return false
|
||||||
@@ -67,6 +72,13 @@ class SerializationPluginDeclarationChecker : DeclarationChecker {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open fun serializationPluginEnabledOn(descriptor: ClassDescriptor): Boolean {
|
||||||
|
// In the CLI/Gradle compiler, this diagnostic is located in the plugin itself.
|
||||||
|
// Therefore, if we are here, plugin is in the compile classpath and enabled.
|
||||||
|
// For the IDE case, see SerializationPluginIDEDeclarationChecker
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
private fun buildSerializableProperties(descriptor: ClassDescriptor, trace: BindingTrace): SerializableProperties? {
|
private fun buildSerializableProperties(descriptor: ClassDescriptor, trace: BindingTrace): SerializableProperties? {
|
||||||
if (!descriptor.annotations.hasAnnotation(SerializationAnnotations.serializableAnnotationFqName)) return null
|
if (!descriptor.annotations.hasAnnotation(SerializationAnnotations.serializableAnnotationFqName)) return null
|
||||||
if (!descriptor.isInternalSerializable) return null
|
if (!descriptor.isInternalSerializable) return null
|
||||||
|
|||||||
+5
@@ -18,6 +18,11 @@ object SerializationPluginErrorsRendering : DefaultErrorMessages.Extension {
|
|||||||
SerializationErrors.INLINE_CLASSES_NOT_SUPPORTED,
|
SerializationErrors.INLINE_CLASSES_NOT_SUPPORTED,
|
||||||
"Inline classes are not supported by kotlinx.serialization yet"
|
"Inline classes are not supported by kotlinx.serialization yet"
|
||||||
)
|
)
|
||||||
|
MAP.put(
|
||||||
|
SerializationErrors.PLUGIN_IS_NOT_ENABLED,
|
||||||
|
"kotlinx.serialization compiler plugin is not applied to the module, so this annotation would not be processed. " +
|
||||||
|
"Make sure that you've setup your buildscript correctly and re-import project."
|
||||||
|
)
|
||||||
MAP.put(
|
MAP.put(
|
||||||
SerializationErrors.SERIALIZABLE_ANNOTATION_IGNORED,
|
SerializationErrors.SERIALIZABLE_ANNOTATION_IGNORED,
|
||||||
"@Serializable annotation is ignored because it is impossible to serialize automatically interfaces or enums. " +
|
"@Serializable annotation is ignored because it is impossible to serialize automatically interfaces or enums. " +
|
||||||
|
|||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlinx.serialization.compiler.diagnostic
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlinx.serialization.idea.getIfEnabledOn
|
||||||
|
|
||||||
|
class SerializationPluginIDEDeclarationChecker : SerializationPluginDeclarationChecker() {
|
||||||
|
override fun serializationPluginEnabledOn(descriptor: ClassDescriptor): Boolean {
|
||||||
|
// In the IDE, plugin is always in the classpath, but enabled only if corresponding compiler settings
|
||||||
|
// were imported into project model from Gradle.
|
||||||
|
return getIfEnabledOn(descriptor) { true } == true
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-2
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.container.useInstance
|
|||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
|
import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
|
||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.diagnostic.SerializationPluginDeclarationChecker
|
import org.jetbrains.kotlinx.serialization.compiler.diagnostic.SerializationPluginIDEDeclarationChecker
|
||||||
|
|
||||||
class SerializationIDEContainerContributor : StorageComponentContainerContributor {
|
class SerializationIDEContainerContributor : StorageComponentContainerContributor {
|
||||||
override fun registerModuleComponents(
|
override fun registerModuleComponents(
|
||||||
@@ -18,6 +18,6 @@ class SerializationIDEContainerContributor : StorageComponentContainerContributo
|
|||||||
platform: TargetPlatform,
|
platform: TargetPlatform,
|
||||||
moduleDescriptor: ModuleDescriptor
|
moduleDescriptor: ModuleDescriptor
|
||||||
) {
|
) {
|
||||||
container.useInstance(SerializationPluginDeclarationChecker())
|
container.useInstance(SerializationPluginIDEDeclarationChecker())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user