SourceNavigationHelper: use API to narrow search scope
This commit is contained in:
+17
-42
@@ -25,7 +25,6 @@ import com.intellij.openapi.roots.ProjectRootManager
|
|||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.psi.JavaPsiFacade
|
import com.intellij.psi.JavaPsiFacade
|
||||||
import com.intellij.psi.PsiClass
|
import com.intellij.psi.PsiClass
|
||||||
import com.intellij.psi.search.EverythingGlobalScope
|
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import com.intellij.psi.stubs.StringStubIndexExtension
|
import com.intellij.psi.stubs.StringStubIndexExtension
|
||||||
import com.intellij.util.containers.ContainerUtil
|
import com.intellij.util.containers.ContainerUtil
|
||||||
@@ -37,8 +36,14 @@ import org.jetbrains.kotlin.context.ContextForNewModule
|
|||||||
import org.jetbrains.kotlin.context.ProjectContext
|
import org.jetbrains.kotlin.context.ProjectContext
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.frontend.di.createLazyResolveSession
|
import org.jetbrains.kotlin.frontend.di.createLazyResolveSession
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.BinaryModuleInfo
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.SourceForBinaryModuleInfo
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.getModuleInfoByVirtualFile
|
||||||
import org.jetbrains.kotlin.idea.decompiler.navigation.MemberMatching.*
|
import org.jetbrains.kotlin.idea.decompiler.navigation.MemberMatching.*
|
||||||
import org.jetbrains.kotlin.idea.stubindex.*
|
import org.jetbrains.kotlin.idea.stubindex.KotlinFullClassNameIndex
|
||||||
|
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelFunctionFqnNameIndex
|
||||||
|
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelPropertyFqnNameIndex
|
||||||
|
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelTypeAliasFqNameIndex
|
||||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -62,23 +67,15 @@ object SourceNavigationHelper {
|
|||||||
SourceNavigationHelper.forceResolve = forceResolve
|
SourceNavigationHelper.forceResolve = forceResolve
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createLibraryOrSourcesScope(
|
private fun targetScope(declaration: KtNamedDeclaration, navigationKind: NavigationKind): GlobalSearchScope? {
|
||||||
declaration: KtNamedDeclaration,
|
|
||||||
navigationKind: NavigationKind
|
|
||||||
): GlobalSearchScope {
|
|
||||||
val containingFile = declaration.containingKtFile
|
val containingFile = declaration.containingKtFile
|
||||||
containingFile.virtualFile ?: return GlobalSearchScope.EMPTY_SCOPE
|
val vFile = containingFile.virtualFile ?: return null
|
||||||
|
val fromModuleInfo = getModuleInfoByVirtualFile(declaration.project, vFile)
|
||||||
|
|
||||||
val includeLibrarySources = navigationKind == NavigationKind.CLASS_FILES_TO_SOURCES
|
return when (navigationKind) {
|
||||||
if (ProjectRootsUtil.isInContent(declaration, false, includeLibrarySources, !includeLibrarySources, true)) {
|
NavigationKind.CLASS_FILES_TO_SOURCES -> (fromModuleInfo as? BinaryModuleInfo)?.sourcesModuleInfo?.sourceScope()
|
||||||
return GlobalSearchScope.EMPTY_SCOPE
|
NavigationKind.SOURCES_TO_CLASS_FILES -> (fromModuleInfo as? SourceForBinaryModuleInfo)?.binariesModuleInfo?.binariesScope()
|
||||||
}
|
}
|
||||||
|
|
||||||
val project = declaration.project
|
|
||||||
return if (includeLibrarySources)
|
|
||||||
KotlinSourceFilterScope.librarySources(EverythingGlobalScope(project), project)
|
|
||||||
else
|
|
||||||
KotlinSourceFilterScope.libraryClassFiles(EverythingGlobalScope(project), project)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 } }
|
||||||
@@ -148,8 +145,6 @@ object SourceNavigationHelper {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
candidates = filterByOrderEntries(declaration, candidates)
|
|
||||||
|
|
||||||
if (!forceResolve) {
|
if (!forceResolve) {
|
||||||
candidates = candidates.filter { sameReceiverPresenceAndParametersCount(it, declaration) }
|
candidates = candidates.filter { sameReceiverPresenceAndParametersCount(it, declaration) }
|
||||||
|
|
||||||
@@ -201,11 +196,8 @@ object SourceNavigationHelper {
|
|||||||
): T? {
|
): T? {
|
||||||
val classFqName = entity.fqName!!
|
val classFqName = entity.fqName!!
|
||||||
|
|
||||||
val librarySourcesScope = createLibraryOrSourcesScope(entity, navigationKind)
|
val scope = targetScope(entity, navigationKind) ?: return null
|
||||||
if (librarySourcesScope === GlobalSearchScope.EMPTY_SCOPE) { // .getProject() == null for EMPTY_SCOPE, and this breaks code
|
return index.get(classFqName.asString(), entity.project, scope).firstOrNull()
|
||||||
return null
|
|
||||||
}
|
|
||||||
return index.get(classFqName.asString(), entity.project, librarySourcesScope).firstOrNull()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findClassOrObject(decompiledClassOrObject: KtClassOrObject, navigationKind: NavigationKind): KtClassOrObject? {
|
private fun findClassOrObject(decompiledClassOrObject: KtClassOrObject, navigationKind: NavigationKind): KtClassOrObject? {
|
||||||
@@ -216,13 +208,9 @@ object SourceNavigationHelper {
|
|||||||
declaration: KtNamedDeclaration,
|
declaration: KtNamedDeclaration,
|
||||||
navigationKind: NavigationKind
|
navigationKind: NavigationKind
|
||||||
): Collection<KtNamedDeclaration> {
|
): Collection<KtNamedDeclaration> {
|
||||||
val librarySourcesScope = createLibraryOrSourcesScope(declaration, navigationKind)
|
val scope = targetScope(declaration, navigationKind) ?: return emptyList()
|
||||||
if (librarySourcesScope === GlobalSearchScope.EMPTY_SCOPE) { // .getProject() == null for EMPTY_SCOPE, and this breaks code
|
|
||||||
return emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
val index = getIndexForTopLevelPropertyOrFunction(declaration)
|
val index = getIndexForTopLevelPropertyOrFunction(declaration)
|
||||||
return index.get(declaration.fqName!!.asString(), declaration.project, librarySourcesScope)
|
return index.get(declaration.fqName!!.asString(), declaration.project, scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getIndexForTopLevelPropertyOrFunction(
|
private fun getIndexForTopLevelPropertyOrFunction(
|
||||||
@@ -244,19 +232,6 @@ object SourceNavigationHelper {
|
|||||||
name == declaration.nameAsSafeName
|
name == declaration.nameAsSafeName
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun filterByOrderEntries(
|
|
||||||
declaration: KtNamedDeclaration,
|
|
||||||
candidates: Collection<KtNamedDeclaration>
|
|
||||||
): List<KtNamedDeclaration> {
|
|
||||||
val fileIndex = ProjectRootManager.getInstance(declaration.project).fileIndex
|
|
||||||
val orderEntries = fileIndex.getOrderEntriesForFile(declaration.containingFile.virtualFile)
|
|
||||||
|
|
||||||
return candidates.filter {
|
|
||||||
val candidateOrderEntries = fileIndex.getOrderEntriesForFile(it.containingFile.virtualFile)
|
|
||||||
ContainerUtil.intersects<OrderEntry>(orderEntries, candidateOrderEntries)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getOriginalPsiClassOrCreateLightClass(classOrObject: KtClassOrObject): PsiClass? {
|
fun getOriginalPsiClassOrCreateLightClass(classOrObject: KtClassOrObject): PsiClass? {
|
||||||
val fqName = classOrObject.fqName
|
val fqName = classOrObject.fqName
|
||||||
if (fqName != null) {
|
if (fqName != null) {
|
||||||
|
|||||||
Reference in New Issue
Block a user