Make write$Self a static function

This commit is contained in:
Leonid Startsev
2018-12-11 15:36:56 +03:00
parent 7c942af13d
commit 36e1d6668b
7 changed files with 50 additions and 17 deletions
@@ -54,5 +54,7 @@ abstract class SerializableCodegen(
protected abstract fun generateInternalConstructor(constructorDescriptor: ClassConstructorDescriptor)
protected abstract fun generateWriteSelfMethod(methodDescriptor: FunctionDescriptor)
protected open fun generateWriteSelfMethod(methodDescriptor: FunctionDescriptor) {
}
}
@@ -13,6 +13,8 @@ import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.TypeTranslator
@@ -20,8 +20,8 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.codegen.CompilationException
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.js.backend.ast.*
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
import org.jetbrains.kotlin.js.translate.context.Namer
@@ -109,7 +109,7 @@ class SerializableCodegenImpl(
}
val superSignature =
classCodegen.typeMapper.mapSignatureSkipGeneric(KSerializerDescriptorResolver.createWriteSelfFunctionDescriptor(superClass))
invokespecial(
invokestatic(
classCodegen.typeMapper.mapType(superClass).internalName,
superSignature.asmMethod.name,
superSignature.asmMethod.descriptor,
@@ -242,8 +242,9 @@ class SerializableCodegenImpl(
load(0, thisAsmType)
if (!superClass.isInternalSerializable) {
require(superClass.constructors.firstOrNull { it.valueParameters.isEmpty() } != null,
{ "Non-serializable parent of serializable $serializableDescriptor must have no arg constructor" })
require(superClass.constructors.firstOrNull { it.valueParameters.isEmpty() } != null) {
"Non-serializable parent of serializable $serializableDescriptor must have no arg constructor"
}
// call
// Sealed classes have private <init> so they cannot be inherited from Java src
@@ -20,13 +20,10 @@ import org.jetbrains.kotlin.codegen.ImplementationBodyCodegen
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializableCompanionCodegen
import org.jetbrains.kotlinx.serialization.compiler.resolve.classSerializer
import org.jetbrains.kotlinx.serialization.compiler.resolve.getSerializableClassDescriptorByCompanion
import org.jetbrains.kotlinx.serialization.compiler.resolve.shouldHaveGeneratedMethodsInCompanion
import org.jetbrains.kotlinx.serialization.compiler.resolve.toClassDescriptor
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
class SerializableCompanionCodegenImpl(private val codegen: ImplementationBodyCodegen) :
SerializableCompanionCodegen(codegen.descriptor, codegen.bindingContext) {
class SerializableCompanionCodegenImpl(private val classCodegen: ImplementationBodyCodegen) :
SerializableCompanionCodegen(classCodegen.descriptor, classCodegen.bindingContext) {
companion object {
fun generateSerializableExtensions(codegen: ImplementationBodyCodegen) {
@@ -38,8 +35,15 @@ class SerializableCompanionCodegenImpl(private val codegen: ImplementationBodyCo
override fun generateSerializerGetter(methodDescriptor: FunctionDescriptor) {
val serial = serializableDescriptor.classSerializer?.toClassDescriptor ?: return
codegen.generateMethod(methodDescriptor) { _, _ ->
stackValueSerializerInstance(codegen, serializableDescriptor.module, serializableDescriptor.defaultType, serial, this, null) {
classCodegen.generateMethod(methodDescriptor) { _, _ ->
stackValueSerializerInstance(
classCodegen,
serializableDescriptor.module,
serializableDescriptor.defaultType,
serial,
this,
null
) {
load(it + 1, kSerializerType)
}
areturn(kSerializerType)
@@ -228,7 +228,7 @@ class SerializerCodegenImpl(
)
store(outputVar, kOutputType)
if (serializableDescriptor.isInternalSerializable) {
val sig = StringBuilder("(${kOutputType.descriptor}${descType.descriptor}")
val sig = StringBuilder("(${objType.descriptor}${kOutputType.descriptor}${descType.descriptor}")
// call obj.write$Self(output, classDesc)
load(objVar, objType)
load(outputVar, kOutputType)
@@ -239,7 +239,7 @@ class SerializerCodegenImpl(
sig.append(kSerializerType.descriptor)
}
sig.append(")V")
invokevirtual(
invokestatic(
objType.internalName, SerialEntityNames.WRITE_SELF_NAME.asString(),
sig.toString(), false
)
@@ -18,13 +18,17 @@ package org.jetbrains.kotlinx.serialization.compiler.resolve
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.*
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.psi.synthetics.SyntheticClassOrObjectDescriptor
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.lazy.LazyClassContext
import org.jetbrains.kotlin.resolve.lazy.declarations.ClassMemberDeclarationProvider
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyClassDescriptor
@@ -424,9 +428,18 @@ object KSerializerDescriptorResolver {
else this.makeNullable()
fun createWriteSelfFunctionDescriptor(thisClass: ClassDescriptor): FunctionDescriptor {
val jvmStaticClass = thisClass.module.findClassAcrossModuleDependencies(
ClassId(
FqName("kotlin.jvm"),
Name.identifier("JvmStatic")
)
)!!
val jvmStaticAnnotation = AnnotationDescriptorImpl(jvmStaticClass.defaultType, mapOf(), jvmStaticClass.source)
val annotations = Annotations.create(listOf(jvmStaticAnnotation))
val f = SimpleFunctionDescriptorImpl.create(
thisClass,
Annotations.EMPTY,
annotations,
SerialEntityNames.WRITE_SELF_NAME,
CallableMemberDescriptor.Kind.SYNTHESIZED,
thisClass.source
@@ -435,6 +448,15 @@ object KSerializerDescriptorResolver {
val args = mutableListOf<ValueParameterDescriptor>()
var i = 0
// object
args.add(
ValueParameterDescriptorImpl(
f, null, i++, Annotations.EMPTY, Name.identifier("self"), thisClass.defaultType, false,
false, false, null, f.source
)
)
// encoder
args.add(
ValueParameterDescriptorImpl(
f,
@@ -451,6 +473,7 @@ object KSerializerDescriptorResolver {
)
)
//descriptor
args.add(
ValueParameterDescriptorImpl(
f,
@@ -469,6 +492,7 @@ object KSerializerDescriptorResolver {
val kSerialClassDesc = thisClass.getClassFromSerializationPackage(SerialEntityNames.KSERIALIZER_CLASS)
// type parameters serialziers
thisClass.declaredTypeParameters.forEach {
val typeArgument = TypeProjectionImpl(it.defaultType)
val kSerialClass = KotlinTypeFactory.simpleNotNullType(Annotations.EMPTY, kSerialClassDesc, listOf(typeArgument))
@@ -497,7 +521,7 @@ object KSerializerDescriptorResolver {
emptyList(),
args,
returnType,
Modality.OPEN,
Modality.FINAL,
Visibilities.PUBLIC
)