From a584de8a7e3cee228da1e64809b3d1508513286b Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Wed, 11 Apr 2018 19:08:32 +0200 Subject: [PATCH] Prefer platform specific declarations when searching for library sources Untested: test infrastructure needed #KT-23223 Fixed --- .../navigation/SourceNavigationHelper.kt | 45 ++++++++++++------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/SourceNavigationHelper.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/SourceNavigationHelper.kt index cfd573a43bd..c4cad84bfe3 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/SourceNavigationHelper.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/navigation/SourceNavigationHelper.kt @@ -34,6 +34,7 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.debugText.getDebugText import org.jetbrains.kotlin.resolve.TargetPlatform +import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult object SourceNavigationHelper { private val LOG = Logger.getInstance(SourceNavigationHelper::class.java) @@ -50,23 +51,18 @@ object SourceNavigationHelper { SourceNavigationHelper.forceResolve = forceResolve } - private fun targetScope(declaration: KtNamedDeclaration, navigationKind: NavigationKind): GlobalSearchScope? { + private fun targetScopes(declaration: KtNamedDeclaration, navigationKind: NavigationKind): List { val containingFile = declaration.containingKtFile - val vFile = containingFile.virtualFile ?: return null + val vFile = containingFile.virtualFile ?: return emptyList() return when (navigationKind) { NavigationKind.CLASS_FILES_TO_SOURCES -> { val binaryModuleInfos = getBinaryLibrariesModuleInfos(declaration.project, vFile) - binaryModuleInfos.map { binaryModuleInfo -> - val platform = binaryModuleInfo.platform - if (platform == null || platform == TargetPlatform.Common) { - listOf(binaryModuleInfo) - } else { - binaryModuleInfo.dependencies().filterIsInstance().filter { - it.platform == TargetPlatform.Common - } + binaryModuleInfo - } - }.flatten().mapNotNull { it.sourcesModuleInfo?.sourceScope() }.union() + val primaryScope = binaryModuleInfos.mapNotNull { it.sourcesModuleInfo?.sourceScope() }.union() + val additionalScope = binaryModuleInfos.flatMap { + it.associatedCommonLibraries() + }.mapNotNull { it.sourcesModuleInfo?.sourceScope() }.union() + primaryScope + additionalScope } NavigationKind.SOURCES_TO_CLASS_FILES -> getLibrarySourcesModuleInfos( @@ -76,7 +72,17 @@ object SourceNavigationHelper { } } - private fun Collection.union() = if (this.isNotEmpty()) GlobalSearchScope.union(this.toTypedArray()) else null + private fun BinaryModuleInfo.associatedCommonLibraries(): List { + val platform = platform + if (platform == null || platform == TargetPlatform.Common) return emptyList() + + return dependencies().filterIsInstance().filter { + it.platform == TargetPlatform.Common + } + } + + private fun Collection.union(): List = + if (this.isNotEmpty()) listOf(GlobalSearchScope.union(this.toTypedArray())) else emptyList() private fun haveRenamesInImports(files: Collection) = files.any { it.importDirectives.any { it.aliasName != null } } @@ -183,8 +189,9 @@ object SourceNavigationHelper { index: StringStubIndexExtension ): T? { val classFqName = entity.fqName ?: return null - val scope = targetScope(entity, navigationKind) ?: return null - return index.get(classFqName.asString(), entity.project, scope).firstOrNull() + return targetScopes(entity, navigationKind).firstNotNullResult { + index.get(classFqName.asString(), entity.project, it).firstOrNull() + } } private fun findClassOrObject(decompiledClassOrObject: KtClassOrObject, navigationKind: NavigationKind): KtClassOrObject? { @@ -195,9 +202,13 @@ object SourceNavigationHelper { declaration: KtNamedDeclaration, navigationKind: NavigationKind ): Collection { - val scope = targetScope(declaration, navigationKind) ?: return emptyList() + val scopes = targetScopes(declaration, navigationKind) val index = getIndexForTopLevelPropertyOrFunction(declaration) - return index.get(declaration.fqName!!.asString(), declaration.project, scope) + for (scope in scopes) { + val candidates = index.get(declaration.fqName!!.asString(), declaration.project, scope) + if (candidates.isNotEmpty()) return candidates + } + return emptyList() } private fun getIndexForTopLevelPropertyOrFunction(