Optimization
This commit is contained in:
+11
-3
@@ -22,29 +22,37 @@ import com.intellij.psi.search.SearchRequestCollector
|
|||||||
import com.intellij.psi.search.SearchScope
|
import com.intellij.psi.search.SearchScope
|
||||||
import com.intellij.util.Processor
|
import com.intellij.util.Processor
|
||||||
import org.jetbrains.kotlin.idea.references.KtArrayAccessReference
|
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.KtArrayAccessExpression
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
import org.jetbrains.kotlin.psi.KtFunction
|
import org.jetbrains.kotlin.psi.KtFunction
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
||||||
|
|
||||||
//TODO: more effective search of 'set'
|
|
||||||
class IndexingOperatorReferenceSearcher(
|
class IndexingOperatorReferenceSearcher(
|
||||||
targetFunction: KtFunction,
|
targetFunction: KtFunction,
|
||||||
searchScope: SearchScope,
|
searchScope: SearchScope,
|
||||||
consumer: Processor<PsiReference>,
|
consumer: Processor<PsiReference>,
|
||||||
optimizer: SearchRequestCollector
|
optimizer: SearchRequestCollector,
|
||||||
|
private val isSet: Boolean
|
||||||
) : OperatorReferenceSearcher<KtArrayAccessExpression>(targetFunction, searchScope, consumer, optimizer, wordsToSearch = listOf("[")) {
|
) : OperatorReferenceSearcher<KtArrayAccessExpression>(targetFunction, searchScope, consumer, optimizer, wordsToSearch = listOf("[")) {
|
||||||
|
|
||||||
override fun processSuspiciousExpression(expression: KtExpression) {
|
override fun processSuspiciousExpression(expression: KtExpression) {
|
||||||
val accessExpression = expression.parent as? KtArrayAccessExpression ?: return
|
val accessExpression = expression.parent as? KtArrayAccessExpression ?: return
|
||||||
if (expression != accessExpression.arrayExpression) return
|
if (expression != accessExpression.arrayExpression) return
|
||||||
|
if (!checkAccessExpression(accessExpression)) return
|
||||||
processReferenceElement(accessExpression)
|
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? {
|
override fun extractReference(element: PsiElement): PsiReference? {
|
||||||
val accessExpression = element as? KtArrayAccessExpression ?: return null
|
val accessExpression = element as? KtArrayAccessExpression ?: return null
|
||||||
|
if (!checkAccessExpression(accessExpression)) return null
|
||||||
return accessExpression.references.firstIsInstance<KtArrayAccessReference>()
|
return accessExpression.references.firstIsInstance<KtArrayAccessReference>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun checkAccessExpression(accessExpression: KtArrayAccessExpression): Boolean {
|
||||||
|
val readWriteAccess = accessExpression.readWriteAccess(useResolveForReadWrite = false)
|
||||||
|
return if (isSet) readWriteAccess.isWrite else readWriteAccess.isRead
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+6
-2
@@ -133,8 +133,12 @@ abstract class OperatorReferenceSearcher<TReferenceElement : KtElement>(
|
|||||||
return UnaryOperatorReferenceSearcher(declaration, unaryOp, searchScope, consumer, optimizer)
|
return UnaryOperatorReferenceSearcher(declaration, unaryOp, searchScope, consumer, optimizer)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name in INDEXING_OPERATION_NAMES) {
|
if (name == OperatorNameConventions.GET) {
|
||||||
return IndexingOperatorReferenceSearcher(declaration, searchScope, consumer, optimizer)
|
return IndexingOperatorReferenceSearcher(declaration, searchScope, consumer, optimizer, isSet = false)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name == OperatorNameConventions.SET) {
|
||||||
|
return IndexingOperatorReferenceSearcher(declaration, searchScope, consumer, optimizer, isSet = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
|
|||||||
@@ -40,8 +40,6 @@ val ALL_SEARCHABLE_OPERATIONS: ImmutableSet<KtToken> = ImmutableSet
|
|||||||
.add(KtTokens.BY_KEYWORD)
|
.add(KtTokens.BY_KEYWORD)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
val INDEXING_OPERATION_NAMES = setOf(OperatorNameConventions.GET, OperatorNameConventions.SET)
|
|
||||||
|
|
||||||
val DELEGATE_ACCESSOR_NAMES = setOf(Name.identifier("getValue"), Name.identifier("setValue"))
|
val DELEGATE_ACCESSOR_NAMES = setOf(Name.identifier("getValue"), Name.identifier("setValue"))
|
||||||
|
|
||||||
val IN_OPERATIONS_TO_SEARCH = setOf(KtTokens.IN_KEYWORD)
|
val IN_OPERATIONS_TO_SEARCH = setOf(KtTokens.IN_KEYWORD)
|
||||||
|
|||||||
+4
-1
@@ -2,10 +2,13 @@
|
|||||||
// OPTIONS: usages
|
// OPTIONS: usages
|
||||||
|
|
||||||
class B(val n: Int) {
|
class B(val n: Int) {
|
||||||
operator fun <caret>get(i: Int): B = B(i)
|
operator fun <caret>get(i: Int) = ""
|
||||||
|
operator fun set(i: Int, s: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
B(1).get(2)
|
B(1).get(2)
|
||||||
B(1)[2]
|
B(1)[2]
|
||||||
|
val b = B(2)
|
||||||
|
b[3] = "a"
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -1,5 +1,6 @@
|
|||||||
|
Checked type of b
|
||||||
Resolved B(1)[2]
|
Resolved B(1)[2]
|
||||||
Searched references to B
|
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:
|
Used plain search of B.get(i: Int) in LocalSearchScope:
|
||||||
CLASS:B
|
CLASS:B
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
Function call 9 B(1).get(2)
|
Function call 10 B(1).get(2)
|
||||||
Implicit 'get' 10 B(1)[2]
|
Implicit 'get' 11 B(1)[2]
|
||||||
+4
-2
@@ -3,11 +3,13 @@
|
|||||||
|
|
||||||
class B(val n: Int) {
|
class B(val n: Int) {
|
||||||
operator fun <caret>set(i: Int, a: B) {}
|
operator fun <caret>set(i: Int, a: B) {}
|
||||||
|
operator fun inc() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
var a = B(1)
|
var a = B(1)
|
||||||
a.set(2, B(2))
|
a.set(2, B(2))
|
||||||
a[2] = B(2)
|
a[1] = B(2)
|
||||||
a[2]
|
a[2]++
|
||||||
|
a[3]
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
Checked type of a
|
Checked type of a
|
||||||
Resolved a[2]
|
Resolved a[1]
|
||||||
Resolved a[2]
|
Resolved a[2]
|
||||||
Searched references to B
|
Searched references to B
|
||||||
Searched references to a in Kotlin files
|
Searched references to a in Kotlin files
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
Function call 10 a.set(2, B(2))
|
Function call 11 a.set(2, B(2))
|
||||||
Implicit 'set' 11 a[2] = B(2)
|
Implicit 'set' 12 a[1] = B(2)
|
||||||
|
Unclassified usage 13 a[2]++
|
||||||
Reference in New Issue
Block a user