Cleanup: KotlinReferenceSearcher

This commit is contained in:
Mikhail Glukhikh
2018-06-20 18:53:05 +03:00
parent ea7db42af6
commit 0a36edcf20
@@ -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)
} }
} }