[klib] Serialized mangled names of declarations along with signatures
^KT-59486 Fixed
This commit is contained in:
committed by
Space Team
parent
10aa5fc7ef
commit
6142d75bb4
+26
-19
@@ -27,6 +27,10 @@ class FirBasedSignatureComposer(val mangler: FirMangler) {
|
||||
|
||||
private val signatureCache = mutableMapOf<FirDeclarationWithParentId, IdSignature.CommonSignature>()
|
||||
|
||||
private fun computeSignatureHashAndDescriptionFor(declaration: FirDeclaration): Pair<Long, String> = mangler.run {
|
||||
declaration.signatureString(compatibleMode = false).let { it.hashMangle to it }
|
||||
}
|
||||
|
||||
fun composeSignature(declaration: FirClassLikeDeclaration): IdSignature? {
|
||||
return composeSignatureImpl(declaration, containingClass = null, forceExpect = false)
|
||||
}
|
||||
@@ -72,24 +76,19 @@ class FirBasedSignatureComposer(val mangler: FirMangler) {
|
||||
}
|
||||
else -> return null
|
||||
}
|
||||
val id = with(mangler) {
|
||||
if (isSetter) {
|
||||
property.setterOrDefault().signatureMangle(compatibleMode = false)
|
||||
} else {
|
||||
property.getterOrDefault().signatureMangle(compatibleMode = false)
|
||||
}
|
||||
}
|
||||
val accessorFqName = if (isSetter) {
|
||||
propSig.declarationFqName + ".<set-${property.name.asString()}>"
|
||||
val accessor = if (isSetter) {
|
||||
property.setterOrDefault()
|
||||
} else {
|
||||
propSig.declarationFqName + ".<get-${property.name.asString()}>"
|
||||
property.getterOrDefault()
|
||||
}
|
||||
val (id, description) = computeSignatureHashAndDescriptionFor(accessor)
|
||||
val accessorFqName = "${propSig.declarationFqName}.${accessor.irName}"
|
||||
val commonSig = IdSignature.CommonSignature(
|
||||
packageFqName = propSig.packageFqName,
|
||||
declarationFqName = accessorFqName,
|
||||
id = id,
|
||||
mask = propSig.mask,
|
||||
description = null, // TODO(KT-59486): Save mangled name here
|
||||
description = description,
|
||||
)
|
||||
val accessorSig = IdSignature.AccessorSignature(propSig, commonSig)
|
||||
return if (fileSig != null) {
|
||||
@@ -140,7 +139,7 @@ class FirBasedSignatureComposer(val mangler: FirMangler) {
|
||||
declarationFqName = classId.relativeClassName.asString(),
|
||||
id = builder.hashId,
|
||||
mask = builder.mask,
|
||||
description = null, // TODO(KT-59486): Save mangled name here
|
||||
description = builder.description,
|
||||
)
|
||||
}
|
||||
is FirTypeAlias -> {
|
||||
@@ -150,7 +149,7 @@ class FirBasedSignatureComposer(val mangler: FirMangler) {
|
||||
declarationFqName = classId.relativeClassName.asString(),
|
||||
id = builder.hashId,
|
||||
mask = builder.mask,
|
||||
description = null, // TODO(KT-59486): Save mangled name here
|
||||
description = builder.description,
|
||||
)
|
||||
}
|
||||
is FirCallableDeclaration -> {
|
||||
@@ -163,7 +162,7 @@ class FirBasedSignatureComposer(val mangler: FirMangler) {
|
||||
declarationFqName = classId?.relativeClassName?.child(callableName)?.asString() ?: callableName.asString(),
|
||||
id = builder.hashId,
|
||||
mask = builder.mask,
|
||||
description = null, // TODO(KT-59486): Save mangled name here
|
||||
description = builder.description,
|
||||
)
|
||||
}
|
||||
is FirScript -> {
|
||||
@@ -172,7 +171,7 @@ class FirBasedSignatureComposer(val mangler: FirMangler) {
|
||||
declarationFqName = declaration.name.asString(),
|
||||
id = builder.hashId,
|
||||
mask = builder.mask,
|
||||
description = null, // TODO(KT-59486): Save mangled name here
|
||||
description = builder.description,
|
||||
)
|
||||
}
|
||||
else -> error("Unsupported FIR declaration in signature composer: ${declaration.render()}")
|
||||
@@ -181,8 +180,16 @@ class FirBasedSignatureComposer(val mangler: FirMangler) {
|
||||
|
||||
private inner class SignatureBuilder(private val forceExpect: Boolean) : FirVisitor<Unit, Any?>() {
|
||||
var hashId: Long? = null
|
||||
var description: String? = null
|
||||
var mask = 0L
|
||||
|
||||
private fun setHashAndDescriptionFor(declaration: FirDeclaration) {
|
||||
computeSignatureHashAndDescriptionFor(declaration).let {
|
||||
hashId = it.first
|
||||
description = it.second
|
||||
}
|
||||
}
|
||||
|
||||
private fun setExpected(f: Boolean) {
|
||||
mask = mask or IdSignature.Flags.IS_EXPECT.encode(f || forceExpect)
|
||||
}
|
||||
@@ -204,22 +211,22 @@ class FirBasedSignatureComposer(val mangler: FirMangler) {
|
||||
}
|
||||
|
||||
override fun visitConstructor(constructor: FirConstructor, data: Any?) {
|
||||
hashId = mangler.run { constructor.signatureMangle(compatibleMode = false) }
|
||||
setHashAndDescriptionFor(constructor)
|
||||
setExpected(constructor.isExpect)
|
||||
}
|
||||
|
||||
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: Any?) {
|
||||
hashId = mangler.run { simpleFunction.signatureMangle(compatibleMode = false) }
|
||||
setHashAndDescriptionFor(simpleFunction)
|
||||
setExpected(simpleFunction.isExpect)
|
||||
}
|
||||
|
||||
override fun visitProperty(property: FirProperty, data: Any?) {
|
||||
hashId = mangler.run { property.signatureMangle(compatibleMode = false) }
|
||||
setHashAndDescriptionFor(property)
|
||||
setExpected(property.isExpect)
|
||||
}
|
||||
|
||||
override fun visitField(field: FirField, data: Any?) {
|
||||
hashId = mangler.run { field.signatureMangle(compatibleMode = false) }
|
||||
setHashAndDescriptionFor(field)
|
||||
setExpected(field.isExpect)
|
||||
}
|
||||
|
||||
|
||||
+7
-16
@@ -46,14 +46,9 @@ internal class IdSignatureSerialization(private val library: KotlinLibraryHeader
|
||||
out.writeInt32NoTag(IdSignatureProtoType.COMMON_SIGNATURE.id)
|
||||
out.writeStringNoTag(signature.packageFqName)
|
||||
out.writeStringNoTag(signature.declarationFqName)
|
||||
val id = signature.id
|
||||
if (id != null) {
|
||||
out.writeBoolNoTag(true)
|
||||
out.writeFixed64NoTag(id)
|
||||
} else {
|
||||
out.writeBoolNoTag(false)
|
||||
}
|
||||
out.ifNotNull(signature.id, out::writeFixed64NoTag)
|
||||
out.writeInt64NoTag(signature.mask)
|
||||
out.ifNotNull(signature.description, out::writeStringNoTag)
|
||||
}
|
||||
is IdSignature.CompositeSignature -> {
|
||||
out.writeInt32NoTag(IdSignatureProtoType.COMPOSITE_SIGNATURE.id)
|
||||
@@ -82,18 +77,15 @@ internal class IdSignatureSerialization(private val library: KotlinLibraryHeader
|
||||
IdSignatureProtoType.COMMON_SIGNATURE.id -> {
|
||||
val packageFqName = input.readString()
|
||||
val declarationFqName = input.readString()
|
||||
val id = if (input.readBool()) {
|
||||
input.readFixed64()
|
||||
} else {
|
||||
null
|
||||
}
|
||||
val id = input.ifTrue(input::readFixed64)
|
||||
val mask = input.readInt64()
|
||||
val description = input.ifTrue(input::readString)
|
||||
return IdSignature.CommonSignature(
|
||||
packageFqName = packageFqName,
|
||||
declarationFqName = declarationFqName,
|
||||
id = id,
|
||||
mask = mask,
|
||||
description = null, // TODO(KT-59486): Deserialize mangled name and save it here
|
||||
description = description,
|
||||
)
|
||||
}
|
||||
IdSignatureProtoType.COMPOSITE_SIGNATURE.id -> {
|
||||
@@ -123,10 +115,9 @@ internal class IdSignatureSerialization(private val library: KotlinLibraryHeader
|
||||
IdSignatureProtoType.COMMON_SIGNATURE.id -> {
|
||||
input.readString()
|
||||
input.readString()
|
||||
if (input.readBool()) {
|
||||
input.readFixed64()
|
||||
}
|
||||
input.ifTrue(input::readFixed64)
|
||||
input.readInt64()
|
||||
input.ifTrue(input::readString)
|
||||
}
|
||||
IdSignatureProtoType.COMPOSITE_SIGNATURE.id -> {
|
||||
skipIdSignature(input)
|
||||
|
||||
+9
-1
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.ir.backend.js.lower.StaticMembersLowering
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.isBuiltInClass
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.util.IdSignatureRenderer
|
||||
import org.jetbrains.kotlin.ir.util.isInterface
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.js.backend.JsToStringGenerationVisitor
|
||||
@@ -418,7 +419,14 @@ class IrModuleToJsTransformer(
|
||||
}
|
||||
|
||||
private fun Set<IrDeclaration>.computeTag(declaration: IrDeclaration): String? {
|
||||
val tag = (backendContext.irFactory as IdSignatureRetriever).declarationSignature(declaration)?.render()
|
||||
// Use LEGACY here because the declaration may come from an old klib, in which its `IdSignature.CommonSignature`
|
||||
// doesn't have `description`, but only `id`. Hence, we always render the signature with `id` instead of `description`,
|
||||
// because otherwise there may be a mismatch when we're computing the tag first for the IrDeclaration deserialized from klib,
|
||||
// and then for the same declaration but constructed from a descriptor.
|
||||
//
|
||||
// The former won't have `description` in its `IdSignature`, the latter will have it,
|
||||
// which will result in different renders unless we use the LEGACY renderer.
|
||||
val tag = (backendContext.irFactory as IdSignatureRetriever).declarationSignature(declaration)?.render(IdSignatureRenderer.LEGACY)
|
||||
|
||||
if (tag == null && !contains(declaration)) {
|
||||
error("signature for ${declaration.render()} not found")
|
||||
|
||||
@@ -69,7 +69,41 @@ class IdSignatureRenderer private constructor(private val showDescriptionForPubl
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
/**
|
||||
* The renderer which ignores [IdSignature.CommonSignature.id] and renders its [IdSignature.CommonSignature.description] instead.
|
||||
*
|
||||
* This results in more human-readable representations of signatures.
|
||||
*
|
||||
* If [IdSignature.CommonSignature.description] is `null`, falls back to rendering [IdSignature.CommonSignature.id].
|
||||
*
|
||||
* For example, for the following function:
|
||||
*
|
||||
* ```kotlin
|
||||
* package com.example
|
||||
*
|
||||
* fun box(): String {}
|
||||
* ```
|
||||
*
|
||||
* its signature rendered with the [DEFAULT] renderer will look like `com.example/box|box(){}[0]`
|
||||
* whereas when using the [LEGACY] renderer, it will look like `com.example/box|2173511048851971368[0]`.
|
||||
*/
|
||||
val DEFAULT = IdSignatureRenderer(showDescriptionForPublicSignatures = true)
|
||||
|
||||
/**
|
||||
* The renderer which ignores [IdSignature.CommonSignature.description] and renders its [IdSignature.CommonSignature.id] instead.
|
||||
*
|
||||
* For example, for the following function:
|
||||
*
|
||||
* ```kotlin
|
||||
* package com.example
|
||||
*
|
||||
* fun box(): String {}
|
||||
* ```
|
||||
*
|
||||
* its signature rendered with the [LEGACY] renderer will look like `com.example/box|2173511048851971368[0]`
|
||||
* whereas when using the [DEFAULT] renderer, it will look like `com.example/box|box(){}[0]`.
|
||||
*/
|
||||
val LEGACY = IdSignatureRenderer(showDescriptionForPublicSignatures = false)
|
||||
}
|
||||
}
|
||||
|
||||
+7
@@ -215,6 +215,10 @@ open class IrFileSerializer(
|
||||
proto.flags = signature.mask
|
||||
}
|
||||
|
||||
if (addDebugInfo) {
|
||||
signature.description?.let { proto.debugInfo = serializeDebugInfo(it) }
|
||||
}
|
||||
|
||||
return proto.build()
|
||||
}
|
||||
|
||||
@@ -228,6 +232,9 @@ open class IrFileSerializer(
|
||||
if (mask != 0L) {
|
||||
proto.flags = mask
|
||||
}
|
||||
if (addDebugInfo) {
|
||||
description?.let { proto.debugInfo = serializeDebugInfo(it) }
|
||||
}
|
||||
}
|
||||
|
||||
return proto.build()
|
||||
|
||||
+2
-2
@@ -74,7 +74,7 @@ abstract class IdSignatureBuilder<D> {
|
||||
declarationFqName = classFqName,
|
||||
id = hashId,
|
||||
mask = mask,
|
||||
description = null, // TODO(KT-59486): Save mangled name here
|
||||
description = description,
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
@@ -83,7 +83,7 @@ abstract class IdSignatureBuilder<D> {
|
||||
declarationFqName = classFqName,
|
||||
id = hashIdAcc,
|
||||
mask = mask,
|
||||
description = null, // TODO(KT-59486): Save mangled name here
|
||||
description = description,
|
||||
)
|
||||
hashIdAcc = null
|
||||
classFqnSegments.run { removeAt(lastIndex) }
|
||||
|
||||
+18
-6
@@ -23,6 +23,19 @@ open class IdSignatureDescriptor(override val mangler: KotlinMangler.DescriptorM
|
||||
IdSignatureBuilder<DeclarationDescriptor>(),
|
||||
DeclarationDescriptorVisitor<Unit, Nothing?> {
|
||||
|
||||
private fun setHashIdFor(declaration: DeclarationDescriptor, isPropertyAccessor: Boolean) {
|
||||
mangler.run {
|
||||
val mangledName = declaration.signatureString(compatibleMode = false)
|
||||
val id = mangledName.hashMangle
|
||||
if (isPropertyAccessor) {
|
||||
hashIdAcc = id
|
||||
} else {
|
||||
hashId = id
|
||||
}
|
||||
description = mangledName
|
||||
}
|
||||
}
|
||||
|
||||
override fun accept(d: DeclarationDescriptor) {
|
||||
d.accept(this, null)
|
||||
}
|
||||
@@ -71,7 +84,7 @@ open class IdSignatureDescriptor(override val mangler: KotlinMangler.DescriptorM
|
||||
|
||||
override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, data: Nothing?) {
|
||||
collectParents(descriptor)
|
||||
hashId = mangler.run { descriptor.signatureMangle(compatibleMode = false) }
|
||||
setHashIdFor(descriptor, isPropertyAccessor = false)
|
||||
isTopLevelPrivate = isTopLevelPrivate or descriptor.isTopLevelPrivate
|
||||
setDescription(descriptor)
|
||||
setExpected(descriptor.isExpect)
|
||||
@@ -115,7 +128,7 @@ open class IdSignatureDescriptor(override val mangler: KotlinMangler.DescriptorM
|
||||
|
||||
override fun visitConstructorDescriptor(constructorDescriptor: ConstructorDescriptor, data: Nothing?) {
|
||||
collectParents(constructorDescriptor)
|
||||
hashId = mangler.run { constructorDescriptor.signatureMangle(compatibleMode = false) }
|
||||
setHashIdFor(constructorDescriptor, isPropertyAccessor = false)
|
||||
platformSpecificConstructor(constructorDescriptor)
|
||||
}
|
||||
|
||||
@@ -131,8 +144,7 @@ open class IdSignatureDescriptor(override val mangler: KotlinMangler.DescriptorM
|
||||
collectParents(actualDeclaration)
|
||||
isTopLevelPrivate = isTopLevelPrivate or actualDeclaration.isTopLevelPrivate
|
||||
|
||||
|
||||
hashId = mangler.run { actualDeclaration.signatureMangle(compatibleMode = false) }
|
||||
setHashIdFor(actualDeclaration, isPropertyAccessor = false)
|
||||
setExpected(actualDeclaration.isExpect)
|
||||
platformSpecificProperty(actualDeclaration)
|
||||
if (type == SpecialDeclarationType.BACKING_FIELD) {
|
||||
@@ -149,7 +161,7 @@ open class IdSignatureDescriptor(override val mangler: KotlinMangler.DescriptorM
|
||||
|
||||
override fun visitPropertyGetterDescriptor(descriptor: PropertyGetterDescriptor, data: Nothing?) {
|
||||
descriptor.correspondingProperty.accept(this, null)
|
||||
hashIdAcc = mangler.run { descriptor.signatureMangle(compatibleMode = false) }
|
||||
setHashIdFor(descriptor, isPropertyAccessor = true)
|
||||
classFqnSegments.add(descriptor.name.asString())
|
||||
setExpected(descriptor.isExpect)
|
||||
platformSpecificGetter(descriptor)
|
||||
@@ -157,7 +169,7 @@ open class IdSignatureDescriptor(override val mangler: KotlinMangler.DescriptorM
|
||||
|
||||
override fun visitPropertySetterDescriptor(descriptor: PropertySetterDescriptor, data: Nothing?) {
|
||||
descriptor.correspondingProperty.accept(this, null)
|
||||
hashIdAcc = mangler.run { descriptor.signatureMangle(compatibleMode = false) }
|
||||
setHashIdFor(descriptor, isPropertyAccessor = true)
|
||||
classFqnSegments.add(descriptor.name.asString())
|
||||
setExpected(descriptor.isExpect)
|
||||
platformSpecificSetter(descriptor)
|
||||
|
||||
Reference in New Issue
Block a user