From 5ce780cafcff1bef7a42b41438a3958710bacf86 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Fri, 2 Sep 2016 16:00:33 +0300 Subject: [PATCH] Optimization --- .../IndexingOperatorReferenceSearcher.kt | 14 +++++++++++--- .../search/usagesSearch/OperatorReferenceSearch.kt | 8 ++++++-- .../kotlin/idea/search/usagesSearch/conventions.kt | 2 -- .../findUsages/kotlin/conventions/get.0.kt | 5 ++++- .../testData/findUsages/kotlin/conventions/get.log | 3 ++- .../findUsages/kotlin/conventions/get.results.txt | 4 ++-- .../findUsages/kotlin/conventions/set.0.kt | 6 ++++-- .../testData/findUsages/kotlin/conventions/set.log | 2 +- .../findUsages/kotlin/conventions/set.results.txt | 5 +++-- 9 files changed, 33 insertions(+), 16 deletions(-) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/IndexingOperatorReferenceSearcher.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/IndexingOperatorReferenceSearcher.kt index 7cdace0ac16..e9c1651f0db 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/IndexingOperatorReferenceSearcher.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/IndexingOperatorReferenceSearcher.kt @@ -22,29 +22,37 @@ import com.intellij.psi.search.SearchRequestCollector import com.intellij.psi.search.SearchScope import com.intellij.util.Processor import org.jetbrains.kotlin.idea.references.KtArrayAccessReference +import org.jetbrains.kotlin.idea.references.readWriteAccess import org.jetbrains.kotlin.psi.KtArrayAccessExpression import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtFunction import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance -//TODO: more effective search of 'set' class IndexingOperatorReferenceSearcher( targetFunction: KtFunction, searchScope: SearchScope, consumer: Processor, - optimizer: SearchRequestCollector + optimizer: SearchRequestCollector, + private val isSet: Boolean ) : OperatorReferenceSearcher(targetFunction, searchScope, consumer, optimizer, wordsToSearch = listOf("[")) { override fun processSuspiciousExpression(expression: KtExpression) { val accessExpression = expression.parent as? KtArrayAccessExpression ?: return if (expression != accessExpression.arrayExpression) return + if (!checkAccessExpression(accessExpression)) return processReferenceElement(accessExpression) } - override fun isReferenceToCheck(ref: PsiReference) = ref is KtArrayAccessReference + override fun isReferenceToCheck(ref: PsiReference) = ref is KtArrayAccessReference && checkAccessExpression(ref.element as KtArrayAccessExpression) override fun extractReference(element: PsiElement): PsiReference? { val accessExpression = element as? KtArrayAccessExpression ?: return null + if (!checkAccessExpression(accessExpression)) return null return accessExpression.references.firstIsInstance() } + + private fun checkAccessExpression(accessExpression: KtArrayAccessExpression): Boolean { + val readWriteAccess = accessExpression.readWriteAccess(useResolveForReadWrite = false) + return if (isSet) readWriteAccess.isWrite else readWriteAccess.isRead + } } \ No newline at end of file diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/OperatorReferenceSearch.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/OperatorReferenceSearch.kt index 59b86f39f2e..cdf60f02bda 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/OperatorReferenceSearch.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/OperatorReferenceSearch.kt @@ -133,8 +133,12 @@ abstract class OperatorReferenceSearcher( return UnaryOperatorReferenceSearcher(declaration, unaryOp, searchScope, consumer, optimizer) } - if (name in INDEXING_OPERATION_NAMES) { - return IndexingOperatorReferenceSearcher(declaration, searchScope, consumer, optimizer) + if (name == OperatorNameConventions.GET) { + return IndexingOperatorReferenceSearcher(declaration, searchScope, consumer, optimizer, isSet = false) + } + + if (name == OperatorNameConventions.SET) { + return IndexingOperatorReferenceSearcher(declaration, searchScope, consumer, optimizer, isSet = true) } return null diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/conventions.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/conventions.kt index de6bc335204..6ba8d714800 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/conventions.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/conventions.kt @@ -40,8 +40,6 @@ val ALL_SEARCHABLE_OPERATIONS: ImmutableSet = ImmutableSet .add(KtTokens.BY_KEYWORD) .build() -val INDEXING_OPERATION_NAMES = setOf(OperatorNameConventions.GET, OperatorNameConventions.SET) - val DELEGATE_ACCESSOR_NAMES = setOf(Name.identifier("getValue"), Name.identifier("setValue")) val IN_OPERATIONS_TO_SEARCH = setOf(KtTokens.IN_KEYWORD) diff --git a/idea/testData/findUsages/kotlin/conventions/get.0.kt b/idea/testData/findUsages/kotlin/conventions/get.0.kt index 3ef92ef3484..b89b2cf5ed4 100644 --- a/idea/testData/findUsages/kotlin/conventions/get.0.kt +++ b/idea/testData/findUsages/kotlin/conventions/get.0.kt @@ -2,10 +2,13 @@ // OPTIONS: usages class B(val n: Int) { - operator fun get(i: Int): B = B(i) + operator fun get(i: Int) = "" + operator fun set(i: Int, s: String) } fun test() { B(1).get(2) B(1)[2] + val b = B(2) + b[3] = "a" } diff --git a/idea/testData/findUsages/kotlin/conventions/get.log b/idea/testData/findUsages/kotlin/conventions/get.log index 573753c0a2d..c57d4c1e152 100644 --- a/idea/testData/findUsages/kotlin/conventions/get.log +++ b/idea/testData/findUsages/kotlin/conventions/get.log @@ -1,5 +1,6 @@ +Checked type of b Resolved B(1)[2] Searched references to B -Searched references to B.get(i: Int) in Kotlin files +Searched references to b in Kotlin files Used plain search of B.get(i: Int) in LocalSearchScope: CLASS:B diff --git a/idea/testData/findUsages/kotlin/conventions/get.results.txt b/idea/testData/findUsages/kotlin/conventions/get.results.txt index f7ef5548901..fa36171d3ce 100644 --- a/idea/testData/findUsages/kotlin/conventions/get.results.txt +++ b/idea/testData/findUsages/kotlin/conventions/get.results.txt @@ -1,2 +1,2 @@ -Function call 9 B(1).get(2) -Implicit 'get' 10 B(1)[2] +Function call 10 B(1).get(2) +Implicit 'get' 11 B(1)[2] \ No newline at end of file diff --git a/idea/testData/findUsages/kotlin/conventions/set.0.kt b/idea/testData/findUsages/kotlin/conventions/set.0.kt index 111b0ed623d..166e584b143 100644 --- a/idea/testData/findUsages/kotlin/conventions/set.0.kt +++ b/idea/testData/findUsages/kotlin/conventions/set.0.kt @@ -3,11 +3,13 @@ class B(val n: Int) { operator fun set(i: Int, a: B) {} + operator fun inc() {} } fun test() { var a = B(1) a.set(2, B(2)) - a[2] = B(2) - a[2] + a[1] = B(2) + a[2]++ + a[3] } diff --git a/idea/testData/findUsages/kotlin/conventions/set.log b/idea/testData/findUsages/kotlin/conventions/set.log index 7c5c86d399d..45c22fca335 100644 --- a/idea/testData/findUsages/kotlin/conventions/set.log +++ b/idea/testData/findUsages/kotlin/conventions/set.log @@ -1,5 +1,5 @@ Checked type of a -Resolved a[2] +Resolved a[1] Resolved a[2] Searched references to B Searched references to a in Kotlin files diff --git a/idea/testData/findUsages/kotlin/conventions/set.results.txt b/idea/testData/findUsages/kotlin/conventions/set.results.txt index 0b6310b3e67..5606a06911a 100644 --- a/idea/testData/findUsages/kotlin/conventions/set.results.txt +++ b/idea/testData/findUsages/kotlin/conventions/set.results.txt @@ -1,2 +1,3 @@ -Function call 10 a.set(2, B(2)) -Implicit 'set' 11 a[2] = B(2) +Function call 11 a.set(2, B(2)) +Implicit 'set' 12 a[1] = B(2) +Unclassified usage 13 a[2]++ \ No newline at end of file