Kx-serialization: generate wrapper type for reference array serializer

This commit is contained in:
Alexander Udalov
2020-10-28 11:54:31 +01:00
parent 42aef01d79
commit f87e46b599
@@ -7,6 +7,7 @@ package org.jetbrains.kotlinx.serialization.compiler.backend.ir
import org.jetbrains.kotlin.backend.common.deepCopyWithVariables
import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.ir.builders.*
@@ -21,11 +22,14 @@ import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.jvm.isJvm
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
@@ -693,7 +697,7 @@ interface IrBuilderExtension {
}
if (serializerClassOriginal.classId == referenceArraySerializerId) {
args = listOf(classReference(kType.arguments[0].type)) + args
args = listOf(wrapperClassReference(kType.arguments.single().type)) + args
typeArgs = listOf(typeArgs[0].makeNotNull()) + typeArgs
}
@@ -714,6 +718,19 @@ interface IrBuilderExtension {
return irInvoke(null, ctor, typeArguments = typeArgs, valueArguments = args, returnTypeHint = substitutedReturnType)
}
private fun IrBuilderWithScope.wrapperClassReference(classType: KotlinType): IrClassReference {
if (compilerContext.platform.isJvm()) {
// "Byte::class" -> "java.lang.Byte::class"
val wrapperFqName = KotlinBuiltIns.getPrimitiveType(classType)?.let(JvmPrimitiveType::get)?.wrapperFqName
if (wrapperFqName != null) {
val wrapperClass = compilerContext.moduleDescriptor.findClassAcrossModuleDependencies(ClassId.topLevel(wrapperFqName))
?: error("Primitive wrapper class for $classType not found: $wrapperFqName")
return classReference(wrapperClass.defaultType)
}
}
return classReference(classType)
}
private fun findSerializerConstructorForTypeArgumentsSerializers(serializer: ClassDescriptor): IrConstructorSymbol? {
val serializableImplementationTypeArguments = extractKSerializerArgumentFromImplementation(serializer)?.arguments
?: throw AssertionError("Serializer does not implement KSerializer??")