From cf6fd4da8155eb63ba5f79866e0195b99593d17c Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Thu, 22 Feb 2018 16:14:35 +0100 Subject: [PATCH] Completion: prevent lookup elements from being duplicated correctly This code prevents completion items from being submitted several times for the same descriptors But some contributors actually do contribute extra items for already processed descriptors Fixes a problem introduced in 1796d40118588c813092f59baf1be2ad387252b5 --- .../idea/completion/BasicCompletionSession.kt | 20 ++++++++++++--- .../idea/completion/DslMembersCompletion.kt | 2 +- .../completion/LookupElementsCollector.kt | 25 +++++++++++-------- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicCompletionSession.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicCompletionSession.kt index bb79aabfa12..7432656a71e 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicCompletionSession.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicCompletionSession.kt @@ -464,8 +464,14 @@ class BasicCompletionSession( .filterNot { it.original in foundDescriptors } .onEach { foundDescriptors += it.original } - collector.addDescriptorElements(unique.toList(), factory) - collector.addDescriptorElements(uniqueNotImportedExtensions.toList(), factory, notImported = true) + collector.addDescriptorElements( + unique.toList(), factory, + prohibitDuplicates = true + ) + collector.addDescriptorElements( + uniqueNotImportedExtensions.toList(), factory, + notImported = true, prohibitDuplicates = true + ) flushToResultSet() } @@ -796,8 +802,14 @@ class BasicCompletionSession( private fun addReferenceVariantElements(lookupElementFactory: LookupElementFactory, descriptorKindFilter: DescriptorKindFilter) { fun addReferenceVariants(referenceVariants: ReferenceVariants) { - collector.addDescriptorElements(referenceVariantsHelper.excludeNonInitializedVariable(referenceVariants.imported, position), lookupElementFactory) - collector.addDescriptorElements(referenceVariants.notImportedExtensions, lookupElementFactory, notImported = true) + collector.addDescriptorElements( + referenceVariantsHelper.excludeNonInitializedVariable(referenceVariants.imported, position), + lookupElementFactory, prohibitDuplicates = true + ) + collector.addDescriptorElements( + referenceVariants.notImportedExtensions, lookupElementFactory, + notImported = true, prohibitDuplicates = true + ) } val referenceVariantsCollector = referenceVariantsCollector!! diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/DslMembersCompletion.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/DslMembersCompletion.kt index cc0d90aa804..9be7a104ce7 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/DslMembersCompletion.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/DslMembersCompletion.kt @@ -64,7 +64,7 @@ class DslMembersCompletion( callTypeAndReceiver = callTypeAndReceiver, receiverTypes = listOf(nearestReceiver.type) ).forEach { descriptor: DeclarationDescriptor -> - collector.addDescriptorElements(descriptor, factory, notImported = true, withReceiverCast = false) + collector.addDescriptorElements(descriptor, factory, notImported = true, withReceiverCast = false, prohibitDuplicates = true) } collector.flushToResultSet() diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/LookupElementsCollector.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/LookupElementsCollector.kt index 37dd294c56f..9794ee01fa1 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/LookupElementsCollector.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/LookupElementsCollector.kt @@ -68,23 +68,26 @@ class LookupElementsCollector( postProcessors.add(processor) } - fun addDescriptorElements(descriptors: Iterable, - lookupElementFactory: AbstractLookupElementFactory, - notImported: Boolean = false, - withReceiverCast: Boolean = false + fun addDescriptorElements( + descriptors: Iterable, + lookupElementFactory: AbstractLookupElementFactory, + notImported: Boolean = false, + withReceiverCast: Boolean = false, + prohibitDuplicates: Boolean = false ) { for (descriptor in descriptors) { - addDescriptorElements(descriptor, lookupElementFactory, notImported, withReceiverCast) + addDescriptorElements(descriptor, lookupElementFactory, notImported, withReceiverCast, prohibitDuplicates) } } fun addDescriptorElements( - descriptor: DeclarationDescriptor, - lookupElementFactory: AbstractLookupElementFactory, - notImported: Boolean = false, - withReceiverCast: Boolean = false + descriptor: DeclarationDescriptor, + lookupElementFactory: AbstractLookupElementFactory, + notImported: Boolean = false, + withReceiverCast: Boolean = false, + prohibitDuplicates: Boolean = false ) { - if (descriptor is CallableDescriptor && descriptor in processedCallables) return + if (prohibitDuplicates && descriptor is CallableDescriptor && descriptor in processedCallables) return var lookupElements = lookupElementFactory.createStandardLookupElementsForDescriptor(descriptor, useReceiverTypes = true) @@ -94,7 +97,7 @@ class LookupElementsCollector( addElements(lookupElements, notImported) - if (descriptor is CallableDescriptor) processedCallables.add(descriptor) + if (prohibitDuplicates && descriptor is CallableDescriptor) processedCallables.add(descriptor) } fun addElement(element: LookupElement, notImported: Boolean = false) {