[kotlin] KTIJ-34299 completion should not be stopped at the chain completion contributor

GitOrigin-RevId: 207583e0559b7263b26c0caf87a8acfaf4ca9133
This commit is contained in:
Andrew Kozlov
2025-05-23 14:07:48 +02:00
committed by intellij-monorepo-bot
parent 5077a7ac5d
commit ec8def6593
7 changed files with 36 additions and 10 deletions

View File

@@ -41,6 +41,10 @@ internal class LookupElementSink(
fun withContributorClass(contributorClass: Class<FirCompletionContributor<*>>): LookupElementSink =
LookupElementSink(resultSet, parameters, groupPriority, contributorClass)
fun passResult(result: CompletionResult) {
resultSet.passResult(result)
}
fun addElement(element: LookupElement) {
decorateLookupElement(element)
?.let(resultSet::addElement)

View File

@@ -193,23 +193,30 @@ internal abstract class FirCompletionContributorBase<C : KotlinRawPositionContex
sink.runRemainingContributors(parameters.delegate) { completionResult ->
val lookupElement = completionResult.lookupElement
val (_, importStrategy) = lookupElement.`object` as? ClassifierLookupObject
?: return@runRemainingContributors
val nameToImport = when (importStrategy) {
val classifierLookupObject = lookupElement.`object` as? ClassifierLookupObject
val nameToImport = when (val importStrategy = classifierLookupObject?.importingStrategy) {
is ImportStrategy.AddImport -> importStrategy.nameToImport
is ImportStrategy.InsertFqNameAndShorten -> importStrategy.fqName
ImportStrategy.DoNothing -> null
} ?: return@runRemainingContributors
else -> null
}
if (nameToImport == null) {
sink.passResult(completionResult)
return@runRemainingContributors
}
val expression = KtPsiFactory.contextual(explicitReceiver)
.createExpression(nameToImport.render() + "." + positionContext.nameExpression.text) as KtDotQualifiedExpression
val receiverExpression = expression.receiverExpression as? KtDotQualifiedExpression
?: return@runRemainingContributors
val nameExpression = expression.selectorExpression as? KtNameReferenceExpression
?: return@runRemainingContributors
if (receiverExpression == null
|| nameExpression == null
) {
sink.passResult(completionResult)
return@runRemainingContributors
}
analyze(nameExpression) {
createLookupElements(

View File

@@ -0,0 +1,8 @@
// REGISTRY: kotlin.k2.chain.completion.enabled true
fun main() {
"".val<caret>
}
// EXIST: { lookupString: ".val", itemText: "val" }
// INVOCATION_COUNT: 0

View File

@@ -4,5 +4,6 @@ fun main() {
Collections.<caret>
}
// ABSENT: Collections
// EXIST: { lookupString: "emptyList", itemText: "Collections.emptyList", tailText: "()", typeText: "kotlin.collections.(Mutable)List<T!>" }
// INVOCATION_COUNT: 0

View File

@@ -4,5 +4,6 @@ fun main() {
DirectoryStream.<caret>
}
// ABSENT: DirectoryStream
// EXIST: { lookupString: "Filter", itemText: "DirectoryStream.Filter", tailText: "<T> (java.nio.file.DirectoryStream)" }
// INVOCATION_COUNT: 0

View File

@@ -33,6 +33,11 @@ public abstract class K2JvmBasicCompletionFullJdkTestGenerated extends AbstractK
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
@TestMetadata("ChainCompletionRemaining.kt")
public void testChainCompletionRemaining() throws Exception {
runTest("../../completion/testData/basic/fullJdk/chain/ChainCompletionRemaining.kt");
}
@TestMetadata("ChainedCallableCompletion.kt")
public void testChainedCallableCompletion() throws Exception {
runTest("../../completion/testData/basic/fullJdk/chain/ChainedCallableCompletion.kt");

View File

@@ -116,7 +116,7 @@
implementationClass="org.jetbrains.kotlin.idea.completion.KotlinFirCompletionContributor"/>
<completion.contributor language="kotlin"
order="first, after KotlinDumbCompletionContributor"
order="last, before default"
implementationClass="org.jetbrains.kotlin.idea.completion.impl.k2.KotlinChainCompletionContributor"/>
<registryKey key="kotlin.k2.chain.completion.enabled"