ReferenceSearch searches references to parameters using optimized way too
#KT-8625 Fixed
This commit is contained in:
@@ -20,7 +20,6 @@ import com.intellij.lang.ASTNode;
|
||||
import com.intellij.navigation.ItemPresentation;
|
||||
import com.intellij.navigation.ItemPresentationProviders;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -176,21 +175,6 @@ public class JetParameter extends JetNamedDeclarationStub<KotlinParameterStub> i
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SearchScope getUseScope() {
|
||||
JetDeclaration function = getOwnerFunction();
|
||||
if (function != null && !(function instanceof JetFunctionLiteral)) {
|
||||
return function.getUseScope();
|
||||
}
|
||||
return super.getUseScope();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public SearchScope getUseScopeExceptNamedArguments() {
|
||||
return super.getUseScope();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JetFunction getOwnerFunction() {
|
||||
PsiElement parent = getParent();
|
||||
|
||||
+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
|
||||
|
||||
+11
-10
@@ -19,13 +19,8 @@ package org.jetbrains.kotlin.idea.findUsages.handlers
|
||||
import com.intellij.find.findUsages.AbstractFindUsagesDialog
|
||||
import com.intellij.find.findUsages.FindUsagesOptions
|
||||
import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.util.Computable
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.psi.search.PsiElementProcessor
|
||||
import com.intellij.psi.search.PsiElementProcessorAdapter
|
||||
import com.intellij.psi.search.searches.MethodReferencesSearch
|
||||
import com.intellij.usageView.UsageInfo
|
||||
import com.intellij.util.CommonProcessors
|
||||
@@ -35,14 +30,15 @@ import org.jetbrains.kotlin.asJava.toLightMethods
|
||||
import org.jetbrains.kotlin.idea.findUsages.*
|
||||
import org.jetbrains.kotlin.idea.findUsages.dialogs.KotlinFindFunctionUsagesDialog
|
||||
import org.jetbrains.kotlin.idea.findUsages.dialogs.KotlinFindPropertyUsagesDialog
|
||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.*
|
||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest
|
||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.searchOverriders
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.UsagesSearch
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.UsagesSearchHelper
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.UsagesSearchRequest
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import java.util.Collections
|
||||
import org.jetbrains.kotlin.psi.JetConstructor
|
||||
import org.jetbrains.kotlin.psi.JetFunction
|
||||
import org.jetbrains.kotlin.psi.JetNamedDeclaration
|
||||
import org.jetbrains.kotlin.psi.JetParameter
|
||||
|
||||
public abstract class KotlinFindMemberUsagesHandler<T : JetNamedDeclaration>
|
||||
protected constructor(declaration: T, elementsToSearch: Collection<PsiElement>, factory: KotlinFindUsagesHandlerFactory)
|
||||
@@ -89,7 +85,12 @@ public abstract class KotlinFindMemberUsagesHandler<T : JetNamedDeclaration>
|
||||
|
||||
val request = runReadAction {
|
||||
@suppress("UNCHECKED_CAST")
|
||||
getSearchHelper(kotlinOptions).newRequest(options.toSearchTarget<T>(element as T, true))
|
||||
val searchTarget = if (element is JetParameter)
|
||||
options.toSearchTarget<T>(element as T, restrictByTarget = false) // named argument usages are outside getUseScope for JetParameter
|
||||
else
|
||||
options.toSearchTarget<T>(element as T, restrictByTarget = true)
|
||||
|
||||
getSearchHelper(kotlinOptions).newRequest(searchTarget)
|
||||
}
|
||||
|
||||
val uniqueProcessor = CommonProcessors.UniqueProcessor(processor)
|
||||
|
||||
+1
-1
@@ -303,7 +303,7 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
||||
String oldParamName = oldParam.getName();
|
||||
|
||||
if (parameterInfo == newReceiverInfo || (oldParamName != null && !oldParamName.equals(parameterInfo.getName()))) {
|
||||
for (PsiReference reference : ChangeSignaturePackage.findParameterUsages(oldParam)) {
|
||||
for (PsiReference reference : ReferencesSearch.search(oldParam, oldParam.getUseScope())) {
|
||||
PsiElement element = reference.getElement();
|
||||
|
||||
if ((element instanceof JetSimpleNameExpression || element instanceof KDocName) &&
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.refactoring.changeSignature
|
||||
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.usageView.UsageInfo
|
||||
import com.intellij.util.CommonProcessors
|
||||
import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory
|
||||
import org.jetbrains.kotlin.idea.findUsages.KotlinPropertyFindUsagesOptions
|
||||
import org.jetbrains.kotlin.psi.JetParameter
|
||||
|
||||
// searching parameter usages via ReferenceSearch is currently too slow (uses non-optimized search for named arguments),
|
||||
// that's why we use KotlinFindUsagesHandler
|
||||
fun findParameterUsages(parameter: JetParameter): Collection<PsiReference> {
|
||||
val project = parameter.project
|
||||
val findUsagesHandler = KotlinFindUsagesHandlerFactory(project).createFindUsagesHandlerNoQuestions(parameter)
|
||||
val processor = CommonProcessors.CollectProcessor<UsageInfo>()
|
||||
val options = KotlinPropertyFindUsagesOptions(project)
|
||||
findUsagesHandler.processElementUsages(parameter, processor, options)
|
||||
return processor.results.map { it.reference }.filterNotNull()
|
||||
}
|
||||
Reference in New Issue
Block a user