Non-imported extensions from different packages do not shadow each other
This commit is contained in:
@@ -19,6 +19,8 @@ package org.jetbrains.kotlin.idea.util
|
|||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.di.InjectorForMacros
|
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.psi.*
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.DelegatingBindingTrace
|
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.scopes.ExplicitImportsScope
|
||||||
import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator
|
import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
import java.util.*
|
import java.util.ArrayList
|
||||||
|
import java.util.HashSet
|
||||||
|
|
||||||
public class ShadowedDeclarationsFilter(
|
public class ShadowedDeclarationsFilter(
|
||||||
private val bindingContext: BindingContext,
|
private val bindingContext: BindingContext,
|
||||||
@@ -64,7 +67,7 @@ public class ShadowedDeclarationsFilter(
|
|||||||
val call = expression.getCall(bindingContext) ?: return nonImportedDeclarations
|
val call = expression.getCall(bindingContext) ?: return nonImportedDeclarations
|
||||||
|
|
||||||
val notShadowed = 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()
|
.values()
|
||||||
.flatMapTo(HashSet<DeclarationDescriptor>()) { group ->
|
.flatMapTo(HashSet<DeclarationDescriptor>()) { group ->
|
||||||
filterEqualSignatureGroup(group + importedDeclarations, call, descriptorsToImport = group)
|
filterEqualSignatureGroup(group + importedDeclarations, call, descriptorsToImport = group)
|
||||||
@@ -80,6 +83,8 @@ public class ShadowedDeclarationsFilter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun packageName(descriptor: DeclarationDescriptor) = descriptor.importableFqName?.parent()
|
||||||
|
|
||||||
private fun <TDescriptor : DeclarationDescriptor> filterEqualSignatureGroup(
|
private fun <TDescriptor : DeclarationDescriptor> filterEqualSignatureGroup(
|
||||||
descriptors: Collection<TDescriptor>,
|
descriptors: Collection<TDescriptor>,
|
||||||
call: Call,
|
call: Call,
|
||||||
|
|||||||
@@ -225,7 +225,6 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess
|
|||||||
|
|
||||||
protected fun getTopLevelExtensions(): Collection<CallableDescriptor> {
|
protected fun getTopLevelExtensions(): Collection<CallableDescriptor> {
|
||||||
val extensions = indicesHelper.getCallableTopLevelExtensions({ prefixMatcher.prefixMatches(it) }, reference!!.expression)
|
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)
|
return ShadowedDeclarationsFilter(bindingContext, moduleDescriptor, project).filterNonImported(extensions, referenceVariants, reference.expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
package ppp
|
||||||
|
|
||||||
|
class C {
|
||||||
|
fun foo() {
|
||||||
|
xx<caret>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package dependency1
|
||||||
|
|
||||||
|
fun Any.xxx(): Int = 1
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package dependency2
|
||||||
|
|
||||||
|
fun ppp.C.xxx(): Int = 1
|
||||||
+6
@@ -113,6 +113,12 @@ public class MultiFileJvmBasicCompletionTestGenerated extends AbstractMultiFileJ
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("MoreSpecificExtensionInDifferentPackage")
|
||||||
|
public void testMoreSpecificExtensionInDifferentPackage() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/MoreSpecificExtensionInDifferentPackage/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("MoreSpecificExtensionIsPrivate")
|
@TestMetadata("MoreSpecificExtensionIsPrivate")
|
||||||
public void testMoreSpecificExtensionIsPrivate() throws Exception {
|
public void testMoreSpecificExtensionIsPrivate() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/MoreSpecificExtensionIsPrivate/");
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/MoreSpecificExtensionIsPrivate/");
|
||||||
|
|||||||
Reference in New Issue
Block a user