From a3218da1c30bee284fb9c9856c537f87961d9d81 Mon Sep 17 00:00:00 2001 From: Leonid Startsev Date: Tue, 25 Jun 2019 14:44:56 +0300 Subject: [PATCH] Add IDE diagnostic on @Serializable classes for non-applied serialization plugin --- .../diagnostic/SerializationErrors.java | 1 + .../SerializationPluginDeclarationChecker.kt | 16 ++++++++++++++-- .../SerializationPluginErrorsRendering.kt | 5 +++++ .../SerializationPluginIDEDeclarationChecker.kt | 17 +++++++++++++++++ .../SerializationIDEContainerContributor.kt | 4 ++-- 5 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 plugins/kotlin-serialization/kotlin-serialization-ide/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginIDEDeclarationChecker.kt diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationErrors.java b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationErrors.java index a5693283302..5e1bd2ec202 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationErrors.java +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationErrors.java @@ -18,6 +18,7 @@ import static org.jetbrains.kotlin.diagnostics.Severity.WARNING; public interface SerializationErrors { DiagnosticFactory0 INLINE_CLASSES_NOT_SUPPORTED = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 PLUGIN_IS_NOT_ENABLED = DiagnosticFactory0.create(WARNING); DiagnosticFactory0 SERIALIZABLE_ANNOTATION_IGNORED = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 NON_SERIALIZABLE_PARENT_MUST_HAVE_NOARG_CTOR = DiagnosticFactory0.create(ERROR); diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginDeclarationChecker.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginDeclarationChecker.kt index c079aa2f4d8..ae45ba478e7 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginDeclarationChecker.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginDeclarationChecker.kt @@ -33,8 +33,8 @@ import org.jetbrains.kotlinx.serialization.compiler.resolve.* internal val SERIALIZABLE_PROPERTIES: WritableSlice = Slices.createSimpleSlice() -class SerializationPluginDeclarationChecker : DeclarationChecker { - override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) { +open class SerializationPluginDeclarationChecker : DeclarationChecker { + final override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) { if (descriptor !is ClassDescriptor) return if (!canBeSerializedInternally(descriptor, context.trace)) return @@ -47,6 +47,11 @@ class SerializationPluginDeclarationChecker : DeclarationChecker { private fun canBeSerializedInternally(descriptor: ClassDescriptor, trace: BindingTrace): Boolean { if (!descriptor.annotations.hasAnnotation(SerializationAnnotations.serializableAnnotationFqName)) return false + if (!serializationPluginEnabledOn(descriptor)) { + trace.reportOnSerializableAnnotation(descriptor, SerializationErrors.PLUGIN_IS_NOT_ENABLED) + return false + } + if (descriptor.isInline) { trace.reportOnSerializableAnnotation(descriptor, SerializationErrors.INLINE_CLASSES_NOT_SUPPORTED) return false @@ -67,6 +72,13 @@ class SerializationPluginDeclarationChecker : DeclarationChecker { 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? { if (!descriptor.annotations.hasAnnotation(SerializationAnnotations.serializableAnnotationFqName)) return null if (!descriptor.isInternalSerializable) return null diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginErrorsRendering.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginErrorsRendering.kt index bad7dc3a4d4..390ea949972 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginErrorsRendering.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginErrorsRendering.kt @@ -18,6 +18,11 @@ object SerializationPluginErrorsRendering : DefaultErrorMessages.Extension { SerializationErrors.INLINE_CLASSES_NOT_SUPPORTED, "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( SerializationErrors.SERIALIZABLE_ANNOTATION_IGNORED, "@Serializable annotation is ignored because it is impossible to serialize automatically interfaces or enums. " + diff --git a/plugins/kotlin-serialization/kotlin-serialization-ide/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginIDEDeclarationChecker.kt b/plugins/kotlin-serialization/kotlin-serialization-ide/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginIDEDeclarationChecker.kt new file mode 100644 index 00000000000..e827c377983 --- /dev/null +++ b/plugins/kotlin-serialization/kotlin-serialization-ide/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginIDEDeclarationChecker.kt @@ -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 + } +} \ No newline at end of file diff --git a/plugins/kotlin-serialization/kotlin-serialization-ide/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationIDEContainerContributor.kt b/plugins/kotlin-serialization/kotlin-serialization-ide/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationIDEContainerContributor.kt index 47b9a25821b..f5878500e0b 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-ide/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationIDEContainerContributor.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-ide/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationIDEContainerContributor.kt @@ -10,7 +10,7 @@ import org.jetbrains.kotlin.container.useInstance import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor 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 { override fun registerModuleComponents( @@ -18,6 +18,6 @@ class SerializationIDEContainerContributor : StorageComponentContainerContributo platform: TargetPlatform, moduleDescriptor: ModuleDescriptor ) { - container.useInstance(SerializationPluginDeclarationChecker()) + container.useInstance(SerializationPluginIDEDeclarationChecker()) } } \ No newline at end of file