Add fast find usages for data class components

This commit add feature for disabling searching for data class ComponentN method and destruction declarations that could encrease usages search.
See KT-23278
This commit is contained in:
Igor Yakovlev
2019-11-05 21:02:25 +03:00
parent 6d9c00addd
commit 1ccda6a8d4
47 changed files with 687 additions and 32 deletions
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
import org.jetbrains.kotlin.idea.search.*
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions.Companion.Empty
import org.jetbrains.kotlin.idea.search.usagesSearch.dataClassComponentFunction
import org.jetbrains.kotlin.idea.search.usagesSearch.filterDataClassComponentsIfDisabled
import org.jetbrains.kotlin.idea.search.usagesSearch.getClassNameForCompanionObject
import org.jetbrains.kotlin.idea.search.usagesSearch.operators.OperatorReferenceSearcher
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope
@@ -77,6 +78,7 @@ class KotlinReferencesSearchParameters(
) : ReferencesSearch.SearchParameters(elementToSearch, scope, ignoreAccessScope, optimizer)
class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearch.SearchParameters>() {
override fun processQuery(queryParameters: ReferencesSearch.SearchParameters, consumer: Processor<in PsiReference>) {
val processor = QueryProcessor(queryParameters, consumer)
runReadAction { processor.processInReadAction() }
@@ -108,7 +110,7 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
val effectiveSearchScope = run {
val elements = if (elementToSearch is KtDeclaration && !isOnlyKotlinSearch(queryParameters.scopeDeterminedByUser)) {
elementToSearch.toLightElements().nullize()
elementToSearch.toLightElements().filterDataClassComponentsIfDisabled(kotlinOptions).nullize()
} else {
null
} ?: listOf(elementToSearch)
@@ -236,7 +238,7 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
if (element.getStrictParentOfType<KtPrimaryConstructor>() != null) {
// Simple parameters without val and var shouldn't be processed here because of local search scope
val methods = LightClassUtil.getLightClassPropertyMethods(element)
methods.allDeclarations.forEach { searchNamedElement(it) }
methods.allDeclarations.filterDataClassComponentsIfDisabled(kotlinOptions).forEach { searchNamedElement(it) }
}
}
@@ -264,7 +266,7 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
}
private fun searchPropertyAccessorMethods(origin: KtParameter) {
origin.toLightElements().forEach { searchNamedElement(it) }
origin.toLightElements().filterDataClassComponentsIfDisabled(kotlinOptions).forEach { searchNamedElement(it) }
}
private fun processKtClassOrObject(element: KtClassOrObject) {
@@ -17,14 +17,12 @@
package org.jetbrains.kotlin.idea.search.usagesSearch
import com.intellij.openapi.application.ApplicationManager
import com.intellij.psi.PsiConstructorCall
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiReference
import com.intellij.psi.*
import com.intellij.psi.search.SearchScope
import com.intellij.psi.search.searches.MethodReferencesSearch
import com.intellij.psi.search.searches.ReferencesSearch
import com.intellij.psi.util.MethodSignatureUtil
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.elements.KtLightElement
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
@@ -38,14 +36,13 @@ import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaMethodDescriptor
import org.jetbrains.kotlin.idea.references.unwrappedTargets
import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest
import org.jetbrains.kotlin.idea.search.declarationsSearch.searchInheritors
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.contains
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.descriptorUtil.isTypeRefinementEnabled
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
@@ -289,3 +286,23 @@ fun PsiElement.searchReferencesOrMethodReferences(): Collection<PsiReference> {
ReferencesSearch.search(this).findAll()
}
}
fun <T : PsiNamedElement> List<T>.filterDataClassComponentsIfDisabled(kotlinOptions: KotlinReferencesSearchOptions): List<T> {
if (kotlinOptions.searchForComponentConventions) return this
fun PsiNamedElement.isComponentElement(): Boolean {
if (this !is PsiMethod) return false
val dataClassParent = ((parent as? KtLightClass)?.kotlinOrigin as? KtClass)?.isData() == true
if (!dataClassParent) return false
if (!Name.isValidIdentifier(name)) return false
val nameIdentifier = Name.identifier(name)
if (!DataClassDescriptorResolver.isComponentLike(nameIdentifier)) return false
return true
}
return filter { !it.isComponentElement() }
}