[FIR] Properly implement serializer extension for klib compilation

^KT-57654 Fixed
This commit is contained in:
Dmitriy Novozhilov
2023-03-29 18:20:15 +03:00
committed by Space Team
parent 6604627fa8
commit 92a59279d5
17 changed files with 353 additions and 213 deletions
@@ -12,26 +12,19 @@ import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.backend.ConstValueProviderImpl
import org.jetbrains.kotlin.fir.backend.extractFirDeclarations
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.serialization.*
import org.jetbrains.kotlin.fir.serialization.constant.ConstValueProvider
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.IrMessageLogger
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.library.SerializedIrFile
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
import org.jetbrains.kotlin.library.metadata.resolver.TopologicalLibraryOrder
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable
import org.jetbrains.kotlin.psi
import org.jetbrains.kotlin.utils.toMetadataVersion
internal fun PhaseContext.firSerializer(
@@ -69,8 +62,10 @@ internal fun PhaseContext.firSerializer(
session,
scopeSession,
actualizedFirDeclarations,
FirNativeKLibSerializerExtension(
session, metadataVersion, FirElementAwareSerializableStringTable(), ConstValueProviderImpl(input.components),
FirKLibSerializerExtension(
session, metadataVersion,
ConstValueProviderImpl(input.components),
allowErrorTypes = false, exportKDoc = false
),
configuration.languageVersionSettings,
)
@@ -134,117 +129,3 @@ internal fun PhaseContext.serializeNativeModule(
return SerializerOutput(serializedMetadata, serializedIr, null, dependencies)
}
class FirNativeKLibSerializerExtension(
override val session: FirSession,
override val metadataVersion: BinaryVersion,
override val stringTable: FirElementAwareSerializableStringTable,
override val constValueProvider: ConstValueProvider?
) : FirKLibSerializerExtension(session, metadataVersion, stringTable, constValueProvider) {
private fun declarationFileId(declaration: FirMemberDeclaration): Int? {
val fileName = declaration.source.psi?.containingFile?.name ?: return null
return stringTable.getStringIndex(fileName)
}
override fun serializeFunction(
function: FirFunction,
proto: ProtoBuf.Function.Builder,
versionRequirementTable: MutableVersionRequirementTable?,
childSerializer: FirElementSerializer
) {
// inspired by KlibMetadataSerializerExtension.serializeFunction
declarationFileId(function)?.let { proto.setExtension(KlibMetadataProtoBuf.functionFile, it) }
function.nonSourceAnnotations(session).forEach {
proto.addExtension(KlibMetadataProtoBuf.functionAnnotation, annotationSerializer.serializeAnnotation(it))
}
function.receiverParameter?.nonSourceAnnotations(session)?.forEach {
proto.addExtension(KlibMetadataProtoBuf.functionExtensionReceiverAnnotation, annotationSerializer.serializeAnnotation(it))
}
// TODO KT-56090 Serialize KDocString
super.serializeFunction(function, proto, versionRequirementTable, childSerializer)
}
override fun serializeValueParameter(parameter: FirValueParameter, proto: ProtoBuf.ValueParameter.Builder) {
parameter.nonSourceAnnotations(session).forEach {
proto.addExtension(KlibMetadataProtoBuf.parameterAnnotation, annotationSerializer.serializeAnnotation(it))
}
super.serializeValueParameter(parameter, proto)
}
override fun serializeProperty(
property: FirProperty,
proto: ProtoBuf.Property.Builder,
versionRequirementTable: MutableVersionRequirementTable?,
childSerializer: FirElementSerializer
) {
// inspired by KlibMetadataSerializerExtension.serializeProperty
declarationFileId(property)?.let { proto.setExtension(KlibMetadataProtoBuf.propertyFile, it) }
property.nonSourceAnnotations(session).forEach {
val extension = when (it.useSiteTarget) { // Revise this code after KT-54385
AnnotationUseSiteTarget.FIELD -> KlibMetadataProtoBuf.propertyBackingFieldAnnotation
AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD -> KlibMetadataProtoBuf.propertyDelegatedFieldAnnotation
else -> KlibMetadataProtoBuf.propertyAnnotation
}
proto.addExtension(extension, annotationSerializer.serializeAnnotation(it))
}
property.receiverParameter?.nonSourceAnnotations(session)?.forEach {
proto.addExtension(KlibMetadataProtoBuf.propertyExtensionReceiverAnnotation, annotationSerializer.serializeAnnotation(it))
}
property.getter?.nonSourceAnnotations(session)?.forEach {
proto.addExtension(KlibMetadataProtoBuf.propertyGetterAnnotation, annotationSerializer.serializeAnnotation(it))
}
property.setter?.nonSourceAnnotations(session)?.forEach {
proto.addExtension(KlibMetadataProtoBuf.propertySetterAnnotation, annotationSerializer.serializeAnnotation(it))
}
serializeConstant(property, proto)
// TODO KT-56090 Serialize KDocString
super.serializeProperty(property, proto, versionRequirementTable, childSerializer)
}
override fun serializeClass(
klass: FirClass,
proto: ProtoBuf.Class.Builder,
versionRequirementTable: MutableVersionRequirementTable,
childSerializer: FirElementSerializer
) {
declarationFileId(klass)?.let { proto.setExtension(KlibMetadataProtoBuf.classFile, it) }
klass.nonSourceAnnotations(session).forEach {
proto.addExtension(KlibMetadataProtoBuf.classAnnotation, annotationSerializer.serializeAnnotation(it))
}
// TODO KT-56090 Serialize KDocString
super.serializeClass(klass, proto, versionRequirementTable, childSerializer)
}
override fun serializeConstructor(
constructor: FirConstructor,
proto: ProtoBuf.Constructor.Builder,
childSerializer: FirElementSerializer
) {
constructor.nonSourceAnnotations(session).forEach {
proto.addExtension(KlibMetadataProtoBuf.constructorAnnotation, annotationSerializer.serializeAnnotation(it))
}
// TODO KT-56090 Serialize KDocString
super.serializeConstructor(constructor, proto, childSerializer)
}
override fun serializeEnumEntry(enumEntry: FirEnumEntry, proto: ProtoBuf.EnumEntry.Builder) {
enumEntry.nonSourceAnnotations(session).forEach {
proto.addExtension(KlibMetadataProtoBuf.enumEntryAnnotation, annotationSerializer.serializeAnnotation(it))
}
super.serializeEnumEntry(enumEntry, proto)
}
override fun serializeTypeAnnotation(annotation: FirAnnotation, proto: ProtoBuf.Type.Builder) {
proto.addExtension(KlibMetadataProtoBuf.typeAnnotation, annotationSerializer.serializeAnnotation(annotation))
super.serializeTypeAnnotation(annotation, proto)
}
override fun serializeTypeParameter(typeParameter: FirTypeParameter, proto: ProtoBuf.TypeParameter.Builder) {
typeParameter.nonSourceAnnotations(session).forEach {
proto.addExtension(KlibMetadataProtoBuf.typeParameterAnnotation, annotationSerializer.serializeAnnotation(it))
}
super.serializeTypeParameter(typeParameter, proto)
}
}