From a6aea5625a4cbdd904ea9848686f1949ed0cadf5 Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Tue, 27 Feb 2018 18:27:52 +0100 Subject: [PATCH] Dsl completion: fix completion when multiple receivers are in scope --- .../idea/completion/DslMembersCompletion.kt | 9 ++-- .../DslCallsWithMultipleReceivers.Data1.kt | 8 ++++ .../basic/DslCallsWithMultipleReceivers.kt | 41 +++++++++++++++++++ .../BasicCompletionWeigherTestGenerated.java | 6 +++ 4 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 idea/idea-completion/testData/weighers/basic/DslCallsWithMultipleReceivers.Data1.kt create mode 100644 idea/idea-completion/testData/weighers/basic/DslCallsWithMultipleReceivers.kt diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/DslMembersCompletion.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/DslMembersCompletion.kt index 9be7a104ce7..bfa535c51e6 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/DslMembersCompletion.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/DslMembersCompletion.kt @@ -23,7 +23,7 @@ class DslMembersCompletion( private val indicesHelper: KotlinIndicesHelper, private val callTypeAndReceiver: CallTypeAndReceiver<*, *> ) { - private val nearestReceiver = receiverTypes?.lastOrNull() + private val nearestReceiver = receiverTypes?.firstOrNull() private val nearestReceiverMarkers = nearestReceiver?.takeIf { it.implicit } ?.let { DslMarkerUtils.extractDslMarkerFqNames(it.type) }.orEmpty() @@ -55,7 +55,7 @@ class DslMembersCompletion( if (nearestReceiver == null || nearestReceiverMarkers.isEmpty()) return val receiverMarkersShortNames = nearestReceiverMarkers.map { it.shortName() }.distinct() - indicesHelper.getCallableTopLevelExtensions( + val extensionDescriptors = indicesHelper.getCallableTopLevelExtensions( nameFilter = { prefixMatcher.prefixMatches(it) }, declarationFilter = { (it as KtModifierListOwner).modifierList?.collectAnnotationEntriesFromStubOrPsi()?.any { it.shortName in receiverMarkersShortNames } @@ -63,8 +63,9 @@ class DslMembersCompletion( }, callTypeAndReceiver = callTypeAndReceiver, receiverTypes = listOf(nearestReceiver.type) - ).forEach { descriptor: DeclarationDescriptor -> - collector.addDescriptorElements(descriptor, factory, notImported = true, withReceiverCast = false, prohibitDuplicates = true) + ) + extensionDescriptors.forEach { + collector.addDescriptorElements(it, factory, notImported = true, withReceiverCast = false, prohibitDuplicates = true) } collector.flushToResultSet() diff --git a/idea/idea-completion/testData/weighers/basic/DslCallsWithMultipleReceivers.Data1.kt b/idea/idea-completion/testData/weighers/basic/DslCallsWithMultipleReceivers.Data1.kt new file mode 100644 index 00000000000..66aad9b1c8d --- /dev/null +++ b/idea/idea-completion/testData/weighers/basic/DslCallsWithMultipleReceivers.Data1.kt @@ -0,0 +1,8 @@ +package dsl + +import test.Dsl +import test.R + +@Dsl +fun R.foo2() {} + diff --git a/idea/idea-completion/testData/weighers/basic/DslCallsWithMultipleReceivers.kt b/idea/idea-completion/testData/weighers/basic/DslCallsWithMultipleReceivers.kt new file mode 100644 index 00000000000..40d860f1e97 --- /dev/null +++ b/idea/idea-completion/testData/weighers/basic/DslCallsWithMultipleReceivers.kt @@ -0,0 +1,41 @@ +// RUNTIME +package test + +class HasFoo { + fun foo10() { + + } +} + +fun main() { + val foo5 = 3 + with(0) { + with("") { + with(HasFoo()) { + r { + foo + } + } + } + } +} + +@DslMarker +annotation class Dsl + + +@Dsl +class R + +fun r(body: R.() -> Unit) { + +} + +fun foo1(i: Int) { + +} + +// ORDER: foo2 +// ORDER: foo10 +// ORDER: foo1 +// ORDER: foo5 diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/weighers/BasicCompletionWeigherTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/weighers/BasicCompletionWeigherTestGenerated.java index cc37a0c0ce3..15368048de0 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/weighers/BasicCompletionWeigherTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/weighers/BasicCompletionWeigherTestGenerated.java @@ -73,6 +73,12 @@ public class BasicCompletionWeigherTestGenerated extends AbstractBasicCompletion doTest(fileName); } + @TestMetadata("DslCallsWithMultipleReceivers.kt") + public void testDslCallsWithMultipleReceivers() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/DslCallsWithMultipleReceivers.kt"); + doTest(fileName); + } + @TestMetadata("ExactMatchForKeyword.kt") public void testExactMatchForKeyword() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/ExactMatchForKeyword.kt");