Prohibit serializable annotation on local classes and anonymous objects

#KT-45541 Fixed
This commit is contained in:
Leonid Startsev
2021-03-18 18:25:53 +03:00
parent 3b789448a3
commit c66cddc442
5 changed files with 39 additions and 11 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2021 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.
*/
@@ -16,6 +16,7 @@ import static org.jetbrains.kotlin.diagnostics.Severity.WARNING;
public interface SerializationErrors {
DiagnosticFactory2<PsiElement, String, String> INLINE_CLASSES_NOT_SUPPORTED = DiagnosticFactory2.create(ERROR);
DiagnosticFactory0<PsiElement> PLUGIN_IS_NOT_ENABLED = DiagnosticFactory0.create(WARNING);
DiagnosticFactory0<PsiElement> LOCAL_CLASSES_NOT_SUPPORTED = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> EXPLICIT_SERIALIZABLE_IS_REQUIRED = DiagnosticFactory0.create(WARNING);
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2021 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.
*/
@@ -13,16 +13,10 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotated
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperInterfaces
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.hasBackingField
import org.jetbrains.kotlin.resolve.isInlineClass
import org.jetbrains.kotlin.resolve.isInlineClassType
import org.jetbrains.kotlin.resolve.descriptorUtil.*
import org.jetbrains.kotlin.resolve.jvm.annotations.TRANSIENT_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotationDescriptor
import org.jetbrains.kotlin.resolve.source.getPsi
@@ -123,6 +117,12 @@ open class SerializationPluginDeclarationChecker : DeclarationChecker {
return false
}
if (DescriptorUtils.isLocal(descriptor)) {
trace.reportOnSerializableAnnotation(descriptor, SerializationErrors.LOCAL_CLASSES_NOT_SUPPORTED)
return false
}
if (descriptor.isInlineClass() && !canSupportInlineClasses(descriptor.module, trace)) {
descriptor.onSerializableAnnotation {
trace.report(
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2021 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.
*/
@@ -25,6 +25,10 @@ object SerializationPluginErrorsRendering : DefaultErrorMessages.Extension {
"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.LOCAL_CLASSES_NOT_SUPPORTED,
"Local class and anonymous objects can not be serializable"
)
MAP.put(
SerializationErrors.EXPLICIT_SERIALIZABLE_IS_REQUIRED,
"Explicit @Serializable annotation on enum class is required when @SerialName or @SerialInfo annotations are used on its members."
@@ -49,6 +49,11 @@ public class SerializationPluginDiagnosticTestGenerated extends AbstractSerializ
runTest("plugins/kotlin-serialization/kotlin-serialization-compiler/testData/diagnostics/LazyRecursionBug.kt");
}
@TestMetadata("LocalAndAnonymous.kt")
public void testLocalAndAnonymous() throws Exception {
runTest("plugins/kotlin-serialization/kotlin-serialization-compiler/testData/diagnostics/LocalAndAnonymous.kt");
}
@TestMetadata("NoSuitableCtorInParent.kt")
public void testNoSuitableCtorInParent() throws Exception {
runTest("plugins/kotlin-serialization/kotlin-serialization-compiler/testData/diagnostics/NoSuitableCtorInParent.kt");
@@ -0,0 +1,18 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER,-UNUSED_VARIABLE
// WITH_RUNTIME
// SKIP_TXT
import kotlinx.serialization.*
fun container() {
<!LOCAL_CLASSES_NOT_SUPPORTED!>@Serializable<!>
class X
val y = <!LOCAL_CLASSES_NOT_SUPPORTED!>@Serializable<!> object {}
}
val topLevelAnon = <!LOCAL_CLASSES_NOT_SUPPORTED!>@Serializable<!> object {}
@Serializable class A {
@Serializable class B // nesting classes are allowed
}