Use correct check in FirSerializationPluginClassChecker to determine if the given type is a enum class.

Otherwise, findTypeSerializerOrContextUnchecked works incorrectly when analyzing code
compiled with Kotlin 1.7.20 and serialization 1.4.1.

#KT-57704 Fixed
This commit is contained in:
Leonid Startsev
2023-04-18 14:54:23 +02:00
committed by Space Team
parent 167ed5e049
commit f29e505bd3
8 changed files with 120 additions and 1 deletions
@@ -8,6 +8,10 @@ package org.jetbrains.kotlin.gradle
import org.gradle.util.GradleVersion
import org.jetbrains.kotlin.gradle.testbase.*
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.io.TempDir
import java.nio.file.Path
import kotlin.io.path.listDirectoryEntries
import kotlin.test.assertTrue
@OtherGradlePluginTests
class K2KotlinxSerializationIT : KGPBaseTest() {
@@ -32,4 +36,23 @@ class K2KotlinxSerializationIT : KGPBaseTest() {
}
}
}
@DisplayName("Compile code with kotlinx.serialization K2 against old K1 library without enum factory support (KT-57704).")
@GradleTest
fun `test kotlinx serialization K2 against K1 library`(gradleVersion: GradleVersion, @TempDir tempDir: Path) {
project("kotlinxSerializationK2AgainstK1Lib/lib", gradleVersion, localRepoDir = tempDir) {
build(":publish") {
assertTasksExecuted(":publish")
val publishedLib = tempDir.resolve("com/example/serialization_lib/serialization_lib/1.0")
assertDirectoryExists(publishedLib)
assertTrue(publishedLib.listDirectoryEntries().isNotEmpty())
}
}
project("kotlinxSerializationK2AgainstK1Lib/app", gradleVersion, localRepoDir = tempDir) {
build(":run") {
assertTasksExecuted(":run")
}
}
}
}
@@ -0,0 +1,33 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
plugins {
kotlin("jvm")
kotlin("plugin.serialization")
`maven-publish`
application
}
repositories {
mavenLocal()
maven("<localRepo>")
mavenCentral()
}
group = "com.example.serialization_app"
version = "1.0"
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1")
implementation("com.example.serialization_lib:serialization_lib:1.0")
}
val compileKotlin: KotlinCompile by tasks
compileKotlin.compilerOptions {
languageVersion.set(KotlinVersion.KOTLIN_2_0)
}
application {
mainClass.set("com.example.serialization_app.MainKt")
}
@@ -0,0 +1,19 @@
/*
* Copyright 2010-2023 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 com.example.serialization_app
import com.example.serialization_lib.*
import kotlinx.serialization.json.*
import kotlinx.serialization.*
@Serializable
class EnumUsage(val access: Access)
fun main() {
val s = Json.encodeToString(EnumUsage.serializer(), EnumUsage(Access.ReadWrite))
if (s != """{"access":"rw"}""") throw AssertionError("Unexpected serialized form: $s")
val usage = Json.decodeFromString<EnumUsage>(s)
if (usage.access != Access.ReadWrite) throw AssertionError("Unexpected deserialized result: ${usage.access}")
}
@@ -0,0 +1,29 @@
plugins {
kotlin("jvm") version "1.7.20"
kotlin("plugin.serialization") version "1.7.20"
`maven-publish`
}
repositories {
mavenLocal()
mavenCentral()
}
group = "com.example.serialization_lib"
version = "1.0"
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1")
}
publishing {
repositories {
maven("<localRepo>")
}
publications {
create<MavenPublication>("Maven") {
from(components["java"])
}
}
}
@@ -0,0 +1,13 @@
/*
* Copyright 2010-2023 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 com.example.serialization_lib
import kotlinx.serialization.*
@Serializable
enum class Access {
Read, Write, @SerialName("rw") ReadWrite, Unknown
}
@@ -536,7 +536,7 @@ object FirSerializationPluginClassChecker : FirClassChecker() {
}
checkTypeArguments(type, source, reporter)
} else {
if (!type.isEnum) {
if (type.toRegularClassSymbol(session)?.isEnumClass != true) {
// enums are always serializable
reporter.reportOn(source, FirSerializationErrors.SERIALIZER_NOT_FOUND, type)
}