Rewrite fetching methods in KotlinShortNamesCache with processor

This commit is contained in:
Nikolay Krasko
2018-11-16 13:22:56 +03:00
parent 25fff006ef
commit 98c6b6837a
@@ -43,7 +43,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.utils.addToStdlib.sequenceOfLazyValues import org.jetbrains.kotlin.psi.KtNamedFunction
class KotlinShortNamesCache(private val project: Project) : PsiShortNamesCache() { class KotlinShortNamesCache(private val project: Project) : PsiShortNamesCache() {
//region Classes //region Classes
@@ -153,35 +153,75 @@ class KotlinShortNamesCache(private val project: Project) : PsiShortNamesCache()
} }
} }
override fun getMethodsByName(name: String, scope: GlobalSearchScope): Array<PsiMethod> { override fun processMethodsWithName(
return getMethodSequenceByName(name, scope).toList().toTypedArray() name: String,
processor: Processor<in PsiMethod>,
scope: GlobalSearchScope,
filter: IdFilter?
): Boolean {
val allFunctionsProcessed = StubIndex.getInstance().processElements(
KotlinFunctionShortNameIndex.getInstance().key,
name,
project,
scope,
filter,
KtNamedFunction::class.java
) { ktNamedFunction ->
val methods = LightClassUtil.getLightClassMethods(ktNamedFunction).filter { it.name == name }
return@processElements methods.all { method ->
processor.process(method)
}
}
if (!allFunctionsProcessed) {
return false
} }
private fun getMethodSequenceByName(name: String, scope: GlobalSearchScope): Sequence<PsiMethod> { for (propertyName in getPropertyNamesCandidatesByAccessorName(Name.identifier(name))) {
val propertiesIndex = KotlinPropertyShortNameIndex.getInstance() val allProcessed = StubIndex.getInstance().processElements(
val functionIndex = KotlinFunctionShortNameIndex.getInstance() KotlinPropertyShortNameIndex.getInstance().key,
propertyName.asString(),
val kotlinFunctionsPsi = functionIndex.get(name, project, scope).asSequence() project,
.flatMap { LightClassUtil.getLightClassMethods(it).asSequence() } scope,
.filter { it.name == name } filter,
KtNamedDeclaration::class.java
val propertyAccessorsPsi = sequenceOfLazyValues({ getPropertyNamesCandidatesByAccessorName(Name.identifier(name)) }) ) { ktNamedDeclaration ->
.flatMap { it.asSequence() } val methods = ktNamedDeclaration.getAccessorLightMethods()
.flatMap { propertiesIndex.get(it.asString(), project, scope).asSequence() } .asSequence()
.flatMap { it.getAccessorLightMethods().allDeclarations.asSequence() }
.filter { it.name == name } .filter { it.name == name }
.map { it as? PsiMethod } .map { it as? PsiMethod }
.filterNotNull()
return sequenceOfLazyValues({ kotlinFunctionsPsi }, { propertyAccessorsPsi }).flatMap { it }.filterNotNull() return@processElements methods.all { method ->
processor.process(method)
}
}
if (!allProcessed) {
return false
}
}
return true
}
override fun getMethodsByName(name: String, scope: GlobalSearchScope): Array<PsiMethod> {
return CancelableArrayCollectProcessor<PsiMethod>().also { processor ->
processMethodsWithName(name, processor, scope, null)
}.toArray(arrayOf())
} }
override fun getMethodsByNameIfNotMoreThan(name: String, scope: GlobalSearchScope, maxCount: Int): Array<PsiMethod> { override fun getMethodsByNameIfNotMoreThan(name: String, scope: GlobalSearchScope, maxCount: Int): Array<PsiMethod> {
require(maxCount >= 0) require(maxCount >= 0)
val psiMethods = getMethodSequenceByName(name, scope)
val limitedByMaxCount = psiMethods.take(maxCount).toList() return CancelableArrayCollectProcessor<PsiMethod>().also { processor ->
if (limitedByMaxCount.size == 0) processMethodsWithName(
return PsiMethod.EMPTY_ARRAY name,
return limitedByMaxCount.toTypedArray() { psiMethod ->
processor.size != maxCount && processor.process(psiMethod)
},
scope,
null
)
}.toArray(PsiMethod.EMPTY_ARRAY)
} }
override fun processMethodsWithName(name: String, scope: GlobalSearchScope, processor: Processor<PsiMethod>): Boolean = override fun processMethodsWithName(name: String, scope: GlobalSearchScope, processor: Processor<PsiMethod>): Boolean =