[NI] Avoid collecting possible types for call expressions

This commit is contained in:
Mikhail Zarechenskiy
2019-09-17 17:58:24 +03:00
parent a83225218f
commit 7bd65c0bcd
@@ -301,29 +301,38 @@ internal fun createSimplePSICallArgument(
val baseType = typeInfoForArgument.type?.unwrap() ?: partiallyResolvedCall?.resultCallAtom?.freshReturnType ?: return null val baseType = typeInfoForArgument.type?.unwrap() ?: partiallyResolvedCall?.resultCallAtom?.freshReturnType ?: return null
val expressionReceiver = ExpressionReceiver.create(ktExpression, baseType, bindingContext) val expressionReceiver = ExpressionReceiver.create(ktExpression, baseType, bindingContext)
// For a sub-call there can't be any smartcast so we use a fast-path here to avoid calling transformToReceiverWithSmartCastInfo function val argumentWithSmartCastInfo =
if (partiallyResolvedCall != null) { if (ktExpression is KtCallExpression || partiallyResolvedCall != null) {
val capturedReceiver = // For a sub-call (partially or fully resolved), there can't be any smartcast
// so we use a fast-path here to avoid calling transformToReceiverWithSmartCastInfo function
ReceiverValueWithSmartCastInfo(expressionReceiver, emptySet(), isStable = true) ReceiverValueWithSmartCastInfo(expressionReceiver, emptySet(), isStable = true)
.prepareReceiverRegardingCaptureTypes() } else {
transformToReceiverWithSmartCastInfo(
ownerDescriptor, bindingContext,
// dataFlowInfoBeforeThisArgument cannot be used here, because of if() { if (x != null) return; x }
typeInfoForArgument.dataFlowInfo,
expressionReceiver,
languageVersionSettings,
dataFlowValueFactory
)
}
return SubKotlinCallArgumentImpl( val capturedArgument = argumentWithSmartCastInfo.prepareReceiverRegardingCaptureTypes()
return if (partiallyResolvedCall != null) {
SubKotlinCallArgumentImpl(
valueArgument, valueArgument,
dataFlowInfoBeforeThisArgument, dataFlowInfoBeforeThisArgument,
typeInfoForArgument.dataFlowInfo, typeInfoForArgument.dataFlowInfo,
capturedReceiver, capturedArgument,
partiallyResolvedCall partiallyResolvedCall
) )
} else {
ExpressionKotlinCallArgumentImpl(
valueArgument,
dataFlowInfoBeforeThisArgument,
typeInfoForArgument.dataFlowInfo,
capturedArgument
)
} }
// we should use DFI after this argument, because there can be some useful smartcast. Popular case: if branches.
val receiverToCast = transformToReceiverWithSmartCastInfo(
ownerDescriptor, bindingContext,
typeInfoForArgument.dataFlowInfo, // dataFlowInfoBeforeThisArgument cannot be used here, because of if() { if (x != null) return; x }
expressionReceiver,
languageVersionSettings,
dataFlowValueFactory
).prepareReceiverRegardingCaptureTypes()
return ExpressionKotlinCallArgumentImpl(valueArgument, dataFlowInfoBeforeThisArgument, typeInfoForArgument.dataFlowInfo, receiverToCast)
} }