IR: use String instead of FqName in IdSignature.PublicSignature

FqName/FqNameUnsafe tend to eagerly compute things like
safe/parent/shortName which take a lot of space.

This change helps to lower strongly reachable memory just before codegen
in JVM IR by about 5% on a relatively big project.
This commit is contained in:
Alexander Udalov
2020-06-10 21:46:29 +02:00
parent d24e136ba8
commit 3154eca218
11 changed files with 102 additions and 113 deletions
@@ -10,12 +10,11 @@ import org.jetbrains.kotlin.fir.FirEffectiveVisibilityImpl
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.backend.Fir2IrSignatureComposer
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
class FirBasedSignatureComposer(private val mangler: FirMangler) : Fir2IrSignatureComposer {
inner class SignatureBuilder : FirVisitorVoid() {
@@ -70,15 +69,21 @@ class FirBasedSignatureComposer(private val mangler: FirMangler) : Fir2IrSignatu
return when {
declaration is FirRegularClass && declaration.visibility != Visibilities.LOCAL -> {
val classId = declaration.classId
IdSignature.PublicSignature(classId.packageFqName, classId.relativeClassName, builder.hashId, builder.mask)
IdSignature.PublicSignature(
classId.packageFqName.asString(), classId.relativeClassName.asString(), builder.hashId, builder.mask
)
}
declaration is FirTypeAlias -> {
val classId = declaration.symbol.classId
IdSignature.PublicSignature(classId.packageFqName, classId.relativeClassName, builder.hashId, builder.mask)
IdSignature.PublicSignature(
classId.packageFqName.asString(), classId.relativeClassName.asString(), builder.hashId, builder.mask
)
}
declaration is FirCallableMemberDeclaration<*> -> {
val callableId = declaration.symbol.callableId
IdSignature.PublicSignature(callableId.packageName, callableId.relativeCallableName, builder.hashId, builder.mask)
IdSignature.PublicSignature(
callableId.packageName.asString(), callableId.relativeCallableName.asString(), builder.hashId, builder.mask
)
}
else -> throw AssertionError("Unsupported FIR declaration in signature composer: ${declaration.render()}")
}
@@ -87,10 +92,10 @@ class FirBasedSignatureComposer(private val mangler: FirMangler) : Fir2IrSignatu
override fun composeAccessorSignature(property: FirProperty, isSetter: Boolean): IdSignature? {
val propertySignature = composeSignature(property) as? IdSignature.PublicSignature ?: return null
val accessorFqName = if (isSetter) {
propertySignature.declarationFqn.child(Name.special("<set-${property.name}>"))
propertySignature.declarationFqName + ".<set-${property.name.asString()}>"
} else {
propertySignature.declarationFqn.child(Name.special("<get-${property.name}>"))
propertySignature.declarationFqName + ".<get-${property.name.asString()}>"
}
return IdSignature.PublicSignature(propertySignature.packageFqn, accessorFqName, propertySignature.id, propertySignature.mask)
return IdSignature.PublicSignature(propertySignature.packageFqName, accessorFqName, propertySignature.id, propertySignature.mask)
}
}
}
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
import org.jetbrains.kotlin.types.KotlinType
@@ -361,22 +362,19 @@ class DeclarationStubGenerator(
private fun findDescriptorForAccessorSignature(signature: IdSignature.AccessorSignature): DeclarationDescriptor? {
val propertyDescriptor = findDescriptorBySignature(signature.propertySignature) as? PropertyDescriptor ?: return null
return propertyDescriptor.accessors.singleOrNull {
it.name == signature.accessorSignature.declarationFqn.shortName()
}
val shortName = signature.accessorSignature.shortName
return propertyDescriptor.accessors.singleOrNull { it.name.asString() == shortName }
}
private fun findDescriptorForPublicSignature(signature: IdSignature.PublicSignature): DeclarationDescriptor? {
val packageDescriptor = moduleDescriptor.getPackage(signature.packageFqName())
val pathSegments = signature.declarationFqn.pathSegments()
val toplevelDescriptors = packageDescriptor.memberScope.getContributedDescriptors { name -> name == pathSegments.first() }
.filter { it.name == pathSegments.first() }
val candidates = pathSegments.drop(1).fold(toplevelDescriptors) { acc, current ->
val nameSegments = signature.nameSegments
val toplevelDescriptors = packageDescriptor.memberScope.getDescriptorsFiltered { name -> name.asString() == nameSegments.first() }
val candidates = nameSegments.drop(1).fold(toplevelDescriptors) { acc, current ->
acc.flatMap { container ->
val classDescriptor = container as? ClassDescriptor ?: return@flatMap emptyList()
val nextStepCandidates = classDescriptor.constructors +
classDescriptor.unsubstitutedMemberScope.getContributedDescriptors { name -> name == current }
nextStepCandidates.filter { it.name == current }
classDescriptor.constructors.filter { it.name.asString() == current } +
classDescriptor.unsubstitutedMemberScope.getDescriptorsFiltered { name -> name.asString() == current }
}
}
return candidates.firstOrNull { symbolTable.signaturer.composeSignature(it) == signature }
@@ -46,10 +46,16 @@ sealed class IdSignature {
return "${if (isPublic) "public" else "private"} ${render()}"
}
class PublicSignature(val packageFqn: FqName, val declarationFqn: FqName, val id: Long?, val mask: Long) : IdSignature() {
class PublicSignature(val packageFqName: String, val declarationFqName: String, val id: Long?, val mask: Long) : IdSignature() {
override val isPublic = true
override fun packageFqName() = packageFqn
override fun packageFqName(): FqName = FqName(packageFqName)
val shortName: String get() = declarationFqName.substringAfterLast('.')
val firstNameSegment: String get() = declarationFqName.substringBefore('.')
val nameSegments: List<String> get() = declarationFqName.split('.')
private fun adaptMask(old: Long): Long {
return old xor Flags.values().fold(0L) { a, f ->
@@ -59,35 +65,34 @@ sealed class IdSignature {
}
override fun topLevelSignature(): IdSignature {
if (declarationFqn.isRoot) {
if (declarationFqName.isEmpty()) {
assert(id == null)
// package signature
return this
}
val pathSegments = declarationFqn.pathSegments()
val nameSegments = nameSegments
if (nameSegments.size == 1) return this
if (pathSegments.size == 1) return this
return PublicSignature(packageFqn, FqName(pathSegments.first().asString()), null, adaptMask(mask))
return PublicSignature(packageFqName, nameSegments.first(), null, adaptMask(mask))
}
override fun isPackageSignature(): Boolean = id == null && declarationFqn.isRoot
override fun isPackageSignature(): Boolean = id == null && declarationFqName.isEmpty()
override fun nearestPublicSig(): PublicSignature = this
override fun flags(): Long = mask
override fun render(): String = "${packageFqn.asString()}/${declarationFqn.asString()}|$id[${mask.toString(2)}]"
override fun render(): String = "$packageFqName/$declarationFqName|$id[${mask.toString(2)}]"
override fun asPublic(): PublicSignature? = this
override fun equals(other: Any?): Boolean =
other is PublicSignature &&
packageFqn == other.packageFqn && declarationFqn == other.declarationFqn && id == other.id && mask == other.mask
other is PublicSignature && packageFqName == other.packageFqName && declarationFqName == other.declarationFqName &&
id == other.id && mask == other.mask
override fun hashCode(): Int =
((packageFqn.hashCode() * 31 + declarationFqn.hashCode()) * 31 + id.hashCode()) * 31 + mask.hashCode()
((packageFqName.hashCode() * 31 + declarationFqName.hashCode()) * 31 + id.hashCode()) * 31 + mask.hashCode()
}
class AccessorSignature(val propertySignature: IdSignature, val accessorSignature: PublicSignature) : IdSignature() {
@@ -121,7 +126,7 @@ sealed class IdSignature {
override fun topLevelSignature(): IdSignature {
val topLevelContainer = container.topLevelSignature()
if (topLevelContainer === container) {
if (topLevelContainer is PublicSignature && topLevelContainer.declarationFqn.isRoot) {
if (topLevelContainer is PublicSignature && topLevelContainer.declarationFqName.isEmpty()) {
// private top level
return this
}
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.ir.util.KotlinMangler
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
class DescriptorByIdSignatureFinder(
private val moduleDescriptor: ModuleDescriptor,
@@ -43,26 +44,25 @@ class DescriptorByIdSignatureFinder(
private fun findDescriptorForAccessorSignature(signature: IdSignature.AccessorSignature): DeclarationDescriptor? {
val propertyDescriptor = findDescriptorBySignature(signature.propertySignature) as? PropertyDescriptor
?: return null
return propertyDescriptor.accessors.singleOrNull {
it.name == signature.accessorSignature.declarationFqn.shortName()
}
val shortName = signature.accessorSignature.shortName
return propertyDescriptor.accessors.singleOrNull { it.name.asString() == shortName }
}
private fun performLookup(signature: IdSignature.PublicSignature): Collection<DeclarationDescriptor> {
val declarationName = signature.declarationFqn.pathSegments().first()
val declarationName = signature.firstNameSegment
return when (lookupMode) {
LookupMode.MODULE_WITH_DEPENDENCIES -> {
moduleDescriptor
.getPackage(signature.packageFqName())
.memberScope
.getContributedDescriptors { name -> name == declarationName }
.getContributedDescriptors { name -> name.asString() == declarationName }
}
LookupMode.MODULE_ONLY -> {
(moduleDescriptor as ModuleDescriptorImpl)
.packageFragmentProviderForModuleContentWithoutDependencies
.getPackageFragments(signature.packageFqName())
.map { it.getMemberScope() }
.flatMap { it.getContributedDescriptors { name -> name == declarationName } }
.flatMap { it.getContributedDescriptors { name -> name.asString() == declarationName } }
}
}
}
@@ -70,16 +70,13 @@ class DescriptorByIdSignatureFinder(
private fun findDescriptorForPublicSignature(signature: IdSignature.PublicSignature): DeclarationDescriptor? {
val toplevelDescriptors = performLookup(signature)
.ifEmpty { return null }
val pathSegments = signature.declarationFqn.pathSegments()
val candidates = pathSegments.drop(1).fold(toplevelDescriptors) { acc, current ->
val candidates = signature.nameSegments.drop(1).fold(toplevelDescriptors) { acc, current ->
acc.flatMap { container ->
val classDescriptor = container as? ClassDescriptor
?: return@flatMap emptyList<DeclarationDescriptor>()
val nextStepCandidates = classDescriptor.constructors +
classDescriptor.unsubstitutedMemberScope.getContributedDescriptors { name -> name == current } +
val classDescriptor = container as? ClassDescriptor ?: return@flatMap emptyList<DeclarationDescriptor>()
classDescriptor.constructors.filter { it.name.asString() == current } +
classDescriptor.unsubstitutedMemberScope.getDescriptorsFiltered { name -> name.asString() == current } +
// Static scope is required only for Enum.values() and Enum.valueOf().
classDescriptor.staticScope.getContributedDescriptors { name -> name == current }
nextStepCandidates.filter { it.name == current }
classDescriptor.staticScope.getDescriptorsFiltered { name -> name.asString() == current }
}
}
@@ -102,4 +99,4 @@ class DescriptorByIdSignatureFinder(
candidateHash == id
}
}
}
}
@@ -5,14 +5,8 @@
package org.jetbrains.kotlin.backend.common.serialization
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import java.util.regex.Pattern
internal val functionPattern = Pattern.compile("^K?(Suspend)?Function\\d+$")
internal val kotlinFqn = FqName("kotlin")
internal val kotlinCoroutinesFqn = kotlinFqn.child(Name.identifier("coroutines"))
internal val kotlinReflectFqn = kotlinFqn.child(Name.identifier("reflect"))
internal val functionalPackages = listOf(kotlinFqn, kotlinCoroutinesFqn, kotlinReflectFqn)
internal val functionalPackages = listOf("kotlin", "kotlin.coroutines", "kotlin.reflect")
@@ -12,12 +12,12 @@ import org.jetbrains.kotlin.backend.common.peek
import org.jetbrains.kotlin.backend.common.pop
import org.jetbrains.kotlin.backend.common.push
import org.jetbrains.kotlin.backend.common.serialization.encodings.*
import org.jetbrains.kotlin.backend.common.serialization.proto.IdSignature.IdsigCase.*
import org.jetbrains.kotlin.backend.common.serialization.proto.IrConst.ValueCase.*
import org.jetbrains.kotlin.backend.common.serialization.proto.IrDeclaration.DeclaratorCase.*
import org.jetbrains.kotlin.backend.common.serialization.proto.IrOperation.OperationCase.*
import org.jetbrains.kotlin.backend.common.serialization.proto.IrStatement.StatementCase
import org.jetbrains.kotlin.backend.common.serialization.proto.IrType.KindCase.*
import org.jetbrains.kotlin.backend.common.serialization.proto.IdSignature.IdsigCase.*
import org.jetbrains.kotlin.backend.common.serialization.proto.IrVarargElement.VarargElementCase
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
@@ -30,9 +30,11 @@ import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.backend.common.serialization.proto.AccessorIdSignature as ProtoAccessorIdSignature
import org.jetbrains.kotlin.backend.common.serialization.proto.FileLocalIdSignature as ProtoFileLocalIdSignature
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
import org.jetbrains.kotlin.backend.common.serialization.proto.IrBlockBody as ProtoBlockBody
@@ -99,10 +101,7 @@ import org.jetbrains.kotlin.backend.common.serialization.proto.IrWhen as ProtoWh
import org.jetbrains.kotlin.backend.common.serialization.proto.IrWhile as ProtoWhile
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.IdSignature as ProtoIdSignature
import org.jetbrains.kotlin.backend.common.serialization.proto.PublicIdSignature as ProtoPublicIdSignature
import org.jetbrains.kotlin.backend.common.serialization.proto.AccessorIdSignature as ProtoAccessorIdSignature
import org.jetbrains.kotlin.backend.common.serialization.proto.FileLocalIdSignature as ProtoFileLocalIdSignature
abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBuiltIns, val symbolTable: SymbolTable, var constructFakeOverrides: Boolean, protected var deserializeBodies: Boolean) {
@@ -122,11 +121,8 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
abstract val deserializeInlineFunctions: Boolean
fun deserializeFqName(fqn: List<Int>): FqName {
return fqn.run {
if (isEmpty()) FqName.ROOT else FqName.fromSegments(map { deserializeString(it) })
}
}
fun deserializeFqName(fqn: List<Int>): String =
fqn.joinToString(".", transform = ::deserializeString)
private fun deserializeIrSymbolAndRemap(code: Long): IrSymbol {
// TODO: could be simplified
@@ -224,9 +220,8 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
val hash = proto.accessorHashId
val mask = proto.flags
val accessorSignature = with(propertySignature) {
IdSignature.PublicSignature(packageFqn, declarationFqn.child(Name.special(name)), hash, mask)
}
val accessorSignature =
IdSignature.PublicSignature(propertySignature.packageFqName, "${propertySignature.declarationFqName}.$name", hash, mask)
return IdSignature.AccessorSignature(propertySignature, accessorSignature)
}
@@ -184,8 +184,8 @@ open class IrFileSerializer(
private fun serializePublicSignature(signature: IdSignature.PublicSignature): ProtoPublicIdSignature {
val proto = ProtoPublicIdSignature.newBuilder()
proto.addAllPackageFqName(serializeFqName(signature.packageFqn))
proto.addAllDeclarationFqName(serializeFqName(signature.declarationFqn))
proto.addAllPackageFqName(serializeFqName(signature.packageFqName))
proto.addAllDeclarationFqName(serializeFqName(signature.declarationFqName))
signature.id?.let { proto.memberUniqId = it }
if (signature.mask != 0L) {
@@ -200,7 +200,7 @@ open class IrFileSerializer(
proto.propertySignature = protoIdSignature(signature.propertySignature)
with(signature.accessorSignature) {
proto.name = serializeString(declarationFqn.shortName().asString())
proto.name = serializeString(shortName)
proto.accessorHashId = id ?: error("Expected hash Id")
if (mask != 0L) {
proto.flags = mask
@@ -297,7 +297,7 @@ open class IrFileSerializer(
private fun serializeAnnotations(annotations: List<IrConstructorCall>) =
annotations.map { serializeConstructorCall(it) }
private fun serializeFqName(fqName: FqName) = fqName.pathSegments().map { serializeString(it.asString()) }
private fun serializeFqName(fqName: String): List<Int> = fqName.split(".").map(::serializeString)
private fun serializeIrStarProjection() = BinaryTypeProjection.STAR_CODE
@@ -1228,7 +1228,7 @@ open class IrFileSerializer(
val proto = ProtoFile.newBuilder()
.setFileEntry(serializeFileEntry(file.fileEntry))
.addAllFqName(serializeFqName(file.fqName))
.addAllFqName(serializeFqName(file.fqName.asString()))
.addAllAnnotation(serializeAnnotations(file.annotations))
file.declarations.forEach {
@@ -7,16 +7,17 @@ package org.jetbrains.kotlin.backend.common.serialization
import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner
import org.jetbrains.kotlin.ir.descriptors.IrAbstractFunctionFactory
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.descriptors.WrappedDeclarationDescriptor
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.library.IrLibrary
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
internal fun IrSymbol.kind(): BinarySymbolData.SymbolKind {
return when (this) {
@@ -81,19 +82,11 @@ class IrModuleDeserializerWithBuiltIns(
}.toMap()
private fun checkIsFunctionInterface(idSig: IdSignature): Boolean {
val publicSig = idSig.asPublic() ?: return false
if (publicSig.packageFqn !in functionalPackages) return false
val declarationFqn = publicSig.declarationFqn
if (declarationFqn.isRoot) return false
val fqnParts = declarationFqn.pathSegments()
val className = fqnParts.first()
return functionPattern.matcher(className.asString()).find()
val publicSig = idSig.asPublic()
return publicSig != null &&
publicSig.packageFqName in functionalPackages &&
publicSig.declarationFqName.isNotEmpty() &&
functionPattern.matcher(publicSig.firstNameSegment).find()
}
override operator fun contains(idSig: IdSignature): Boolean {
@@ -106,11 +99,10 @@ class IrModuleDeserializerWithBuiltIns(
delegate.deserializeReachableDeclarations()
}
private fun computeFunctionDescriptor(className: Name): FunctionClassDescriptor {
val nameString = className.asString()
val isK = nameString[0] == 'K'
val isSuspend = (if (isK) nameString[1] else nameString[0]) == 'S'
val arity = nameString.run { substring(indexOfFirst { it.isDigit() }).toInt(10) }
private fun computeFunctionDescriptor(className: String): FunctionClassDescriptor {
val isK = className[0] == 'K'
val isSuspend = (if (isK) className[1] else className[0]) == 'S'
val arity = className.run { substring(indexOfFirst { it.isDigit() }).toInt(10) }
return functionFactory.run {
when {
isK && isSuspend -> kSuspendFunctionClassDescriptor(arity)
@@ -124,11 +116,11 @@ class IrModuleDeserializerWithBuiltIns(
private fun resolveFunctionalInterface(idSig: IdSignature, symbolKind: BinarySymbolData.SymbolKind): IrSymbol {
val publicSig = idSig.asPublic() ?: error("$idSig has to be public")
val fqnParts = publicSig.declarationFqn.pathSegments()
val fqnParts = publicSig.nameSegments
val className = fqnParts.firstOrNull() ?: error("Expected class name for $idSig")
val functionDescriptor = computeFunctionDescriptor(className)
val topLevelSignature = IdSignature.PublicSignature(publicSig.packageFqn, FqName(className.asString()), null, publicSig.mask)
val topLevelSignature = IdSignature.PublicSignature(publicSig.packageFqName, className, null, publicSig.mask)
val functionClass = when (functionDescriptor.functionKind) {
FunctionClassDescriptor.Kind.KSuspendFunction -> functionFactory.kSuspendFunctionN(functionDescriptor.arity) { callback ->
@@ -148,19 +140,19 @@ class IrModuleDeserializerWithBuiltIns(
return when (fqnParts.size) {
1 -> functionClass.symbol.also { assert(symbolKind == BinarySymbolData.SymbolKind.CLASS_SYMBOL) }
2 -> {
val memberName = fqnParts[1]!!
functionClass.declarations.single { it is IrDeclarationWithName && it.name == memberName }.let {
val memberName = fqnParts[1]
functionClass.declarations.single { it is IrDeclarationWithName && it.name.asString() == memberName }.let {
(it as IrSymbolOwner).symbol
}
}
3 -> {
assert(idSig is IdSignature.AccessorSignature)
assert(symbolKind == BinarySymbolData.SymbolKind.FUNCTION_SYMBOL)
val propertyName = fqnParts[1]!!
val accessorName = fqnParts[2]!!
functionClass.declarations.filterIsInstance<IrProperty>().single { it.name == propertyName }.let { p ->
p.getter?.let { g -> if (g.name == accessorName) return g.symbol }
p.setter?.let { s -> if (s.name == accessorName) return s.symbol }
val propertyName = fqnParts[1]
val accessorName = fqnParts[2]
functionClass.declarations.filterIsInstance<IrProperty>().single { it.name.asString() == propertyName }.let { p ->
p.getter?.let { g -> if (g.name.asString() == accessorName) return g.symbol }
p.setter?.let { s -> if (s.name.asString() == accessorName) return s.symbol }
error("No accessor found for signature $idSig")
}
}
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.ir.util.NaiveSourceBasedFileEntryImpl
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.library.IrLibrary
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.protobuf.CodedInputStream
import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite.newInstance
import org.jetbrains.kotlin.resolve.descriptorUtil.module
@@ -173,7 +174,7 @@ abstract class KotlinIrLinker(
}
}
val fqName = fileDeserializer.deserializeFqName(fileProto.fqNameList)
val fqName = FqName(fileDeserializer.deserializeFqName(fileProto.fqNameList))
val packageFragmentDescriptor = EmptyPackageFragmentDescriptor(moduleDescriptor, fqName)
@@ -26,10 +26,12 @@ abstract class IdSignatureBuilder<D> {
}
protected fun build(): IdSignature {
val packageFqName = packageFqn.asString()
val classFqName = classFqnSegments.joinToString(".")
return if (hashIdAcc == null) {
IdSignature.PublicSignature(packageFqn, FqName.fromSegments(classFqnSegments), hashId, mask)
IdSignature.PublicSignature(packageFqName, classFqName, hashId, mask)
} else {
val accessorSignature = IdSignature.PublicSignature(packageFqn, FqName.fromSegments(classFqnSegments), hashIdAcc, mask)
val accessorSignature = IdSignature.PublicSignature(packageFqName, classFqName, hashIdAcc, mask)
hashIdAcc = null
classFqnSegments.run { removeAt(lastIndex) }
val propertySignature = build()
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.ir.util.KotlinMangler
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.name.FqName
open class IdSignatureSerializer(val mangler: KotlinMangler.IrMangler) : IdSignatureComputer {
@@ -96,11 +95,12 @@ open class IdSignatureSerializer(val mangler: KotlinMangler.IrMangler) : IdSigna
private val publicSignatureBuilder = PublicIdSigBuilder()
private fun composeContainerIdSignature(container: IrDeclarationParent): IdSignature {
if (container is IrPackageFragment) return IdSignature.PublicSignature(container.fqName, FqName.ROOT, null, 0)
if (container is IrDeclaration) return table.signatureByDeclaration(container)
error("Unexpected container ${container.render()}")
}
private fun composeContainerIdSignature(container: IrDeclarationParent): IdSignature =
when (container) {
is IrPackageFragment -> IdSignature.PublicSignature(container.fqName.asString(), "", null, 0)
is IrDeclaration -> table.signatureByDeclaration(container)
else -> error("Unexpected container ${container.render()}")
}
fun composePublicIdSignature(declaration: IrDeclaration): IdSignature {
assert(mangler.run { declaration.isExported() }) {
@@ -130,4 +130,4 @@ open class IdSignatureSerializer(val mangler: KotlinMangler.IrMangler) : IdSigna
}
}
}
}
}