diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/KotlinShortNamesCache.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/KotlinShortNamesCache.kt index b3a8fe07fa4..b7c14f8ee35 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/KotlinShortNamesCache.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/KotlinShortNamesCache.kt @@ -42,6 +42,7 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.utils.addToStdlib.sequenceOfLazyValues class KotlinShortNamesCache(private val project: Project) : PsiShortNamesCache() { @@ -158,15 +159,6 @@ class KotlinShortNamesCache(private val project: Project) : PsiShortNamesCache() return limitedByMaxCount.toTypedArray() } - override fun getFieldsByNameIfNotMoreThan(name: String, scope: GlobalSearchScope, maxCount: Int): Array { - require(maxCount >= 0) - val psiFields = getFieldSequenceByName(name, scope) - val limitedByMaxCount = psiFields.take(maxCount).toList() - if (limitedByMaxCount.size == 0) - return PsiField.EMPTY_ARRAY - return limitedByMaxCount.toTypedArray() - } - override fun processMethodsWithName(name: String, scope: GlobalSearchScope, processor: Processor): Boolean = ContainerUtil.process(getMethodsByName(name, scope), processor) @@ -190,14 +182,8 @@ class KotlinShortNamesCache(private val project: Project) : PsiShortNamesCache() } } - private fun getFieldSequenceByName(name: String, scope: GlobalSearchScope): Sequence { - return KotlinPropertyShortNameIndex.getInstance().get(name, project, scope).asSequence() - .map { LightClassUtil.getLightClassBackingField(it) } - .filterNotNull() - } - - override fun getFieldsByName(name: String, scope: GlobalSearchScope): Array { - return getFieldSequenceByName(name, scope).toList().toTypedArray() + override fun processAllFieldNames(processor: Processor, scope: GlobalSearchScope, filter: IdFilter?): Boolean { + return processAllFieldNames(processor) } override fun getAllFieldNames(): Array { @@ -206,14 +192,52 @@ class KotlinShortNamesCache(private val project: Project) : PsiShortNamesCache() }.toArray(arrayOf()) } - override fun processAllFieldNames(processor: Processor, scope: GlobalSearchScope, filter: IdFilter?): Boolean { - return processAllFieldNames(processor) - } - private fun processAllFieldNames(processor: Processor): Boolean { return KotlinPropertyShortNameIndex.getInstance().processAllKeys(project, processor) } + override fun processFieldsWithName( + name: String, + processor: Processor, + scope: GlobalSearchScope, + filter: IdFilter? + ): Boolean { + return StubIndex.getInstance().processElements( + KotlinPropertyShortNameIndex.getInstance().key, + name, + project, + scope, + filter, + KtNamedDeclaration::class.java + ) { ktNamedDeclaration -> + val field = LightClassUtil.getLightClassBackingField(ktNamedDeclaration) + ?: return@processElements true + + return@processElements processor.process(field) + } + } + + override fun getFieldsByName(name: String, scope: GlobalSearchScope): Array { + return CancelableArrayCollectProcessor().also { processor -> + processFieldsWithName(name, processor, scope, null) + }.toArray(arrayOf()) + } + + override fun getFieldsByNameIfNotMoreThan(name: String, scope: GlobalSearchScope, maxCount: Int): Array { + require(maxCount >= 0) + + return CancelableArrayCollectProcessor().also { processor -> + processFieldsWithName( + name, + { psiField -> + processor.size != maxCount && processor.process(psiField) + }, + scope, + null + ) + }.toArray(PsiField.EMPTY_ARRAY) + } + private class CancelableArrayCollectProcessor : Processor { val troveSet = ContainerUtil.newTroveSet() private val processor = Processors.cancelableCollectProcessor(troveSet) @@ -222,6 +246,8 @@ class KotlinShortNamesCache(private val project: Project) : PsiShortNamesCache() return processor.process(value) } + val size: Int get() = troveSet.size + fun toArray(a: Array): Array = troveSet.toArray(a) } }