Check for name when searching Companion.serializer() function to generate
Name check was forgotten during refactoring, so any user function with matching signature could be overwritten by the plugin, while correct function would not have body. #KT-55682 Fixed
This commit is contained in:
committed by
Space Team
parent
0b4f534d35
commit
bf60819824
+16
-9
@@ -35,10 +35,13 @@ class SerializableCompanionIrGenerator(
|
||||
|
||||
companion object {
|
||||
fun getSerializerGetterFunction(serializableIrClass: IrClass): IrSimpleFunction? {
|
||||
val irClass = if (serializableIrClass.isSerializableObject) serializableIrClass else serializableIrClass.companionObject() ?: return null
|
||||
val irClass =
|
||||
if (serializableIrClass.isSerializableObject) serializableIrClass else serializableIrClass.companionObject() ?: return null
|
||||
return irClass.findDeclaration<IrSimpleFunction> {
|
||||
(it.valueParameters.size == serializableIrClass.typeParameters.size
|
||||
&& it.valueParameters.all { p -> p.type.isKSerializer() }) && it.returnType.isKSerializer()
|
||||
it.name == SerialEntityNames.SERIALIZER_PROVIDER_NAME
|
||||
&& it.valueParameters.size == serializableIrClass.typeParameters.size
|
||||
&& it.valueParameters.all { p -> p.type.isKSerializer() }
|
||||
&& it.returnType.isKSerializer()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,10 +60,12 @@ class SerializableCompanionIrGenerator(
|
||||
}
|
||||
|
||||
fun generate() {
|
||||
val serializerGetterFunction = getSerializerGetterFunction(serializableIrClass) ?: throw IllegalStateException(
|
||||
"Can't find synthesized 'Companion.serializer()' function to generate, " +
|
||||
"probably clash with user-defined function has occurred"
|
||||
)
|
||||
val serializerGetterFunction =
|
||||
getSerializerGetterFunction(serializableIrClass)?.takeIf { it.isFromPlugin(compilerContext.afterK2) }
|
||||
?: throw IllegalStateException(
|
||||
"Can't find synthesized 'Companion.serializer()' function to generate, " +
|
||||
"probably clash with user-defined function has occurred"
|
||||
)
|
||||
|
||||
if (serializableIrClass.isSerializableObject
|
||||
|| serializableIrClass.isAbstractOrSealedSerializableClass
|
||||
@@ -115,7 +120,8 @@ class SerializableCompanionIrGenerator(
|
||||
)
|
||||
)
|
||||
|
||||
val kSerializerIrClass = compilerContext.referenceClass(ClassId(SerializationPackages.packageFqName, SerialEntityNames.KSERIALIZER_NAME))!!.owner
|
||||
val kSerializerIrClass =
|
||||
compilerContext.referenceClass(ClassId(SerializationPackages.packageFqName, SerialEntityNames.KSERIALIZER_NAME))!!.owner
|
||||
val targetIrType =
|
||||
kSerializerIrClass.defaultType.substitute(mapOf(kSerializerIrClass.typeParameters[0].symbol to compilerContext.irBuiltIns.anyType))
|
||||
|
||||
@@ -154,7 +160,8 @@ class SerializableCompanionIrGenerator(
|
||||
|
||||
private fun getOrCreateSerializerVarargFactory(): IrSimpleFunction {
|
||||
irClass.findDeclaration<IrSimpleFunction> {
|
||||
it.valueParameters.size == 1
|
||||
it.name == SerialEntityNames.SERIALIZER_PROVIDER_NAME
|
||||
&& it.valueParameters.size == 1
|
||||
&& it.valueParameters.first().isVararg
|
||||
&& it.returnType.isKSerializer()
|
||||
&& it.isFromPlugin(compilerContext.afterK2)
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
|
||||
// WITH_STDLIB
|
||||
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.descriptors.*
|
||||
import kotlinx.serialization.builtins.*
|
||||
|
||||
|
||||
@Serializable
|
||||
data class Main(val fields: MainFields) {
|
||||
companion object {
|
||||
fun fieldsSerializer(): KSerializer<MainFields> = MainFields.serializer()
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class MainFields(val firstName: String?)
|
||||
|
||||
@Serializable
|
||||
data class Box<T>(val boxed: T) {
|
||||
companion object {
|
||||
fun <T> serializerLike(tSer: KSerializer<T>): KSerializer<List<Box<T>>> = ListSerializer(serializer(tSer))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun box(): String {
|
||||
if (Main.fieldsSerializer().descriptor.toString() != "MainFields(firstName: kotlin.String?)") return "Error1"
|
||||
if (MainFields.serializer().descriptor.toString() != "MainFields(firstName: kotlin.String?)") return "Error2"
|
||||
if (Main.serializer().descriptor.toString() != "Main(fields: MainFields)") return "Error3"
|
||||
val boxListDesc = Box.serializerLike(String.serializer()).descriptor
|
||||
if (boxListDesc.toString() != "kotlin.collections.ArrayList(Box(boxed: kotlin.String))") return boxListDesc.toString()
|
||||
val boxDesc = Box.serializer(String.serializer()).descriptor
|
||||
if (boxDesc.toString() != "Box(boxed: kotlin.String)") return boxDesc.toString()
|
||||
return "OK"
|
||||
}
|
||||
+6
@@ -158,6 +158,12 @@ public class SerializationFirBlackBoxTestGenerated extends AbstractSerialization
|
||||
public void testUseSerializersChain() throws Exception {
|
||||
runTest("plugins/kotlinx-serialization/testData/boxIr/useSerializersChain.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("userDefinedSerializerInCompanion.kt")
|
||||
public void testUserDefinedSerializerInCompanion() throws Exception {
|
||||
runTest("plugins/kotlinx-serialization/testData/boxIr/userDefinedSerializerInCompanion.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+6
@@ -156,4 +156,10 @@ public class SerializationIrBoxTestGenerated extends AbstractSerializationIrBoxT
|
||||
public void testUseSerializersChain() throws Exception {
|
||||
runTest("plugins/kotlinx-serialization/testData/boxIr/useSerializersChain.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("userDefinedSerializerInCompanion.kt")
|
||||
public void testUserDefinedSerializerInCompanion() throws Exception {
|
||||
runTest("plugins/kotlinx-serialization/testData/boxIr/userDefinedSerializerInCompanion.kt");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user