diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/StaticMembersCompletion.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/StaticMembersCompletion.kt index b12684ae2b1..b1e42195e9b 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/StaticMembersCompletion.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/StaticMembersCompletion.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.idea.core.KotlinIndicesHelper import org.jetbrains.kotlin.idea.core.targetDescriptors import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.KtCallableDeclaration import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtObjectDeclaration @@ -87,23 +88,26 @@ class StaticMembersCompletion( //TODO: better presentation for lookup elements from imports too //TODO: from the same file - fun membersFromIndices(indicesHelper: KotlinIndicesHelper): Collection { + fun processMembersFromIndices(indicesHelper: KotlinIndicesHelper, processor: (DeclarationDescriptor) -> Unit) { val descriptorKindFilter = DescriptorKindFilter.CALLABLES exclude DescriptorKindExclude.Extensions val nameFilter: (String) -> Boolean = { prefixMatcher.prefixMatches(it) } - val result = ArrayList() + val filter = { declaration: KtCallableDeclaration, objectDeclaration: KtObjectDeclaration -> + !declaration.hasModifier(KtTokens.OVERRIDE_KEYWORD) && objectDeclaration.isTopLevelOrCompanion() + } + indicesHelper.processObjectMembers(descriptorKindFilter, nameFilter, filter) { + if (it !in alreadyAdded) { //TODO: substitution + processor(it) + } + } if (isJvmModule) { - indicesHelper.getJavaStaticMembers(descriptorKindFilter, nameFilter).filterTo(result) { it !in alreadyAdded } //TODO: substitution + indicesHelper.processJavaStaticMembers(descriptorKindFilter, nameFilter){ + if (it !in alreadyAdded) { //TODO: substitution + processor(it) + } + } } - - indicesHelper.getObjectMembers(descriptorKindFilter, nameFilter) filter@ { declaration, objectDeclaration -> - !declaration.hasModifier(KtTokens.OVERRIDE_KEYWORD) && objectDeclaration.isTopLevelOrCompanion() - }.filterTo(result) { - it !in alreadyAdded //TODO: substitution - } - - return result } private fun KtObjectDeclaration.isTopLevelOrCompanion(): Boolean { @@ -125,8 +129,9 @@ class StaticMembersCompletion( fun completeFromIndices(indicesHelper: KotlinIndicesHelper, collector: LookupElementsCollector) { val factory = decoratedLookupElementFactory(ItemPriority.STATIC_MEMBER) - membersFromIndices(indicesHelper) - .flatMap { factory.createStandardLookupElementsForDescriptor(it, useReceiverTypes = true) } - .forEach { collector.addElement(it) } + processMembersFromIndices(indicesHelper) { + factory.createStandardLookupElementsForDescriptor(it, useReceiverTypes = true).forEach { collector.addElement(it) } + collector.flushToResultSet() + } } } diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletionSession.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletionSession.kt index c467a2d9807..295298e6154 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletionSession.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletionSession.kt @@ -137,9 +137,12 @@ class SmartCompletionSession(configuration: CompletionSessionConfiguration, para if (staticMembersCompletion != null && configuration.completeStaticMembers) { val decoratedFactory = staticMembersCompletion.decoratedLookupElementFactory(ItemPriority.STATIC_MEMBER) - staticMembersCompletion.membersFromIndices(indicesHelper(false)) - .flatMap { filter(it, decoratedFactory) } - .forEach { collector.addElement(it) } + staticMembersCompletion.processMembersFromIndices(indicesHelper(false)) { + filter(it, decoratedFactory).forEach { + collector.addElement(it) + flushToResultSet() + } + } } } } diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/KotlinIndicesHelper.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/KotlinIndicesHelper.kt index e1feb28e1b7..4a0f114881e 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/KotlinIndicesHelper.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/KotlinIndicesHelper.kt @@ -197,14 +197,13 @@ public class KotlinIndicesHelper( .filter(descriptorFilter) } - public fun getObjectMembers( + public fun processObjectMembers( descriptorKindFilter: DescriptorKindFilter, nameFilter: (String) -> Boolean, - filter: (KtCallableDeclaration, KtObjectDeclaration) -> Boolean - ): Collection { - val result = LinkedHashSet() - - fun addFromIndex(index: StringStubIndexExtension) { + filter: (KtCallableDeclaration, KtObjectDeclaration) -> Boolean, + processor: (DeclarationDescriptor) -> Unit + ) { + fun processIndex(index: StringStubIndexExtension) { for (name in index.getAllKeys(project)) { ProgressManager.checkCanceled() if (!nameFilter(name)) continue @@ -214,24 +213,28 @@ public class KotlinIndicesHelper( if (objectDeclaration.isObjectLiteral()) continue if (!visibilityFilterMayIncludeAccessible && declaration.hasModifier(KtTokens.PRIVATE_KEYWORD)) continue if (!filter(declaration, objectDeclaration)) continue - declaration.resolveToDescriptorsWithHack().filterTo(result) { descriptorKindFilter.accepts(it) && descriptorFilter(it) } + for (descriptor in declaration.resolveToDescriptorsWithHack()) { + if (descriptorKindFilter.accepts(descriptor) && descriptorFilter(descriptor)) { + processor(descriptor) + } + } } } } if (descriptorKindFilter.kindMask.and(DescriptorKindFilter.FUNCTIONS_MASK) != 0) { - addFromIndex(KotlinFunctionShortNameIndex.getInstance()) + processIndex(KotlinFunctionShortNameIndex.getInstance()) } if (descriptorKindFilter.kindMask.and(DescriptorKindFilter.VARIABLES_MASK) != 0) { - addFromIndex(KotlinPropertyShortNameIndex.getInstance()) + processIndex(KotlinPropertyShortNameIndex.getInstance()) } - - return result } - public fun getJavaStaticMembers(descriptorKindFilter: DescriptorKindFilter, nameFilter: (String) -> Boolean): Collection { - val result = LinkedHashSet() - + public fun processJavaStaticMembers( + descriptorKindFilter: DescriptorKindFilter, + nameFilter: (String) -> Boolean, + processor: (DeclarationDescriptor) -> Unit + ) { val idFilter = IdFilter.getProjectIdFilter(resolutionFacade.project, false) val shortNamesCache = PsiShortNamesCache.getInstance(project) @@ -246,12 +249,13 @@ public class KotlinIndicesHelper( val descriptor = method.getJavaMethodDescriptor(resolutionFacade) ?: continue val container = descriptor.containingDeclaration as? ClassDescriptor ?: continue if (descriptorKindFilter.accepts(descriptor) && descriptorFilter(descriptor)) { - result.add(descriptor) + processor(descriptor) - val samAdapter = container.staticScope.getContributedFunctions(descriptor.name, NoLookupLocation.FROM_IDE) + // SAM-adapter + container.staticScope.getContributedFunctions(descriptor.name, NoLookupLocation.FROM_IDE) .filterIsInstance>() .firstOrNull { it.originForSam.original == descriptor.original } - result.addIfNotNull(samAdapter) + ?.let { processor(it) } } } true @@ -267,14 +271,12 @@ public class KotlinIndicesHelper( if (!visibilityFilterMayIncludeAccessible && field.hasModifierProperty(PsiModifier.PRIVATE)) continue val descriptor = field.getJavaFieldDescriptor() ?: continue if (descriptorKindFilter.accepts(descriptor) && descriptorFilter(descriptor)) { - result.add(descriptor) + processor(descriptor) } } true } shortNamesCache.processAllFieldNames(fieldNamesProcessor, scope, idFilter) - - return result } private fun findTopLevelCallables(fqName: FqName): Collection {