Implemented fast search for binary operators
This commit is contained in:
+19
-19
@@ -37,21 +37,22 @@ import org.jetbrains.kotlin.idea.search.KOTLIN_NAMED_ARGUMENT_SEARCH_CONTEXT
|
||||
import org.jetbrains.kotlin.idea.search.allScope
|
||||
import org.jetbrains.kotlin.idea.search.effectiveSearchScope
|
||||
import org.jetbrains.kotlin.idea.search.unionSafe
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.*
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.OperatorReferenceSearcher
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.dataClassComponentFunction
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.getClassNameForCompanionObject
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.getSpecialNamesToSearch
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.parents
|
||||
import org.jetbrains.kotlin.resolve.dataClassUtils.isComponentLike
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
data class KotlinReferencesSearchOptions(val acceptCallableOverrides: Boolean = false,
|
||||
val acceptOverloads: Boolean = false,
|
||||
val acceptExtensionsOfDeclarationClass: Boolean = false,
|
||||
val acceptCompanionObjectMembers: Boolean = false,
|
||||
val searchForComponentConventions: Boolean = true,
|
||||
val searchInvokeOperator: Boolean = true,
|
||||
val searchForOperatorConventions: Boolean = true,
|
||||
val searchNamedArguments: Boolean = true) {
|
||||
fun anyEnabled(): Boolean = acceptCallableOverrides || acceptOverloads || acceptExtensionsOfDeclarationClass
|
||||
|
||||
@@ -119,35 +120,31 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
|
||||
searchLightElements(queryParameters, element, consumer)
|
||||
}
|
||||
|
||||
//TODO: operator functions from Java
|
||||
if (element is KtFunction) {
|
||||
val referenceSearcher = OperatorReferenceSearcher.createForKtFunction(
|
||||
element, effectiveSearchScope, consumer, queryParameters.optimizer, kotlinOptions)
|
||||
referenceSearcher?.run()
|
||||
}
|
||||
|
||||
if (kotlinOptions.searchForComponentConventions) {
|
||||
when (element) {
|
||||
is KtFunction -> {
|
||||
if (name != null && isComponentLike(name)) {
|
||||
DestructuringDeclarationReferenceSearcher(element, effectiveSearchScope, consumer, queryParameters.optimizer).run()
|
||||
}
|
||||
}
|
||||
|
||||
is KtParameter -> {
|
||||
val componentFunctionDescriptor = runReadAction { element.dataClassComponentFunction() }
|
||||
if (componentFunctionDescriptor != null) {
|
||||
val containingClass = element.getStrictParentOfType<KtClassOrObject>()?.toLightClass()
|
||||
searchDataClassComponentUsages(queryParameters, containingClass, componentFunctionDescriptor, consumer)
|
||||
searchDataClassComponentUsages(queryParameters, containingClass, componentFunctionDescriptor, consumer, kotlinOptions)
|
||||
}
|
||||
}
|
||||
|
||||
is KtLightParameter -> {
|
||||
val componentFunctionDescriptor = runReadAction { element.kotlinOrigin?.dataClassComponentFunction() }
|
||||
if (componentFunctionDescriptor != null) {
|
||||
searchDataClassComponentUsages(queryParameters, element.method.containingClass, componentFunctionDescriptor, consumer)
|
||||
searchDataClassComponentUsages(queryParameters, element.method.containingClass, componentFunctionDescriptor, consumer, kotlinOptions)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: Java invoke's
|
||||
if (kotlinOptions.searchInvokeOperator && element is KtFunction && name == OperatorNameConventions.INVOKE.asString()) {
|
||||
InvokeOperatorReferenceSearcher(element, effectiveSearchScope, consumer, queryParameters.optimizer).run()
|
||||
}
|
||||
}
|
||||
|
||||
private fun searchNamedArguments(parameter: KtParameter, queryParameters: ReferencesSearch.SearchParameters) {
|
||||
@@ -242,14 +239,17 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
|
||||
private fun searchDataClassComponentUsages(queryParameters: ReferencesSearch.SearchParameters,
|
||||
containingClass: PsiClass?,
|
||||
componentFunctionDescriptor: FunctionDescriptor,
|
||||
consumer: Processor<PsiReference>
|
||||
consumer: Processor<PsiReference>,
|
||||
kotlinOptions: KotlinReferencesSearchOptions
|
||||
) {
|
||||
val componentFunction = containingClass?.methods?.find {
|
||||
it.name == componentFunctionDescriptor.name.asString() && it.parameterList.parametersCount == 0
|
||||
}
|
||||
if (componentFunction != null) {
|
||||
searchNamedElement(queryParameters, componentFunction)
|
||||
DestructuringDeclarationReferenceSearcher.runForPsiMethod(componentFunction, queryParameters.effectiveSearchScope, consumer, queryParameters.optimizer)
|
||||
val searcher = OperatorReferenceSearcher.createForPsiMethod(
|
||||
componentFunction, queryParameters.effectiveSearchScope, consumer, queryParameters.optimizer, kotlinOptions)
|
||||
searcher!!.run()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.search.usagesSearch
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.psi.search.SearchRequestCollector
|
||||
import com.intellij.psi.search.SearchScope
|
||||
import com.intellij.util.Processor
|
||||
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
||||
import org.jetbrains.kotlin.lexer.KtSingleValueToken
|
||||
import org.jetbrains.kotlin.psi.KtBinaryExpression
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
||||
|
||||
class BinaryOperatorReferenceSearcher(
|
||||
targetDeclaration: KtDeclaration,
|
||||
private val operationTokens: List<KtSingleValueToken>,
|
||||
searchScope: SearchScope,
|
||||
consumer: Processor<PsiReference>,
|
||||
optimizer: SearchRequestCollector
|
||||
) : OperatorReferenceSearcher<KtBinaryExpression>(targetDeclaration, searchScope, consumer, optimizer, wordsToSearch = operationTokens.map { it.value }) {
|
||||
|
||||
override fun processSuspiciousExpression(expression: KtExpression) {
|
||||
val binaryExpression = expression.parent as? KtBinaryExpression ?: return
|
||||
if (binaryExpression.operationToken !in operationTokens) return
|
||||
if (expression != binaryExpression.left) return
|
||||
processReferenceElement(binaryExpression)
|
||||
}
|
||||
|
||||
override fun isReferenceToCheck(ref: PsiReference): Boolean {
|
||||
return ref is KtSimpleNameReference && ref.element.getReferencedNameElementType() in operationTokens
|
||||
}
|
||||
|
||||
override fun extractReference(element: PsiElement): PsiReference? {
|
||||
val binaryExpression = element as? KtBinaryExpression ?: return null
|
||||
if (binaryExpression.operationToken !in operationTokens) return null
|
||||
return binaryExpression.operationReference.references.firstIsInstance<KtSimpleNameReference>()
|
||||
}
|
||||
}
|
||||
+1
-18
@@ -17,16 +17,12 @@
|
||||
package org.jetbrains.kotlin.idea.search.usagesSearch
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.psi.search.SearchRequestCollector
|
||||
import com.intellij.psi.search.SearchScope
|
||||
import com.intellij.util.Processor
|
||||
import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.idea.references.KtDestructuringDeclarationReference
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.ExpressionsOfTypeProcessor.Companion.logPresentation
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.ExpressionsOfTypeProcessor.Companion.testLog
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.dataClassUtils.getComponentIndex
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
||||
@@ -36,20 +32,7 @@ class DestructuringDeclarationReferenceSearcher(
|
||||
searchScope: SearchScope,
|
||||
consumer: Processor<PsiReference>,
|
||||
optimizer: SearchRequestCollector
|
||||
) : OperatorReferenceSearcher<KtDestructuringDeclaration>(targetDeclaration, searchScope, consumer, optimizer, wordToSearch = "(") {
|
||||
|
||||
companion object {
|
||||
fun runForPsiMethod(
|
||||
componentFunction: PsiMethod,
|
||||
scope: SearchScope,
|
||||
consumer: Processor<PsiReference>,
|
||||
optimizer: SearchRequestCollector
|
||||
) {
|
||||
if (componentFunction !is KtLightMethod) return //TODO
|
||||
val ktDeclarationTarget = componentFunction.kotlinOrigin as? KtDeclaration ?: return //TODO?
|
||||
DestructuringDeclarationReferenceSearcher(ktDeclarationTarget, scope, consumer, optimizer).run()
|
||||
}
|
||||
}
|
||||
) : OperatorReferenceSearcher<KtDestructuringDeclaration>(targetDeclaration, searchScope, consumer, optimizer, wordsToSearch = listOf("(")) {
|
||||
|
||||
private val componentIndex = when (targetDeclaration) {
|
||||
is KtParameter -> targetDeclaration.dataClassComponentFunction()?.name?.asString()?.let { getComponentIndex(it) }
|
||||
|
||||
+3
-4
@@ -28,10 +28,8 @@ import com.intellij.psi.search.searches.ReferencesSearch
|
||||
import com.intellij.util.Processor
|
||||
import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
||||
@@ -46,12 +44,10 @@ import org.jetbrains.kotlin.idea.search.restrictToKotlinSources
|
||||
import org.jetbrains.kotlin.idea.util.FuzzyType
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.kdoc.psi.impl.KDocName
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import java.util.*
|
||||
|
||||
//TODO: check if smart search is too expensive
|
||||
@@ -592,6 +588,8 @@ class ExpressionsOfTypeProcessor(
|
||||
}
|
||||
|
||||
private fun PsiElement.isOperatorExpensiveToSearch(): Boolean {
|
||||
return false //TODO
|
||||
/*
|
||||
when (this) {
|
||||
is KtFunction -> {
|
||||
if (name?.startsWith("component") == true || name == OperatorNameConventions.INVOKE.asString()) return false
|
||||
@@ -607,6 +605,7 @@ class ExpressionsOfTypeProcessor(
|
||||
return false
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
private fun KotlinType.containsTypeOrDerivedInside(type: FuzzyType): Boolean {
|
||||
|
||||
+5
-5
@@ -25,16 +25,16 @@ import com.intellij.util.Processor
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.idea.references.KtInvokeFunctionReference
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
||||
|
||||
class InvokeOperatorReferenceSearcher(
|
||||
targetDeclaration: KtDeclaration,
|
||||
targetDeclaration: KtFunction,
|
||||
searchScope: SearchScope,
|
||||
consumer: Processor<PsiReference>,
|
||||
optimizer: SearchRequestCollector
|
||||
) : OperatorReferenceSearcher<KtCallExpression>(targetDeclaration, searchScope, consumer, optimizer, wordToSearch = null) {
|
||||
) : OperatorReferenceSearcher<KtCallExpression>(targetDeclaration, searchScope, consumer, optimizer, wordsToSearch = emptyList()) {
|
||||
|
||||
companion object {
|
||||
fun runForPsiMethod(
|
||||
@@ -44,8 +44,8 @@ class InvokeOperatorReferenceSearcher(
|
||||
optimizer: SearchRequestCollector
|
||||
) {
|
||||
if (invokeFunction !is KtLightMethod) return //TODO
|
||||
val ktDeclarationTarget = invokeFunction.kotlinOrigin as? KtDeclaration ?: return //TODO?
|
||||
InvokeOperatorReferenceSearcher(ktDeclarationTarget, scope, consumer, optimizer).run()
|
||||
val ktFunction = invokeFunction.kotlinOrigin as? KtFunction ?: return //TODO?
|
||||
InvokeOperatorReferenceSearcher(ktFunction, scope, consumer, optimizer).run()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+71
-13
@@ -17,29 +17,29 @@
|
||||
package org.jetbrains.kotlin.idea.search.usagesSearch
|
||||
|
||||
import com.intellij.openapi.roots.ProjectRootManager
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.PsiRecursiveElementWalkingVisitor
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.search.*
|
||||
import com.intellij.util.Processor
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
|
||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinRequestResultProcessor
|
||||
import org.jetbrains.kotlin.idea.search.restrictToKotlinSources
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.ExpressionsOfTypeProcessor.Companion.logPresentation
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.ExpressionsOfTypeProcessor.Companion.testLog
|
||||
import org.jetbrains.kotlin.idea.util.fuzzyExtensionReceiverType
|
||||
import org.jetbrains.kotlin.idea.util.toFuzzyType
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.dataClassUtils.isComponentLike
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.util.isValidOperator
|
||||
import java.util.*
|
||||
|
||||
@@ -48,7 +48,7 @@ abstract class OperatorReferenceSearcher<TReferenceElement : KtElement>(
|
||||
private val searchScope: SearchScope,
|
||||
private val consumer: Processor<PsiReference>,
|
||||
private val optimizer: SearchRequestCollector,
|
||||
private val wordToSearch: String?
|
||||
private val wordsToSearch: List<String>
|
||||
) {
|
||||
private val project = targetDeclaration.project
|
||||
|
||||
@@ -70,6 +70,62 @@ abstract class OperatorReferenceSearcher<TReferenceElement : KtElement>(
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun createForKtFunction(
|
||||
function: KtFunction,
|
||||
searchScope: SearchScope,
|
||||
consumer: Processor<PsiReference>,
|
||||
optimizer: SearchRequestCollector,
|
||||
options: KotlinReferencesSearchOptions
|
||||
): OperatorReferenceSearcher<*>? {
|
||||
val name = function.name ?: return null
|
||||
return create(function, name, searchScope, consumer, optimizer, options)
|
||||
}
|
||||
|
||||
fun createForPsiMethod(
|
||||
psiMethod: PsiMethod,
|
||||
searchScope: SearchScope,
|
||||
consumer: Processor<PsiReference>,
|
||||
optimizer: SearchRequestCollector,
|
||||
options: KotlinReferencesSearchOptions
|
||||
): OperatorReferenceSearcher<*>? {
|
||||
if (psiMethod !is KtLightMethod) return null //TODO?
|
||||
val ktDeclaration = psiMethod.kotlinOrigin as? KtDeclaration ?: return null //TODO?
|
||||
return create(ktDeclaration, psiMethod.name, searchScope, consumer, optimizer, options)
|
||||
}
|
||||
|
||||
private fun create(
|
||||
declaration: KtDeclaration,
|
||||
functionName: String,
|
||||
searchScope: SearchScope,
|
||||
consumer: Processor<PsiReference>,
|
||||
optimizer: SearchRequestCollector,
|
||||
options: KotlinReferencesSearchOptions
|
||||
): OperatorReferenceSearcher<*>? {
|
||||
if (!Name.isValidIdentifier(functionName)) return null
|
||||
val name = Name.identifier(functionName)
|
||||
|
||||
if (isComponentLike(name)) {
|
||||
if (!options.searchForComponentConventions) return null
|
||||
return DestructuringDeclarationReferenceSearcher(declaration, searchScope, consumer, optimizer)
|
||||
}
|
||||
|
||||
if (!options.searchForOperatorConventions) return null
|
||||
if (declaration !is KtFunction) return null
|
||||
|
||||
if (name == OperatorNameConventions.INVOKE) {
|
||||
return InvokeOperatorReferenceSearcher(declaration, searchScope, consumer, optimizer)
|
||||
}
|
||||
|
||||
val binaryOp = OperatorConventions.BINARY_OPERATION_NAMES.inverse()[name]
|
||||
if (binaryOp != null) {
|
||||
val assignmentOp = OperatorConventions.ASSIGNMENT_OPERATION_COUNTERPARTS.inverse()[binaryOp]
|
||||
val operationTokens = listOf(binaryOp, assignmentOp).filterNotNull()
|
||||
return BinaryOperatorReferenceSearcher(declaration, operationTokens, searchScope, consumer, optimizer)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private object SearchesInProgress : ThreadLocal<HashSet<KtDeclaration>>() {
|
||||
override fun initialValue() = HashSet<KtDeclaration>()
|
||||
}
|
||||
@@ -77,9 +133,9 @@ abstract class OperatorReferenceSearcher<TReferenceElement : KtElement>(
|
||||
|
||||
open fun run() {
|
||||
val inProgress = SearchesInProgress.get()
|
||||
try {
|
||||
if (!inProgress.add(targetDeclaration)) return //TODO: it's not quite correct
|
||||
if (!inProgress.add(targetDeclaration)) return //TODO: it's not quite correct
|
||||
|
||||
try {
|
||||
val usePlainSearch = when (ExpressionsOfTypeProcessor.mode) {
|
||||
ExpressionsOfTypeProcessor.Mode.ALWAYS_SMART -> false
|
||||
ExpressionsOfTypeProcessor.Mode.ALWAYS_PLAIN -> true
|
||||
@@ -131,11 +187,13 @@ abstract class OperatorReferenceSearcher<TReferenceElement : KtElement>(
|
||||
}
|
||||
else {
|
||||
scope as GlobalSearchScope
|
||||
if (wordToSearch != null) {
|
||||
if (wordsToSearch.isNotEmpty()) {
|
||||
val unwrappedElement = targetDeclaration.namedUnwrappedElement ?: return
|
||||
val resultProcessor = KotlinRequestResultProcessor(unwrappedElement,
|
||||
filter = { ref -> isReferenceToCheck(ref) })
|
||||
optimizer.searchWord(wordToSearch, scope.restrictToKotlinSources(), UsageSearchContext.IN_CODE, true, unwrappedElement, resultProcessor)
|
||||
wordsToSearch.forEach {
|
||||
optimizer.searchWord(it, scope.restrictToKotlinSources(), UsageSearchContext.IN_CODE, true, unwrappedElement, resultProcessor)
|
||||
}
|
||||
}
|
||||
else {
|
||||
val psiManager = PsiManager.getInstance(project)
|
||||
|
||||
@@ -62,11 +62,13 @@ fun Name.getOperationSymbolsToSearch(): Pair<Set<KtToken>, Class<*>?> {
|
||||
val unaryOp = UNARY_OPERATION_NAMES_WITH_DEPRECATED_INVERTED[this]
|
||||
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)) to KtSimpleNameReference::class.java
|
||||
}
|
||||
*/
|
||||
|
||||
val assignmentOp = ASSIGNMENT_OPERATIONS.inverse()[this]
|
||||
if (assignmentOp != null) return setOf(assignmentOp) to KtSimpleNameReference::class.java
|
||||
|
||||
+2
-2
@@ -131,9 +131,9 @@ abstract class KotlinFindMemberUsagesHandler<T : KtNamedDeclaration>
|
||||
val uniqueProcessor = CommonProcessors.UniqueProcessor(processor)
|
||||
|
||||
if (options.isUsages) {
|
||||
// we disable searchForComponentConventions and searchInvokeOperator for ReferencesSearch because they will be searched by MethodReferencesSearch
|
||||
// we disable searchForComponentConventions and searchForOperatorConventions for ReferencesSearch because they will be searched by MethodReferencesSearch
|
||||
val kotlinSearchOptions = createKotlinReferencesSearchOptions(options)
|
||||
.copy(searchForComponentConventions = false, searchInvokeOperator = false)
|
||||
.copy(searchForComponentConventions = false, searchForOperatorConventions = false)
|
||||
val searchParameters = KotlinReferencesSearchParameters(element, options.searchScope, kotlinOptions = kotlinSearchOptions)
|
||||
|
||||
with(applyQueryFilters(element, options, ReferencesSearch.search(searchParameters))) {
|
||||
|
||||
+5
-9
@@ -22,14 +22,11 @@ import com.intellij.psi.search.UsageSearchContext
|
||||
import com.intellij.psi.search.searches.MethodReferencesSearch
|
||||
import com.intellij.util.Processor
|
||||
import org.jetbrains.kotlin.idea.search.restrictToKotlinSources
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.DestructuringDeclarationReferenceSearcher
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.InvokeOperatorReferenceSearcher
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.OperatorReferenceSearcher
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.getOperationSymbolsToSearch
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.lexer.KtSingleValueToken
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.dataClassUtils.isComponentLike
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
class KotlinConventionMethodReferencesSearcher() : QueryExecutorBase<PsiReference, MethodReferencesSearch.SearchParameters>(true) {
|
||||
override fun processQuery(queryParameters: MethodReferencesSearch.SearchParameters, consumer: Processor<PsiReference>) {
|
||||
@@ -38,11 +35,10 @@ class KotlinConventionMethodReferencesSearcher() : QueryExecutorBase<PsiReferenc
|
||||
if (!Name.isValidIdentifier(name)) return
|
||||
val identifier = Name.identifier(name)
|
||||
|
||||
if (isComponentLike(identifier)) {
|
||||
DestructuringDeclarationReferenceSearcher.runForPsiMethod(method, queryParameters.effectiveSearchScope, consumer, queryParameters.optimizer)
|
||||
}
|
||||
else if (identifier == OperatorNameConventions.INVOKE) {
|
||||
InvokeOperatorReferenceSearcher.runForPsiMethod(method, queryParameters.effectiveSearchScope, consumer, queryParameters.optimizer)
|
||||
val operatorSearcher = OperatorReferenceSearcher.createForPsiMethod(
|
||||
method, queryParameters.effectiveSearchScope, consumer, queryParameters.optimizer, KotlinReferencesSearchOptions.Empty)
|
||||
if (operatorSearcher != null) {
|
||||
operatorSearcher.run()
|
||||
}
|
||||
else {
|
||||
val operationSymbolsToSearch = identifier.getOperationSymbolsToSearch()
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// OPTIONS: usages
|
||||
|
||||
class A(val n: Int) {
|
||||
fun <caret>compareTo(other: A): Int = compareTo(other.n)
|
||||
fun compareTo(m: Int): Int = n.compareTo(m)
|
||||
infix operator fun <caret>compareTo(other: A): Int = compareTo(other.n)
|
||||
infix operator fun compareTo(m: Int): Int = n.compareTo(m)
|
||||
}
|
||||
|
||||
fun test() {
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
Resolved (x, y)
|
||||
Resolved b1 + b2
|
||||
Searched references to A
|
||||
Searched references to B
|
||||
Searched references to parameter b1 in f() in Kotlin files
|
||||
Searched references to parameter b2 in f() in Kotlin files
|
||||
Searched references to parameter other in plus() in Kotlin files
|
||||
Searched references to plus() in Kotlin files
|
||||
Used plain search in LocalSearchScope:
|
||||
CLASS:A
|
||||
Used plain search in whole search scope
|
||||
Used plain search in LocalSearchScope:
|
||||
CLASS:B
|
||||
FUN:plus
|
||||
@@ -2,7 +2,7 @@
|
||||
// OPTIONS: usages
|
||||
|
||||
class A(val n: Int) {
|
||||
fun <caret>contains(k: Int): Boolean = k <= n
|
||||
infix operator fun <caret>contains(k: Int): Boolean = k <= n
|
||||
}
|
||||
|
||||
fun test() {
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
// FIND_BY_REF
|
||||
|
||||
class A(val n: Int) {
|
||||
override fun equals(other: Any?): Boolean = other is A && other.n <caret>== n
|
||||
infix override fun equals(other: Any?): Boolean = other is A && other.n <caret>== n
|
||||
}
|
||||
|
||||
fun test() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Function call 10 A(0) == A(1)
|
||||
Function call 11 A(0) != A(1)
|
||||
Function call 12 A(0) equals A(1)
|
||||
Function call 6 override fun equals(other: Any?): Boolean = other is A && other.n == n
|
||||
Function call 6 infix override fun equals(other: Any?): Boolean = other is A && other.n == n
|
||||
@@ -2,11 +2,11 @@
|
||||
// OPTIONS: usages
|
||||
|
||||
class A<T: Any> {
|
||||
public fun <caret>iterator(): Iterator<T> = throw IllegalStateException("")
|
||||
operator fun <caret>iterator(): Iterator<T> = throw IllegalStateException("")
|
||||
}
|
||||
|
||||
class B<T: Any> {
|
||||
public fun iterator(): Iterator<T> = throw IllegalStateException("")
|
||||
operator fun iterator(): Iterator<T> = throw IllegalStateException("")
|
||||
}
|
||||
|
||||
fun test() {
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
// OPTIONS: usages
|
||||
|
||||
class B(val n: Int) {
|
||||
fun <caret>get(i: Int): B = B(i)
|
||||
operator fun <caret>get(i: Int): B = B(i)
|
||||
}
|
||||
|
||||
fun test() {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class Delegate() {
|
||||
fun <caret>getValue(thisRef: Any?, property: KProperty<*>): String = ":)"
|
||||
operator fun <caret>getValue(thisRef: Any?, property: KProperty<*>): String = ":)"
|
||||
}
|
||||
|
||||
val p: String by Delegate()
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
// OPTIONS: usages
|
||||
|
||||
class A(val n: Int) {
|
||||
fun <caret>inc(): A = A(n + 1)
|
||||
operator fun <caret>inc(): A = A(n + 1)
|
||||
}
|
||||
|
||||
fun test() {
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
// OPTIONS: usages
|
||||
|
||||
class A(val n: Int) {
|
||||
fun <caret>plus(m: Int): A = A(n + m)
|
||||
fun plus(a: A): A = this + a.n
|
||||
operator fun <caret>plus(m: Int): A = A(n + m)
|
||||
operator fun plus(a: A): A = this + a.n
|
||||
}
|
||||
|
||||
fun test() {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
Checked type of a
|
||||
Checked type of a
|
||||
Resolved A(0) + A(1)
|
||||
Resolved A(0) + A(1)
|
||||
Resolved A(0) + A(1) + 2
|
||||
Resolved A(0) + A(1) + 2
|
||||
Resolved A(0) + A(1) + 2
|
||||
Resolved A(0) + A(1) + 2
|
||||
Resolved A(0) + A(1) + 2
|
||||
Resolved A(0) + A(1) + 2
|
||||
Resolved a += 1
|
||||
Resolved a += 1
|
||||
Resolved a += A(1)
|
||||
Resolved a += A(1)
|
||||
Searched references to A
|
||||
Searched references to A
|
||||
Searched references to A.plus() in Kotlin files
|
||||
Searched references to A.plus() in Kotlin files
|
||||
Searched references to A.plus() in Kotlin files
|
||||
Searched references to A.plus() in Kotlin files
|
||||
Searched references to a in Kotlin files
|
||||
Searched references to a in Kotlin files
|
||||
Searched references to parameter a in A.plus() in Kotlin files
|
||||
Searched references to parameter a in A.plus() in Kotlin files
|
||||
Used plain search in LocalSearchScope:
|
||||
CLASS:A
|
||||
Used plain search in LocalSearchScope:
|
||||
CLASS:A
|
||||
@@ -2,4 +2,4 @@ Function call 10 A(0) + A(1) + 2
|
||||
Function call 11 A(0) plus A(1) plus 2
|
||||
Function call 12 A(0).plus(A(1).plus(2))
|
||||
Function call 15 a += 1
|
||||
Function call 6 fun plus(a: A): A = this + a.n
|
||||
Function call 6 operator fun plus(a: A): A = this + a.n
|
||||
@@ -2,11 +2,11 @@
|
||||
// OPTIONS: usages
|
||||
|
||||
class A(var n: Int) {
|
||||
fun <caret>plusAssign(m: Int) {
|
||||
operator fun <caret>plusAssign(m: Int) {
|
||||
n += m
|
||||
}
|
||||
|
||||
fun plusAssign(a: A) {
|
||||
operator fun plusAssign(a: A) {
|
||||
this += a.n
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class Delegate() {
|
||||
fun getValue(thisRef: Any?, property: KProperty<*>): String = ":)"
|
||||
fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
|
||||
operator fun getValue(thisRef: Any?, property: KProperty<*>): String = ":)"
|
||||
|
||||
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
|
||||
}
|
||||
|
||||
fun <caret>propertyDelegated(property: KProperty<*>) {
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
Property delegation 15 var p: String by Delegate()
|
||||
Property delegation 16 var p: String by Delegate()
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
// OPTIONS: usages
|
||||
|
||||
class B(val n: Int) {
|
||||
fun <caret>set(i: Int, a: B) {}
|
||||
operator fun <caret>set(i: Int, a: B) {}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class Delegate() {
|
||||
fun getValue(thisRef: Any?, property: KProperty<*>): String = ":)"
|
||||
fun <caret>setValue(thisRef: Any?, property: KProperty<*>, value: String) {
|
||||
operator fun getValue(thisRef: Any?, property: KProperty<*>): String = ":)"
|
||||
|
||||
operator fun <caret>setValue(thisRef: Any?, property: KProperty<*>, value: String) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
Property delegation 13 var p: String by Delegate()
|
||||
Property delegation 14 var p: String by Delegate()
|
||||
Reference in New Issue
Block a user