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 }