From d4fc6774f3cce5d8ae85d2cfbfb6f4f64125f112 Mon Sep 17 00:00:00 2001 From: Leonid Startsev Date: Tue, 17 Mar 2020 17:07:45 +0300 Subject: [PATCH] Support new 'typeParametersSerializers' function from GeneratedSerializer --- .../backend/common/SerializerCodegen.kt | 36 ++++++++----------- .../backend/ir/SerializerIrGenerator.kt | 12 +++++++ .../backend/js/SerializerJsTranslator.kt | 7 ++++ .../backend/jvm/SerializerCodegenImpl.kt | 5 +++ .../resolve/KSerializerDescriptorResolver.kt | 11 +++--- .../compiler/resolve/NamingConventions.kt | 8 ++++- 6 files changed, 52 insertions(+), 27 deletions(-) diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializerCodegen.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializerCodegen.kt index 97033d447fa..a3a1ed859fb 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializerCodegen.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializerCodegen.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlinx.serialization.compiler.backend.common @@ -21,7 +10,6 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered import org.jetbrains.kotlinx.serialization.compiler.resolve.* abstract class SerializerCodegen( @@ -45,7 +33,7 @@ abstract class SerializerCodegen( generateSerialDesc() val save = generateSaveIfNeeded() val load = generateLoadIfNeeded() - generateDescriptorGetterIfNeeded() + generateMembersFromGeneratedSerializer() if (!prop && (save || load)) generateSerialDesc() if (serializableDescriptor.declaredTypeParameters.isNotEmpty()) { @@ -55,15 +43,19 @@ abstract class SerializerCodegen( } } - private fun generateDescriptorGetterIfNeeded(): Boolean { - val function = getMemberToGenerate( - serializerDescriptor, SerialEntityNames.GENERATED_DESCRIPTOR_GETTER.identifier, - { true }, { true } - ) ?: return false - generateChildSerializersGetter(function) - return true + private fun generateMembersFromGeneratedSerializer() { + getMemberToGenerate( + serializerDescriptor, SerialEntityNames.CHILD_SERIALIZERS_GETTER.identifier, + { true }, { it.isEmpty() } + )?.let { generateChildSerializersGetter(it) } + getMemberToGenerate( + serializerDescriptor, SerialEntityNames.TYPE_PARAMS_SERIALIZERS_GETTER.identifier, + { true }, { it.isEmpty() } + )?.takeIf { it.kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE }?.let { generateTypeParamsSerializersGetter(it) } } + protected abstract fun generateTypeParamsSerializersGetter(function: FunctionDescriptor) + protected abstract fun generateChildSerializersGetter(function: FunctionDescriptor) protected val generatedSerialDescPropertyDescriptor = getPropertyToGenerate( diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerIrGenerator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerIrGenerator.kt index d84c7a10a21..95d95dd04f9 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerIrGenerator.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerIrGenerator.kt @@ -194,6 +194,18 @@ open class SerializerIrGenerator(val irClass: IrClass, final override val compil +irReturn(array) } + override fun generateTypeParamsSerializersGetter(function: FunctionDescriptor) = irClass.contributeFunction(function) { irFun -> + val typeParams = serializableDescriptor.declaredTypeParameters.mapIndexed { idx, _ -> + irGetField( + irGet(irFun.dispatchReceiverParameter!!), + compilerContext.symbolTable.referenceField(localSerializersFieldsDescriptors[idx]).owner + ) + } + val kSerType = ((irFun.returnType as IrSimpleType).arguments.first() as IrTypeProjection).type + val array = createArrayOfExpression(kSerType, typeParams) + +irReturn(array) + } + override fun generateSerializableClassProperty(property: PropertyDescriptor) { /* Already implemented in .generateSerialClassDesc ? */ } diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializerJsTranslator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializerJsTranslator.kt index 1f3cb6b8c72..4d4b28231ff 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializerJsTranslator.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializerJsTranslator.kt @@ -111,6 +111,13 @@ open class SerializerJsTranslator( +JsReturn(JsArrayLiteral(allSerializers)) } + override fun generateTypeParamsSerializersGetter(function: FunctionDescriptor) = generateFunction(function) { _, _ -> + val typeParams = serializableDescriptor.declaredTypeParameters.mapIndexed { idx, _ -> + JsNameRef(context.scope().declareName("$typeArgPrefix$idx"), JsThisRef()) + } + +JsReturn(JsArrayLiteral(typeParams)) + } + override fun generateSerializableClassProperty(property: PropertyDescriptor) { val propDesc = generatedSerialDescPropertyDescriptor ?: return val propTranslator = DefaultPropertyTranslator( diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializerCodegenImpl.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializerCodegenImpl.kt index 5f9fb7c6f67..0d15f075d5b 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializerCodegenImpl.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializerCodegenImpl.kt @@ -185,6 +185,11 @@ open class SerializerCodegenImpl( } } + override fun generateTypeParamsSerializersGetter(function: FunctionDescriptor) = codegen.generateMethod(function) { _, _ -> + genArrayOfTypeParametersSerializers() + areturn(kSerializerArrayType) + } + override fun generateChildSerializersGetter(function: FunctionDescriptor) { codegen.generateMethod(function) { _, _ -> val size = serializableProperties.size diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializerDescriptorResolver.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializerDescriptorResolver.kt index e035c8c6bd5..399f366179d 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializerDescriptorResolver.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializerDescriptorResolver.kt @@ -16,8 +16,6 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.platform.js.isJs -import org.jetbrains.kotlin.platform.jvm.isJvm import org.jetbrains.kotlin.platform.konan.isNative import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor import org.jetbrains.kotlin.resolve.BindingContext @@ -213,11 +211,16 @@ object KSerializerDescriptorResolver { shouldAddSerializerFunction { classDescriptor.checkSaveMethodParameters(it.valueParameters) } val isLoad = name == SerialEntityNames.LOAD_NAME && shouldAddSerializerFunction { classDescriptor.checkLoadMethodParameters(it.valueParameters) } - val isDescriptorGetter = name == SerialEntityNames.GENERATED_DESCRIPTOR_GETTER && + val isDescriptorGetter = name == SerialEntityNames.CHILD_SERIALIZERS_GETTER && thisDescriptor.typeConstructor.supertypes.any(::isGeneratedKSerializer) && shouldAddSerializerFunction { true /* TODO? */ } - if (isSave || isLoad || isDescriptorGetter) { + val isTypeParamsSerializersGetter = name == SerialEntityNames.TYPE_PARAMS_SERIALIZERS_GETTER && + thisDescriptor.typeConstructor.supertypes.any(::isGeneratedKSerializer) && + classDescriptor.declaredTypeParameters.isNotEmpty() && + shouldAddSerializerFunction { true /* TODO? */ } + + if (isSave || isLoad || isDescriptorGetter || isTypeParamsSerializersGetter) { result.add(doCreateSerializerFunction(thisDescriptor, name)) } } diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/NamingConventions.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/NamingConventions.kt index 212498e28b3..9585e23ea65 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/NamingConventions.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/NamingConventions.kt @@ -1,3 +1,8 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + package org.jetbrains.kotlinx.serialization.compiler.resolve import org.jetbrains.kotlin.name.FqName @@ -66,7 +71,8 @@ object SerialEntityNames { val SERIAL_DESC_FIELD_NAME = Name.identifier(SERIAL_DESC_FIELD) val SAVE_NAME = Name.identifier(SAVE) val LOAD_NAME = Name.identifier(LOAD) - val GENERATED_DESCRIPTOR_GETTER = Name.identifier("childSerializers") + val CHILD_SERIALIZERS_GETTER = Name.identifier("childSerializers") + val TYPE_PARAMS_SERIALIZERS_GETTER = Name.identifier("typeParametersSerializers") val WRITE_SELF_NAME = Name.identifier("write\$Self") val SERIALIZER_PROVIDER_NAME = Name.identifier("serializer")