Fix completing members for receivers shadowed by DslMarker
#KT-20396 Fixed
This commit is contained in:
+12
-7
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.idea.codeInsight
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
@@ -177,14 +178,18 @@ class ReferenceVariantsHelper(
|
||||
val containingDeclaration = resolutionScope.ownerDescriptor
|
||||
|
||||
val smartCastManager = resolutionFacade.frontendService<SmartCastManager>()
|
||||
val implicitReceiverTypes = resolutionScope.getImplicitReceiversWithInstance().flatMap {
|
||||
val languageVersionSettings = resolutionFacade.frontendService<LanguageVersionSettings>()
|
||||
|
||||
val implicitReceiverTypes = resolutionScope.getImplicitReceiversWithInstance(
|
||||
languageVersionSettings.supportsFeature(LanguageFeature.DslMarkersSupport)
|
||||
).flatMap {
|
||||
smartCastManager.getSmartCastVariantsWithLessSpecificExcluded(
|
||||
it.value,
|
||||
bindingContext,
|
||||
containingDeclaration,
|
||||
dataFlowInfo,
|
||||
resolutionFacade.frontendService<LanguageVersionSettings>(),
|
||||
resolutionFacade.frontendService<DataFlowValueFactory>()
|
||||
it.value,
|
||||
bindingContext,
|
||||
containingDeclaration,
|
||||
dataFlowInfo,
|
||||
languageVersionSettings,
|
||||
resolutionFacade.frontendService<DataFlowValueFactory>()
|
||||
)
|
||||
}.toSet()
|
||||
|
||||
|
||||
@@ -17,12 +17,12 @@
|
||||
package org.jetbrains.kotlin.idea.util
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.resolve.frontendService
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isImportDirectiveExpression
|
||||
@@ -306,7 +306,9 @@ fun CallTypeAndReceiver<*, *>.receiverTypesWithIndex(
|
||||
ExpressionReceiver.create(receiverExpression, receiverType, bindingContext)
|
||||
}
|
||||
|
||||
val implicitReceiverValues = resolutionScope.getImplicitReceiversWithInstance().map { it.value }
|
||||
val implicitReceiverValues = resolutionScope.getImplicitReceiversWithInstance(
|
||||
excludeShadowedByDslMarkers = languageVersionSettings.supportsFeature(LanguageFeature.DslMarkersSupport)
|
||||
).map { it.value }
|
||||
|
||||
val dataFlowInfo = bindingContext.getDataFlowInfoBefore(contextElement)
|
||||
|
||||
@@ -357,20 +359,3 @@ private fun receiverValueTypes(
|
||||
listOf(receiverValue.type)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun Collection<ReceiverType>.shadowedByDslMarkers(): Set<ReceiverType> {
|
||||
val typesByDslScopes = LinkedHashMap<FqName, MutableList<ReceiverType>>()
|
||||
|
||||
this
|
||||
.mapNotNull { receiver ->
|
||||
val dslMarkers = receiver.extractDslMarkers()
|
||||
(receiver to dslMarkers).takeIf { dslMarkers.isNotEmpty() }
|
||||
}
|
||||
.forEach { (v, dslMarkers) -> dslMarkers.forEach { typesByDslScopes.getOrPut(it, { mutableListOf() }) += v } }
|
||||
|
||||
val shadowedDslReceivers = mutableSetOf<ReceiverType>()
|
||||
typesByDslScopes.flatMapTo(shadowedDslReceivers) { (_, v) -> v.asSequence().drop(1).asIterable() }
|
||||
|
||||
return shadowedDslReceivers
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.idea.util
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtFunctionLiteral
|
||||
@@ -24,14 +25,16 @@ import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.renderer.render
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.DslMarkerUtils
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.getImplicitReceiversHierarchy
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||
import java.util.*
|
||||
import kotlin.collections.LinkedHashSet
|
||||
|
||||
fun LexicalScope.getImplicitReceiversWithInstance(): Collection<ReceiverParameterDescriptor>
|
||||
= getImplicitReceiversWithInstanceToExpression().keys
|
||||
fun LexicalScope.getImplicitReceiversWithInstance(excludeShadowedByDslMarkers: Boolean = false): Collection<ReceiverParameterDescriptor> =
|
||||
getImplicitReceiversWithInstanceToExpression(excludeShadowedByDslMarkers).keys
|
||||
|
||||
interface ReceiverExpressionFactory {
|
||||
val isImmediate: Boolean
|
||||
@@ -48,9 +51,18 @@ fun LexicalScope.getFactoryForImplicitReceiverWithSubtypeOf(receiverType: Kotlin
|
||||
?.value
|
||||
}
|
||||
|
||||
fun LexicalScope.getImplicitReceiversWithInstanceToExpression(): Map<ReceiverParameterDescriptor, ReceiverExpressionFactory?> {
|
||||
fun LexicalScope.getImplicitReceiversWithInstanceToExpression(
|
||||
excludeShadowedByDslMarkers: Boolean = false
|
||||
): Map<ReceiverParameterDescriptor, ReceiverExpressionFactory?> {
|
||||
val allReceivers = getImplicitReceiversHierarchy()
|
||||
// we use a set to workaround a bug with receiver for companion object present twice in the result of getImplicitReceiversHierarchy()
|
||||
val receivers = LinkedHashSet(getImplicitReceiversHierarchy())
|
||||
val receivers = LinkedHashSet(
|
||||
if (excludeShadowedByDslMarkers) {
|
||||
allReceivers - allReceivers.shadowedByDslMarkers()
|
||||
} else {
|
||||
allReceivers
|
||||
}
|
||||
)
|
||||
|
||||
val outerDeclarationsWithInstance = LinkedHashSet<DeclarationDescriptor>()
|
||||
var current: DeclarationDescriptor? = ownerDescriptor
|
||||
@@ -109,3 +121,17 @@ private fun thisQualifierName(receiver: ReceiverParameterDescriptor): Name? {
|
||||
val functionLiteral = DescriptorToSourceUtils.descriptorToDeclaration(descriptor) as? KtFunctionLiteral
|
||||
return functionLiteral?.findLabelAndCall()?.first
|
||||
}
|
||||
|
||||
private fun List<ReceiverParameterDescriptor>.shadowedByDslMarkers(): Set<ReceiverParameterDescriptor> {
|
||||
val typesByDslScopes = LinkedHashMap<FqName, MutableList<ReceiverParameterDescriptor>>()
|
||||
|
||||
this.mapNotNull { receiver ->
|
||||
val dslMarkers = DslMarkerUtils.extractDslMarkerFqNames(receiver.value).all()
|
||||
(receiver to dslMarkers).takeIf { dslMarkers.isNotEmpty() }
|
||||
}.forEach { (v, dslMarkers) -> dslMarkers.forEach { typesByDslScopes.getOrPut(it, { mutableListOf() }) += v } }
|
||||
|
||||
val shadowedDslReceivers = mutableSetOf<ReceiverParameterDescriptor>()
|
||||
typesByDslScopes.flatMapTo(shadowedDslReceivers) { (_, v) -> v.asSequence().drop(1).asIterable() }
|
||||
|
||||
return shadowedDslReceivers
|
||||
}
|
||||
Reference in New Issue
Block a user