Added support of external serializers to the FIR
Co-authored-by: Leonid Startsev <leonid.startsev@jetbrains.com> Merge-request: KT-MR-7334 Merged-by: Sergey Shanshin <Sergey.Shanshin@jetbrains.com>
This commit is contained in:
committed by
Space Team
parent
817afcd4af
commit
5a1c2c56bd
+8
-6
@@ -15,12 +15,9 @@ import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.companionObject
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.isInlineClass
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializerCodegen
|
||||
import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.bitMaskSlotCount
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.hasCompanionObjectAsSerializer
|
||||
|
||||
/**
|
||||
* Generates only specific declarations, but NOT their bodies.
|
||||
@@ -43,7 +40,12 @@ class IrPreGenerator(
|
||||
private fun preGenerateWriteSelfMethodIfNeeded() {
|
||||
if (!irClass.isInternalSerializable) return
|
||||
val serializerDescriptor = irClass.classSerializer(compilerContext)?.owner ?: return
|
||||
if (!irClass.shouldHaveSpecificSyntheticMethods { serializerDescriptor.findPluginGeneratedMethod(SerialEntityNames.SAVE) }) return
|
||||
if (!irClass.shouldHaveSpecificSyntheticMethods {
|
||||
serializerDescriptor.findPluginGeneratedMethod(
|
||||
SerialEntityNames.SAVE,
|
||||
compilerContext.afterK2
|
||||
)
|
||||
}) return
|
||||
if (irClass.findWriteSelfMethod() != null) return
|
||||
val method = irClass.addFunction {
|
||||
name = SerialEntityNames.WRITE_SELF_NAME
|
||||
@@ -95,7 +97,7 @@ class IrPreGenerator(
|
||||
if (!irClass.isInternalSerializable) return
|
||||
// do not add synthetic deserialization constructor if .deserialize method is customized
|
||||
if (irClass.hasCompanionObjectAsSerializer && irClass.companionObject()
|
||||
?.findPluginGeneratedMethod(SerialEntityNames.LOAD) == null
|
||||
?.findPluginGeneratedMethod(SerialEntityNames.LOAD, compilerContext.afterK2) == null
|
||||
) return
|
||||
if (irClass.isValue) return
|
||||
if (irClass.findSerializableSyntheticConstructor() != null) return
|
||||
@@ -133,4 +135,4 @@ class IrPreGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+10
-5
@@ -57,9 +57,9 @@ internal val IrClass.isInternallySerializableObject: Boolean
|
||||
get() = kind == ClassKind.OBJECT && hasSerializableOrMetaAnnotationWithoutArgs()
|
||||
|
||||
|
||||
internal fun IrClass.findPluginGeneratedMethod(name: String): IrSimpleFunction? {
|
||||
internal fun IrClass.findPluginGeneratedMethod(name: String, afterK2: Boolean): IrSimpleFunction? {
|
||||
return this.functions.find {
|
||||
it.name.asString() == name && it.isFromPlugin()
|
||||
it.name.asString() == name && it.isFromPlugin(afterK2)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,8 +147,13 @@ fun IrClass.getSuperClassNotAny(): IrClass? {
|
||||
}
|
||||
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
internal fun IrDeclaration.isFromPlugin(): Boolean =
|
||||
this.origin == IrDeclarationOrigin.GeneratedByPlugin(SerializationPluginKey) || (this.descriptor as? CallableMemberDescriptor)?.kind == CallableMemberDescriptor.Kind.SYNTHESIZED // old FE doesn't specify origin
|
||||
internal fun IrDeclaration.isFromPlugin(afterK2: Boolean): Boolean =
|
||||
if (afterK2) {
|
||||
this.origin == IrDeclarationOrigin.GeneratedByPlugin(SerializationPluginKey)
|
||||
} else {
|
||||
// old FE doesn't specify custom origin
|
||||
(this.descriptor as? CallableMemberDescriptor)?.kind == CallableMemberDescriptor.Kind.SYNTHESIZED
|
||||
}
|
||||
|
||||
internal fun IrConstructor.isSerializationCtor(): Boolean {
|
||||
/*kind == CallableMemberDescriptor.Kind.SYNTHESIZED does not work because DeserializedClassConstructorDescriptor loses its kind*/
|
||||
@@ -248,4 +253,4 @@ fun IrSimpleType.argumentTypesOrUpperBounds(): List<IrType> {
|
||||
}
|
||||
|
||||
internal inline fun IrClass.shouldHaveSpecificSyntheticMethods(functionPresenceChecker: () -> IrSimpleFunction?) =
|
||||
!isValue && (isAbstractOrSealedSerializableClass || functionPresenceChecker() != null)
|
||||
!isValue && (isAbstractOrSealedSerializableClass || functionPresenceChecker() != null)
|
||||
|
||||
+1
-1
@@ -157,7 +157,7 @@ class SerializableCompanionIrGenerator(
|
||||
it.valueParameters.size == 1
|
||||
&& it.valueParameters.first().isVararg
|
||||
&& it.returnType.isKSerializer()
|
||||
&& it.isFromPlugin()
|
||||
&& it.isFromPlugin(compilerContext.afterK2)
|
||||
}?.let { return it }
|
||||
val kSerializerStarType = compilerContext.getClassFromRuntime(SerialEntityNames.KSERIALIZER_CLASS).starProjectedType
|
||||
val f = irClass.addFunction(
|
||||
|
||||
+2
-2
@@ -359,7 +359,7 @@ class SerializableIrGenerator(
|
||||
|
||||
private fun generateSyntheticInternalConstructor() {
|
||||
val serializerDescriptor = irClass.classSerializer(compilerContext)?.owner ?: return
|
||||
if (irClass.shouldHaveSpecificSyntheticMethods { serializerDescriptor.findPluginGeneratedMethod(LOAD) }) {
|
||||
if (irClass.shouldHaveSpecificSyntheticMethods { serializerDescriptor.findPluginGeneratedMethod(LOAD, compilerContext.afterK2) }) {
|
||||
val constrDesc = irClass.constructors.find(IrConstructor::isSerializationCtor) ?: return
|
||||
generateInternalConstructor(constrDesc)
|
||||
}
|
||||
@@ -367,7 +367,7 @@ class SerializableIrGenerator(
|
||||
|
||||
private fun generateSyntheticMethods() {
|
||||
val serializerDescriptor = irClass.classSerializer(compilerContext)?.owner ?: return
|
||||
if (irClass.shouldHaveSpecificSyntheticMethods { serializerDescriptor.findPluginGeneratedMethod(SAVE) }) {
|
||||
if (irClass.shouldHaveSpecificSyntheticMethods { serializerDescriptor.findPluginGeneratedMethod(SAVE, compilerContext.afterK2) }) {
|
||||
val func = irClass.findWriteSelfMethod() ?: return
|
||||
func.origin = SERIALIZATION_PLUGIN_ORIGIN
|
||||
generateWriteSelfMethod(func)
|
||||
|
||||
+8
-7
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.isInlineClass
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationDescriptorSerializerPlugin
|
||||
@@ -63,7 +62,7 @@ open class SerializerIrGenerator(
|
||||
protected val generatedSerialDescPropertyDescriptor = getProperty(
|
||||
SerialEntityNames.SERIAL_DESC_FIELD,
|
||||
{ true }
|
||||
)?.takeIf { it.isFromPlugin() }
|
||||
)?.takeIf { it.isFromPlugin(compilerContext.afterK2) }
|
||||
|
||||
protected val anySerialDescProperty = getProperty(
|
||||
SerialEntityNames.SERIAL_DESC_FIELD,
|
||||
@@ -592,15 +591,17 @@ open class SerializerIrGenerator(
|
||||
val prop = generatedSerialDescPropertyDescriptor?.let { generateSerializableClassProperty(it); true } ?: false
|
||||
if (prop)
|
||||
generateSerialDesc()
|
||||
val save = irClass.findPluginGeneratedMethod(SAVE)?.let { generateSave(it); true } ?: false
|
||||
val load = irClass.findPluginGeneratedMethod(LOAD)?.let { generateLoad(it); true } ?: false
|
||||
irClass.findPluginGeneratedMethod(SerialEntityNames.CHILD_SERIALIZERS_GETTER.identifier)?.let { generateChildSerializersGetter(it) }
|
||||
irClass.findPluginGeneratedMethod(SerialEntityNames.TYPE_PARAMS_SERIALIZERS_GETTER.identifier)
|
||||
val withFir = compilerContext.afterK2
|
||||
val save = irClass.findPluginGeneratedMethod(SAVE, withFir)?.let { generateSave(it); true } ?: false
|
||||
val load = irClass.findPluginGeneratedMethod(LOAD, withFir)?.let { generateLoad(it); true } ?: false
|
||||
irClass.findPluginGeneratedMethod(SerialEntityNames.CHILD_SERIALIZERS_GETTER.identifier, withFir)
|
||||
?.let { generateChildSerializersGetter(it) }
|
||||
irClass.findPluginGeneratedMethod(SerialEntityNames.TYPE_PARAMS_SERIALIZERS_GETTER.identifier, withFir)
|
||||
?.let { generateTypeParamsSerializersGetter(it) }
|
||||
if (!prop && (save || load))
|
||||
generateSerialDesc()
|
||||
if (serializableIrClass.typeParameters.isNotEmpty()) {
|
||||
findSerializerConstructorForTypeArgumentsSerializers(irClass)?.takeIf { it.owner.isFromPlugin() }?.let {
|
||||
findSerializerConstructorForTypeArgumentsSerializers(irClass)?.takeIf { it.owner.isFromPlugin(withFir) }?.let {
|
||||
generateGenericFieldsAndConstructor(it.owner)
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.backend.common.CompilationException
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrIntrinsicExtension
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContextImpl
|
||||
import org.jetbrains.kotlin.backend.common.runOnFilePostfix
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.fileParent
|
||||
|
||||
Reference in New Issue
Block a user