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,
|
moduleDescriptor: ModuleDescriptor,
|
||||||
resolutionFacade: ResolutionFacade,
|
resolutionFacade: ResolutionFacade,
|
||||||
stableSmartCastsOnly: Boolean
|
stableSmartCastsOnly: Boolean
|
||||||
): Collection<KotlinType>? {
|
): List<KotlinType>? {
|
||||||
return receiverTypesWithIndex(bindingContext, contextElement, moduleDescriptor, resolutionFacade, stableSmartCastsOnly)?.map { it.type }
|
return receiverTypesWithIndex(bindingContext, contextElement, moduleDescriptor, resolutionFacade, stableSmartCastsOnly)?.map { it.type }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,7 +260,7 @@ fun CallTypeAndReceiver<*, *>.receiverTypesWithIndex(
|
|||||||
resolutionFacade: ResolutionFacade,
|
resolutionFacade: ResolutionFacade,
|
||||||
stableSmartCastsOnly: Boolean,
|
stableSmartCastsOnly: Boolean,
|
||||||
withImplicitReceiversWhenExplicitPresent: Boolean = false
|
withImplicitReceiversWhenExplicitPresent: Boolean = false
|
||||||
): Collection<ReceiverType>? {
|
): List<ReceiverType>? {
|
||||||
val languageVersionSettings = resolutionFacade.frontendService<LanguageVersionSettings>()
|
val languageVersionSettings = resolutionFacade.frontendService<LanguageVersionSettings>()
|
||||||
|
|
||||||
val receiverExpression: KtExpression?
|
val receiverExpression: KtExpression?
|
||||||
|
|||||||
@@ -417,7 +417,7 @@ abstract class CompletionSession(
|
|||||||
bindingContext: BindingContext,
|
bindingContext: BindingContext,
|
||||||
nameExpression: KtSimpleNameExpression,
|
nameExpression: KtSimpleNameExpression,
|
||||||
callTypeAndReceiver: CallTypeAndReceiver<*, *>
|
callTypeAndReceiver: CallTypeAndReceiver<*, *>
|
||||||
): Collection<ReceiverType>? {
|
): List<ReceiverType>? {
|
||||||
var receiverTypes = callTypeAndReceiver.receiverTypesWithIndex(
|
var receiverTypes = callTypeAndReceiver.receiverTypesWithIndex(
|
||||||
bindingContext, nameExpression, moduleDescriptor, resolutionFacade,
|
bindingContext, nameExpression, moduleDescriptor, resolutionFacade,
|
||||||
stableSmartCastsOnly = true, /* we don't include smart cast receiver types for "unstable" receiver value to mark members grayed */
|
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.idea.util.ReceiverType
|
||||||
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.collectAnnotationEntriesFromStubOrPsi
|
import org.jetbrains.kotlin.psi.psiUtil.collectAnnotationEntriesFromStubOrPsi
|
||||||
import org.jetbrains.kotlin.resolve.calls.DslMarkerUtils
|
|
||||||
|
|
||||||
class DslMembersCompletion(
|
class DslMembersCompletion(
|
||||||
private val prefixMatcher: PrefixMatcher,
|
private val prefixMatcher: PrefixMatcher,
|
||||||
private val elementFactory: LookupElementFactory,
|
private val elementFactory: LookupElementFactory,
|
||||||
receiverTypes: Collection<ReceiverType>?,
|
receiverTypes: List<ReceiverType>?,
|
||||||
private val collector: LookupElementsCollector,
|
private val collector: LookupElementsCollector,
|
||||||
private val indicesHelper: KotlinIndicesHelper,
|
private val indicesHelper: KotlinIndicesHelper,
|
||||||
private val callTypeAndReceiver: CallTypeAndReceiver<*, *>
|
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()
|
private val nearestReceiverMarkers = nearestReceiver?.takeIf { it.implicit }?.extractDslMarkers().orEmpty()
|
||||||
|
|
||||||
fun completeDslFunctions() {
|
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");
|
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")
|
@TestMetadata("root.kt")
|
||||||
public void testRoot() throws Exception {
|
public void testRoot() throws Exception {
|
||||||
runTest("idea/idea-completion/testData/basic/common/dslMarker/root.kt");
|
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");
|
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")
|
@TestMetadata("root.kt")
|
||||||
public void testRoot() throws Exception {
|
public void testRoot() throws Exception {
|
||||||
runTest("idea/idea-completion/testData/basic/common/dslMarker/root.kt");
|
runTest("idea/idea-completion/testData/basic/common/dslMarker/root.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user