ReferenceSearch searches references to parameters using optimized way too
#KT-8625 Fixed
This commit is contained in:
+58
-22
@@ -19,9 +19,8 @@ package org.jetbrains.kotlin.idea.search.ideaExtensions
|
||||
import com.intellij.openapi.application.QueryExecutorBase
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.search.LocalSearchScope
|
||||
import com.intellij.psi.search.RequestResultProcessor
|
||||
import com.intellij.psi.search.SearchScope
|
||||
import com.intellij.psi.impl.cache.CacheManager
|
||||
import com.intellij.psi.search.*
|
||||
import com.intellij.psi.search.searches.ReferencesSearch
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.util.Processor
|
||||
@@ -29,8 +28,11 @@ import org.jetbrains.kotlin.asJava.KotlinLightMethod
|
||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
|
||||
import org.jetbrains.kotlin.idea.JetFileType
|
||||
import org.jetbrains.kotlin.idea.references.JetSimpleNameReference
|
||||
import org.jetbrains.kotlin.idea.search.KOTLIN_NAMED_ARGUMENT_SEARCH_CONTEXT
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.UsagesSearchLocation
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.getSpecialNamesToSearch
|
||||
import org.jetbrains.kotlin.idea.stubindex.JetSourceFilterScope
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -45,28 +47,16 @@ public class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, Referenc
|
||||
|
||||
val words = unwrappedElement.getSpecialNamesToSearch()
|
||||
|
||||
val resultProcessor = object : RequestResultProcessor() {
|
||||
private val referenceService = PsiReferenceService.getService()
|
||||
|
||||
override fun processTextOccurrence(element: PsiElement, offsetInElement: Int, consumer: Processor<PsiReference>): Boolean {
|
||||
return referenceService.getReferences(element, PsiReferenceService.Hints.NO_HINTS).all { ref ->
|
||||
ProgressManager.checkCanceled()
|
||||
|
||||
when {
|
||||
!ReferenceRange.containsOffsetInElement(ref, offsetInElement) -> true
|
||||
!ref.isReferenceTo(unwrappedElement) -> true
|
||||
else -> consumer.process(ref)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val effectiveSearchScope = runReadAction { queryParameters.effectiveSearchScope }
|
||||
|
||||
words.forEach { word ->
|
||||
queryParameters.getOptimizer().searchWord(word, effectiveSearchScope,
|
||||
UsagesSearchLocation.EVERYWHERE.searchContext, true, unwrappedElement,
|
||||
resultProcessor)
|
||||
queryParameters.optimizer.searchWord(word, effectiveSearchScope,
|
||||
UsagesSearchLocation.EVERYWHERE.searchContext, true, unwrappedElement,
|
||||
MyRequestResultProcessor(unwrappedElement) { !it.isNamedArgumentReference()/* they are processed later*/ })
|
||||
}
|
||||
|
||||
if (unwrappedElement is JetParameter) {
|
||||
runReadAction { searchNamedArguments(unwrappedElement, queryParameters) }
|
||||
}
|
||||
|
||||
if (!(unwrappedElement is JetElement && isOnlyKotlinSearch(effectiveSearchScope))) {
|
||||
@@ -74,6 +64,52 @@ public class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, Referenc
|
||||
}
|
||||
}
|
||||
|
||||
private fun searchNamedArguments(parameter: JetParameter, queryParameters: ReferencesSearch.SearchParameters) {
|
||||
val function = parameter.ownerFunction ?: return
|
||||
if (function.nameAsName?.isSpecial ?: true) return
|
||||
val project = function.project
|
||||
var namedArgsScope = function.useScope.intersectWith(queryParameters.scopeDeterminedByUser)
|
||||
|
||||
if (namedArgsScope is GlobalSearchScope) {
|
||||
namedArgsScope = JetSourceFilterScope.kotlinSources(namedArgsScope, project)
|
||||
|
||||
val filesWithFunctionName = CacheManager.SERVICE.getInstance(project).getVirtualFilesWithWord(
|
||||
function.name!!, UsageSearchContext.IN_CODE, namedArgsScope, true)
|
||||
namedArgsScope = GlobalSearchScope.filesScope(project, filesWithFunctionName.asList())
|
||||
}
|
||||
|
||||
queryParameters.optimizer.searchWord(parameter.name!!,
|
||||
namedArgsScope,
|
||||
KOTLIN_NAMED_ARGUMENT_SEARCH_CONTEXT,
|
||||
true,
|
||||
parameter,
|
||||
MyRequestResultProcessor(parameter) { it.isNamedArgumentReference() })
|
||||
}
|
||||
|
||||
private fun PsiReference.isNamedArgumentReference(): Boolean {
|
||||
return this is JetSimpleNameReference && expression.parent is JetValueArgumentName
|
||||
}
|
||||
|
||||
private class MyRequestResultProcessor(
|
||||
private val unwrappedElement: PsiElement,
|
||||
private val filter: (PsiReference) -> Boolean
|
||||
) : RequestResultProcessor() {
|
||||
private val referenceService = PsiReferenceService.getService()
|
||||
|
||||
override fun processTextOccurrence(element: PsiElement, offsetInElement: Int, consumer: Processor<PsiReference>): Boolean {
|
||||
return referenceService.getReferences(element, PsiReferenceService.Hints.NO_HINTS).all { ref ->
|
||||
ProgressManager.checkCanceled()
|
||||
|
||||
when {
|
||||
!filter(ref) -> true
|
||||
!ReferenceRange.containsOffsetInElement(ref, offsetInElement) -> true
|
||||
!ref.isReferenceTo(unwrappedElement) -> true
|
||||
else -> consumer.process(ref)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
public fun processJetClassOrObject(element: JetClassOrObject, queryParameters: ReferencesSearch.SearchParameters) {
|
||||
val className = element.getName()
|
||||
|
||||
+3
-3
@@ -251,8 +251,8 @@ class PropertyUsagesSearchHelper(
|
||||
override fun makeItemList(target: UsagesSearchTarget<JetNamedDeclaration>): List<UsagesSearchRequestItem> {
|
||||
val element = target.element
|
||||
if (element is JetParameter) {
|
||||
val realUsagesScope = element.useScopeExceptNamedArguments
|
||||
val realUsagesTarget = target.withScope(realUsagesScope and target.effectiveScope)
|
||||
val realUsagesScope = element.useScope and target.effectiveScope
|
||||
val realUsagesTarget = target.withScope(realUsagesScope)
|
||||
val realUsagesFilter = makeFilter(target) and !(PsiReference::isNamedArgumentUsage).searchFilter
|
||||
val realUsagesRequest = UsagesSearchRequestItem(realUsagesTarget, makeWordList(target), realUsagesFilter, makeAdditionalSearchDelegate(target.element))
|
||||
|
||||
@@ -266,7 +266,7 @@ class PropertyUsagesSearchHelper(
|
||||
return listOf(realUsagesRequest)
|
||||
}
|
||||
|
||||
var scope = target.effectiveScope
|
||||
var scope = function.useScope and target.effectiveScope
|
||||
if (scope is GlobalSearchScope) {
|
||||
scope = JetSourceFilterScope.kotlinSources(scope, element.project)
|
||||
}
|
||||
|
||||
+1
-1
@@ -96,7 +96,7 @@ public class UsagesSearchRequestItem(
|
||||
val additionalFileFilters: Collection<AdditionalFileFilter> = emptyList()
|
||||
)
|
||||
|
||||
public data class AdditionalFileFilter(
|
||||
public class AdditionalFileFilter(
|
||||
val word: String,
|
||||
val searchContext: Short,
|
||||
val caseSensitively: Boolean
|
||||
|
||||
Reference in New Issue
Block a user