Fixed filtering of shadowed declarations after changes in extensions treatment
This commit is contained in:
+20
-12
@@ -58,10 +58,11 @@ class ReferenceVariantsHelper(
|
||||
kindFilter: DescriptorKindFilter,
|
||||
nameFilter: (Name) -> Boolean,
|
||||
filterOutJavaGettersAndSetters: Boolean = false,
|
||||
filterOutShadowed: Boolean = true,
|
||||
useRuntimeReceiverType: Boolean = false
|
||||
): Collection<DeclarationDescriptor>
|
||||
= getReferenceVariants(expression, CallTypeAndReceiver.detect(expression),
|
||||
kindFilter, nameFilter, filterOutJavaGettersAndSetters, useRuntimeReceiverType)
|
||||
kindFilter, nameFilter, filterOutJavaGettersAndSetters, filterOutShadowed, useRuntimeReceiverType)
|
||||
|
||||
fun getReferenceVariants(
|
||||
contextElement: PsiElement,
|
||||
@@ -69,32 +70,39 @@ class ReferenceVariantsHelper(
|
||||
kindFilter: DescriptorKindFilter,
|
||||
nameFilter: (Name) -> Boolean,
|
||||
filterOutJavaGettersAndSetters: Boolean = false,
|
||||
filterOutShadowed: Boolean = true,
|
||||
useRuntimeReceiverType: Boolean = false
|
||||
): Collection<DeclarationDescriptor> {
|
||||
var variants: Collection<DeclarationDescriptor>
|
||||
= getReferenceVariantsNoVisibilityFilter(contextElement, kindFilter, nameFilter, callTypeAndReceiver, useRuntimeReceiverType)
|
||||
.filter { !it.isAnnotatedAsHidden() && visibilityFilter(it) }
|
||||
|
||||
ShadowedDeclarationsFilter.create(bindingContext, resolutionFacade, contextElement, callTypeAndReceiver)?.let {
|
||||
variants = it.filter(variants)
|
||||
if (filterOutShadowed) {
|
||||
ShadowedDeclarationsFilter.create(bindingContext, resolutionFacade, contextElement, callTypeAndReceiver)?.let {
|
||||
variants = it.filter(variants)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (filterOutJavaGettersAndSetters) {
|
||||
val accessorMethodsToRemove = HashSet<FunctionDescriptor>()
|
||||
for (variant in variants) {
|
||||
if (variant is SyntheticJavaPropertyDescriptor) {
|
||||
accessorMethodsToRemove.add(variant.getMethod.original)
|
||||
accessorMethodsToRemove.addIfNotNull(variant.setMethod?.original)
|
||||
}
|
||||
}
|
||||
|
||||
variants = variants.filter { it !is FunctionDescriptor || it.original !in accessorMethodsToRemove }
|
||||
variants = filterOutJavaGettersAndSetters(variants)
|
||||
}
|
||||
|
||||
return variants
|
||||
}
|
||||
|
||||
fun filterOutJavaGettersAndSetters(variants: Collection<DeclarationDescriptor>): Collection<DeclarationDescriptor> {
|
||||
val accessorMethodsToRemove = HashSet<FunctionDescriptor>()
|
||||
for (variant in variants) {
|
||||
if (variant is SyntheticJavaPropertyDescriptor) {
|
||||
accessorMethodsToRemove.add(variant.getMethod.original)
|
||||
accessorMethodsToRemove.addIfNotNull(variant.setMethod?.original)
|
||||
}
|
||||
}
|
||||
|
||||
return variants.filter { it !is FunctionDescriptor || it.original !in accessorMethodsToRemove }
|
||||
}
|
||||
|
||||
private fun getReferenceVariantsNoVisibilityFilter(
|
||||
contextElement: PsiElement,
|
||||
kindFilter: DescriptorKindFilter,
|
||||
|
||||
+6
-9
@@ -209,7 +209,11 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
collector.addElements(additionalItems)
|
||||
}
|
||||
|
||||
collector.addDescriptorElements(referenceVariants)
|
||||
referenceVariants?.let {
|
||||
val (imported, notImported) = it
|
||||
collector.addDescriptorElements(imported)
|
||||
collector.addDescriptorElements(notImported, notImported = true)
|
||||
}
|
||||
|
||||
completeKeywords()
|
||||
|
||||
@@ -233,13 +237,6 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
|
||||
flushToResultSet()
|
||||
|
||||
if (completionKind == CompletionKind.ALL && callTypeAndReceiver.shouldCompleteCallableExtensions()) {
|
||||
for (extension in getCallableTopLevelExtensions()) {
|
||||
collector.addDescriptorElements(extension, !isImportableDescriptorImported(extension))
|
||||
}
|
||||
flushToResultSet()
|
||||
}
|
||||
|
||||
if (completionKind != CompletionKind.KEYWORDS_ONLY) {
|
||||
completeNonImported()
|
||||
|
||||
@@ -411,7 +408,7 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
}
|
||||
|
||||
if (callTypeAndReceiver.receiver != null) {
|
||||
val referenceVariantsSet = referenceVariants.toSet()
|
||||
val referenceVariantsSet = referenceVariants!!.imported.toSet()
|
||||
superClasses = superClasses.filter { it in referenceVariantsSet }
|
||||
}
|
||||
|
||||
|
||||
+35
-17
@@ -260,18 +260,41 @@ abstract class CompletionSession(protected val configuration: CompletionSessionC
|
||||
return context
|
||||
}
|
||||
|
||||
protected val referenceVariants: Collection<DeclarationDescriptor> by lazy(LazyThreadSafetyMode.NONE) {
|
||||
if (descriptorKindFilter != null) {
|
||||
referenceVariantsHelper.getReferenceVariants(
|
||||
nameExpression!!,
|
||||
descriptorKindFilter!!,
|
||||
descriptorNameFilter,
|
||||
filterOutJavaGettersAndSetters = configuration.filterOutJavaGettersAndSetters
|
||||
).excludeNonInitializedVariable(nameExpression)
|
||||
/* TODO: not protected because of KT-9809 */
|
||||
data class ReferenceVariants(val imported: Collection<DeclarationDescriptor>, val notImportedExtensions: Collection<CallableDescriptor>)
|
||||
|
||||
protected val referenceVariants: ReferenceVariants? by lazy {
|
||||
if (descriptorKindFilter == null) return@lazy null
|
||||
|
||||
var variants = referenceVariantsHelper.getReferenceVariants(
|
||||
nameExpression!!,
|
||||
descriptorKindFilter!!,
|
||||
descriptorNameFilter,
|
||||
filterOutJavaGettersAndSetters = false,
|
||||
filterOutShadowed = false)
|
||||
|
||||
variants = variants.excludeNonInitializedVariable(nameExpression)
|
||||
|
||||
val shadowedDeclarationsFilter = ShadowedDeclarationsFilter.create(bindingContext, resolutionFacade, position, callTypeAndReceiver)
|
||||
|
||||
var notImportedExtensions: Collection<CallableDescriptor> = emptyList()
|
||||
if (callTypeAndReceiver.shouldCompleteCallableExtensions()) {
|
||||
val extensions = indicesHelper.getCallableTopLevelExtensions({ prefixMatcher.prefixMatches(it) }, callTypeAndReceiver, expression!!, bindingContext)
|
||||
val pair = extensions.partition { isImportableDescriptorImported(it) }
|
||||
variants += pair.first
|
||||
notImportedExtensions = pair.second
|
||||
}
|
||||
else {
|
||||
emptyList()
|
||||
|
||||
if (shadowedDeclarationsFilter != null) {
|
||||
variants = shadowedDeclarationsFilter.filter(variants)
|
||||
notImportedExtensions = shadowedDeclarationsFilter.filterNonImported(notImportedExtensions, variants)
|
||||
}
|
||||
|
||||
if (configuration.filterOutJavaGettersAndSetters) {
|
||||
variants = referenceVariantsHelper.filterOutJavaGettersAndSetters(variants)
|
||||
}
|
||||
|
||||
ReferenceVariants(variants, notImportedExtensions)
|
||||
}
|
||||
|
||||
// filters out variable inside its initializer
|
||||
@@ -296,7 +319,7 @@ abstract class CompletionSession(protected val configuration: CompletionSessionC
|
||||
filterOutJavaGettersAndSetters = configuration.filterOutJavaGettersAndSetters
|
||||
).excludeNonInitializedVariable(nameExpression)
|
||||
return descriptors.filter { descriptor ->
|
||||
referenceVariants.none { compareDescriptors(project, it, descriptor) }
|
||||
referenceVariants!!.imported.none { compareDescriptors(project, it, descriptor) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,14 +340,9 @@ abstract class CompletionSession(protected val configuration: CompletionSessionC
|
||||
&& this !is CallTypeAndReceiver.IMPORT_DIRECTIVE
|
||||
}
|
||||
|
||||
protected fun getCallableTopLevelExtensions(): Collection<CallableDescriptor> {
|
||||
return indicesHelper.getCallableTopLevelExtensions({ prefixMatcher.prefixMatches(it) }, callTypeAndReceiver, expression!!, bindingContext)
|
||||
.filterShadowedNonImported() //TODO: not correct!
|
||||
}
|
||||
|
||||
private fun Collection<CallableDescriptor>.filterShadowedNonImported(): Collection<CallableDescriptor> {
|
||||
val filter = ShadowedDeclarationsFilter.create(bindingContext, resolutionFacade, nameExpression!!, callTypeAndReceiver)
|
||||
return if (filter != null) filter.filterNonImported(this, referenceVariants) else this
|
||||
return if (filter != null) filter.filterNonImported(this, referenceVariants!!.imported) else this
|
||||
}
|
||||
|
||||
protected fun addClassesFromIndex(kindFilter: (ClassKind) -> Boolean) {
|
||||
|
||||
+3
-11
@@ -73,17 +73,9 @@ class SmartCompletionSession(configuration: CompletionSessionConfiguration, para
|
||||
if (nameExpression != null) {
|
||||
val filter = smartCompletion!!.descriptorFilter
|
||||
if (filter != null) {
|
||||
referenceVariants.forEach { collector.addElements(filter(it)) }
|
||||
flushToResultSet()
|
||||
|
||||
if (callTypeAndReceiver.shouldCompleteCallableExtensions()) {
|
||||
for (extension in getCallableTopLevelExtensions()) {
|
||||
val elements = filter(extension)
|
||||
if (elements.isNotEmpty()) {
|
||||
collector.addElements(elements, !isImportableDescriptorImported(extension))
|
||||
}
|
||||
}
|
||||
}
|
||||
val (imported, notImported) = referenceVariants!!
|
||||
imported.forEach { collector.addElements(filter(it)) }
|
||||
notImported.forEach { collector.addElements(filter(it), notImported = true) }
|
||||
|
||||
flushToResultSet()
|
||||
|
||||
|
||||
+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
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package ppp
|
||||
|
||||
import dependency1.xxx
|
||||
import dependency2.xxx
|
||||
|
||||
interface I
|
||||
|
||||
fun I.xxx() {}
|
||||
|
||||
class C : I {
|
||||
fun foo() {
|
||||
xx<caret>
|
||||
}
|
||||
}
|
||||
|
||||
// EXIST: { lookupString: "xxx", itemText: "xxx", tailText: "() for C in dependency2", typeText: "Int" }
|
||||
// NOTHING_ELSE
|
||||
+6
@@ -311,6 +311,12 @@ public class MultiFileJvmBasicCompletionTestGenerated extends AbstractMultiFileJ
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("PreferMoreSpecificExtension3")
|
||||
public void testPreferMoreSpecificExtension3() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/PreferMoreSpecificExtension3/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("PropertyKeysEmptyString")
|
||||
public void testPropertyKeysEmptyString() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/PropertyKeysEmptyString/");
|
||||
|
||||
Reference in New Issue
Block a user