Correct value passed as containingDeclarationOrModule to SmartCastUtils

This commit is contained in:
Valentin Kipyatkov
2015-04-07 15:26:29 +03:00
parent 33f119a65a
commit 3faf6cc3e8
3 changed files with 22 additions and 17 deletions
@@ -70,6 +70,7 @@ public class ReferenceVariantsHelper(
): Collection<DeclarationDescriptor> {
val parent = expression.getParent()
val resolutionScope = context[BindingContext.RESOLUTION_SCOPE, expression] ?: return listOf()
val containingDeclaration = resolutionScope.getContainingDeclaration()
if (parent is JetImportDirective || parent is JetPackageDirective) {
return resolutionScope.getDescriptorsFiltered(kindFilter.restrictedToKinds(DescriptorKindFilter.PACKAGES_MASK), nameFilter)
@@ -100,10 +101,7 @@ public class ReferenceVariantsHelper(
val receiverValue = ExpressionReceiver(receiverExpression, expressionType)
val dataFlowInfo = context.getDataFlowInfo(expression)
for (variant in SmartCastUtils.getSmartCastVariantsWithLessSpecificExcluded(receiverValue,
context,
resolutionScope.getContainingDeclaration(),
dataFlowInfo)) {
for (variant in SmartCastUtils.getSmartCastVariantsWithLessSpecificExcluded(receiverValue, context, containingDeclaration, dataFlowInfo)) {
descriptors.addMembersFromReceiver(variant, callType, kindFilter, nameFilter)
}
@@ -129,7 +127,7 @@ public class ReferenceVariantsHelper(
if (descriptor is CallableDescriptor && descriptor.getExtensionReceiverParameter() != null) {
val dispatchReceiver = descriptor.getDispatchReceiverParameter()
if (dispatchReceiver == null || dispatchReceiver in receivers) {
descriptorsSet.addAll(descriptor.substituteExtensionIfCallable(receiverValues, context, dataFlowInfo, CallType.NORMAL))
descriptorsSet.addAll(descriptor.substituteExtensionIfCallable(receiverValues, context, dataFlowInfo, CallType.NORMAL, containingDeclaration))
}
}
else {
@@ -196,7 +194,7 @@ public class ReferenceVariantsHelper(
val extensionsFilter = kindFilter.exclude(DescriptorKindExclude.NonExtensions)
fun processExtension(descriptor: DeclarationDescriptor) {
addAll((descriptor as CallableDescriptor).substituteExtensionIfCallable(receiver, callType, context, dataFlowInfo))
addAll((descriptor as CallableDescriptor).substituteExtensionIfCallable(receiver, callType, context, dataFlowInfo, resolutionScope.getContainingDeclaration()))
}
// process member extensions from implicit receivers separately to filter out ones from implicit receivers with no instance
@@ -46,9 +46,10 @@ public fun CallableDescriptor.substituteExtensionIfCallable(
receivers: Collection<ReceiverValue>,
context: BindingContext,
dataFlowInfo: DataFlowInfo,
callType: CallType
callType: CallType,
containingDeclarationOrModule: DeclarationDescriptor
): Collection<CallableDescriptor> {
val sequence = receivers.sequence().flatMap { substituteExtensionIfCallable(it, callType, context, dataFlowInfo).sequence() }
val sequence = receivers.sequence().flatMap { substituteExtensionIfCallable(it, callType, context, dataFlowInfo, containingDeclarationOrModule).sequence() }
if (getTypeParameters().isEmpty()) { // optimization for non-generic callables
return sequence.firstOrNull()?.let { listOf(it) } ?: listOf()
}
@@ -57,19 +58,26 @@ public fun CallableDescriptor.substituteExtensionIfCallable(
}
}
public fun CallableDescriptor.substituteExtensionIfCallableWithImplicitReceiver(scope: JetScope, context: BindingContext, dataFlowInfo: DataFlowInfo): Collection<CallableDescriptor>
= substituteExtensionIfCallable(scope.getImplicitReceiversWithInstance().map { it.getValue() }, context, dataFlowInfo, CallType.NORMAL)
public fun CallableDescriptor.substituteExtensionIfCallableWithImplicitReceiver(
scope: JetScope,
context: BindingContext,
dataFlowInfo: DataFlowInfo
): Collection<CallableDescriptor> {
val receiverValues = scope.getImplicitReceiversWithInstance().map { it.getValue() }
return substituteExtensionIfCallable(receiverValues, context, dataFlowInfo, CallType.NORMAL, scope.getContainingDeclaration())
}
public fun CallableDescriptor.substituteExtensionIfCallable(
receiver: ReceiverValue,
callType: CallType,
bindingContext: BindingContext,
dataFlowInfo: DataFlowInfo
dataFlowInfo: DataFlowInfo,
containingDeclarationOrModule: DeclarationDescriptor
): Collection<CallableDescriptor> {
if (!receiver.exists()) return listOf()
if (!callType.canCall(this)) return listOf()
var types = SmartCastUtils.getSmartCastVariants(receiver, bindingContext, getContainingDeclaration(), dataFlowInfo).sequence()
var types = SmartCastUtils.getSmartCastVariants(receiver, bindingContext, containingDeclarationOrModule, dataFlowInfo).sequence()
if (callType == CallType.SAFE) {
types = types.map { it.makeNotNullable() }
@@ -85,9 +85,8 @@ public class KotlinIndicesHelper(
if (receiverValues.isEmpty()) return emptyList()
val dataFlowInfo = bindingContext.getDataFlowInfo(expression)
val containingDeclaration = bindingContext[BindingContext.RESOLUTION_SCOPE, expression]?.getContainingDeclaration() ?: return emptyList()
val receiverTypeNames = possibleReceiverTypeNames(receiverValues.map { it.first }, containingDeclaration, dataFlowInfo)
val receiverTypeNames = possibleReceiverTypeNames(receiverValues.map { it.first }, dataFlowInfo)
val index = JetTopLevelExtensionsByReceiverTypeIndex.INSTANCE
@@ -102,10 +101,10 @@ public class KotlinIndicesHelper(
return findSuitableExtensions(declarations, receiverValues, dataFlowInfo, bindingContext)
}
private fun possibleReceiverTypeNames(receiverValues: Collection<ReceiverValue>, containingDeclaration: DeclarationDescriptor, dataFlowInfo: DataFlowInfo): Set<String> {
private fun possibleReceiverTypeNames(receiverValues: Collection<ReceiverValue>, dataFlowInfo: DataFlowInfo): Set<String> {
val result = HashSet<String>()
for (receiverValue in receiverValues) {
for (type in SmartCastUtils.getSmartCastVariants(receiverValue, bindingContext, containingDeclaration, dataFlowInfo)) {
for (type in SmartCastUtils.getSmartCastVariants(receiverValue, bindingContext, moduleDescriptor, dataFlowInfo)) {
result.addTypeNames(type)
}
}
@@ -150,7 +149,7 @@ public class KotlinIndicesHelper(
fun processDescriptor(descriptor: CallableDescriptor) {
if (visibilityFilter(descriptor)) {
for ((receiverValue, callType) in receiverValues) {
result.addAll(descriptor.substituteExtensionIfCallable(receiverValue, callType, bindingContext, dataFlowInfo))
result.addAll(descriptor.substituteExtensionIfCallable(receiverValue, callType, bindingContext, dataFlowInfo, moduleDescriptor))
}
}
}