diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DescriptorByIdSignatureFinder.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DescriptorByIdSignatureFinder.kt index 4b50acd5f36..8bbf6747544 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DescriptorByIdSignatureFinder.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DescriptorByIdSignatureFinder.kt @@ -6,10 +6,34 @@ package org.jetbrains.kotlin.backend.common.serialization 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 -class DescriptorByIdSignatureFinder(private val moduleDescriptor: ModuleDescriptor, private val mangler: KotlinMangler.DescriptorMangler) { +class DescriptorByIdSignatureFinder( + private val moduleDescriptor: ModuleDescriptor, + private val mangler: KotlinMangler.DescriptorMangler, + private val lookupMode: LookupMode +) { + init { + assert(lookupMode != LookupMode.MODULE_ONLY || moduleDescriptor is ModuleDescriptorImpl) + } + + /** + * Sets search scope for [findDescriptorBySignature]. + */ + enum class LookupMode { + /** + * Perform search of descriptor in [moduleDescriptor] and its dependencies. + */ + MODULE_WITH_DEPENDENCIES, + + /** + * Perform search of descriptor only in [moduleDescriptor]. + */ + MODULE_ONLY + } + fun findDescriptorBySignature(signature: IdSignature): DeclarationDescriptor? = when (signature) { is IdSignature.AccessorSignature -> findDescriptorForAccessorSignature(signature) is IdSignature.PublicSignature -> findDescriptorForPublicSignature(signature) @@ -24,11 +48,29 @@ class DescriptorByIdSignatureFinder(private val moduleDescriptor: ModuleDescript } } + private fun performLookup(signature: IdSignature.PublicSignature): Collection { + val declarationName = signature.declarationFqn.pathSegments().first() + return when (lookupMode) { + LookupMode.MODULE_WITH_DEPENDENCIES -> { + moduleDescriptor + .getPackage(signature.packageFqName()) + .memberScope + .getContributedDescriptors { name -> name == declarationName } + } + LookupMode.MODULE_ONLY -> { + (moduleDescriptor as ModuleDescriptorImpl) + .packageFragmentProviderForModuleContentWithoutDependencies + .getPackageFragments(signature.packageFqName()) + .map { it.getMemberScope() } + .flatMap { it.getContributedDescriptors { name -> name == declarationName } } + } + } + } + private fun findDescriptorForPublicSignature(signature: IdSignature.PublicSignature): DeclarationDescriptor? { - val packageDescriptor = moduleDescriptor.getPackage(signature.packageFqName()) + val toplevelDescriptors = performLookup(signature) + .ifEmpty { return null } 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 -> acc.flatMap { container -> val classDescriptor = container as? ClassDescriptor @@ -50,7 +92,7 @@ class DescriptorByIdSignatureFinder(private val moduleDescriptor: ModuleDescript } } - private fun findDescriptorByHash(candidates: List, id: Long?): DeclarationDescriptor? = + private fun findDescriptorByHash(candidates: Collection, id: Long?): DeclarationDescriptor? = candidates.firstOrNull { candidate -> if (id == null) { // We don't compute id for typealiases and classes. diff --git a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt index e77b522bb67..c4af7a5c00c 100644 --- a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt +++ b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt @@ -111,7 +111,10 @@ class JvmIrLinker(currentModule: ModuleDescriptor?, logger: LoggingContext, buil // TODO: implement proper check whether `idSig` belongs to this module override fun contains(idSig: IdSignature): Boolean = true - private val descriptorFinder = DescriptorByIdSignatureFinder(moduleDescriptor, manglerDesc) + private val descriptorFinder = DescriptorByIdSignatureFinder( + moduleDescriptor, manglerDesc, + DescriptorByIdSignatureFinder.LookupMode.MODULE_ONLY + ) private fun resolveDescriptor(idSig: IdSignature): DeclarationDescriptor { return descriptorFinder.findDescriptorBySignature(idSig) ?: error("No descriptor found for $idSig")