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:
+14
-9
@@ -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
|
||||
}
|
||||
|
||||
+12
-15
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-7
@@ -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")
|
||||
|
||||
+8
-13
@@ -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)
|
||||
}
|
||||
|
||||
+5
-5
@@ -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 {
|
||||
|
||||
+23
-31
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -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)
|
||||
|
||||
|
||||
+4
-2
@@ -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()
|
||||
|
||||
+7
-7
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user