Support new 'typeParametersSerializers' function

from GeneratedSerializer
This commit is contained in:
Leonid Startsev
2020-03-17 17:07:45 +03:00
parent ceb3cfbfd5
commit d4fc6774f3
6 changed files with 52 additions and 27 deletions
@@ -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(
@@ -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 ? */
}
@@ -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(
@@ -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
@@ -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))
}
}
@@ -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")