KT-33903: consider imports from objects when removing descriptors duplicates

- `ImportedFromObjectCallableDescriptor` and descriptors in general do
not have consistent `equals`,  which leads to duplication in completion
when multiple functions from objects are imported, or when function is
visible in some scope both implicitly and by import (see KT33903_1.kt)
- ^KT-33903 Fixed
This commit is contained in:
Roman Golyshev
2019-09-20 19:23:44 +03:00
committed by Roman Golyshev
parent cdebd6bc05
commit 0239229dfc
5 changed files with 52 additions and 2 deletions
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.descriptors.MemberDescriptor
import org.jetbrains.kotlin.idea.completion.handlers.WithExpressionPrefixInsertHandler
import org.jetbrains.kotlin.idea.completion.handlers.WithTailInsertHandler
import org.jetbrains.kotlin.idea.core.completion.DeclarationLookupObject
import org.jetbrains.kotlin.resolve.ImportedFromObjectCallableDescriptor
import java.util.*
import kotlin.math.max
@@ -90,7 +91,7 @@ class LookupElementsCollector(
withReceiverCast: Boolean = false,
prohibitDuplicates: Boolean = false
) {
if (prohibitDuplicates && descriptor is CallableDescriptor && descriptor in processedCallables) return
if (prohibitDuplicates && descriptor is CallableDescriptor && unwrapIfImportedFromObject(descriptor) in processedCallables) return
var lookupElements = lookupElementFactory.createStandardLookupElementsForDescriptor(descriptor, useReceiverTypes = true)
@@ -100,7 +101,7 @@ class LookupElementsCollector(
addElements(lookupElements, notImported)
if (prohibitDuplicates && descriptor is CallableDescriptor) processedCallables.add(descriptor)
if (prohibitDuplicates && descriptor is CallableDescriptor) processedCallables.add(unwrapIfImportedFromObject(descriptor))
}
fun addElement(element: LookupElement, notImported: Boolean = false) {
@@ -176,3 +177,6 @@ class LookupElementsCollector(
resultSet.restartCompletionOnPrefixChange(prefixCondition)
}
}
private fun unwrapIfImportedFromObject(descriptor: CallableDescriptor): CallableDescriptor =
if (descriptor is ImportedFromObjectCallableDescriptor<*>) descriptor.callableFromObject else descriptor
+13
View File
@@ -0,0 +1,13 @@
import Obj.foo
import Obj.foo
object Obj {
fun Any.foo() {}
fun usage() {
Any().foo<caret>
}
}
// EXIST: foo
// NUMBER: 1
+13
View File
@@ -0,0 +1,13 @@
import Obj.foo
import Obj.foo
object Obj {
fun Any.foo() {}
}
fun usage() {
Any().foo<caret>
}
// EXIST: foo
// NUMBER: 1
@@ -441,6 +441,16 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes
runTest("idea/idea-completion/testData/basic/common/KT13780_1.kt");
}
@TestMetadata("KT33903_1.kt")
public void testKT33903_1() throws Exception {
runTest("idea/idea-completion/testData/basic/common/KT33903_1.kt");
}
@TestMetadata("KT33903_2.kt")
public void testKT33903_2() throws Exception {
runTest("idea/idea-completion/testData/basic/common/KT33903_2.kt");
}
@TestMetadata("LocalMultideclarationValues.kt")
public void testLocalMultideclarationValues() throws Exception {
runTest("idea/idea-completion/testData/basic/common/LocalMultideclarationValues.kt");
@@ -441,6 +441,16 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT
runTest("idea/idea-completion/testData/basic/common/KT13780_1.kt");
}
@TestMetadata("KT33903_1.kt")
public void testKT33903_1() throws Exception {
runTest("idea/idea-completion/testData/basic/common/KT33903_1.kt");
}
@TestMetadata("KT33903_2.kt")
public void testKT33903_2() throws Exception {
runTest("idea/idea-completion/testData/basic/common/KT33903_2.kt");
}
@TestMetadata("LocalMultideclarationValues.kt")
public void testLocalMultideclarationValues() throws Exception {
runTest("idea/idea-completion/testData/basic/common/LocalMultideclarationValues.kt");