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