Allow defining custom KSerializer for non-generic class as a class
Previously only objects were allowed. Due to a bug, this accidentally worked in old backend. #KT-46444 Fixed Fixes https://github.com/Kotlin/kotlinx.serialization/issues/1587
This commit is contained in:
+8
-1
@@ -1093,7 +1093,14 @@ interface IrBuilderExtension {
|
||||
|
||||
val typeParameters = ctorDecl.parentAsClass.typeParameters
|
||||
val substitutedReturnType = ctorDecl.returnType.substitute(typeParameters, typeArgs)
|
||||
return irInvoke(null, ctor, typeArguments = typeArgs, valueArguments = args, returnTypeHint = substitutedReturnType)
|
||||
return irInvoke(
|
||||
null,
|
||||
ctor,
|
||||
// User may declare serializer with fixed type arguments, e.g. class SomeSerializer : KSerializer<ClosedRange<Float>>
|
||||
typeArguments = typeArgs.takeIf { it.size == ctorDecl.typeParameters.size }.orEmpty(),
|
||||
valueArguments = args.takeIf { it.size == ctorDecl.valueParameters.size }.orEmpty(),
|
||||
returnTypeHint = substitutedReturnType
|
||||
)
|
||||
}
|
||||
|
||||
fun collectSerialInfoAnnotations(irClass: IrClass): List<IrConstructorCall> {
|
||||
|
||||
+6
@@ -25,6 +25,12 @@ public class SerializationIrBoxTestGenerated extends AbstractSerializationIrBoxT
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/kotlin-serialization/kotlin-serialization-compiler/testData/boxIr"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("classSerializerAsObject.kt")
|
||||
public void testClassSerializerAsObject() throws Exception {
|
||||
runTest("plugins/kotlin-serialization/kotlin-serialization-compiler/testData/boxIr/classSerializerAsObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("multimoduleInheritance.kt")
|
||||
public void testMultimoduleInheritance() throws Exception {
|
||||
|
||||
plugins/kotlin-serialization/kotlin-serialization-compiler/testData/boxIr/classSerializerAsObject.kt
Vendored
+68
@@ -0,0 +1,68 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
|
||||
// WITH_RUNTIME
|
||||
|
||||
package a
|
||||
|
||||
import kotlinx.serialization.*
|
||||
|
||||
import kotlinx.serialization.descriptors.*
|
||||
import kotlinx.serialization.encoding.*
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class Dummy
|
||||
|
||||
class DummyBox<T>
|
||||
|
||||
@Serializable(ClassSerializerOnClass::class)
|
||||
class DummySpecified
|
||||
|
||||
class ClassSerializerGeneric : KSerializer<DummyBox<String>> {
|
||||
override val descriptor get() = PrimitiveSerialDescriptor("ClassSerializerGeneric", PrimitiveKind.INT)
|
||||
override fun deserialize(decoder: Decoder): DummyBox<String> = TODO()
|
||||
override fun serialize(encoder: Encoder, value:DummyBox<String>): Unit = TODO()
|
||||
}
|
||||
|
||||
class ClassSerializerDummy : KSerializer<Dummy> {
|
||||
override val descriptor get() = PrimitiveSerialDescriptor("ClassSerializerDummy", PrimitiveKind.INT)
|
||||
override fun deserialize(decoder: Decoder): Dummy = TODO()
|
||||
override fun serialize(encoder: Encoder, value: Dummy): Unit = TODO()
|
||||
}
|
||||
|
||||
object ObjectSerializerGeneric: KSerializer<DummyBox<String>> {
|
||||
override val descriptor get() = PrimitiveSerialDescriptor("ObjectSerializerGeneric", PrimitiveKind.INT)
|
||||
override fun deserialize(decoder: Decoder): DummyBox<String> = TODO()
|
||||
override fun serialize(encoder: Encoder, value: DummyBox<String>): Unit = TODO()
|
||||
}
|
||||
|
||||
object ObjectSerializerDummy: KSerializer<Dummy> {
|
||||
override val descriptor get() = PrimitiveSerialDescriptor("ObjectSerializerDummy", PrimitiveKind.INT)
|
||||
override fun deserialize(decoder: Decoder): Dummy = TODO()
|
||||
override fun serialize(encoder: Encoder, value:Dummy): Unit = TODO()
|
||||
}
|
||||
|
||||
class ClassSerializerOnClass: KSerializer<DummySpecified> {
|
||||
override val descriptor get() = PrimitiveSerialDescriptor("ClassSerializerOnClass", PrimitiveKind.INT)
|
||||
override fun deserialize(decoder: Decoder): DummySpecified = TODO()
|
||||
override fun serialize(encoder: Encoder, value:DummySpecified): Unit = TODO()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
class Holder(
|
||||
@Serializable(ClassSerializerGeneric::class) val a: DummyBox<String>,
|
||||
@Serializable(ClassSerializerDummy::class) val b: Dummy,
|
||||
@Serializable(ObjectSerializerGeneric::class) val c: DummyBox<String>,
|
||||
@Serializable(ObjectSerializerDummy::class) val d: Dummy,
|
||||
val e: DummySpecified
|
||||
)
|
||||
|
||||
fun box(): String {
|
||||
val descs = Holder.serializer().descriptor.elementDescriptors.toList()
|
||||
assertEquals("ClassSerializerGeneric", descs[0].serialName)
|
||||
assertEquals("ClassSerializerDummy", descs[1].serialName)
|
||||
assertEquals("ObjectSerializerGeneric", descs[2].serialName)
|
||||
assertEquals("ObjectSerializerDummy", descs[3].serialName)
|
||||
assertEquals("ClassSerializerOnClass", descs[4].serialName)
|
||||
return "OK"
|
||||
}
|
||||
Reference in New Issue
Block a user