Optimize reference search for convention functions

This commit is contained in:
Natalia Ukhorskaya
2016-02-09 21:39:25 +03:00
parent 1f6894cdd4
commit 5ae394fec0
4 changed files with 32 additions and 25 deletions
@@ -62,18 +62,20 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
val unwrappedElement = element.namedUnwrappedElement ?: return
val specialSymbols = runReadAction { unwrappedElement.getSpecialNamesToSearch() }
val words = runReadAction {
val classNameForCompanionObject = unwrappedElement.getClassNameForCompanionObject()
unwrappedElement.getSpecialNamesToSearch() +
(if (classNameForCompanionObject != null) listOf(classNameForCompanionObject) else emptyList())
specialSymbols.first +
(if (classNameForCompanionObject != null) listOf(classNameForCompanionObject) else emptyList())
}
val effectiveSearchScope = runReadAction { queryParameters.effectiveSearchScope }
val refFilter: (PsiReference) -> Boolean = if (unwrappedElement is KtParameter)
({ ref: PsiReference -> !ref.isNamedArgumentReference()/* they are processed later*/ })
else
({true})
val refFilter: (PsiReference) -> Boolean = when {
unwrappedElement is KtParameter -> ({ ref: PsiReference -> !ref.isNamedArgumentReference()/* they are processed later*/ })
specialSymbols.second != null -> { ref -> ref.javaClass == specialSymbols.second }
else -> ({true})
}
val kotlinOptions = (queryParameters as? KotlinReferencesSearchParameters)?.kotlinOptions
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.idea.search.usagesSearch
import com.google.common.collect.ImmutableSet
import org.jetbrains.kotlin.idea.references.*
import org.jetbrains.kotlin.lexer.KtToken
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.Name
@@ -45,30 +46,30 @@ val IN_OPERATIONS_TO_SEARCH = setOf(KtTokens.IN_KEYWORD)
val COMPARISON_OPERATIONS_TO_SEARCH = setOf(KtTokens.LT, KtTokens.GT)
fun Name.getOperationSymbolsToSearch(): Set<KtToken> {
fun Name.getOperationSymbolsToSearch(): Pair<Set<KtToken>, Class<*>?> {
when (this) {
OperatorNameConventions.COMPARE_TO -> return COMPARISON_OPERATIONS_TO_SEARCH
OperatorNameConventions.EQUALS -> return EQUALS_OPERATIONS
OperatorNameConventions.CONTAINS -> return IN_OPERATIONS_TO_SEARCH
OperatorNameConventions.ITERATOR -> return IN_OPERATIONS_TO_SEARCH
in INDEXING_OPERATION_NAMES -> return setOf(KtTokens.LBRACKET)
in DELEGATE_ACCESSOR_NAMES -> return setOf(KtTokens.BY_KEYWORD)
DelegatedPropertyResolver.PROPERTY_DELEGATED_FUNCTION_NAME -> return setOf(KtTokens.BY_KEYWORD)
OperatorNameConventions.COMPARE_TO -> return COMPARISON_OPERATIONS_TO_SEARCH to KtSimpleNameReference::class.java
OperatorNameConventions.EQUALS -> return EQUALS_OPERATIONS to KtSimpleNameReference::class.java
OperatorNameConventions.CONTAINS -> return IN_OPERATIONS_TO_SEARCH to KtSimpleNameReference::class.java
OperatorNameConventions.ITERATOR -> return IN_OPERATIONS_TO_SEARCH to KtForLoopInReference::class.java
in INDEXING_OPERATION_NAMES -> return setOf(KtTokens.LBRACKET) to KtArrayAccessReference::class.java
in DELEGATE_ACCESSOR_NAMES -> return setOf(KtTokens.BY_KEYWORD) to KtPropertyDelegationMethodsReference::class.java
DelegatedPropertyResolver.PROPERTY_DELEGATED_FUNCTION_NAME -> return setOf(KtTokens.BY_KEYWORD) to KtPropertyDelegationMethodsReference::class.java
}
if (isComponentLike(this)) return setOf(KtTokens.LPAR)
if (isComponentLike(this)) return setOf(KtTokens.LPAR) to KtDestructuringDeclarationReference::class.java
val unaryOp = UNARY_OPERATION_NAMES_WITH_DEPRECATED_INVERTED[this]
if (unaryOp != null) return setOf(unaryOp)
if (unaryOp != null) return setOf(unaryOp) to KtSimpleNameReference::class.java
val binaryOp = BINARY_OPERATION_NAMES.inverse()[this]
if (binaryOp != null) {
val assignmentOp = ASSIGNMENT_OPERATION_COUNTERPARTS.inverse()[binaryOp]
return if (assignmentOp != null) setOf(binaryOp, assignmentOp) else setOf(binaryOp)
return (if (assignmentOp != null) setOf(binaryOp, assignmentOp) else setOf(binaryOp)) to KtSimpleNameReference::class.java
}
val assignmentOp = ASSIGNMENT_OPERATIONS.inverse()[this]
if (assignmentOp != null) return setOf(assignmentOp)
if (assignmentOp != null) return setOf(assignmentOp) to KtSimpleNameReference::class.java
return emptySet()
return emptySet<KtToken>() to null
}
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.asJava.LightClassUtil.PropertyAccessorsPsiMethods
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.references.KtDestructuringDeclarationReference
import org.jetbrains.kotlin.lexer.KtSingleValueToken
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.Name
@@ -63,17 +64,20 @@ fun PsiNamedElement.getClassNameForCompanionObject(): String? {
}
}
fun PsiNamedElement.getSpecialNamesToSearch(): List<String> {
fun PsiNamedElement.getSpecialNamesToSearch(): Pair<List<String>, Class<*>?> {
val name = name
return when {
name == null || !Name.isValidIdentifier(name) -> Collections.emptyList<String>()
name == null || !Name.isValidIdentifier(name) -> Collections.emptyList<String>() to null
this is KtParameter -> {
val componentFunctionName = this.dataClassComponentFunction()?.name
if (componentFunctionName == null) return Collections.emptyList<String>()
if (componentFunctionName == null) return Collections.emptyList<String>() to null
return listOf(componentFunctionName.asString(), KtTokens.LPAR.value)
return listOf(componentFunctionName.asString(), KtTokens.LPAR.value) to KtDestructuringDeclarationReference::class.java
}
else -> {
val operationSymbolsToSearch = Name.identifier(name).getOperationSymbolsToSearch()
operationSymbolsToSearch.first.map { (it as KtSingleValueToken).value } to operationSymbolsToSearch.second
}
else -> Name.identifier(name).getOperationSymbolsToSearch().map { (it as KtSingleValueToken).value }
}
}
@@ -207,7 +207,7 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
private fun isConventionalName(namedDeclaration: KtNamedDeclaration): Boolean {
val name = namedDeclaration.nameAsName
return name!!.getOperationSymbolsToSearch().isNotEmpty() || name == OperatorNameConventions.INVOKE
return name!!.getOperationSymbolsToSearch().first.isNotEmpty() || name == OperatorNameConventions.INVOKE
}
private fun hasNonTrivialUsages(declaration: KtNamedDeclaration): Boolean {