Support @SerialInfo annotation for Native
This commit is contained in:
+28
-4
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.ir.declarations.*
|
|||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
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.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
@@ -46,7 +47,7 @@ class SerializerIrGenerator(val irClass: IrClass, override val compilerContext:
|
|||||||
override val BackendContext.localSymbolTable: SymbolTable
|
override val BackendContext.localSymbolTable: SymbolTable
|
||||||
get() = _table
|
get() = _table
|
||||||
|
|
||||||
private val serializableIrClass = compilerContext.externalSymbols.referenceClass(serializableDescriptor)
|
private val serializableIrClass = compilerContext.externalSymbols.referenceClass(serializableDescriptor).owner
|
||||||
|
|
||||||
override fun generateSerialDesc() {
|
override fun generateSerialDesc() {
|
||||||
val desc: PropertyDescriptor = generatedSerialDescPropertyDescriptor ?: return
|
val desc: PropertyDescriptor = generatedSerialDescPropertyDescriptor ?: return
|
||||||
@@ -97,9 +98,21 @@ class SerializerIrGenerator(val irClass: IrClass, override val compilerContext:
|
|||||||
for (classProp in orderedProperties) {
|
for (classProp in orderedProperties) {
|
||||||
if (classProp.transient) continue
|
if (classProp.transient) continue
|
||||||
+addFieldCall(classProp.name)
|
+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(
|
+irSetField(
|
||||||
generateReceiverExpressionForFieldAccess(
|
generateReceiverExpressionForFieldAccess(
|
||||||
thisAsReceiverParameter.symbol,
|
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) =
|
override fun generateGenericFieldsAndConstructor(typedConstructorDescriptor: ClassConstructorDescriptor) =
|
||||||
irClass.contributeCtor(typedConstructorDescriptor) { ctor ->
|
irClass.contributeCtor(typedConstructorDescriptor) { ctor ->
|
||||||
// generate call to primary ctor to init serialClassDesc and super()
|
// 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 ->
|
override fun generateSave(function: FunctionDescriptor) = irClass.contributeFunction(function) { saveFunc ->
|
||||||
|
|
||||||
val fieldInitializer: (SerializableProperty) -> IrExpression? =
|
val fieldInitializer: (SerializableProperty) -> IrExpression? =
|
||||||
buildInitializersRemapping(serializableIrClass.owner).run { { invoke(it.irField) } }
|
buildInitializersRemapping(serializableIrClass).run { { invoke(it.irField) } }
|
||||||
|
|
||||||
fun irThis(): IrExpression =
|
fun irThis(): IrExpression =
|
||||||
IrGetValueImpl(startOffset, endOffset, saveFunc.dispatchReceiverParameter!!.symbol)
|
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() }
|
var args: List<IrExpression> = localProps.map { it.get() }
|
||||||
val ctor: IrConstructorSymbol = if (serializableDescriptor.isInternalSerializable) {
|
val ctor: IrConstructorSymbol = if (serializableDescriptor.isInternalSerializable) {
|
||||||
val ctorDesc = serializableIrClass
|
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()
|
args = listOf(irGet(bitMasks[0])) + args + irNull()
|
||||||
ctorDesc.symbol
|
ctorDesc.symbol
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+5
-1
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.types.*
|
|||||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||||
import org.jetbrains.kotlin.types.typeUtil.supertypes
|
import org.jetbrains.kotlin.types.typeUtil.supertypes
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.KSERIALIZER_CLASS
|
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
|
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationPackages.packageFqName
|
||||||
|
|
||||||
fun isAllowedToHaveAutoGeneratedSerializerMethods(classDescriptor: ClassDescriptor): Boolean {
|
fun isAllowedToHaveAutoGeneratedSerializerMethods(classDescriptor: ClassDescriptor): Boolean {
|
||||||
@@ -73,6 +74,9 @@ internal val DeclarationDescriptor.serializableWith: KotlinType?
|
|||||||
internal val DeclarationDescriptor.serializerForClass: KotlinType?
|
internal val DeclarationDescriptor.serializerForClass: KotlinType?
|
||||||
get() = annotations.findAnnotationKotlinTypeValue(SerializationAnnotations.serializerAnnotationFqName, module, "forClass")
|
get() = annotations.findAnnotationKotlinTypeValue(SerializationAnnotations.serializerAnnotationFqName, module, "forClass")
|
||||||
|
|
||||||
|
internal val ClassDescriptor.isSerialInfoAnnotation: Boolean
|
||||||
|
get() = annotations.hasAnnotation(serialInfoFqName)
|
||||||
|
|
||||||
val Annotations.serialNameValue: String?
|
val Annotations.serialNameValue: String?
|
||||||
get() {
|
get() {
|
||||||
val value = findAnnotationConstantValue<String?>(SerializationAnnotations.serialNameAnnotationFqName, "value")
|
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>>> =
|
fun Annotated.annotationsWithArguments(): List<Triple<ClassDescriptor, List<ValueArgument>, List<ValueParameterDescriptor>>> =
|
||||||
annotations.asSequence()
|
annotations.asSequence()
|
||||||
.filter { it.type.toClassDescriptor?.annotations?.hasAnnotation(SerializationAnnotations.serialInfoFqName) == true }
|
.filter { it.type.toClassDescriptor?.isSerialInfoAnnotation == true }
|
||||||
.filterIsInstance<LazyAnnotationDescriptor>()
|
.filterIsInstance<LazyAnnotationDescriptor>()
|
||||||
.mapNotNull { annDesc ->
|
.mapNotNull { annDesc ->
|
||||||
annDesc.type.toClassDescriptor?.let {
|
annDesc.type.toClassDescriptor?.let {
|
||||||
|
|||||||
Reference in New Issue
Block a user