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.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<PsiReference>,
|
||||
optimizer: SearchRequestCollector
|
||||
optimizer: SearchRequestCollector,
|
||||
private val isSet: Boolean
|
||||
) : OperatorReferenceSearcher<KtArrayAccessExpression>(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<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)
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -40,8 +40,6 @@ val ALL_SEARCHABLE_OPERATIONS: ImmutableSet<KtToken> = 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)
|
||||
|
||||
+4
-1
@@ -2,10 +2,13 @@
|
||||
// OPTIONS: usages
|
||||
|
||||
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() {
|
||||
B(1).get(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]
|
||||
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
|
||||
|
||||
@@ -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]
|
||||
+4
-2
@@ -3,11 +3,13 @@
|
||||
|
||||
class B(val n: Int) {
|
||||
operator fun <caret>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]
|
||||
}
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
@@ -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]++
|
||||
Reference in New Issue
Block a user