diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/CallType.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/CallType.kt index 3d5954be548..f8b736c85c7 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/CallType.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/CallType.kt @@ -249,7 +249,7 @@ fun CallTypeAndReceiver<*, *>.receiverTypes( moduleDescriptor: ModuleDescriptor, resolutionFacade: ResolutionFacade, stableSmartCastsOnly: Boolean -): Collection? { +): List? { return receiverTypesWithIndex(bindingContext, contextElement, moduleDescriptor, resolutionFacade, stableSmartCastsOnly)?.map { it.type } } @@ -260,7 +260,7 @@ fun CallTypeAndReceiver<*, *>.receiverTypesWithIndex( resolutionFacade: ResolutionFacade, stableSmartCastsOnly: Boolean, withImplicitReceiversWhenExplicitPresent: Boolean = false -): Collection? { +): List? { val languageVersionSettings = resolutionFacade.frontendService() val receiverExpression: KtExpression? 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 48e874264bd..5bfb93e7698 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 @@ -417,7 +417,7 @@ abstract class CompletionSession( bindingContext: BindingContext, nameExpression: KtSimpleNameExpression, callTypeAndReceiver: CallTypeAndReceiver<*, *> - ): Collection? { + ): List? { var receiverTypes = callTypeAndReceiver.receiverTypesWithIndex( bindingContext, nameExpression, moduleDescriptor, resolutionFacade, stableSmartCastsOnly = true, /* we don't include smart cast receiver types for "unstable" receiver value to mark members grayed */ 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 54b39cf4ffa..6666123362c 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 @@ -11,17 +11,23 @@ import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver import org.jetbrains.kotlin.idea.util.ReceiverType import org.jetbrains.kotlin.psi.KtModifierListOwner import org.jetbrains.kotlin.psi.psiUtil.collectAnnotationEntriesFromStubOrPsi -import org.jetbrains.kotlin.resolve.calls.DslMarkerUtils class DslMembersCompletion( private val prefixMatcher: PrefixMatcher, private val elementFactory: LookupElementFactory, - receiverTypes: Collection?, + receiverTypes: List?, private val collector: LookupElementsCollector, private val indicesHelper: KotlinIndicesHelper, private val callTypeAndReceiver: CallTypeAndReceiver<*, *> ) { - private val nearestReceiver = receiverTypes?.firstOrNull() + /** + * It is stated that `two implicit receivers of the same DSL are not accessible in the same scope`, + * that's why we need only the last one of the receivers to provide the completion (see [DslMarker]). + * + * When the last receiver is not a part of DSL, [nearestReceiverMarkers] will be empty, and dsl + * members would not be suggested in the autocompletion (see KT-30996). + */ + private val nearestReceiver = receiverTypes?.lastOrNull() private val nearestReceiverMarkers = nearestReceiver?.takeIf { it.implicit }?.extractDslMarkers().orEmpty() fun completeDslFunctions() { diff --git a/idea/idea-completion/testData/basic/common/dslMarker/noDslCompletionForNonDslReciever.kt b/idea/idea-completion/testData/basic/common/dslMarker/noDslCompletionForNonDslReciever.kt new file mode 100644 index 00000000000..2c76b9419e2 --- /dev/null +++ b/idea/idea-completion/testData/basic/common/dslMarker/noDslCompletionForNonDslReciever.kt @@ -0,0 +1,15 @@ +@DslMarker +annotation class MyDSL + +@MyDSL +class HTML + +@MyDSL +fun HTML.foo() { } + +fun HTML.test() { + val x = 1 + x. +} + +// ABSENT: foo \ No newline at end of file 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 eb3686176f3..1b032af05bc 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 @@ -1175,6 +1175,11 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes runTest("idea/idea-completion/testData/basic/common/dslMarker/container.kt"); } + @TestMetadata("noDslCompletionForNonDslReciever.kt") + public void testNoDslCompletionForNonDslReciever() throws Exception { + runTest("idea/idea-completion/testData/basic/common/dslMarker/noDslCompletionForNonDslReciever.kt"); + } + @TestMetadata("root.kt") public void testRoot() throws Exception { runTest("idea/idea-completion/testData/basic/common/dslMarker/root.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 513617c9b9a..9b67f4f2669 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 @@ -1175,6 +1175,11 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT runTest("idea/idea-completion/testData/basic/common/dslMarker/container.kt"); } + @TestMetadata("noDslCompletionForNonDslReciever.kt") + public void testNoDslCompletionForNonDslReciever() throws Exception { + runTest("idea/idea-completion/testData/basic/common/dslMarker/noDslCompletionForNonDslReciever.kt"); + } + @TestMetadata("root.kt") public void testRoot() throws Exception { runTest("idea/idea-completion/testData/basic/common/dslMarker/root.kt");