Do not create cacheableChildSerializers unless it is necessary
Creation of this property in the SerializerIrGenerator.<init> can lead to a 'Serializer not found' internal error when generator is applied to a fully-customized external serializer. In that case, generator is still created, but none of the generateSave/Load functions are called, so cacheableChildSerializers(Property) is not necessary. #KT-57730 Fixed Fixes https://github.com/Kotlin/kotlinx.serialization/issues/2260
This commit is contained in:
committed by
Space Team
parent
54c07f5ebb
commit
d9e16fb76e
+15
-9
@@ -66,11 +66,9 @@ open class SerializerIrGenerator(
|
|||||||
SerialEntityNames.SERIAL_DESC_FIELD
|
SerialEntityNames.SERIAL_DESC_FIELD
|
||||||
) { true }?.takeIf { it.isFromPlugin(compilerContext.afterK2) }
|
) { true }?.takeIf { it.isFromPlugin(compilerContext.afterK2) }
|
||||||
|
|
||||||
protected val anySerialDescProperty = getProperty(
|
protected val irAnySerialDescProperty = getProperty(
|
||||||
SerialEntityNames.SERIAL_DESC_FIELD,
|
SerialEntityNames.SERIAL_DESC_FIELD,
|
||||||
) { true } // remove true?
|
) { true }
|
||||||
|
|
||||||
protected val irAnySerialDescProperty = anySerialDescProperty
|
|
||||||
|
|
||||||
fun getProperty(
|
fun getProperty(
|
||||||
name: String,
|
name: String,
|
||||||
@@ -83,13 +81,16 @@ open class SerializerIrGenerator(
|
|||||||
private set
|
private set
|
||||||
|
|
||||||
// child serializers cached if serializable class is internal
|
// child serializers cached if serializable class is internal
|
||||||
private val cachedChildSerializersProperty = if (isGeneratedSerializer)
|
private val cachedChildSerializersProperty by lazy {
|
||||||
serializableIrClass.companionObject()?.properties?.singleOrNull { it.name == CACHED_CHILD_SERIALIZERS_PROPERTY_NAME }
|
if (isGeneratedSerializer)
|
||||||
else null
|
serializableIrClass.companionObject()?.properties?.singleOrNull { it.name == CACHED_CHILD_SERIALIZERS_PROPERTY_NAME }
|
||||||
|
else null
|
||||||
|
}
|
||||||
|
|
||||||
// non-object serializers which can be cached
|
// non-object serializers which can be cached
|
||||||
private val cacheableChildSerializers =
|
private val cacheableChildSerializers by lazy {
|
||||||
serializableIrClass.createCachedChildSerializers(properties.serializableProperties).map { it != null }
|
serializableIrClass.createCachedChildSerializers(properties.serializableProperties).map { it != null }
|
||||||
|
}
|
||||||
|
|
||||||
// null if was not found — we're in FIR
|
// null if was not found — we're in FIR
|
||||||
private fun findLocalSerializersFieldDescriptors(): List<IrProperty?> {
|
private fun findLocalSerializersFieldDescriptors(): List<IrProperty?> {
|
||||||
@@ -230,7 +231,12 @@ open class SerializerIrGenerator(
|
|||||||
|
|
||||||
val allSerializers = serializableProperties.mapIndexed { index, property ->
|
val allSerializers = serializableProperties.mapIndexed { index, property ->
|
||||||
requireNotNull(
|
requireNotNull(
|
||||||
serializerTower(this@SerializerIrGenerator, irFun.dispatchReceiverParameter!!, property, cachedChildSerializerByIndex(index))
|
serializerTower(
|
||||||
|
this@SerializerIrGenerator,
|
||||||
|
irFun.dispatchReceiverParameter!!,
|
||||||
|
property,
|
||||||
|
cachedChildSerializerByIndex(index)
|
||||||
|
)
|
||||||
) { "Property ${property.name} must have a serializer" }
|
) { "Property ${property.name} must have a serializer" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,4 +25,4 @@ object URLSerializer : KSerializer<URL> {
|
|||||||
fun box(): String {
|
fun box(): String {
|
||||||
if (URLSerializer.descriptor.toString() != "PrimitiveDescriptor(java.net.URL)") return URLSerializer.descriptor.toString()
|
if (URLSerializer.descriptor.toString() != "PrimitiveDescriptor(java.net.URL)") return URLSerializer.descriptor.toString()
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+30
@@ -0,0 +1,30 @@
|
|||||||
|
// TARGET_BACKEND: JVM_IR
|
||||||
|
|
||||||
|
// FULL_JDK
|
||||||
|
// WITH_STDLIB
|
||||||
|
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
import kotlinx.serialization.descriptors.*
|
||||||
|
import kotlinx.serialization.encoding.*
|
||||||
|
import java.math.BigDecimal
|
||||||
|
|
||||||
|
@Serializable(with = DataBigDecimal.Serializer::class)
|
||||||
|
data class DataBigDecimal(val value: BigDecimal) {
|
||||||
|
|
||||||
|
@kotlinx.serialization.Serializer(forClass = DataBigDecimal::class)
|
||||||
|
object Serializer : KSerializer<DataBigDecimal> {
|
||||||
|
|
||||||
|
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("my.DataBigDecimal", PrimitiveKind.STRING)
|
||||||
|
|
||||||
|
override fun deserialize(decoder: Decoder): DataBigDecimal =
|
||||||
|
TODO()
|
||||||
|
|
||||||
|
override fun serialize(encoder: Encoder, value: DataBigDecimal): Unit =
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
if (DataBigDecimal.Serializer.descriptor.toString() != "PrimitiveDescriptor(my.DataBigDecimal)") return DataBigDecimal.Serializer.descriptor.toString()
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+6
@@ -81,6 +81,12 @@ public class SerializationFirLightTreeBlackBoxTestGenerated extends AbstractSeri
|
|||||||
runTest("plugins/kotlinx-serialization/testData/boxIr/externalSerialierJava.kt");
|
runTest("plugins/kotlinx-serialization/testData/boxIr/externalSerialierJava.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("externalSerializerForClassWithNonSerializableType.kt")
|
||||||
|
public void testExternalSerializerForClassWithNonSerializableType() throws Exception {
|
||||||
|
runTest("plugins/kotlinx-serialization/testData/boxIr/externalSerializerForClassWithNonSerializableType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("generatedClassifiersViaLibraryDependency.kt")
|
@TestMetadata("generatedClassifiersViaLibraryDependency.kt")
|
||||||
public void testGeneratedClassifiersViaLibraryDependency() throws Exception {
|
public void testGeneratedClassifiersViaLibraryDependency() throws Exception {
|
||||||
|
|||||||
+6
@@ -79,6 +79,12 @@ public class SerializationIrBoxTestGenerated extends AbstractSerializationIrBoxT
|
|||||||
runTest("plugins/kotlinx-serialization/testData/boxIr/externalSerialierJava.kt");
|
runTest("plugins/kotlinx-serialization/testData/boxIr/externalSerialierJava.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("externalSerializerForClassWithNonSerializableType.kt")
|
||||||
|
public void testExternalSerializerForClassWithNonSerializableType() throws Exception {
|
||||||
|
runTest("plugins/kotlinx-serialization/testData/boxIr/externalSerializerForClassWithNonSerializableType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("generatedClassifiersViaLibraryDependency.kt")
|
@TestMetadata("generatedClassifiersViaLibraryDependency.kt")
|
||||||
public void testGeneratedClassifiersViaLibraryDependency() throws Exception {
|
public void testGeneratedClassifiersViaLibraryDependency() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user