From 8d999a2c13bbc5a3412160d543315091bfa86043 Mon Sep 17 00:00:00 2001 From: Leonid Startsev Date: Thu, 15 Oct 2020 22:42:06 +0300 Subject: [PATCH] Disable kx.ser plugin inside descriptors serialization in the IDE Since IDE does not perform any serialization of descriptors, and metadata written to the 'serializationDescriptorSerializer' deleted only on call to DescriptorSerializer, enabling this extension in the IDE effectively causes memory leaks. #KT-39624 Fixed Pass SerializationDescriptorSerializerPlugin to other extensions directly instead of using static val in companion. --- .../META-INF/kotlinx-serialization.xml | 1 - .../backend/common/SerializerCodegen.kt | 6 +++-- .../backend/ir/SerializerForEnumsGenerator.kt | 2 +- .../backend/ir/SerializerIrGenerator.kt | 17 ++++++++++---- .../js/SerializerForEnumsTranslator.kt | 2 +- .../backend/js/SerializerJsTranslator.kt | 17 ++++++++++---- .../backend/jvm/SerializerCodegenImpl.kt | 10 ++++---- .../backend/jvm/SerializerForEnumsCodegen.kt | 2 +- .../SerializationCodegenExtension.kt | 4 ++-- .../SerializationComponentRegistrar.kt | 23 +++++++++++-------- ...erializationDescriptorSerializerPlugin.kt} | 2 +- .../extensions/SerializationJsExtension.kt | 4 ++-- .../SerializationLoweringExtension.kt | 9 ++++---- .../SerializationResolveExtension.kt | 4 ++-- .../resolve/KSerializerDescriptorResolver.kt | 8 +++---- .../resolve/SerializableProperties.kt | 5 ++-- 16 files changed, 69 insertions(+), 47 deletions(-) rename plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/{SerializationDescriptorPluginForKotlinxSerialization.kt => SerializationDescriptorSerializerPlugin.kt} (95%) diff --git a/idea/resources/META-INF/kotlinx-serialization.xml b/idea/resources/META-INF/kotlinx-serialization.xml index e07cc010ae4..3e2a22229ab 100644 --- a/idea/resources/META-INF/kotlinx-serialization.xml +++ b/idea/resources/META-INF/kotlinx-serialization.xml @@ -4,7 +4,6 @@ - diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializerCodegen.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializerCodegen.kt index a3a1ed859fb..53ba437fb65 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializerCodegen.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializerCodegen.kt @@ -10,15 +10,17 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationDescriptorSerializerPlugin import org.jetbrains.kotlinx.serialization.compiler.resolve.* abstract class SerializerCodegen( protected val serializerDescriptor: ClassDescriptor, - bindingContext: BindingContext + bindingContext: BindingContext, + metadataPlugin: SerializationDescriptorSerializerPlugin? ) : AbstractSerialGenerator(bindingContext, serializerDescriptor) { val serializableDescriptor: ClassDescriptor = getSerializableClassDescriptorBySerializer(serializerDescriptor)!! protected val serialName: String = serializableDescriptor.serialName() - protected val properties = bindingContext.serializablePropertiesFor(serializableDescriptor) + protected val properties = bindingContext.serializablePropertiesFor(serializableDescriptor, metadataPlugin) protected val serializableProperties = properties.serializableProperties private fun checkSerializability() { diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerForEnumsGenerator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerForEnumsGenerator.kt index 5015364709f..c5471b75d7d 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerForEnumsGenerator.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerForEnumsGenerator.kt @@ -29,7 +29,7 @@ class SerializerForEnumsGenerator( compilerContext: SerializationPluginContext, bindingContext: BindingContext ) : - SerializerIrGenerator(irClass, compilerContext, bindingContext) { + SerializerIrGenerator(irClass, compilerContext, bindingContext, null) { override fun generateSave(function: FunctionDescriptor) = irClass.contributeFunction(function) { saveFunc -> fun irThis(): IrExpression = diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerIrGenerator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerIrGenerator.kt index ebd938b84ed..608760c51a0 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerIrGenerator.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerIrGenerator.kt @@ -32,6 +32,7 @@ import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializerCodegen import org.jetbrains.kotlinx.serialization.compiler.backend.common.getSerialTypeInfo +import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationDescriptorSerializerPlugin import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext import org.jetbrains.kotlinx.serialization.compiler.resolve.* import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.DECODER_CLASS @@ -44,15 +45,20 @@ import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.UN // Is creating synthetic origin is a good idea or not? object SERIALIZABLE_PLUGIN_ORIGIN : IrDeclarationOriginImpl("SERIALIZER") -open class SerializerIrGenerator(val irClass: IrClass, final override val compilerContext: SerializationPluginContext, bindingContext: BindingContext) : - SerializerCodegen(irClass.descriptor, bindingContext), IrBuilderExtension { +open class SerializerIrGenerator( + val irClass: IrClass, + final override val compilerContext: SerializationPluginContext, + bindingContext: BindingContext, + metadataPlugin: SerializationDescriptorSerializerPlugin? +) : + SerializerCodegen(irClass.descriptor, bindingContext, metadataPlugin), IrBuilderExtension { protected val serializableIrClass = compilerContext.symbolTable.referenceClass(serializableDescriptor).owner protected val irAnySerialDescProperty = anySerialDescProperty?.let { compilerContext.symbolTable.referenceProperty(it) } protected open val serialDescImplClass: ClassDescriptor = serializerDescriptor - .getClassFromInternalSerializationPackage(SERIAL_DESCRIPTOR_CLASS_IMPL) + .getClassFromInternalSerializationPackage(SERIAL_DESCRIPTOR_CLASS_IMPL) override fun generateSerialDesc() { val desc: PropertyDescriptor = generatedSerialDescPropertyDescriptor ?: return @@ -493,13 +499,14 @@ open class SerializerIrGenerator(val irClass: IrClass, final override val compil fun generate( irClass: IrClass, context: SerializationPluginContext, - bindingContext: BindingContext + bindingContext: BindingContext, + metadataPlugin: SerializationDescriptorSerializerPlugin? ) { val serializableDesc = getSerializableClassDescriptorBySerializer(irClass.symbol.descriptor) ?: return if (serializableDesc.isSerializableEnum()) { SerializerForEnumsGenerator(irClass, context, bindingContext).generate() } else { - SerializerIrGenerator(irClass, context, bindingContext).generate() + SerializerIrGenerator(irClass, context, bindingContext, metadataPlugin).generate() } irClass.patchDeclarationParents(irClass.parent) } diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializerForEnumsTranslator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializerForEnumsTranslator.kt index 71b5ea0c83e..62d1a6152f9 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializerForEnumsTranslator.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializerForEnumsTranslator.kt @@ -20,7 +20,7 @@ class SerializerForEnumsTranslator( descriptor: ClassDescriptor, translator: DeclarationBodyVisitor, context: TranslationContext -) : SerializerJsTranslator(descriptor, translator, context) { +) : SerializerJsTranslator(descriptor, translator, context, null) { override fun generateSave(function: FunctionDescriptor) = generateFunction(function) { jsFun, ctx -> val encoderClass = serializerDescriptor.getClassFromSerializationPackage(SerialEntityNames.ENCODER_CLASS) val serialClassDescRef = JsNameRef(context.getNameForDescriptor(anySerialDescProperty!!), JsThisRef()) diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializerJsTranslator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializerJsTranslator.kt index d056deb019f..75e792df367 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializerJsTranslator.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializerJsTranslator.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.psi.KtPureClassOrObject import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializerCodegen import org.jetbrains.kotlinx.serialization.compiler.backend.common.getSerialTypeInfo +import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationDescriptorSerializerPlugin import org.jetbrains.kotlinx.serialization.compiler.resolve.* import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.SERIAL_DESCRIPTOR_CLASS_IMPL import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.typeArgPrefix @@ -32,8 +33,9 @@ import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.ty open class SerializerJsTranslator( descriptor: ClassDescriptor, val translator: DeclarationBodyVisitor, - val context: TranslationContext -) : SerializerCodegen(descriptor, context.bindingContext()) { + val context: TranslationContext, + metadataPlugin: SerializationDescriptorSerializerPlugin? +) : SerializerCodegen(descriptor, context.bindingContext(), metadataPlugin) { internal fun generateFunction(descriptor: FunctionDescriptor, bodyGen: JsBlockBuilder.(JsFunction, TranslationContext) -> Unit) { val f = context.buildFunction(descriptor, bodyGen) @@ -351,7 +353,11 @@ open class SerializerJsTranslator( // deserialization constructor call // todo: external deserialization with primary constructor and setters calls after resolution of KT-11586 - val constrDesc = KSerializerDescriptorResolver.createLoadConstructorDescriptor(serializableDescriptor, context.bindingContext()) + val constrDesc = KSerializerDescriptorResolver.createLoadConstructorDescriptor( + serializableDescriptor, + context.bindingContext(), + null + ) val constrRef = context.getInnerNameForDescriptor(constrDesc).makeRef() val args: MutableList = bitMasks.toMutableList() args += localProps @@ -363,13 +369,14 @@ open class SerializerJsTranslator( fun translate( descriptor: ClassDescriptor, translator: DeclarationBodyVisitor, - context: TranslationContext + context: TranslationContext, + metadataPlugin: SerializationDescriptorSerializerPlugin? ) { val serializableDesc = getSerializableClassDescriptorBySerializer(descriptor) ?: return if (serializableDesc.isSerializableEnum()) { SerializerForEnumsTranslator(descriptor, translator, context).generate() } else { - SerializerJsTranslator(descriptor, translator, context).generate() + SerializerJsTranslator(descriptor, translator, context, metadataPlugin).generate() } } } diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializerCodegenImpl.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializerCodegenImpl.kt index a33358dfa79..02d35959278 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializerCodegenImpl.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializerCodegenImpl.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.psi.ValueArgument import org.jetbrains.kotlin.resolve.jvm.AsmTypes import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializerCodegen +import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationDescriptorSerializerPlugin import org.jetbrains.kotlinx.serialization.compiler.resolve.* import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.typeArgPrefix import org.jetbrains.org.objectweb.asm.Label @@ -21,8 +22,9 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter open class SerializerCodegenImpl( protected val codegen: ImplementationBodyCodegen, - serializableClass: ClassDescriptor -) : SerializerCodegen(codegen.descriptor, codegen.bindingContext) { + serializableClass: ClassDescriptor, + metadataPlugin: SerializationDescriptorSerializerPlugin? +) : SerializerCodegen(codegen.descriptor, codegen.bindingContext, metadataPlugin) { private val serialDescField = "\$\$serialDesc" @@ -34,12 +36,12 @@ open class SerializerCodegenImpl( private val staticDescriptor = serializableDescriptor.declaredTypeParameters.isEmpty() companion object { - fun generateSerializerExtensions(codegen: ImplementationBodyCodegen) { + fun generateSerializerExtensions(codegen: ImplementationBodyCodegen, metadataPlugin: SerializationDescriptorSerializerPlugin?) { val serializableClass = getSerializableClassDescriptorBySerializer(codegen.descriptor) ?: return val serializerCodegen = if (serializableClass.isSerializableEnum()) { SerializerForEnumsCodegen(codegen, serializableClass) } else { - SerializerCodegenImpl(codegen, serializableClass) + SerializerCodegenImpl(codegen, serializableClass, metadataPlugin) } serializerCodegen.generate() } diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializerForEnumsCodegen.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializerForEnumsCodegen.kt index 04af0fa80ed..516b2daac1c 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializerForEnumsCodegen.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializerForEnumsCodegen.kt @@ -12,7 +12,7 @@ import org.jetbrains.org.objectweb.asm.Type class SerializerForEnumsCodegen( codegen: ImplementationBodyCodegen, serializableClass: ClassDescriptor -) : SerializerCodegenImpl(codegen, serializableClass) { +) : SerializerCodegenImpl(codegen, serializableClass, null) { override fun generateSave(function: FunctionDescriptor) = codegen.generateMethod(function) { _, _ -> // fun save(output: KOutput, obj : T) val outputVar = 1 diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationCodegenExtension.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationCodegenExtension.kt index 8ea648b00fd..2a6d75b449e 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationCodegenExtension.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationCodegenExtension.kt @@ -23,11 +23,11 @@ import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.SerializableCode import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.SerializableCompanionCodegenImpl import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.SerializerCodegenImpl -open class SerializationCodegenExtension : ExpressionCodegenExtension { +open class SerializationCodegenExtension @JvmOverloads constructor(val metadataPlugin: SerializationDescriptorSerializerPlugin? = null) : ExpressionCodegenExtension { override fun generateClassSyntheticParts(codegen: ImplementationBodyCodegen) { SerialInfoCodegenImpl.generateSerialInfoImplBody(codegen) SerializableCodegenImpl.generateSerializableExtensions(codegen) - SerializerCodegenImpl.generateSerializerExtensions(codegen) + SerializerCodegenImpl.generateSerializerExtensions(codegen, metadataPlugin) SerializableCompanionCodegenImpl.generateSerializableExtensions(codegen) } diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationComponentRegistrar.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationComponentRegistrar.kt index 75313dd7043..d5949df18f7 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationComponentRegistrar.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationComponentRegistrar.kt @@ -30,19 +30,22 @@ class SerializationComponentRegistrar : ComponentRegistrar { } companion object { - internal val serializationDescriptorSerializer = SerializationDescriptorPluginForKotlinxSerialization() - fun registerExtensions(project: Project) { - SyntheticResolveExtension.registerExtension(project, SerializationResolveExtension()) - - ExpressionCodegenExtension.registerExtension(project, SerializationCodegenExtension()) - JsSyntheticTranslateExtension.registerExtension(project, SerializationJsExtension()) - IrGenerationExtension.registerExtension(project, SerializationLoweringExtension()) - - StorageComponentContainerContributor.registerExtension(project, SerializationPluginComponentContainerContributor()) - + // This method is never called in the IDE, therefore this extension is not available there. + // Since IDE does not perform any serialization of descriptors, metadata written to the 'serializationDescriptorSerializer' + // is never deleted, effectively causing memory leaks. + // So we create SerializationDescriptorSerializerPlugin only outside of IDE. + val serializationDescriptorSerializer = SerializationDescriptorSerializerPlugin() DescriptorSerializerPlugin.registerExtension(project, serializationDescriptorSerializer) registerProtoExtensions() + + SyntheticResolveExtension.registerExtension(project, SerializationResolveExtension(serializationDescriptorSerializer)) + + ExpressionCodegenExtension.registerExtension(project, SerializationCodegenExtension(serializationDescriptorSerializer)) + JsSyntheticTranslateExtension.registerExtension(project, SerializationJsExtension(serializationDescriptorSerializer)) + IrGenerationExtension.registerExtension(project, SerializationLoweringExtension(serializationDescriptorSerializer)) + + StorageComponentContainerContributor.registerExtension(project, SerializationPluginComponentContainerContributor()) } diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationDescriptorPluginForKotlinxSerialization.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationDescriptorSerializerPlugin.kt similarity index 95% rename from plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationDescriptorPluginForKotlinxSerialization.kt rename to plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationDescriptorSerializerPlugin.kt index f1c229a2e3e..df604d678f0 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationDescriptorPluginForKotlinxSerialization.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationDescriptorSerializerPlugin.kt @@ -16,7 +16,7 @@ import org.jetbrains.kotlin.serialization.SerializerExtension import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializableProperties import org.jetbrains.kotlinx.serialization.compiler.resolve.isInternalSerializable -class SerializationDescriptorPluginForKotlinxSerialization : DescriptorSerializerPlugin { +class SerializationDescriptorSerializerPlugin : DescriptorSerializerPlugin { private val descriptorMetadataMap: MutableMap = hashMapOf() private val ClassDescriptor.needSaveProgramOrder: Boolean diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationJsExtension.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationJsExtension.kt index c73e5e8f763..b037f708a96 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationJsExtension.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationJsExtension.kt @@ -25,9 +25,9 @@ import org.jetbrains.kotlinx.serialization.compiler.backend.js.SerializableCompa import org.jetbrains.kotlinx.serialization.compiler.backend.js.SerializableJsTranslator import org.jetbrains.kotlinx.serialization.compiler.backend.js.SerializerJsTranslator -open class SerializationJsExtension: JsSyntheticTranslateExtension { +open class SerializationJsExtension @JvmOverloads constructor(val metadataPlugin: SerializationDescriptorSerializerPlugin? = null): JsSyntheticTranslateExtension { override fun generateClassSyntheticParts(declaration: KtPureClassOrObject, descriptor: ClassDescriptor, translator: DeclarationBodyVisitor, context: TranslationContext) { - SerializerJsTranslator.translate(descriptor, translator, context) + SerializerJsTranslator.translate(descriptor, translator, context, metadataPlugin) SerializableJsTranslator.translate(declaration, descriptor, context) SerializableCompanionJsTranslator.translate(descriptor, translator, context) } diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationLoweringExtension.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationLoweringExtension.kt index 3234d0d81b1..7453383e170 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationLoweringExtension.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationLoweringExtension.kt @@ -40,22 +40,23 @@ fun ClassLoweringPass.runOnFileInOrder(irFile: IrFile) { typealias SerializationPluginContext = IrPluginContext private class SerializerClassLowering( - val context: SerializationPluginContext + val context: SerializationPluginContext, + val metadataPlugin: SerializationDescriptorSerializerPlugin? ) : IrElementTransformerVoid(), ClassLoweringPass { override fun lower(irClass: IrClass) { SerializableIrGenerator.generate(irClass, context, context.bindingContext) - SerializerIrGenerator.generate(irClass, context, context.bindingContext) + SerializerIrGenerator.generate(irClass, context, context.bindingContext, metadataPlugin) SerializableCompanionIrGenerator.generate(irClass, context, context.bindingContext) } } -open class SerializationLoweringExtension : IrGenerationExtension { +open class SerializationLoweringExtension @JvmOverloads constructor(val metadataPlugin: SerializationDescriptorSerializerPlugin? = null) : IrGenerationExtension { override fun generate( moduleFragment: IrModuleFragment, pluginContext: IrPluginContext ) { - val serializerClassLowering = SerializerClassLowering(pluginContext) + val serializerClassLowering = SerializerClassLowering(pluginContext, metadataPlugin) for (file in moduleFragment.files) serializerClassLowering.runOnFileInOrder(file) } diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationResolveExtension.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationResolveExtension.kt index 908fe46921b..3e56c7254d1 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationResolveExtension.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationResolveExtension.kt @@ -34,7 +34,7 @@ import org.jetbrains.kotlinx.serialization.compiler.resolve.* import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationAnnotations.serialInfoFqName import java.util.* -open class SerializationResolveExtension : SyntheticResolveExtension { +open class SerializationResolveExtension @JvmOverloads constructor(val metadataPlugin: SerializationDescriptorSerializerPlugin? = null) : SyntheticResolveExtension { override fun getSyntheticNestedClassNames(thisDescriptor: ClassDescriptor): List = when { thisDescriptor.annotations.hasAnnotation(serialInfoFqName) && thisDescriptor.platform?.isJvm() == true -> listOf(SerialEntityNames.IMPL_NAME) (thisDescriptor.shouldHaveGeneratedSerializer) && !thisDescriptor.hasCompanionObjectAsSerializer -> @@ -87,7 +87,7 @@ open class SerializationResolveExtension : SyntheticResolveExtension { if (thisDescriptor.isInternalSerializable) { // do not add synthetic deserialization constructor if .deserialize method is customized if (thisDescriptor.hasCompanionObjectAsSerializer && SerializerCodegen.getSyntheticLoadMember(thisDescriptor.companionObjectDescriptor!!) == null) return - result.add(KSerializerDescriptorResolver.createLoadConstructorDescriptor(thisDescriptor, bindingContext)) + result.add(KSerializerDescriptorResolver.createLoadConstructorDescriptor(thisDescriptor, bindingContext, metadataPlugin)) } } diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializerDescriptorResolver.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializerDescriptorResolver.kt index b22cd0ef5f6..353bc1875b8 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializerDescriptorResolver.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializerDescriptorResolver.kt @@ -16,13 +16,11 @@ 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.platform.konan.isNative import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.calls.components.isVararg import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.descriptorUtil.module -import org.jetbrains.kotlin.resolve.descriptorUtil.platform import org.jetbrains.kotlin.resolve.lazy.LazyClassContext import org.jetbrains.kotlin.resolve.lazy.declarations.ClassMemberDeclarationProvider import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyClassDescriptor @@ -31,6 +29,7 @@ import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.typeUtil.createProjection import org.jetbrains.kotlin.types.typeUtil.makeNullable import org.jetbrains.kotlinx.serialization.compiler.backend.ir.SimpleSyntheticPropertyDescriptor +import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationDescriptorSerializerPlugin import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.IMPL_NAME import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.SERIALIZER_CLASS_NAME import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.typeArgPrefix @@ -288,7 +287,8 @@ object KSerializerDescriptorResolver { fun createLoadConstructorDescriptor( classDescriptor: ClassDescriptor, - bindingContext: BindingContext + bindingContext: BindingContext, + metadataPlugin: SerializationDescriptorSerializerPlugin? ): ClassConstructorDescriptor { if (!classDescriptor.isInternalSerializable) throw IllegalArgumentException() @@ -302,7 +302,7 @@ object KSerializerDescriptorResolver { val markerDesc = classDescriptor.getKSerializerConstructorMarker() val markerType = markerDesc.toSimpleType(nullable = true) - val serializableProperties = bindingContext.serializablePropertiesFor(classDescriptor).serializableProperties + val serializableProperties = bindingContext.serializablePropertiesFor(classDescriptor, metadataPlugin).serializableProperties val parameterDescsAsProps = serializableProperties.map { it.descriptor } val bitMaskSlotsCount = serializableProperties.bitMaskSlotCount() var i = 0 diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/SerializableProperties.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/SerializableProperties.kt index 650ee90f156..86e88e16a28 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/SerializableProperties.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/SerializableProperties.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ import org.jetbrains.kotlin.serialization.deserialization.getName import org.jetbrains.kotlinx.serialization.compiler.diagnostic.SERIALIZABLE_PROPERTIES import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationComponentRegistrar +import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationDescriptorSerializerPlugin import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginMetadataExtensions class SerializableProperties(private val serializableClass: ClassDescriptor, val bindingContext: BindingContext) { @@ -88,9 +89,9 @@ class SerializableProperties(private val serializableClass: ClassDescriptor, val internal fun List.bitMaskSlotCount() = size / 32 + 1 internal fun bitMaskSlotAt(propertyIndex: Int) = propertyIndex / 32 -internal fun BindingContext.serializablePropertiesFor(classDescriptor: ClassDescriptor): SerializableProperties { +internal fun BindingContext.serializablePropertiesFor(classDescriptor: ClassDescriptor, serializationDescriptorSerializer: SerializationDescriptorSerializerPlugin? = null): SerializableProperties { val props = this.get(SERIALIZABLE_PROPERTIES, classDescriptor) ?: SerializableProperties(classDescriptor, this) - SerializationComponentRegistrar.serializationDescriptorSerializer.putIfNeeded(classDescriptor, props) + serializationDescriptorSerializer?.putIfNeeded(classDescriptor, props) return props }