Optimization

This commit is contained in:
Valentin Kipyatkov
2016-09-02 16:00:33 +03:00
parent 0f32574be0
commit 5ce780cafc
9 changed files with 33 additions and 16 deletions
@@ -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
}
}
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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]++