diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt index dc8b369b8f8..7cd94f2b0af 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt @@ -53,20 +53,22 @@ class ReferenceVariantsHelper( expression: KtSimpleNameExpression, kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean, - filterOutJavaGettersAndSetters: Boolean = false, + filterOutJavaGettersAndSetters: Boolean = true, filterOutShadowed: Boolean = true, + excludeNonInitializedVariable: Boolean = true, useReceiverType: KotlinType? = null ): Collection = getReferenceVariants(expression, CallTypeAndReceiver.detect(expression), - kindFilter, nameFilter, filterOutJavaGettersAndSetters, filterOutShadowed, useReceiverType) + kindFilter, nameFilter, filterOutJavaGettersAndSetters, filterOutShadowed, excludeNonInitializedVariable, useReceiverType) fun getReferenceVariants( contextElement: PsiElement, callTypeAndReceiver: CallTypeAndReceiver<*, *>, kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean, - filterOutJavaGettersAndSetters: Boolean = false, + filterOutJavaGettersAndSetters: Boolean = true, filterOutShadowed: Boolean = true, + excludeNonInitializedVariable: Boolean = true, useReceiverType: KotlinType? = null ): Collection { var variants: Collection @@ -79,12 +81,13 @@ class ReferenceVariantsHelper( } } - - if (filterOutJavaGettersAndSetters) { + if (filterOutJavaGettersAndSetters && kindFilter.kindMask.and(DescriptorKindFilter.FUNCTIONS_MASK) != 0) { variants = filterOutJavaGettersAndSetters(variants) } - variants = variants.excludeNonInitializedVariable(contextElement) + if (excludeNonInitializedVariable && kindFilter.kindMask.and(DescriptorKindFilter.VARIABLES_MASK) != 0) { + variants = excludeNonInitializedVariable(variants, contextElement) + } return variants } @@ -102,16 +105,16 @@ class ReferenceVariantsHelper( } // filters out variable inside its initializer - private fun Collection.excludeNonInitializedVariable(contextElement: PsiElement): Collection { + fun excludeNonInitializedVariable(variants: Collection, contextElement: PsiElement): Collection { for (element in contextElement.parentsWithSelf) { val parent = element.parent if (parent is KtVariableDeclaration && element == parent.initializer) { val descriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, parent] - return this.filter { it != descriptor } + return variants.filter { it != descriptor } } if (element is KtDeclaration) break // we can use variable inside lambda or anonymous object located in its initializer } - return this + return variants } private fun getReferenceVariantsNoVisibilityFilter( 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 dcd630243d0..607d7e1edeb 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 @@ -172,7 +172,7 @@ class BasicCompletionSession( val contextVariableTypesForSmartCompletion = withCollectRequiredContextVariableTypes(::completeWithSmartCompletion) fun completeReferenceVariants(lookupElementFactory: LookupElementFactory) { - val (imported, notImported) = referenceVariants!! + val (imported, notImported) = referenceVariantsWithNonInitializedVarExcluded!! collector.addDescriptorElements(imported, lookupElementFactory) collector.addDescriptorElements(notImported, lookupElementFactory, notImported = true) } 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 9e4f6491c82..b2826c5e10b 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 @@ -284,6 +284,9 @@ abstract class CompletionSession(protected val configuration: CompletionSessionC if (nameExpression != null && descriptorKindFilter != null) collectReferenceVariants(descriptorKindFilter!!, nameExpression) else null } + protected val referenceVariantsWithNonInitializedVarExcluded: ReferenceVariants? by lazy { + referenceVariants?.let { ReferenceVariants(referenceVariantsHelper.excludeNonInitializedVariable(it.imported, position), it.notImportedExtensions) } + } private fun collectReferenceVariants(descriptorKindFilter: DescriptorKindFilter, nameExpression: KtSimpleNameExpression, runtimeReceiver: ExpressionReceiver? = null): ReferenceVariants { var variants = referenceVariantsHelper.getReferenceVariants( @@ -292,6 +295,7 @@ abstract class CompletionSession(protected val configuration: CompletionSessionC descriptorNameFilter, filterOutJavaGettersAndSetters = false, filterOutShadowed = false, + excludeNonInitializedVariable = false, useReceiverType = runtimeReceiver?.type) val shadowedDeclarationsFilter = if (runtimeReceiver != null) diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletionSession.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletionSession.kt index 4b7ce0b7898..d1adc3fe655 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletionSession.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletionSession.kt @@ -78,7 +78,7 @@ class SmartCompletionSession(configuration: CompletionSessionConfiguration, para val filter = smartCompletion!!.descriptorFilter var contextVariableTypesForReferenceVariants = filter?.let { withCollectRequiredContextVariableTypes { lookupElementFactory -> - val (imported, notImported) = referenceVariants ?: return@withCollectRequiredContextVariableTypes + val (imported, notImported) = referenceVariantsWithNonInitializedVarExcluded ?: return@withCollectRequiredContextVariableTypes imported.forEach { collector.addElements(filter(it, lookupElementFactory)) } notImported.forEach { collector.addElements(filter(it, lookupElementFactory), notImported = true) } } diff --git a/idea/idea-completion/testData/basic/common/shadowing/InInitializer7.kt b/idea/idea-completion/testData/basic/common/shadowing/InInitializer7.kt new file mode 100644 index 00000000000..3f0f18b5c84 --- /dev/null +++ b/idea/idea-completion/testData/basic/common/shadowing/InInitializer7.kt @@ -0,0 +1,7 @@ +val xxx: String = "" + +class C { + val xxx = x +} + +// ABSENT: xxx diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java index 15873a2d71c..cb275c5312a 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java @@ -1929,6 +1929,12 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes doTest(fileName); } + @TestMetadata("InInitializer7.kt") + public void testInInitializer7() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/InInitializer7.kt"); + doTest(fileName); + } + @TestMetadata("Locals1.kt") public void testLocals1() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/Locals1.kt"); diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmBasicCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmBasicCompletionTestGenerated.java index 6ed68194804..a0c0129552f 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmBasicCompletionTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmBasicCompletionTestGenerated.java @@ -1929,6 +1929,12 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT doTest(fileName); } + @TestMetadata("InInitializer7.kt") + public void testInInitializer7() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/InInitializer7.kt"); + doTest(fileName); + } + @TestMetadata("Locals1.kt") public void testLocals1() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/shadowing/Locals1.kt");