Extract IdSignature serializer from IrFileSerializer

^KT-61642
This commit is contained in:
Johan Bay
2023-09-02 07:56:32 +02:00
committed by Space Cloud
parent a041e51ff2
commit 64e601bea0
2 changed files with 122 additions and 97 deletions
@@ -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<IdSignature, Int>,
private val protoIdSignatureArray: ArrayList<ProtoIdSignature>
) {
private fun serializeFqName(fqName: String): List<Int> = 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
}
}
}
@@ -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<IdSignature, Int>()
protected val protoIdSignatureArray = arrayListOf<ProtoIdSignature>()
private val idSignatureSerializer = IdSignatureSerializer(
::serializeString,
::serializeDebugInfo,
protoIdSignatureMap,
protoIdSignatureArray
)
protected val protoBodyArray = mutableListOf<XStatementOrExpression>()
@@ -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)
}