Support @SerialInfo annotation for Native

This commit is contained in:
Leonid Startsev
2018-12-04 17:59:16 +03:00
parent 13af036024
commit f2e27da5bb
2 changed files with 33 additions and 5 deletions
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.resolve.BindingContext
@@ -46,7 +47,7 @@ class SerializerIrGenerator(val irClass: IrClass, override val compilerContext:
override val BackendContext.localSymbolTable: SymbolTable
get() = _table
private val serializableIrClass = compilerContext.externalSymbols.referenceClass(serializableDescriptor)
private val serializableIrClass = compilerContext.externalSymbols.referenceClass(serializableDescriptor).owner
override fun generateSerialDesc() {
val desc: PropertyDescriptor = generatedSerialDescPropertyDescriptor ?: return
@@ -97,9 +98,21 @@ class SerializerIrGenerator(val irClass: IrClass, override val compilerContext:
for (classProp in orderedProperties) {
if (classProp.transient) continue
+addFieldCall(classProp.name)
// serialDesc.pushAnnotation(...) todo
// add property annotations
copySerialInfoAnnotationsToDescriptor(
classProp.irField.correspondingProperty?.annotations.orEmpty(),
irGet(localDesc),
serialDescImplClass.referenceMethod(CallingConventions.addAnnotation)
)
}
// add class annotations
copySerialInfoAnnotationsToDescriptor(
serializableIrClass.annotations,
irGet(localDesc),
serialDescImplClass.referenceMethod(CallingConventions.addClassAnnotation)
)
// save local descriptor to field
+irSetField(
generateReceiverExpressionForFieldAccess(
thisAsReceiverParameter.symbol,
@@ -114,6 +127,17 @@ class SerializerIrGenerator(val irClass: IrClass, override val compilerContext:
}
}
private fun IrBlockBodyBuilder.copySerialInfoAnnotationsToDescriptor(
annotations: List<IrCall>,
receiver: IrExpression,
method: IrFunctionSymbol
) {
annotations.forEach { annotationCall ->
if ((annotationCall.descriptor as? ClassConstructorDescriptor)?.constructedClass?.isSerialInfoAnnotation == true)
+irInvoke(receiver, method, annotationCall)
}
}
override fun generateGenericFieldsAndConstructor(typedConstructorDescriptor: ClassConstructorDescriptor) =
irClass.contributeCtor(typedConstructorDescriptor) { ctor ->
// generate call to primary ctor to init serialClassDesc and super()
@@ -159,7 +183,7 @@ class SerializerIrGenerator(val irClass: IrClass, override val compilerContext:
override fun generateSave(function: FunctionDescriptor) = irClass.contributeFunction(function) { saveFunc ->
val fieldInitializer: (SerializableProperty) -> IrExpression? =
buildInitializersRemapping(serializableIrClass.owner).run { { invoke(it.irField) } }
buildInitializersRemapping(serializableIrClass).run { { invoke(it.irField) } }
fun irThis(): IrExpression =
IrGetValueImpl(startOffset, endOffset, saveFunc.dispatchReceiverParameter!!.symbol)
@@ -374,7 +398,7 @@ class SerializerIrGenerator(val irClass: IrClass, override val compilerContext:
var args: List<IrExpression> = localProps.map { it.get() }
val ctor: IrConstructorSymbol = if (serializableDescriptor.isInternalSerializable) {
val ctorDesc = serializableIrClass
.owner.constructors.single { it.origin == SERIALIZABLE_PLUGIN_ORIGIN }
.constructors.single { it.origin == SERIALIZABLE_PLUGIN_ORIGIN }
args = listOf(irGet(bitMasks[0])) + args + irNull()
ctorDesc.symbol
} else {
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
import org.jetbrains.kotlin.types.typeUtil.supertypes
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.KSERIALIZER_CLASS
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationAnnotations.serialInfoFqName
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationPackages.packageFqName
fun isAllowedToHaveAutoGeneratedSerializerMethods(classDescriptor: ClassDescriptor): Boolean {
@@ -73,6 +74,9 @@ internal val DeclarationDescriptor.serializableWith: KotlinType?
internal val DeclarationDescriptor.serializerForClass: KotlinType?
get() = annotations.findAnnotationKotlinTypeValue(SerializationAnnotations.serializerAnnotationFqName, module, "forClass")
internal val ClassDescriptor.isSerialInfoAnnotation: Boolean
get() = annotations.hasAnnotation(serialInfoFqName)
val Annotations.serialNameValue: String?
get() {
val value = findAnnotationConstantValue<String?>(SerializationAnnotations.serialNameAnnotationFqName, "value")
@@ -227,7 +231,7 @@ fun ClassDescriptor.toSimpleType(nullable: Boolean = true) = KotlinTypeFactory.s
fun Annotated.annotationsWithArguments(): List<Triple<ClassDescriptor, List<ValueArgument>, List<ValueParameterDescriptor>>> =
annotations.asSequence()
.filter { it.type.toClassDescriptor?.annotations?.hasAnnotation(SerializationAnnotations.serialInfoFqName) == true }
.filter { it.type.toClassDescriptor?.isSerialInfoAnnotation == true }
.filterIsInstance<LazyAnnotationDescriptor>()
.mapNotNull { annDesc ->
annDesc.type.toClassDescriptor?.let {