Files
kotlin-fork/plugins/kotlinx-serialization/testData/boxIr/caching.kt
T
Sergey.Shanshin 441b22c0fd [KxSerialization] Fixed error accessing the descriptor from companion
Relates #KT-57647

If a serialization descriptor is used in the companion, then when accessing the child elements, an array of cached child serializers may be read.
Since the serialization plugin adds its declarations to the class after the declarations from the source code, the initialization of the array of child serializers occurs after the execution of the user code.
This can lead to N PE errors when trying to access an unfilled cached child serializer.

The solution is to change the order of declarations so that the declaration with the property of cached child serializers comes first.

Merge-request: KT-MR-10545
Merged-by: Sergey Shanshin <Sergey.Shanshin@jetbrains.com>
2023-06-09 15:32:28 +00:00

59 lines
1.4 KiB
Kotlin
Vendored

// TARGET_BACKEND: JVM_IR
// WITH_STDLIB
import kotlinx.serialization.*
// Serializers for classes containing themselves as properties should be cached correctly
@Serializable
class Plain(val p: Plain? = null)
@Serializable
sealed class Sealed(val p: Sealed? = null)
@Serializable
open class Open(val p: Open? = null)
@Serializable
abstract class Abstract(val p: Abstract? = null)
@Serializable
class GenericHolder<T> {
var value: T? = null
}
@Serializable
sealed class SealedGeneric {
var holder = GenericHolder<SealedGeneric>()
}
@Serializable
sealed class SealedListGeneric {
var holder = GenericHolder<GenericHolder<List<SealedListGeneric>>>()
}
@Serializable
class AccessFromCompanion(@Contextual val category: Any) {
companion object {
init {
serializer().descriptor.getElementDescriptor(0).isNullable
}
var isNullable = serializer().descriptor.getElementDescriptor(0).isNullable
val isNullable2 = serializer<AccessFromCompanion>().descriptor.getElementDescriptor(0).isNullable
}
}
fun box(): String {
// A correctly cached class must be initialized correctly in order to exclude cyclic nesting of caches
Plain.serializer()
Sealed.serializer()
Open.serializer()
Abstract.serializer()
SealedGeneric.serializer()
SealedListGeneric.serializer()
AccessFromCompanion("any")
return "OK"
}