From 446dcfbbda5dc20ca00df8313343a31339fa067a Mon Sep 17 00:00:00 2001 From: Andrew Kozlov Date: Mon, 2 Sep 2024 20:43:33 +0200 Subject: [PATCH] [kotlin] KTIJ-26747 smooth refactoring GitOrigin-RevId: ea2aec3ef2f715d687bf9496aa3c150db93951be --- .../FirCallableCompletionContributor.kt | 64 ++++++++++--------- .../helpers/ShadowedCallablesFilter.kt | 12 ++-- 2 files changed, 40 insertions(+), 36 deletions(-) diff --git a/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/contributors/FirCallableCompletionContributor.kt b/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/contributors/FirCallableCompletionContributor.kt index ee0d98d8cf30..59c51cc910b9 100644 --- a/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/contributors/FirCallableCompletionContributor.kt +++ b/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/contributors/FirCallableCompletionContributor.kt @@ -145,7 +145,7 @@ internal open class FirCallableCompletionContributor( } .filterIfInsideAnnotationEntryArgument(positionContext.position, weighingContext.expectedType) .filterOutShadowedCallables(weighingContext.expectedType) - .filterOutUninitializedCallables(positionContext.position) + .filterNot(isUninitializedCallable(positionContext.position)) for (callableWithMetadata in callablesWithMetadata) { addCallableSymbolToCompletion( @@ -520,43 +520,49 @@ internal open class FirCallableCompletionContributor( explicitReceiverTypeHint: KaType? = null, ) = CallableWithMetadataForCompletion(signature, explicitReceiverTypeHint, options, symbolOrigin) - context(KaSession) - private fun Sequence.filterOutUninitializedCallables( - position: PsiElement - ): Sequence { - val uninitializedCallablesForPosition = collectUninitializedCallablesForPosition(position) - return filterNot { it.signature.symbol.psi in uninitializedCallablesForPosition } - } + private fun isUninitializedCallable( + position: PsiElement, + ): (CallableWithMetadataForCompletion) -> Boolean { + val uninitializedCallablesForPosition = buildSet { + for (parent in position.parents(withSelf = false)) { + when (val grandParent = parent.parent) { + is KtParameter -> { + if (grandParent.defaultValue == parent) { + // Filter out the current parameter and all parameters initialized after the current one. + // In the following example: + // ``` + // fun test(a, b: Int = , c: Int) {} + // ``` + // `a` and `b` should not show up in completion. + val originalOrSelf = getOriginalDeclarationOrSelf( + declaration = grandParent, + originalKtFile = basicContext.originalKtFile, + ) + generateSequence(originalOrSelf) { it.nextSiblingOfSameType() } + .forEach(::add) + } + } - context(KaSession) - private fun collectUninitializedCallablesForPosition(position: PsiElement): Set = buildSet { - for (parent in position.parents(withSelf = false)) { - when (val grandParent = parent.parent) { - is KtParameter -> { - if (grandParent.defaultValue == parent) { - // Filter out current parameter and all parameters initialized after current parameter. In the following example: - // ``` - // fun test(a, b: Int = , c: Int) {} - // ``` - // `a` and `b` should not show up in completion. - val originalOrSelf = getOriginalDeclarationOrSelf(grandParent, basicContext.originalKtFile) - originalOrSelf.getNextParametersWithSelf().forEach { add(it) } + is KtProperty -> { + if (grandParent.initializer == parent) { + val declaration = getOriginalDeclarationOrSelf( + declaration = grandParent, + originalKtFile = basicContext.originalKtFile, + ) + add(declaration) + } } } - is KtProperty -> { - if (grandParent.initializer == parent) { - add(getOriginalDeclarationOrSelf(grandParent, basicContext.originalKtFile)) - } - } + if (parent is KtDeclaration) break // we can use variable inside lambda or anonymous object located in its initializer } + } - if (parent is KtDeclaration) break // we can use variable inside lambda or anonymous object located in its initializer + return { callable: CallableWithMetadataForCompletion -> + callable.signature.symbol.psi in uninitializedCallablesForPosition } } - private fun KtParameter.getNextParametersWithSelf(): Sequence = generateSequence({ this }, { it.nextSiblingOfSameType() }) - context(KaSession) private fun Sequence.filterOutShadowedCallables( expectedType: KaType?, diff --git a/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/contributors/helpers/ShadowedCallablesFilter.kt b/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/contributors/helpers/ShadowedCallablesFilter.kt index 382249a4947b..c45eb1e4dca4 100644 --- a/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/contributors/helpers/ShadowedCallablesFilter.kt +++ b/plugins/kotlin/completion/impl-k2/src/org/jetbrains/kotlin/idea/completion/impl/k2/contributors/helpers/ShadowedCallablesFilter.kt @@ -45,15 +45,13 @@ internal class ShadowedCallablesFilter { typeArgumentsAreRequired: Boolean, ): FilterResult { // there is no need to create simplified signature if `KaCallableSignature<*>` is already processed - if (callable in processedSignatures) return FilterResult(excludeFromCompletion = true, options) - processedSignatures.add(callable) - - val importingStrategy = options.importingStrategy - val updatedImportingStrategy = ImportStrategy.DoNothing + if (!processedSignatures.add(callable)) return FilterResult(excludeFromCompletion = true, options) // if callable is already imported, try updating importing strategy - if ((isAlreadyImported || symbolOrigin is CompletionSymbolOrigin.Scope) && importingStrategy != updatedImportingStrategy) { - val updatedOptions = options.withImportingStrategy(updatedImportingStrategy) + if ((isAlreadyImported || symbolOrigin is CompletionSymbolOrigin.Scope) + && options.importingStrategy != ImportStrategy.DoNothing + ) { + val updatedOptions = options.withImportingStrategy(ImportStrategy.DoNothing) val excludeFromCompletion = processSignatureConsideringOptions(callable, updatedOptions, symbolOrigin, typeArgumentsAreRequired) if (!excludeFromCompletion) { return FilterResult(excludeFromCompletion, updatedOptions)