Cleanup: KotlinReferenceSearcher
This commit is contained in:
+52
-44
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.compatibility.ExecutorProcessor
|
|||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
||||||
import org.jetbrains.kotlin.idea.search.*
|
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.dataClassComponentFunction
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.getClassNameForCompanionObject
|
import org.jetbrains.kotlin.idea.search.usagesSearch.getClassNameForCompanionObject
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.operators.OperatorReferenceSearcher
|
import org.jetbrains.kotlin.idea.search.usagesSearch.operators.OperatorReferenceSearcher
|
||||||
@@ -46,13 +47,15 @@ import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.parents
|
import org.jetbrains.kotlin.psi.psiUtil.parents
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
data class KotlinReferencesSearchOptions(val acceptCallableOverrides: Boolean = false,
|
data class KotlinReferencesSearchOptions(
|
||||||
val acceptOverloads: Boolean = false,
|
val acceptCallableOverrides: Boolean = false,
|
||||||
val acceptExtensionsOfDeclarationClass: Boolean = false,
|
val acceptOverloads: Boolean = false,
|
||||||
val acceptCompanionObjectMembers: Boolean = false,
|
val acceptExtensionsOfDeclarationClass: Boolean = false,
|
||||||
val searchForComponentConventions: Boolean = true,
|
val acceptCompanionObjectMembers: Boolean = false,
|
||||||
val searchForOperatorConventions: Boolean = true,
|
val searchForComponentConventions: Boolean = true,
|
||||||
val searchNamedArguments: Boolean = true) {
|
val searchForOperatorConventions: Boolean = true,
|
||||||
|
val searchNamedArguments: Boolean = true
|
||||||
|
) {
|
||||||
fun anyEnabled(): Boolean = acceptCallableOverrides || acceptOverloads || acceptExtensionsOfDeclarationClass
|
fun anyEnabled(): Boolean = acceptCallableOverrides || acceptOverloads || acceptExtensionsOfDeclarationClass
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -61,12 +64,12 @@ data class KotlinReferencesSearchOptions(val acceptCallableOverrides: Boolean =
|
|||||||
}
|
}
|
||||||
|
|
||||||
class KotlinReferencesSearchParameters(
|
class KotlinReferencesSearchParameters(
|
||||||
elementToSearch: PsiElement,
|
elementToSearch: PsiElement,
|
||||||
scope: SearchScope = runReadAction { elementToSearch.project.allScope() },
|
scope: SearchScope = runReadAction { elementToSearch.project.allScope() },
|
||||||
ignoreAccessScope: Boolean = false,
|
ignoreAccessScope: Boolean = false,
|
||||||
optimizer: SearchRequestCollector? = null,
|
optimizer: SearchRequestCollector? = null,
|
||||||
val kotlinOptions: KotlinReferencesSearchOptions = KotlinReferencesSearchOptions.Empty)
|
val kotlinOptions: KotlinReferencesSearchOptions = Empty
|
||||||
: ReferencesSearch.SearchParameters(elementToSearch, scope, ignoreAccessScope, optimizer)
|
) : ReferencesSearch.SearchParameters(elementToSearch, scope, ignoreAccessScope, optimizer)
|
||||||
|
|
||||||
class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearch.SearchParameters>() {
|
class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearch.SearchParameters>() {
|
||||||
override fun processQuery(queryParameters: ReferencesSearch.SearchParameters, consumer: ExecutorProcessor<PsiReference>) {
|
override fun processQuery(queryParameters: ReferencesSearch.SearchParameters, consumer: ExecutorProcessor<PsiReference>) {
|
||||||
@@ -77,8 +80,7 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
|
|||||||
|
|
||||||
private class QueryProcessor(val queryParameters: ReferencesSearch.SearchParameters, val consumer: ExecutorProcessor<PsiReference>) {
|
private class QueryProcessor(val queryParameters: ReferencesSearch.SearchParameters, val consumer: ExecutorProcessor<PsiReference>) {
|
||||||
|
|
||||||
private val kotlinOptions = (queryParameters as? KotlinReferencesSearchParameters)?.kotlinOptions
|
private val kotlinOptions = (queryParameters as? KotlinReferencesSearchParameters)?.kotlinOptions ?: Empty
|
||||||
?: KotlinReferencesSearchOptions.Empty
|
|
||||||
|
|
||||||
private val longTasks = ArrayList<() -> Unit>()
|
private val longTasks = ArrayList<() -> Unit>()
|
||||||
|
|
||||||
@@ -95,8 +97,7 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
|
|||||||
val effectiveSearchScope = run {
|
val effectiveSearchScope = run {
|
||||||
val elements = if (unwrappedElement is KtDeclaration && !isOnlyKotlinSearch(queryParameters.scopeDeterminedByUser)) {
|
val elements = if (unwrappedElement is KtDeclaration && !isOnlyKotlinSearch(queryParameters.scopeDeterminedByUser)) {
|
||||||
unwrappedElement.toLightElements()
|
unwrappedElement.toLightElements()
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
listOf(unwrappedElement)
|
listOf(unwrappedElement)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +117,8 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
|
|||||||
if (kotlinOptions.anyEnabled()) {
|
if (kotlinOptions.anyEnabled()) {
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
queryParameters.optimizer.searchWord(
|
queryParameters.optimizer.searchWord(
|
||||||
name, effectiveSearchScope, UsageSearchContext.IN_CODE, true, unwrappedElement, resultProcessor)
|
name, effectiveSearchScope, UsageSearchContext.IN_CODE, true, unwrappedElement, resultProcessor
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +126,8 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
|
|||||||
val classNameForCompanionObject = unwrappedElement.getClassNameForCompanionObject()
|
val classNameForCompanionObject = unwrappedElement.getClassNameForCompanionObject()
|
||||||
if (classNameForCompanionObject != null) {
|
if (classNameForCompanionObject != null) {
|
||||||
queryParameters.optimizer.searchWord(
|
queryParameters.optimizer.searchWord(
|
||||||
classNameForCompanionObject, effectiveSearchScope, UsageSearchContext.ANY, true, unwrappedElement, resultProcessor)
|
classNameForCompanionObject, effectiveSearchScope, UsageSearchContext.ANY, true, unwrappedElement, resultProcessor
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unwrappedElement is KtParameter && kotlinOptions.searchNamedArguments) {
|
if (unwrappedElement is KtParameter && kotlinOptions.searchNamedArguments) {
|
||||||
@@ -137,7 +140,8 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
|
|||||||
|
|
||||||
if (element is KtFunction || element is PsiMethod) {
|
if (element is KtFunction || element is PsiMethod) {
|
||||||
val referenceSearcher = OperatorReferenceSearcher.create(
|
val referenceSearcher = OperatorReferenceSearcher.create(
|
||||||
element, effectiveSearchScope, consumer, queryParameters.optimizer, kotlinOptions)
|
element, effectiveSearchScope, consumer, queryParameters.optimizer, kotlinOptions
|
||||||
|
)
|
||||||
if (referenceSearcher != null) {
|
if (referenceSearcher != null) {
|
||||||
longTasks.add { referenceSearcher.run() }
|
longTasks.add { referenceSearcher.run() }
|
||||||
}
|
}
|
||||||
@@ -174,17 +178,20 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
|
|||||||
namedArgsScope = KotlinSourceFilterScope.sourcesAndLibraries(namedArgsScope, project)
|
namedArgsScope = KotlinSourceFilterScope.sourcesAndLibraries(namedArgsScope, project)
|
||||||
|
|
||||||
val filesWithFunctionName = CacheManager.SERVICE.getInstance(project).getVirtualFilesWithWord(
|
val filesWithFunctionName = CacheManager.SERVICE.getInstance(project).getVirtualFilesWithWord(
|
||||||
function.name!!, UsageSearchContext.IN_CODE, namedArgsScope, true)
|
function.name!!, UsageSearchContext.IN_CODE, namedArgsScope, true
|
||||||
|
)
|
||||||
namedArgsScope = GlobalSearchScope.filesScope(project, filesWithFunctionName.asList())
|
namedArgsScope = GlobalSearchScope.filesScope(project, filesWithFunctionName.asList())
|
||||||
}
|
}
|
||||||
|
|
||||||
val processor = KotlinRequestResultProcessor(parameter, filter = { it.isNamedArgumentReference() })
|
val processor = KotlinRequestResultProcessor(parameter, filter = { it.isNamedArgumentReference() })
|
||||||
queryParameters.optimizer.searchWord(parameterName,
|
queryParameters.optimizer.searchWord(
|
||||||
namedArgsScope,
|
parameterName,
|
||||||
KOTLIN_NAMED_ARGUMENT_SEARCH_CONTEXT,
|
namedArgsScope,
|
||||||
true,
|
KOTLIN_NAMED_ARGUMENT_SEARCH_CONTEXT,
|
||||||
parameter,
|
true,
|
||||||
processor)
|
parameter,
|
||||||
|
processor
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun searchLightElements(element: PsiElement) {
|
private fun searchLightElements(element: PsiElement) {
|
||||||
@@ -220,12 +227,10 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
|
|||||||
if (declaration is KtProperty || (declaration is KtParameter && declaration.hasValOrVar())) {
|
if (declaration is KtProperty || (declaration is KtParameter && declaration.hasValOrVar())) {
|
||||||
searchNamedElement(declaration as PsiNamedElement)
|
searchNamedElement(declaration as PsiNamedElement)
|
||||||
processStaticsFromCompanionObject(declaration)
|
processStaticsFromCompanionObject(declaration)
|
||||||
}
|
} else if (declaration is KtPropertyAccessor) {
|
||||||
else if (declaration is KtPropertyAccessor) {
|
|
||||||
val property = declaration.getStrictParentOfType<KtProperty>()
|
val property = declaration.getStrictParentOfType<KtProperty>()
|
||||||
searchNamedElement(property)
|
searchNamedElement(property)
|
||||||
}
|
} else if (declaration is KtFunction) {
|
||||||
else if (declaration is KtFunction) {
|
|
||||||
processStaticsFromCompanionObject(declaration)
|
processStaticsFromCompanionObject(declaration)
|
||||||
if (element.isMangled) {
|
if (element.isMangled) {
|
||||||
searchNamedElement(declaration) { it.restrictToKotlinSources() }
|
searchNamedElement(declaration) { it.restrictToKotlinSources() }
|
||||||
@@ -256,22 +261,22 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
|
|||||||
val originLightClass = element.getStrictParentOfType<KtClass>()?.toLightClass()
|
val originLightClass = element.getStrictParentOfType<KtClass>()?.toLightClass()
|
||||||
if (originLightClass != null) {
|
if (originLightClass != null) {
|
||||||
val lightDeclarations: List<KtLightMember<*>?> =
|
val lightDeclarations: List<KtLightMember<*>?> =
|
||||||
originLightClass.methods.map { it as? KtLightMethod } +
|
originLightClass.methods.map { it as? KtLightMethod } + originLightClass.fields.map { it as? KtLightField }
|
||||||
originLightClass.fields.map { it as? KtLightField }
|
|
||||||
|
|
||||||
for (declaration in element.declarations) {
|
for (declaration in element.declarations) {
|
||||||
lightDeclarations
|
lightDeclarations
|
||||||
.firstOrNull { it?.kotlinOrigin == declaration }
|
.firstOrNull { it?.kotlinOrigin == declaration }
|
||||||
?.let { searchNamedElement(it) }
|
?.let { searchNamedElement(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun searchDataClassComponentUsages(containingClass: PsiClass?,
|
private fun searchDataClassComponentUsages(
|
||||||
componentFunctionDescriptor: FunctionDescriptor,
|
containingClass: PsiClass?,
|
||||||
kotlinOptions: KotlinReferencesSearchOptions
|
componentFunctionDescriptor: FunctionDescriptor,
|
||||||
|
kotlinOptions: KotlinReferencesSearchOptions
|
||||||
) {
|
) {
|
||||||
val componentFunction = containingClass?.methods?.firstOrNull {
|
val componentFunction = containingClass?.methods?.firstOrNull {
|
||||||
it.name == componentFunctionDescriptor.name.asString() && it.parameterList.parametersCount == 0
|
it.name == componentFunctionDescriptor.name.asString() && it.parameterList.parametersCount == 0
|
||||||
@@ -280,7 +285,8 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
|
|||||||
searchNamedElement(componentFunction)
|
searchNamedElement(componentFunction)
|
||||||
|
|
||||||
val searcher = OperatorReferenceSearcher.create(
|
val searcher = OperatorReferenceSearcher.create(
|
||||||
componentFunction, queryParameters.effectiveSearchScope, consumer, queryParameters.optimizer, kotlinOptions)
|
componentFunction, queryParameters.effectiveSearchScope, consumer, queryParameters.optimizer, kotlinOptions
|
||||||
|
)
|
||||||
longTasks.add { searcher!!.run() }
|
longTasks.add { searcher!!.run() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -291,8 +297,8 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
|
|||||||
|
|
||||||
private fun findStaticMethodsFromCompanionObject(declaration: KtDeclaration): List<PsiMethod> {
|
private fun findStaticMethodsFromCompanionObject(declaration: KtDeclaration): List<PsiMethod> {
|
||||||
val originObject = declaration.parents
|
val originObject = declaration.parents
|
||||||
.dropWhile { it is KtClassBody }
|
.dropWhile { it is KtClassBody }
|
||||||
.firstOrNull() as? KtObjectDeclaration ?: return emptyList()
|
.firstOrNull() as? KtObjectDeclaration ?: return emptyList()
|
||||||
if (!originObject.isCompanion()) return emptyList()
|
if (!originObject.isCompanion()) return emptyList()
|
||||||
val originClass = originObject.getStrictParentOfType<KtClass>()
|
val originClass = originObject.getStrictParentOfType<KtClass>()
|
||||||
val originLightClass = originClass?.toLightClass() ?: return emptyList()
|
val originLightClass = originClass?.toLightClass() ?: return emptyList()
|
||||||
@@ -309,9 +315,11 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
|
|||||||
val baseScope = queryParameters.effectiveSearchScope(element)
|
val baseScope = queryParameters.effectiveSearchScope(element)
|
||||||
val scope = if (modifyScope != null) modifyScope(baseScope) else baseScope
|
val scope = if (modifyScope != null) modifyScope(baseScope) else baseScope
|
||||||
val context = UsageSearchContext.IN_CODE + UsageSearchContext.IN_FOREIGN_LANGUAGES + UsageSearchContext.IN_COMMENTS
|
val context = UsageSearchContext.IN_CODE + UsageSearchContext.IN_FOREIGN_LANGUAGES + UsageSearchContext.IN_COMMENTS
|
||||||
val resultProcessor = KotlinRequestResultProcessor(element,
|
val resultProcessor = KotlinRequestResultProcessor(
|
||||||
queryParameters.elementToSearch.namedUnwrappedElement ?: element,
|
element,
|
||||||
options = kotlinOptions)
|
queryParameters.elementToSearch.namedUnwrappedElement ?: element,
|
||||||
|
options = kotlinOptions
|
||||||
|
)
|
||||||
queryParameters.optimizer.searchWord(name, scope, context.toShort(), true, element, resultProcessor)
|
queryParameters.optimizer.searchWord(name, scope, context.toShort(), true, element, resultProcessor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user