KT-39398 Wrong import of unrelated object member is suggested for receiver
Receiver of a function call '<receiver>.foo()' (where receiver is a class/object/alias name) might be specified incorrectly - corresponding [companion] object might not be declared. Before this commit '<receiver>' was considered to be undefined (null). As a consequence, import suggestion included all 'foo()' functions from the search scope. Now as a value of '<receiver>' we set class/object/alias itself resulting in an empty import suggestion list. See org/jetbrains/kotlin/idea/util/CallType.kt:307 (#extractReceiverTypeFrom(descriptor: ClassDescriptor)).
This commit is contained in:
committed by
Nikita Bobko
parent
365821ae54
commit
decfcd28d2
+19
-12
@@ -29,12 +29,10 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.classValueType
|
|||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
|
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
|
||||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude
|
||||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassQualifier
|
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.TypeAliasQualifier
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS
|
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS
|
||||||
|
import org.jetbrains.kotlin.util.isJavaDescriptor
|
||||||
import org.jetbrains.kotlin.util.supertypesWithAny
|
import org.jetbrains.kotlin.util.supertypesWithAny
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -309,15 +307,24 @@ fun CallTypeAndReceiver<*, *>.receiverTypesWithIndex(
|
|||||||
|
|
||||||
val resolutionScope = contextElement.getResolutionScope(bindingContext, resolutionFacade)
|
val resolutionScope = contextElement.getResolutionScope(bindingContext, resolutionFacade)
|
||||||
|
|
||||||
|
fun extractReceiverTypeFrom(descriptor: ClassDescriptor): KotlinType? = // companion object type or class itself
|
||||||
|
descriptor.classValueType ?: (if (descriptor.isFinalOrEnum || descriptor.isJavaDescriptor) null else descriptor.defaultType)
|
||||||
|
|
||||||
|
fun tryExtractReceiver(context: BindingContext) = context.get(BindingContext.QUALIFIER, receiverExpression)
|
||||||
|
|
||||||
|
fun tryExtractClassDescriptor(context: BindingContext): ClassDescriptor? =
|
||||||
|
(tryExtractReceiver(context) as? ClassQualifier)?.descriptor
|
||||||
|
|
||||||
|
fun tryExtractClassDescriptorFromAlias(context: BindingContext): ClassDescriptor? =
|
||||||
|
(tryExtractReceiver(context) as? TypeAliasQualifier)?.classDescriptor
|
||||||
|
|
||||||
|
fun extractReceiverTypeFrom(context: BindingContext, receiverExpression: KtExpression): KotlinType? {
|
||||||
|
return context.getType(receiverExpression) ?: tryExtractClassDescriptor(context)?.let { extractReceiverTypeFrom(it) }
|
||||||
|
?: tryExtractClassDescriptorFromAlias(context)?.let { extractReceiverTypeFrom(it) }
|
||||||
|
}
|
||||||
|
|
||||||
val expressionReceiver = receiverExpression?.let {
|
val expressionReceiver = receiverExpression?.let {
|
||||||
val receiverType =
|
val receiverType = extractReceiverTypeFrom(bindingContext, receiverExpression) ?: return emptyList()
|
||||||
bindingContext.getType(receiverExpression) ?: (bindingContext.get(
|
|
||||||
BindingContext.QUALIFIER,
|
|
||||||
receiverExpression
|
|
||||||
) as? ClassQualifier)?.descriptor?.classValueType ?: (bindingContext.get(
|
|
||||||
BindingContext.QUALIFIER,
|
|
||||||
receiverExpression
|
|
||||||
) as? TypeAliasQualifier)?.classDescriptor?.classValueType ?: return emptyList()
|
|
||||||
ExpressionReceiver.create(receiverExpression, receiverType, bindingContext)
|
ExpressionReceiver.create(receiverExpression, receiverType, bindingContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user