Rework SerialInfo$Impl annotation implementation to be available in FIR:

- IR plugin does not use it anymore,
regular annotation instantiation feature is used
(insertion of IrConstructorCall(annotationCtorSymbol)).

- IR plugin still generates `SerialInfo$Impl` class to be compatible
with previously compiled code & libraries.

- Custom implementation over descriptors in IR plugin is removed;
plugin now delegates to the existing lowering with some tweaks.

- $Impl descriptor is removed from FE 1.0 because it is no longer needed
for IR plugin; it shouldn't be exposed to users so FIR doesn't need it either.

- Since language lowering is now used, it is possible to correctly instantiate
SerialInfo annotations with default values even if they are from other modules
and even if they were not processed by the plugin.

#KT-48733 Fixed
Fixes https://github.com/Kotlin/kotlinx.serialization/issues/1574
This commit is contained in:
Leonid Startsev
2022-10-07 19:15:00 +02:00
committed by Space Team
parent 3c43416042
commit f1b1837f40
10 changed files with 286 additions and 564 deletions
@@ -24,14 +24,13 @@ import org.jetbrains.kotlinx.serialization.compiler.resolve.*
open class SerializationResolveExtension @JvmOverloads constructor(val metadataPlugin: SerializationDescriptorSerializerPlugin? = null) : SyntheticResolveExtension {
override fun getSyntheticNestedClassNames(thisDescriptor: ClassDescriptor): List<Name> = when {
thisDescriptor.isSerialInfoAnnotation && thisDescriptor.platform?.isJvm() == true -> listOf(SerialEntityNames.IMPL_NAME)
(thisDescriptor.shouldHaveGeneratedSerializer) && !thisDescriptor.hasCompanionObjectAsSerializer ->
listOf(SerialEntityNames.SERIALIZER_CLASS_NAME)
else -> listOf()
}
override fun getPossibleSyntheticNestedClassNames(thisDescriptor: ClassDescriptor): List<Name>? {
return listOf(SerialEntityNames.IMPL_NAME, SerialEntityNames.SERIALIZER_CLASS_NAME)
return listOf(SerialEntityNames.SERIALIZER_CLASS_NAME)
}
override fun getSyntheticFunctionNames(thisDescriptor: ClassDescriptor): List<Name> = when {
@@ -73,9 +72,7 @@ open class SerializationResolveExtension @JvmOverloads constructor(val metadataP
declarationProvider: ClassMemberDeclarationProvider,
result: MutableSet<ClassDescriptor>
) {
if (thisDescriptor.isSerialInfoAnnotation && name == SerialEntityNames.IMPL_NAME)
result.add(KSerializerDescriptorResolver.addSerialInfoImplClass(thisDescriptor, declarationProvider, ctx))
else if (thisDescriptor.shouldHaveGeneratedSerializer && name == SerialEntityNames.SERIALIZER_CLASS_NAME &&
if (thisDescriptor.shouldHaveGeneratedSerializer && name == SerialEntityNames.SERIALIZER_CLASS_NAME &&
result.none { it.name == SerialEntityNames.SERIALIZER_CLASS_NAME }
)
result.add(KSerializerDescriptorResolver.addSerializerImplClass(thisDescriptor, declarationProvider, ctx))
@@ -88,7 +85,6 @@ open class SerializationResolveExtension @JvmOverloads constructor(val metadataP
else null
override fun addSyntheticSupertypes(thisDescriptor: ClassDescriptor, supertypes: MutableList<KotlinType>) {
KSerializerDescriptorResolver.addSerialInfoSuperType(thisDescriptor, supertypes)
KSerializerDescriptorResolver.addSerializerSupertypes(thisDescriptor, supertypes)
KSerializerDescriptorResolver.addSerializerFactorySuperType(thisDescriptor, supertypes)
}
@@ -125,7 +121,6 @@ open class SerializationResolveExtension @JvmOverloads constructor(val metadataP
fromSupertypes: ArrayList<PropertyDescriptor>,
result: MutableSet<PropertyDescriptor>
) {
KSerializerDescriptorResolver.generateDescriptorsForAnnotationImpl(thisDescriptor, fromSupertypes, result)
KSerializerDescriptorResolver.generateSerializerProperties(thisDescriptor, fromSupertypes, name, result)
}
}
@@ -47,12 +47,6 @@ object KSerializerDescriptorResolver {
&& (thisDescriptor.containingDeclaration as ClassDescriptor).isSerialInfoAnnotation
}
fun addSerialInfoSuperType(thisDescriptor: ClassDescriptor, supertypes: MutableList<KotlinType>) {
if (isSerialInfoImpl(thisDescriptor)) {
supertypes.add((thisDescriptor.containingDeclaration as LazyClassDescriptor).toSimpleType(false))
}
}
fun addSerializerFactorySuperType(classDescriptor: ClassDescriptor, supertypes: MutableList<KotlinType>) {
if (!classDescriptor.needSerializerFactory()) return
val serializerFactoryClass =
@@ -72,36 +66,6 @@ object KSerializerDescriptorResolver {
supertypes.add(classDescriptor.createSerializerTypeFor(serializableClassDescriptor.defaultType, fqName))
}
fun addSerialInfoImplClass(
interfaceDesc: ClassDescriptor,
declarationProvider: ClassMemberDeclarationProvider,
ctx: LazyClassContext
): ClassDescriptor {
val interfaceDecl = declarationProvider.correspondingClassOrObject!!
val scope = ctx.declarationScopeProvider.getResolutionScopeForDeclaration(declarationProvider.ownerInfo!!.scopeAnchor)
val props = interfaceDecl.primaryConstructorParameters
// if there is some properties, there will be a public synthetic constructor at the codegen phase
val primaryCtorVisibility = if (props.isEmpty()) DescriptorVisibilities.PUBLIC else DescriptorVisibilities.PRIVATE
val descriptor = SyntheticClassOrObjectDescriptor(
ctx,
interfaceDecl,
interfaceDesc,
IMPL_NAME,
interfaceDesc.source,
scope,
Modality.FINAL,
DescriptorVisibilities.PUBLIC,
Annotations.create(listOf(createDeprecatedHiddenAnnotation(interfaceDesc.module))),
primaryCtorVisibility,
ClassKind.CLASS,
false
)
descriptor.initialize()
return descriptor
}
fun addSerializerImplClass(
thisDescriptor: ClassDescriptor,
declarationProvider: ClassMemberDeclarationProvider,
@@ -628,23 +592,6 @@ object KSerializerDescriptorResolver {
return f
}
fun generateDescriptorsForAnnotationImpl(
thisDescriptor: ClassDescriptor,
fromSupertypes: List<PropertyDescriptor>,
result: MutableCollection<PropertyDescriptor>
) {
if (isSerialInfoImpl(thisDescriptor)) {
result.add(
fromSupertypes.first().newCopyBuilder().apply {
setOwner(thisDescriptor)
setModality(Modality.FINAL)
setKind(CallableMemberDescriptor.Kind.SYNTHESIZED)
setDispatchReceiverParameter(thisDescriptor.thisAsReceiverParameter)
}.build()!!
)
}
}
// create properties typeSerial0, typeSerial1, etc... for storing generic arguments' serializers
private fun createLocalSerializersFieldsDescriptor(
name: Name,