From 64e601bea08d67cb8d596fcfdf1c986849689dd2 Mon Sep 17 00:00:00 2001 From: Johan Bay Date: Sat, 2 Sep 2023 07:56:32 +0200 Subject: [PATCH] Extract IdSignature serializer from IrFileSerializer ^KT-61642 --- .../serialization/IdSignatureSerializer.kt | 113 ++++++++++++++++++ .../common/serialization/IrFileSerializer.kt | 106 ++-------------- 2 files changed, 122 insertions(+), 97 deletions(-) create mode 100644 compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IdSignatureSerializer.kt diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IdSignatureSerializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IdSignatureSerializer.kt new file mode 100644 index 00000000000..37ded0dd2ac --- /dev/null +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IdSignatureSerializer.kt @@ -0,0 +1,113 @@ +/* + * 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.backend.common.serialization + +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.ir.util.IdSignature +import java.util.ArrayList + +class IdSignatureSerializer( + private val serializeString: (String) -> Int, + private val serializeDebugInfo: (String) -> Int, + private val protoIdSignatureMap: MutableMap, + private val protoIdSignatureArray: ArrayList +) { + + private fun serializeFqName(fqName: String): List = fqName.split(".").map { serializeString(it) } + private fun serializePublicSignature(signature: IdSignature.CommonSignature): ProtoCommonIdSignature { + val proto = ProtoCommonIdSignature.newBuilder() + proto.addAllPackageFqName(serializeFqName(signature.packageFqName)) + proto.addAllDeclarationFqName(serializeFqName(signature.declarationFqName)) + + signature.id?.let { proto.memberUniqId = it } + if (signature.mask != 0L) { + proto.flags = signature.mask + } + + signature.description?.let { proto.debugInfo = serializeDebugInfo(it) } + + return proto.build() + } + + private fun serializeAccessorSignature(signature: IdSignature.AccessorSignature): ProtoAccessorIdSignature { + val proto = ProtoAccessorIdSignature.newBuilder() + + proto.propertySignature = protoIdSignature(signature.propertySignature) + with(signature.accessorSignature) { + proto.name = serializeString(shortName) + proto.accessorHashId = id ?: error("Expected hash Id") + if (mask != 0L) { + proto.flags = mask + } + description?.let { proto.debugInfo = serializeDebugInfo(it) } + } + + return proto.build() + } + + private fun serializePrivateSignature(signature: IdSignature.FileLocalSignature): ProtoFileLocalIdSignature { + val proto = ProtoFileLocalIdSignature.newBuilder() + + proto.container = protoIdSignature(signature.container) + proto.localId = signature.id + signature.description?.let { proto.debugInfo = serializeDebugInfo(it) } + + return proto.build() + } + + private fun serializeScopeLocalSignature(signature: IdSignature.ScopeLocalDeclaration): Int = signature.id + + private fun serializeCompositeSignature(signature: IdSignature.CompositeSignature): ProtoCompositeSignature { + val proto = ProtoCompositeSignature.newBuilder() + + proto.containerSig = protoIdSignature(signature.container) + proto.innerSig = protoIdSignature(signature.inner) + + return proto.build() + } + + @Suppress("UNUSED_PARAMETER") + private fun serializeFileSignature(signature: IdSignature.FileSignature): ProtoFileSignature = ProtoFileSignature.getDefaultInstance() + + private fun serializeLocalSignature(signature: IdSignature.LocalSignature): ProtoLocalSignature { + val proto = ProtoLocalSignature.newBuilder() + + proto.addAllLocalFqName(serializeFqName(signature.localFqn)) + signature.hashSig?.let { proto.localHash = it } + signature.description?.let { proto.debugInfo = serializeDebugInfo(it) } + + return proto.build() + } + + private fun serializeIdSignature(idSignature: IdSignature): ProtoIdSignature { + val proto = ProtoIdSignature.newBuilder() + when (idSignature) { + is IdSignature.CommonSignature -> proto.publicSig = serializePublicSignature(idSignature) + is IdSignature.AccessorSignature -> proto.accessorSig = serializeAccessorSignature(idSignature) + is IdSignature.FileLocalSignature -> proto.privateSig = serializePrivateSignature(idSignature) + is IdSignature.ScopeLocalDeclaration -> proto.scopedLocalSig = serializeScopeLocalSignature(idSignature) + is IdSignature.CompositeSignature -> proto.compositeSig = serializeCompositeSignature(idSignature) + is IdSignature.LocalSignature -> proto.localSig = serializeLocalSignature(idSignature) + is IdSignature.FileSignature -> proto.fileSig = serializeFileSignature(idSignature) + is IdSignature.SpecialFakeOverrideSignature -> {} + is IdSignature.LoweredDeclarationSignature -> error("LoweredDeclarationSignature is not expected here") + } + return proto.build() + } + + fun protoIdSignature(idSig: IdSignature): Int { + return protoIdSignatureMap.getOrPut(idSig) { + protoIdSignatureArray.add(serializeIdSignature(idSig)) + protoIdSignatureArray.size - 1 + } + } +} diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt index 43c283c5cf6..ceba63f7f79 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt @@ -29,13 +29,8 @@ import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.utils.filterIsInstanceAnd import org.jetbrains.kotlin.utils.addToStdlib.applyIf import java.io.File -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.FieldAccessCommon as ProtoFieldAccessCommon import org.jetbrains.kotlin.backend.common.serialization.proto.FileEntry as ProtoFileEntry -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.IrAnonymousInit as ProtoAnonymousInit import org.jetbrains.kotlin.backend.common.serialization.proto.IrBlock as ProtoBlock @@ -107,7 +102,6 @@ import org.jetbrains.kotlin.backend.common.serialization.proto.IrVarargElement a import org.jetbrains.kotlin.backend.common.serialization.proto.IrVariable as ProtoVariable import org.jetbrains.kotlin.backend.common.serialization.proto.IrWhen as ProtoWhen import org.jetbrains.kotlin.backend.common.serialization.proto.IrWhile as ProtoWhile -import org.jetbrains.kotlin.backend.common.serialization.proto.LocalSignature as ProtoLocalSignature import org.jetbrains.kotlin.backend.common.serialization.proto.Loop as ProtoLoop import org.jetbrains.kotlin.backend.common.serialization.proto.MemberAccessCommon as ProtoMemberAccessCommon import org.jetbrains.kotlin.backend.common.serialization.proto.NullableIrExpression as ProtoNullableIrExpression @@ -137,6 +131,12 @@ open class IrFileSerializer( // so use this index to store signature only once. private val protoIdSignatureMap = mutableMapOf() protected val protoIdSignatureArray = arrayListOf() + private val idSignatureSerializer = IdSignatureSerializer( + ::serializeString, + ::serializeDebugInfo, + protoIdSignatureMap, + protoIdSignatureArray + ) protected val protoBodyArray = mutableListOf() @@ -207,97 +207,9 @@ open class IrFileSerializer( /* ------- IdSignature ------------------------------------------------------ */ - private fun serializePublicSignature(signature: IdSignature.CommonSignature): ProtoCommonIdSignature { - val proto = ProtoCommonIdSignature.newBuilder() - proto.addAllPackageFqName(serializeFqName(signature.packageFqName)) - proto.addAllDeclarationFqName(serializeFqName(signature.declarationFqName)) - - signature.id?.let { proto.memberUniqId = it } - if (signature.mask != 0L) { - proto.flags = signature.mask - } - - signature.description?.let { proto.debugInfo = serializeDebugInfo(it) } - - return proto.build() - } - - private fun serializeAccessorSignature(signature: IdSignature.AccessorSignature): ProtoAccessorIdSignature { - val proto = ProtoAccessorIdSignature.newBuilder() - - proto.propertySignature = protoIdSignature(signature.propertySignature) - with(signature.accessorSignature) { - proto.name = serializeString(shortName) - proto.accessorHashId = id ?: error("Expected hash Id") - if (mask != 0L) { - proto.flags = mask - } - description?.let { proto.debugInfo = serializeDebugInfo(it) } - } - - return proto.build() - } - - private fun serializePrivateSignature(signature: IdSignature.FileLocalSignature): ProtoFileLocalIdSignature { - val proto = ProtoFileLocalIdSignature.newBuilder() - - proto.container = protoIdSignature(signature.container) - proto.localId = signature.id - signature.description?.let { proto.debugInfo = serializeDebugInfo(it) } - - return proto.build() - } - - private fun serializeScopeLocalSignature(signature: IdSignature.ScopeLocalDeclaration): Int = signature.id - - private fun serializeCompositeSignature(signature: IdSignature.CompositeSignature): ProtoCompositeSignature { - val proto = ProtoCompositeSignature.newBuilder() - - proto.containerSig = protoIdSignature(signature.container) - proto.innerSig = protoIdSignature(signature.inner) - - return proto.build() - } - - @Suppress("UNUSED_PARAMETER") - private fun serializeFileSignature(signature: IdSignature.FileSignature): ProtoFileSignature = ProtoFileSignature.getDefaultInstance() - - private fun serializeLocalSignature(signature: IdSignature.LocalSignature): ProtoLocalSignature { - val proto = ProtoLocalSignature.newBuilder() - - proto.addAllLocalFqName(serializeFqName(signature.localFqn)) - signature.hashSig?.let { proto.localHash = it } - signature.description?.let { proto.debugInfo = serializeDebugInfo(it) } - - return proto.build() - } - - private fun serializeIdSignature(idSignature: IdSignature): ProtoIdSignature { - val proto = ProtoIdSignature.newBuilder() - when (idSignature) { - is IdSignature.CommonSignature -> proto.publicSig = serializePublicSignature(idSignature) - is IdSignature.AccessorSignature -> proto.accessorSig = serializeAccessorSignature(idSignature) - is IdSignature.FileLocalSignature -> proto.privateSig = serializePrivateSignature(idSignature) - is IdSignature.ScopeLocalDeclaration -> proto.scopedLocalSig = serializeScopeLocalSignature(idSignature) - is IdSignature.CompositeSignature -> proto.compositeSig = serializeCompositeSignature(idSignature) - is IdSignature.LocalSignature -> proto.localSig = serializeLocalSignature(idSignature) - is IdSignature.FileSignature -> proto.fileSig = serializeFileSignature(idSignature) - is IdSignature.SpecialFakeOverrideSignature -> {} - is IdSignature.LoweredDeclarationSignature -> error("LoweredDeclarationSignature is not expected here") - } - return proto.build() - } - private fun protoIdSignature(declaration: IrDeclaration): Int { val idSig = declarationTable.signatureByDeclaration(declaration, compatibilityMode.oldSignatures) - return protoIdSignature(idSig) - } - - private fun protoIdSignature(idSig: IdSignature): Int { - return protoIdSignatureMap.getOrPut(idSig) { - protoIdSignatureArray.add(serializeIdSignature(idSig)) - protoIdSignatureArray.size - 1 - } + return idSignatureSerializer.protoIdSignature(idSig) } /* ------- IrSymbols -------------------------------------------------------- */ @@ -349,7 +261,7 @@ open class IrFileSerializer( val symbolKind = protoSymbolKind(symbol) val signatureId = when { - symbol is IrFileSymbol -> protoIdSignature(IdSignature.FileSignature(symbol)) // TODO: special signature for files? + symbol is IrFileSymbol -> idSignatureSerializer.protoIdSignature(IdSignature.FileSignature(symbol)) // TODO: special signature for files? else -> { val declaration = symbol.owner as? IrDeclaration ?: error("Expected IrDeclaration: ${symbol.owner.render()}") protoIdSignature(declaration) @@ -1448,7 +1360,7 @@ open class IrFileSerializer( // TODO: keep order similar val sigIndex = protoIdSignatureMap[idSig] - ?: if (it is IrErrorDeclaration) protoIdSignature(idSig) else error("Not found ID for $idSig (${it.render()})") + ?: if (it is IrErrorDeclaration) idSignatureSerializer.protoIdSignature(idSig) else error("Not found ID for $idSig (${it.render()})") topLevelDeclarations.add(SerializedDeclaration(sigIndex, idSig.render(), byteArray)) proto.addDeclarationId(sigIndex) }