diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/ShadowedDeclarationsFilter.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/ShadowedDeclarationsFilter.kt index 7d1d6647b4e..7176e55b231 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/ShadowedDeclarationsFilter.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/ShadowedDeclarationsFilter.kt @@ -19,6 +19,8 @@ package org.jetbrains.kotlin.idea.util import com.intellij.openapi.project.Project import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.di.InjectorForMacros +import org.jetbrains.kotlin.idea.imports.importableFqName +import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DelegatingBindingTrace @@ -34,7 +36,8 @@ import org.jetbrains.kotlin.resolve.scopes.ChainedScope import org.jetbrains.kotlin.resolve.scopes.ExplicitImportsScope import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator import org.jetbrains.kotlin.types.TypeUtils -import java.util.* +import java.util.ArrayList +import java.util.HashSet public class ShadowedDeclarationsFilter( private val bindingContext: BindingContext, @@ -64,7 +67,7 @@ public class ShadowedDeclarationsFilter( val call = expression.getCall(bindingContext) ?: return nonImportedDeclarations val notShadowed = nonImportedDeclarations - .groupBy { signature(it) } + .groupBy { signature(it) to packageName(it) } // same signature non-imported declarations from different packages do not shadow each other .values() .flatMapTo(HashSet()) { group -> filterEqualSignatureGroup(group + importedDeclarations, call, descriptorsToImport = group) @@ -80,6 +83,8 @@ public class ShadowedDeclarationsFilter( } } + private fun packageName(descriptor: DeclarationDescriptor) = descriptor.importableFqName?.parent() + private fun filterEqualSignatureGroup( descriptors: Collection, call: Call, diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionSession.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionSession.kt index 24b04f0cefe..199f55b42cf 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionSession.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionSession.kt @@ -225,7 +225,6 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess protected fun getTopLevelExtensions(): Collection { val extensions = indicesHelper.getCallableTopLevelExtensions({ prefixMatcher.prefixMatches(it) }, reference!!.expression) - //TODO: it filters out too much return ShadowedDeclarationsFilter(bindingContext, moduleDescriptor, project).filterNonImported(extensions, referenceVariants, reference.expression) } diff --git a/idea/idea-completion/testData/basic/multifile/MoreSpecificExtensionInDifferentPackage/MoreSpecificExtensionInDifferentPackage.kt b/idea/idea-completion/testData/basic/multifile/MoreSpecificExtensionInDifferentPackage/MoreSpecificExtensionInDifferentPackage.kt new file mode 100644 index 00000000000..3ce4973cefd --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/MoreSpecificExtensionInDifferentPackage/MoreSpecificExtensionInDifferentPackage.kt @@ -0,0 +1,11 @@ +package ppp + +class C { + fun foo() { + xx + } +} + +// EXIST: { lookupString: "xxx", itemText: "xxx", tailText: "() for Any in dependency1", typeText: "Int" } +// EXIST: { lookupString: "xxx", itemText: "xxx", tailText: "() for C in dependency2", typeText: "Int" } +// NOTHING_ELSE diff --git a/idea/idea-completion/testData/basic/multifile/MoreSpecificExtensionInDifferentPackage/MoreSpecificExtensionInDifferentPackage2.dependency1.kt b/idea/idea-completion/testData/basic/multifile/MoreSpecificExtensionInDifferentPackage/MoreSpecificExtensionInDifferentPackage2.dependency1.kt new file mode 100644 index 00000000000..87e37403a89 --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/MoreSpecificExtensionInDifferentPackage/MoreSpecificExtensionInDifferentPackage2.dependency1.kt @@ -0,0 +1,3 @@ +package dependency1 + +fun Any.xxx(): Int = 1 diff --git a/idea/idea-completion/testData/basic/multifile/MoreSpecificExtensionInDifferentPackage/MoreSpecificExtensionInDifferentPackage2.dependency2.kt b/idea/idea-completion/testData/basic/multifile/MoreSpecificExtensionInDifferentPackage/MoreSpecificExtensionInDifferentPackage2.dependency2.kt new file mode 100644 index 00000000000..fedbe04b2ca --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/MoreSpecificExtensionInDifferentPackage/MoreSpecificExtensionInDifferentPackage2.dependency2.kt @@ -0,0 +1,3 @@ +package dependency2 + +fun ppp.C.xxx(): Int = 1 diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/MultiFileJvmBasicCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/MultiFileJvmBasicCompletionTestGenerated.java index 0881e552f59..b8b20b345bc 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/MultiFileJvmBasicCompletionTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/MultiFileJvmBasicCompletionTestGenerated.java @@ -113,6 +113,12 @@ public class MultiFileJvmBasicCompletionTestGenerated extends AbstractMultiFileJ doTest(fileName); } + @TestMetadata("MoreSpecificExtensionInDifferentPackage") + public void testMoreSpecificExtensionInDifferentPackage() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/MoreSpecificExtensionInDifferentPackage/"); + doTest(fileName); + } + @TestMetadata("MoreSpecificExtensionIsPrivate") public void testMoreSpecificExtensionIsPrivate() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/MoreSpecificExtensionIsPrivate/");