KT-30996: Use the last receiver to complete dsl methods
- change `detectReceiverTypes` return type to `List` instead of `Collection` - it reflects that receiver types are actually ordered - did not propagate signature changes to all possible places because it creates too much noise in git history - ^KT-30996 Fixed
This commit is contained in:
committed by
Roman Golyshev
parent
b2d2ba5811
commit
b422485440
@@ -249,7 +249,7 @@ fun CallTypeAndReceiver<*, *>.receiverTypes(
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
resolutionFacade: ResolutionFacade,
|
||||
stableSmartCastsOnly: Boolean
|
||||
): Collection<KotlinType>? {
|
||||
): List<KotlinType>? {
|
||||
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<ReceiverType>? {
|
||||
): List<ReceiverType>? {
|
||||
val languageVersionSettings = resolutionFacade.frontendService<LanguageVersionSettings>()
|
||||
|
||||
val receiverExpression: KtExpression?
|
||||
|
||||
@@ -417,7 +417,7 @@ abstract class CompletionSession(
|
||||
bindingContext: BindingContext,
|
||||
nameExpression: KtSimpleNameExpression,
|
||||
callTypeAndReceiver: CallTypeAndReceiver<*, *>
|
||||
): Collection<ReceiverType>? {
|
||||
): List<ReceiverType>? {
|
||||
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 */
|
||||
|
||||
+9
-3
@@ -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<ReceiverType>?,
|
||||
receiverTypes: List<ReceiverType>?,
|
||||
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() {
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
@DslMarker
|
||||
annotation class MyDSL
|
||||
|
||||
@MyDSL
|
||||
class HTML
|
||||
|
||||
@MyDSL
|
||||
fun HTML.foo() { }
|
||||
|
||||
fun HTML.test() {
|
||||
val x = 1
|
||||
x.<caret>
|
||||
}
|
||||
|
||||
// ABSENT: foo
|
||||
+5
@@ -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");
|
||||
|
||||
+5
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user