Extension points for synthetic function contributions

Pass real type arguments serializers to runtime lib
This commit is contained in:
Leonid Startsev
2017-11-15 12:33:36 +03:00
parent 703d715334
commit 0f7a356af8
3 changed files with 30 additions and 6 deletions
@@ -123,9 +123,12 @@ class SerializerJsTranslator(declaration: KtPureClassOrObject,
val serialClassDescRef = JsNameRef(context.getNameForDescriptor(serialDescPropertyDescriptor!!), JsThisRef())
// output.writeBegin(desc, [])
val typeParams = serializableDescriptor.declaredTypeParameters.mapIndexed { idx, _ ->
JsNameRef(context.scope().declareName("$typeArgPrefix$idx"), JsThisRef())
}
val call = JsInvocation(JsNameRef(wBeginFunc, JsNameRef(jsFun.parameters[0].name)),
serialClassDescRef,
JsArrayLiteral())
JsArrayLiteral(typeParams))
val objRef = JsNameRef(jsFun.parameters[1].name)
// output = output.writeBegin...
val localOutputName = jsFun.scope.declareFreshName("output")
@@ -229,10 +232,13 @@ class SerializerJsTranslator(declaration: KtPureClassOrObject,
+JsVars(localProps.map { JsVars.JsVar(it.name) }, true)
//input = input.readBegin(...)
val typeParams = serializableDescriptor.declaredTypeParameters.mapIndexed { idx, _ ->
JsNameRef(context.scope().declareName("$typeArgPrefix$idx"), JsThisRef())
}
val inputVar = JsNameRef(jsFun.scope.declareFreshName("input"))
val readBeginF = inputClass.getFuncDesc("readBegin").single()
val call = JsInvocation(JsNameRef(context.getNameForDescriptor(readBeginF), JsNameRef(jsFun.parameters[0].name)),
serialClassDescRef, JsArrayLiteral())
serialClassDescRef, JsArrayLiteral(typeParams))
+JsVars(JsVars.JsVar(inputVar.name, call))
// while(true) {
@@ -140,8 +140,7 @@ class SerializerCodegenImpl(
// output = output.writeBegin(classDesc, new KSerializer[0])
load(outputVar, kOutputType)
load(descVar, descType)
iconst(0)
newarray(kSerializerType) // todo: use some predefined empty array
genArrayOfTypeParametersSerializers()
invokevirtual(kOutputType.internalName, "writeBegin",
"(" + descType.descriptor + kSerializerArrayType.descriptor +
")" + kOutputType.descriptor, false)
@@ -184,6 +183,19 @@ class SerializerCodegenImpl(
}
}
internal fun InstructionAdapter.genArrayOfTypeParametersSerializers() {
val size = serializableDescriptor.declaredTypeParameters.size
iconst(size)
newarray(kSerializerType) // todo: use some predefined empty array, if size is 0
for (i in 0 until size) {
dup() // array
iconst(i) // index
load(0, kSerializerType) // this.serialTypeI
getfield(codegen.typeMapper.mapClass(codegen.descriptor).internalName, "$typeArgPrefix$i", kSerializerType.descriptor)
astore(kSerializerType)
}
}
override fun generateLoad(
function: FunctionDescriptor
) {
@@ -218,8 +230,7 @@ class SerializerCodegenImpl(
// input = input.readBegin(classDesc, new KSerializer[0])
load(inputVar, kInputType)
load(descVar, descType)
iconst(0)
newarray(kSerializerType) // todo: use some predefined empty array
genArrayOfTypeParametersSerializers()
invokevirtual(kInputType.internalName, "readBegin",
"(" + descType.descriptor + kSerializerArrayType.descriptor +
")" + kInputType.descriptor, false)
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.resolve.lazy.LazyClassContext
import org.jetbrains.kotlin.resolve.lazy.declarations.ClassMemberDeclarationProvider
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializerDescriptorResolver
import org.jetbrains.kotlinx.serialization.compiler.resolve.getSerializableClassDescriptorByCompanion
import org.jetbrains.kotlinx.serialization.compiler.resolve.isInternalSerializable
import org.jetbrains.kotlinx.serialization.compiler.resolve.serialInfoFqName
import java.util.*
@@ -37,6 +38,12 @@ class SerializationResolveExtension : SyntheticResolveExtension {
else -> listOf()
}
override fun getSyntheticFunctionNames(thisDescriptor: ClassDescriptor): List<Name> = when {
thisDescriptor.isCompanionObject && getSerializableClassDescriptorByCompanion(thisDescriptor) != null ->
listOf(KSerializerDescriptorResolver.SERIALIZER_PROVIDER_NAME)
else -> emptyList()
}
override fun generateSyntheticClasses(thisDescriptor: ClassDescriptor, name: Name, ctx: LazyClassContext, declarationProvider: ClassMemberDeclarationProvider, result: MutableSet<ClassDescriptor>) {
if (thisDescriptor.annotations.hasAnnotation(serialInfoFqName) && name == KSerializerDescriptorResolver.IMPL_NAME)
result.add(KSerializerDescriptorResolver.addSerialInfoImplClass(thisDescriptor, declarationProvider, ctx))