From 676d92f03e27498c5ff717af9445e88e1055a758 Mon Sep 17 00:00:00 2001 From: Vsevolod Tolstopyatov Date: Mon, 10 Jan 2022 16:31:18 +0300 Subject: [PATCH] Attempt to use only java.lang.Class from the implementation of constructSerializerForGivenTypeArgs Prerequisite for #1819 --- .../serialization/internal/Platform.kt | 42 ++++++++++--------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/core/jvmMain/src/kotlinx/serialization/internal/Platform.kt b/core/jvmMain/src/kotlinx/serialization/internal/Platform.kt index b4a966b8f..74f4c4e0b 100644 --- a/core/jvmMain/src/kotlinx/serialization/internal/Platform.kt +++ b/core/jvmMain/src/kotlinx/serialization/internal/Platform.kt @@ -28,24 +28,27 @@ internal actual fun ArrayList.toNativeArrayImpl(eClass: KCl internal actual fun KClass<*>.platformSpecificSerializerNotRegistered(): Nothing = serializerNotRegistered() -@Suppress("UNCHECKED_CAST") internal actual fun KClass.constructSerializerForGivenTypeArgs(vararg args: KSerializer): KSerializer? { - val jClass = this.java - if (jClass.isEnum && jClass.isNotAnnotated()) { - return jClass.createEnumSerializer() + return java.constructSerializerForGivenTypeArgs(*args) +} + +@Suppress("UNCHECKED_CAST") +private fun Class.constructSerializerForGivenTypeArgs(vararg args: KSerializer): KSerializer? { + if (isEnum && isNotAnnotated()) { + return createEnumSerializer() } - if (jClass.isInterface) { + if (isInterface) { return interfaceSerializer() } // Search for serializer defined on companion object. - val serializer = invokeSerializerOnCompanion(jClass, *args) + val serializer = invokeSerializerOnCompanion(this, *args) if (serializer != null) return serializer // Check whether it's serializable object - findObjectSerializer(jClass)?.let { return it } + findObjectSerializer()?.let { return it } // Search for default serializer if no serializer is defined in companion object. // It is required for named companions val fromNamedCompanion = try { - jClass.declaredClasses.singleOrNull { it.simpleName == ("\$serializer") } + declaredClasses.singleOrNull { it.simpleName == ("\$serializer") } ?.getField("INSTANCE")?.get(null) as? KSerializer } catch (e: NoSuchFieldException) { null @@ -63,31 +66,30 @@ private fun Class.isNotAnnotated(): Boolean { getAnnotation(Polymorphic::class.java) == null } -private fun KClass.polymorphicSerializer(): KSerializer? { +private fun Class.polymorphicSerializer(): KSerializer? { /* * Last resort: check for @Polymorphic or Serializable(with = PolymorphicSerializer::class) * annotations. */ - val jClass = java - if (jClass.getAnnotation(Polymorphic::class.java) != null) { - return PolymorphicSerializer(this) + if (getAnnotation(Polymorphic::class.java) != null) { + return PolymorphicSerializer(this.kotlin) } - val serializable = jClass.getAnnotation(Serializable::class.java) + val serializable = getAnnotation(Serializable::class.java) if (serializable != null && serializable.with == PolymorphicSerializer::class) { - return PolymorphicSerializer(this) + return PolymorphicSerializer(this.kotlin) } return null } -private fun KClass.interfaceSerializer(): KSerializer? { +private fun Class.interfaceSerializer(): KSerializer? { /* * Interfaces are @Polymorphic by default. * Check if it has no annotations or `@Serializable(with = PolymorphicSerializer::class)`, * otherwise bailout. */ - val serializable = java.getAnnotation(Serializable::class.java) + val serializable = getAnnotation(Serializable::class.java) if (serializable == null || serializable.with == PolymorphicSerializer::class) { - return PolymorphicSerializer(this) + return PolymorphicSerializer(this.kotlin) } return null } @@ -122,15 +124,15 @@ private fun Class.createEnumSerializer(): KSerializer? { return EnumSerializer(canonicalName, constants as Array>) as? KSerializer } -private fun findObjectSerializer(jClass: Class): KSerializer? { +private fun Class.findObjectSerializer(): KSerializer? { // Check it is an object without using kotlin-reflect val field = - jClass.declaredFields.singleOrNull { it.name == "INSTANCE" && it.type == jClass && Modifier.isStatic(it.modifiers) } + declaredFields.singleOrNull { it.name == "INSTANCE" && it.type == this && Modifier.isStatic(it.modifiers) } ?: return null // Retrieve its instance and call serializer() val instance = field.get(null) val method = - jClass.methods.singleOrNull { it.name == "serializer" && it.parameterTypes.isEmpty() && it.returnType == KSerializer::class.java } + methods.singleOrNull { it.name == "serializer" && it.parameterTypes.isEmpty() && it.returnType == KSerializer::class.java } ?: return null val result = method.invoke(instance) @Suppress("UNCHECKED_CAST")