[FIR] Remove FirDeclarationsForMetadataProviderExtension extension
`IrGeneratedDeclarationsRegistrar` should be now used instead to register IR declarations in resulting metadata
This commit is contained in:
-2
@@ -34,8 +34,6 @@ class FirPluginPrototypeExtensionRegistrar : FirExtensionRegistrar() {
|
||||
+::AdditionalMembersGenerator
|
||||
+::CompanionGenerator
|
||||
+::MembersOfSerializerGenerator
|
||||
|
||||
+::AllPropertiesConstructorMetadataProvider
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-48
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.plugin.generators
|
||||
|
||||
import org.jetbrains.kotlin.GeneratedDeclarationKey
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.containingClassLookupTag
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
|
||||
import org.jetbrains.kotlin.fir.extensions.FirDeclarationsForMetadataProviderExtension
|
||||
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
|
||||
import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
|
||||
import org.jetbrains.kotlin.fir.plugin.createConstructor
|
||||
import org.jetbrains.kotlin.fir.plugin.fqn
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.scopes.getProperties
|
||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||
|
||||
class AllPropertiesConstructorMetadataProvider(session: FirSession) : FirDeclarationsForMetadataProviderExtension(session) {
|
||||
companion object {
|
||||
val ANNOTATION_FQN = "AllPropertiesConstructor".fqn()
|
||||
val PREDICATE = DeclarationPredicate.create { annotated(ANNOTATION_FQN) }
|
||||
}
|
||||
|
||||
private object Key : GeneratedDeclarationKey()
|
||||
|
||||
override fun provideDeclarationsForClass(klass: FirClass, scopeSession: ScopeSession): List<FirDeclaration> {
|
||||
if (!session.predicateBasedProvider.matches(PREDICATE, klass)) return emptyList()
|
||||
val scope = klass.unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = false, memberRequiredPhase = null)
|
||||
val properties = scope.getCallableNames()
|
||||
.flatMap { scope.getProperties(it) }
|
||||
.sortedBy { it.containingClassLookupTag() == klass.symbol.toLookupTag() }
|
||||
val constructor = createConstructor(klass.symbol, Key) {
|
||||
for (property in properties) {
|
||||
valueParameter(property.name, property.resolvedReturnType)
|
||||
}
|
||||
}
|
||||
return listOf(constructor)
|
||||
}
|
||||
|
||||
override fun FirDeclarationPredicateRegistrar.registerPredicates() {
|
||||
register(PREDICATE)
|
||||
}
|
||||
}
|
||||
+6
-4
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.ir.plugin
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.plugin.generators.AllPropertiesConstructorMetadataProvider
|
||||
import org.jetbrains.kotlin.fir.plugin.fqn
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildValueParameter
|
||||
@@ -29,6 +29,10 @@ import java.util.Comparator
|
||||
* Parent class should be Any or class, annotated with @AllPropertiesConstructor
|
||||
*/
|
||||
class AllPropertiesConstructorIrGenerator(val context: IrPluginContext) : IrElementVisitorVoid {
|
||||
companion object {
|
||||
private val ANNOTATION_FQN = "AllPropertiesConstructor".fqn()
|
||||
}
|
||||
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
@@ -89,8 +93,6 @@ class AllPropertiesConstructorIrGenerator(val context: IrPluginContext) : IrElem
|
||||
}
|
||||
|
||||
private fun IrClass.hasAnnotation(): Boolean {
|
||||
return annotations.findAnnotation(AllPropertiesConstructorMetadataProvider.ANNOTATION_FQN) != null
|
||||
return annotations.hasAnnotation(ANNOTATION_FQN)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
-1
@@ -17,7 +17,6 @@ class FirSerializationExtensionRegistrar : FirExtensionRegistrar() {
|
||||
+::SerializationFirResolveExtension
|
||||
+::SerializationFirSupertypesExtension
|
||||
+::FirSerializationCheckersComponent
|
||||
+::SerializationFirDeclarationsForMetadataProvider
|
||||
|
||||
// services
|
||||
+::DependencySerializationInfoProvider
|
||||
|
||||
-126
@@ -1,126 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlinx.serialization.compiler.fir
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isFinal
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isInline
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.extensions.FirDeclarationsForMetadataProviderExtension
|
||||
import org.jetbrains.kotlin.fir.moduleData
|
||||
import org.jetbrains.kotlin.fir.plugin.createConstructor
|
||||
import org.jetbrains.kotlin.fir.plugin.createMemberFunction
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.defaultType
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.toConeType
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.JvmStandardClassIds
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import org.jetbrains.kotlinx.serialization.compiler.fir.services.serializablePropertiesProvider
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
|
||||
|
||||
class SerializationFirDeclarationsForMetadataProvider(session: FirSession) : FirDeclarationsForMetadataProviderExtension(session) {
|
||||
override fun provideDeclarationsForClass(klass: FirClass, scopeSession: ScopeSession): List<FirDeclaration> {
|
||||
// FIXME: multi-field value classes require additional 'if' here, but they're not supported for now in serialization K2.
|
||||
return if (klass.symbol.isInline || with(session) { !klass.symbol.isInternalSerializable }) emptyList()
|
||||
// As we deprecated 'customize serializer via companion', we know for sure
|
||||
// that serialize/deserialize functions are synthetic and generated by our plugin.
|
||||
else listOfNotNull(generateDeserializationConstructor(klass), generateWriteSelf(klass))
|
||||
}
|
||||
|
||||
private fun generateDeserializationConstructor(klass: FirClass): FirDeclaration =
|
||||
createConstructor(klass.symbol, SerializationPluginKey, isPrimary = false) {
|
||||
// deserialization constructor for final classes could be internal, because it can't be called in inheritors
|
||||
visibility = if (klass.isFinal) Visibilities.Internal else Visibilities.Public
|
||||
|
||||
val serializableProperties =
|
||||
session.serializablePropertiesProvider.getSerializablePropertiesForClass(klass.symbol).serializableProperties
|
||||
val bitMaskSlotCount = serializableProperties.bitMaskSlotCount()
|
||||
repeat(bitMaskSlotCount) {
|
||||
valueParameter(Name.identifier("seen$it"), session.builtinTypes.intType.type)
|
||||
}
|
||||
serializableProperties.forEach { prop ->
|
||||
valueParameter(
|
||||
prop.originalDescriptorName,
|
||||
prop.propertySymbol.resolvedReturnType.makeNullableIfNotPrimitive(session.typeContext)
|
||||
)
|
||||
}
|
||||
val markerType =
|
||||
ClassId(SerializationPackages.internalPackageFqName, SerialEntityNames.SERIAL_CTOR_MARKER_NAME).constructClassLikeType(
|
||||
emptyArray(),
|
||||
isNullable = true
|
||||
)
|
||||
valueParameter(SerialEntityNames.dummyParamName, markerType)
|
||||
}
|
||||
|
||||
private fun generateWriteSelf(klass: FirClass): FirDeclaration? {
|
||||
// write$Self in K1 is created only on JVM (see SerializationResolveExtension)
|
||||
if (!session.moduleData.platform.isJvm()) return null
|
||||
return createMemberFunction(
|
||||
klass.symbol,
|
||||
SerializationPluginKey,
|
||||
SerialEntityNames.WRITE_SELF_NAME,
|
||||
session.builtinTypes.unitType.type
|
||||
) {
|
||||
// write$Self for final classes could be internal, because it can't be called in inheritors
|
||||
visibility = if (klass.isFinal) Visibilities.Internal else Visibilities.Public
|
||||
|
||||
klass.typeParameters.forEach {
|
||||
typeParameter(it.symbol.name)
|
||||
}
|
||||
|
||||
valueParameter(Name.identifier("self"), { functionTypeParams ->
|
||||
klass.symbol.constructType(functionTypeParams.map { it.toConeType() }.toTypedArray(), false)
|
||||
})
|
||||
|
||||
valueParameter(
|
||||
Name.identifier("output"),
|
||||
SerializationRuntimeClassIds.compositeEncoderClassId.constructClassLikeType(emptyArray(), false)
|
||||
)
|
||||
|
||||
valueParameter(
|
||||
Name.identifier("serialDesc"),
|
||||
SerializationRuntimeClassIds.descriptorClassId.constructClassLikeType(emptyArray(), false)
|
||||
)
|
||||
|
||||
klass.typeParameters.forEachIndexed { i, _ ->
|
||||
valueParameter(Name.identifier("${SerialEntityNames.typeArgPrefix}$i"), { functionTps ->
|
||||
SerializersClassIds.kSerializerId.constructClassLikeType(arrayOf(functionTps[i].toConeType()), false)
|
||||
})
|
||||
}
|
||||
}.apply { replaceAnnotations(listOfNotNull(createJvmStaticAnnotation())) }
|
||||
}
|
||||
|
||||
private fun createJvmStaticAnnotation(): FirAnnotation? {
|
||||
val jvmStatic =
|
||||
session.symbolProvider.getClassLikeSymbolByClassId(JvmStandardClassIds.Annotations.JvmStatic) as? FirRegularClassSymbol
|
||||
?: return null
|
||||
val jvmStaticCtor =
|
||||
jvmStatic.declarationSymbols.firstIsInstanceOrNull<FirConstructorSymbol>() ?: return null
|
||||
|
||||
return buildAnnotationCall {
|
||||
annotationTypeRef = jvmStatic.defaultType().toFirResolvedTypeRef()
|
||||
calleeReference = buildResolvedNamedReference {
|
||||
name = jvmStatic.name
|
||||
resolvedSymbol = jvmStaticCtor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun ConeKotlinType.makeNullableIfNotPrimitive(typeContext: ConeTypeContext): ConeKotlinType =
|
||||
if (isPrimitive) this else withNullability(ConeNullability.NULLABLE, typeContext)
|
||||
Reference in New Issue
Block a user