From e4c2d4937f28644922598e5ae8ba2c5792aaf868 Mon Sep 17 00:00:00 2001 From: Roman Artemev Date: Mon, 16 Aug 2021 14:48:55 +0300 Subject: [PATCH] [KLIB] Extract signature deserialization into separate class --- .../serialization/IdSignatureDeserializer.kt | 112 ++++++++++++++++++ .../serialization/IrSymbolDeserializer.kt | 98 +-------------- 2 files changed, 116 insertions(+), 94 deletions(-) create mode 100644 compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IdSignatureDeserializer.kt diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IdSignatureDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IdSignatureDeserializer.kt new file mode 100644 index 00000000000..7a0ea83646a --- /dev/null +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IdSignatureDeserializer.kt @@ -0,0 +1,112 @@ +/* + * Copyright 2010-2021 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.backend.common.serialization + +import org.jetbrains.kotlin.ir.symbols.IrFileSymbol +import org.jetbrains.kotlin.ir.util.IdSignature +import org.jetbrains.kotlin.ir.util.IdSignature.FileSignature +import org.jetbrains.kotlin.protobuf.CodedInputStream +import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite +import org.jetbrains.kotlin.backend.common.serialization.proto.AccessorIdSignature as ProtoAccessorIdSignature +import org.jetbrains.kotlin.backend.common.serialization.proto.CommonIdSignature as ProtoCommonIdSignature +import org.jetbrains.kotlin.backend.common.serialization.proto.CompositeSignature as ProtoCompositeSignature +import org.jetbrains.kotlin.backend.common.serialization.proto.FileLocalIdSignature as ProtoFileLocalIdSignature +import org.jetbrains.kotlin.backend.common.serialization.proto.FileSignature as ProtoFileSignature +import org.jetbrains.kotlin.backend.common.serialization.proto.IdSignature as ProtoIdSignature +import org.jetbrains.kotlin.backend.common.serialization.proto.LocalSignature as ProtoLocalSignature +import org.jetbrains.kotlin.backend.common.serialization.proto.LoweredIdSignature as ProtoLoweredIdSignature + +class IdSignatureDeserializer(private val fileReader: IrLibraryFile, fileSymbol: IrFileSymbol?) { + + private fun readSignature(index: Int): CodedInputStream = fileReader.signature(index).codedInputStream + + private val fileSignature: FileSignature? = fileSymbol?.let { FileSignature(it) } + + private fun loadSignatureProto(index: Int): ProtoIdSignature { + return ProtoIdSignature.parseFrom(readSignature(index), extensionRegistryLite) + } + + private val signatureCache = HashMap() + + fun deserializeIdSignature(index: Int): IdSignature { + return signatureCache.getOrPut(index) { + val sigData = loadSignatureProto(index) + deserializeSignatureData(sigData) + } + } + + private fun deserializePublicIdSignature(proto: ProtoCommonIdSignature): IdSignature.CommonSignature { + val pkg = fileReader.deserializeFqName(proto.packageFqNameList) + val cls = fileReader.deserializeFqName(proto.declarationFqNameList) + val memberId = if (proto.hasMemberUniqId()) proto.memberUniqId else null + + return IdSignature.CommonSignature(pkg, cls, memberId, proto.flags) + } + + private fun deserializeAccessorIdSignature(proto: ProtoAccessorIdSignature): IdSignature.AccessorSignature { + val propertySignature = deserializeIdSignature(proto.propertySignature) + require(propertySignature is IdSignature.CommonSignature) { "For public accessor corresponding property supposed to be public as well" } + val name = fileReader.deserializeString(proto.name) + val hash = proto.accessorHashId + val mask = proto.flags + + val accessorSignature = + IdSignature.CommonSignature(propertySignature.packageFqName, "${propertySignature.declarationFqName}.$name", hash, mask) + + return IdSignature.AccessorSignature(propertySignature, accessorSignature) + } + + private fun deserializeFileLocalIdSignature(proto: ProtoFileLocalIdSignature): IdSignature { + return IdSignature.FileLocalSignature(deserializeIdSignature(proto.container), proto.localId) + } + + private fun deserializeScopeLocalIdSignature(proto: Int): IdSignature { + return IdSignature.ScopeLocalDeclaration(proto) + } + + private fun deserializeLoweredDeclarationSignature(proto: ProtoLoweredIdSignature): IdSignature.LoweredDeclarationSignature { + return IdSignature.LoweredDeclarationSignature(deserializeIdSignature(proto.parentSignature), proto.stage, proto.index) + } + + private fun deserializeCompositeIdSignature(proto: ProtoCompositeSignature): IdSignature.CompositeSignature { + val containerSig = deserializeIdSignature(proto.containerSig) + val innerSig = deserializeIdSignature(proto.innerSig) + return IdSignature.CompositeSignature(containerSig, innerSig) + } + + private fun deserializeLocalIdSignature(proto: ProtoLocalSignature): IdSignature.LocalSignature { + val localFqn = fileReader.deserializeFqName(proto.localFqNameList) + val localHash = if (proto.hasLocalHash()) proto.localHash else null + val description = if (proto.hasDebugInfo()) fileReader.deserializeDebugInfo(proto.debugInfo) else null + return IdSignature.LocalSignature(localFqn, localHash, description) + } + + @Suppress("UNUSED_PARAMETER") + private fun deserializeFileIdSignature(proto: ProtoFileSignature): FileSignature = fileSignature ?: error("Provide file symbol") + + private fun deserializeSignatureData(proto: ProtoIdSignature): IdSignature { + return when (proto.idSigCase) { + ProtoIdSignature.IdSigCase.PUBLIC_SIG -> deserializePublicIdSignature(proto.publicSig) + ProtoIdSignature.IdSigCase.ACCESSOR_SIG -> deserializeAccessorIdSignature(proto.accessorSig) + ProtoIdSignature.IdSigCase.PRIVATE_SIG -> deserializeFileLocalIdSignature(proto.privateSig) + ProtoIdSignature.IdSigCase.SCOPED_LOCAL_SIG -> deserializeScopeLocalIdSignature(proto.scopedLocalSig) + ProtoIdSignature.IdSigCase.COMPOSITE_SIG -> deserializeCompositeIdSignature(proto.compositeSig) + ProtoIdSignature.IdSigCase.LOCAL_SIG -> deserializeLocalIdSignature(proto.localSig) + ProtoIdSignature.IdSigCase.FILE_SIG -> deserializeFileIdSignature(proto.fileSig) + // IR IC part + ProtoIdSignature.IdSigCase.IC_SIG -> deserializeLoweredDeclarationSignature(proto.icSig) + else -> error("Unexpected IdSignature kind: ${proto.idSigCase}") + } + } + + fun signatureToIndexMapping(): Map { + return signatureCache.entries.associate { it.value to it.key } + } + + companion object { + private val extensionRegistryLite = ExtensionRegistryLite.newInstance() + } +} \ No newline at end of file diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrSymbolDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrSymbolDeserializer.kt index 2021d815eab..ebc1cc679bb 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrSymbolDeserializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrSymbolDeserializer.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.backend.common.serialization import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData import org.jetbrains.kotlin.backend.common.serialization.proto.Actual -import org.jetbrains.kotlin.backend.common.serialization.proto.IdSignature.IdSigCase.* import org.jetbrains.kotlin.ir.symbols.IrFileSymbol import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol @@ -16,17 +15,8 @@ import org.jetbrains.kotlin.ir.symbols.impl.IrAnonymousInitializerSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrLocalDelegatedPropertySymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl -import org.jetbrains.kotlin.ir.util.* -import org.jetbrains.kotlin.protobuf.CodedInputStream -import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite -import org.jetbrains.kotlin.backend.common.serialization.proto.AccessorIdSignature as ProtoAccessorIdSignature -import org.jetbrains.kotlin.backend.common.serialization.proto.CommonIdSignature as ProtoCommonIdSignature -import org.jetbrains.kotlin.backend.common.serialization.proto.CompositeSignature as ProtoCompositeSignature -import org.jetbrains.kotlin.backend.common.serialization.proto.FileLocalIdSignature as ProtoFileLocalIdSignature -import org.jetbrains.kotlin.backend.common.serialization.proto.FileSignature as ProtoFileSignature -import org.jetbrains.kotlin.backend.common.serialization.proto.IdSignature as ProtoIdSignature -import org.jetbrains.kotlin.backend.common.serialization.proto.LocalSignature as ProtoLocalSignature -import org.jetbrains.kotlin.backend.common.serialization.proto.LoweredIdSignature as ProtoLoweredIdSignature +import org.jetbrains.kotlin.ir.util.IdSignature +import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable class IrSymbolDeserializer( val symbolTable: ReferenceSymbolTable, @@ -40,8 +30,6 @@ class IrSymbolDeserializer( val deserializePublicSymbol: (IdSignature, BinarySymbolData.SymbolKind) -> IrSymbol, ) { - private val fileSignature: IdSignature.FileSignature = IdSignature.FileSignature(fileSymbol) - fun deserializeIrSymbol(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol { return deserializedSymbols.getOrPut(idSig) { val symbol = referenceDeserializedSymbol(symbolKind, idSig) @@ -115,87 +103,9 @@ class IrSymbolDeserializer( } } - private fun readSignature(index: Int): CodedInputStream = - fileReader.signature(index).codedInputStream - - private fun loadSignatureProto(index: Int): ProtoIdSignature { - return ProtoIdSignature.parseFrom(readSignature(index), ExtensionRegistryLite.newInstance()) - } - - private val signatureCache = HashMap() + private val signatureDeserializer = IdSignatureDeserializer(fileReader, fileSymbol) fun deserializeIdSignature(index: Int): IdSignature { - return signatureCache.getOrPut(index) { - val sigData = loadSignatureProto(index) - deserializeSignatureData(sigData) - } - } - - /* -------------------------------------------------------------- */ - - // TODO: Think about isolating id signature related logic behind corresponding interface - - private fun deserializePublicIdSignature(proto: ProtoCommonIdSignature): IdSignature.CommonSignature { - val pkg = fileReader.deserializeFqName(proto.packageFqNameList) - val cls = fileReader.deserializeFqName(proto.declarationFqNameList) - val memberId = if (proto.hasMemberUniqId()) proto.memberUniqId else null - - return IdSignature.CommonSignature(pkg, cls, memberId, proto.flags) - } - - private fun deserializeAccessorIdSignature(proto: ProtoAccessorIdSignature): IdSignature.AccessorSignature { - val propertySignature = deserializeIdSignature(proto.propertySignature) - require(propertySignature is IdSignature.CommonSignature) { "For public accessor corresponding property supposed to be public as well" } - val name = fileReader.deserializeString(proto.name) - val hash = proto.accessorHashId - val mask = proto.flags - - val accessorSignature = - IdSignature.CommonSignature(propertySignature.packageFqName, "${propertySignature.declarationFqName}.$name", hash, mask) - - return IdSignature.AccessorSignature(propertySignature, accessorSignature) - } - - private fun deserializeFileLocalIdSignature(proto: ProtoFileLocalIdSignature): IdSignature { - return IdSignature.FileLocalSignature(deserializeIdSignature(proto.container), proto.localId) - } - - private fun deserializeScopeLocalIdSignature(proto: Int): IdSignature { - return IdSignature.ScopeLocalDeclaration(proto) - } - - private fun deserializeLoweredDeclarationSignature(proto: ProtoLoweredIdSignature): IdSignature.LoweredDeclarationSignature { - return IdSignature.LoweredDeclarationSignature(deserializeIdSignature(proto.parentSignature), proto.stage, proto.index) - } - - private fun deserializeCompositeIdSignature(proto: ProtoCompositeSignature): IdSignature.CompositeSignature { - val containerSig = deserializeIdSignature(proto.containerSig) - val innerSig = deserializeIdSignature(proto.innerSig) - return IdSignature.CompositeSignature(containerSig, innerSig) - } - - private fun deserializeLocalIdSignature(proto: ProtoLocalSignature): IdSignature.LocalSignature { - val localFqn = fileReader.deserializeFqName(proto.localFqNameList) - val localHash = if (proto.hasLocalHash()) proto.localHash else null - val description = if (proto.hasDebugInfo()) fileReader.deserializeDebugInfo(proto.debugInfo) else null - return IdSignature.LocalSignature(localFqn, localHash, description) - } - - @Suppress("UNUSED_PARAMETER") - private fun deserializeFileIdSignature(proto: ProtoFileSignature): IdSignature.FileSignature = fileSignature - - fun deserializeSignatureData(proto: ProtoIdSignature): IdSignature { - return when (proto.idSigCase) { - PUBLIC_SIG -> deserializePublicIdSignature(proto.publicSig) - ACCESSOR_SIG -> deserializeAccessorIdSignature(proto.accessorSig) - PRIVATE_SIG -> deserializeFileLocalIdSignature(proto.privateSig) - SCOPED_LOCAL_SIG -> deserializeScopeLocalIdSignature(proto.scopedLocalSig) - COMPOSITE_SIG -> deserializeCompositeIdSignature(proto.compositeSig) - LOCAL_SIG -> deserializeLocalIdSignature(proto.localSig) - FILE_SIG -> deserializeFileIdSignature(proto.fileSig) - // IR IC part - IC_SIG -> deserializeLoweredDeclarationSignature(proto.icSig) - else -> error("Unexpected IdSignature kind: ${proto.idSigCase}") - } + return signatureDeserializer.deserializeIdSignature(index) } }