From 7bd65c0bcdba8d5f756ae8685756e4ae3878d03a Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Tue, 17 Sep 2019 17:58:24 +0300 Subject: [PATCH] [NI] Avoid collecting possible types for call expressions --- .../resolve/calls/tower/NewCallArguments.kt | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewCallArguments.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewCallArguments.kt index 3e6ea7a5655..eb41fb3ba44 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewCallArguments.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/NewCallArguments.kt @@ -301,29 +301,38 @@ internal fun createSimplePSICallArgument( val baseType = typeInfoForArgument.type?.unwrap() ?: partiallyResolvedCall?.resultCallAtom?.freshReturnType ?: return null 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 - if (partiallyResolvedCall != null) { - val capturedReceiver = + val argumentWithSmartCastInfo = + if (ktExpression is KtCallExpression || partiallyResolvedCall != null) { + // 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) - .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, dataFlowInfoBeforeThisArgument, typeInfoForArgument.dataFlowInfo, - capturedReceiver, + capturedArgument, 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) }