Prefer platform specific declarations when searching for library sources
Untested: test infrastructure needed #KT-23223 Fixed
This commit is contained in:
+28
-17
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.debugText.getDebugText
|
import org.jetbrains.kotlin.psi.debugText.getDebugText
|
||||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||||
|
|
||||||
object SourceNavigationHelper {
|
object SourceNavigationHelper {
|
||||||
private val LOG = Logger.getInstance(SourceNavigationHelper::class.java)
|
private val LOG = Logger.getInstance(SourceNavigationHelper::class.java)
|
||||||
@@ -50,23 +51,18 @@ object SourceNavigationHelper {
|
|||||||
SourceNavigationHelper.forceResolve = forceResolve
|
SourceNavigationHelper.forceResolve = forceResolve
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun targetScope(declaration: KtNamedDeclaration, navigationKind: NavigationKind): GlobalSearchScope? {
|
private fun targetScopes(declaration: KtNamedDeclaration, navigationKind: NavigationKind): List<GlobalSearchScope> {
|
||||||
val containingFile = declaration.containingKtFile
|
val containingFile = declaration.containingKtFile
|
||||||
val vFile = containingFile.virtualFile ?: return null
|
val vFile = containingFile.virtualFile ?: return emptyList()
|
||||||
|
|
||||||
return when (navigationKind) {
|
return when (navigationKind) {
|
||||||
NavigationKind.CLASS_FILES_TO_SOURCES -> {
|
NavigationKind.CLASS_FILES_TO_SOURCES -> {
|
||||||
val binaryModuleInfos = getBinaryLibrariesModuleInfos(declaration.project, vFile)
|
val binaryModuleInfos = getBinaryLibrariesModuleInfos(declaration.project, vFile)
|
||||||
binaryModuleInfos.map { binaryModuleInfo ->
|
val primaryScope = binaryModuleInfos.mapNotNull { it.sourcesModuleInfo?.sourceScope() }.union()
|
||||||
val platform = binaryModuleInfo.platform
|
val additionalScope = binaryModuleInfos.flatMap {
|
||||||
if (platform == null || platform == TargetPlatform.Common) {
|
it.associatedCommonLibraries()
|
||||||
listOf(binaryModuleInfo)
|
}.mapNotNull { it.sourcesModuleInfo?.sourceScope() }.union()
|
||||||
} else {
|
primaryScope + additionalScope
|
||||||
binaryModuleInfo.dependencies().filterIsInstance<BinaryModuleInfo>().filter {
|
|
||||||
it.platform == TargetPlatform.Common
|
|
||||||
} + binaryModuleInfo
|
|
||||||
}
|
|
||||||
}.flatten().mapNotNull { it.sourcesModuleInfo?.sourceScope() }.union()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NavigationKind.SOURCES_TO_CLASS_FILES -> getLibrarySourcesModuleInfos(
|
NavigationKind.SOURCES_TO_CLASS_FILES -> getLibrarySourcesModuleInfos(
|
||||||
@@ -76,7 +72,17 @@ object SourceNavigationHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Collection<GlobalSearchScope>.union() = if (this.isNotEmpty()) GlobalSearchScope.union(this.toTypedArray()) else null
|
private fun BinaryModuleInfo.associatedCommonLibraries(): List<BinaryModuleInfo> {
|
||||||
|
val platform = platform
|
||||||
|
if (platform == null || platform == TargetPlatform.Common) return emptyList()
|
||||||
|
|
||||||
|
return dependencies().filterIsInstance<BinaryModuleInfo>().filter {
|
||||||
|
it.platform == TargetPlatform.Common
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Collection<GlobalSearchScope>.union(): List<GlobalSearchScope> =
|
||||||
|
if (this.isNotEmpty()) listOf(GlobalSearchScope.union(this.toTypedArray())) else emptyList()
|
||||||
|
|
||||||
private fun haveRenamesInImports(files: Collection<KtFile>) = files.any { it.importDirectives.any { it.aliasName != null } }
|
private fun haveRenamesInImports(files: Collection<KtFile>) = files.any { it.importDirectives.any { it.aliasName != null } }
|
||||||
|
|
||||||
@@ -183,8 +189,9 @@ object SourceNavigationHelper {
|
|||||||
index: StringStubIndexExtension<T>
|
index: StringStubIndexExtension<T>
|
||||||
): T? {
|
): T? {
|
||||||
val classFqName = entity.fqName ?: return null
|
val classFqName = entity.fqName ?: return null
|
||||||
val scope = targetScope(entity, navigationKind) ?: return null
|
return targetScopes(entity, navigationKind).firstNotNullResult {
|
||||||
return index.get(classFqName.asString(), entity.project, scope).firstOrNull()
|
index.get(classFqName.asString(), entity.project, it).firstOrNull()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findClassOrObject(decompiledClassOrObject: KtClassOrObject, navigationKind: NavigationKind): KtClassOrObject? {
|
private fun findClassOrObject(decompiledClassOrObject: KtClassOrObject, navigationKind: NavigationKind): KtClassOrObject? {
|
||||||
@@ -195,9 +202,13 @@ object SourceNavigationHelper {
|
|||||||
declaration: KtNamedDeclaration,
|
declaration: KtNamedDeclaration,
|
||||||
navigationKind: NavigationKind
|
navigationKind: NavigationKind
|
||||||
): Collection<KtNamedDeclaration> {
|
): Collection<KtNamedDeclaration> {
|
||||||
val scope = targetScope(declaration, navigationKind) ?: return emptyList()
|
val scopes = targetScopes(declaration, navigationKind)
|
||||||
val index = getIndexForTopLevelPropertyOrFunction(declaration)
|
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(
|
private fun getIndexForTopLevelPropertyOrFunction(
|
||||||
|
|||||||
Reference in New Issue
Block a user