[NI] Minor, simplify code a bit for sub calls preparation
This commit is contained in:
+20
-14
@@ -294,30 +294,36 @@ internal fun createSimplePSICallArgument(
|
|||||||
): SimplePSIKotlinCallArgument? {
|
): SimplePSIKotlinCallArgument? {
|
||||||
|
|
||||||
val ktExpression = KtPsiUtil.getLastElementDeparenthesized(valueArgument.getArgumentExpression(), statementFilter) ?: return null
|
val ktExpression = KtPsiUtil.getLastElementDeparenthesized(valueArgument.getArgumentExpression(), statementFilter) ?: return null
|
||||||
val onlyResolvedCall = ktExpression.getCall(bindingContext)?.let {
|
val partiallyResolvedCall = ktExpression.getCall(bindingContext)?.let {
|
||||||
bindingContext.get(BindingContext.ONLY_RESOLVED_CALL, it)?.result
|
bindingContext.get(BindingContext.ONLY_RESOLVED_CALL, it)?.result
|
||||||
}
|
}
|
||||||
// todo hack for if expression: sometimes we not write properly type information for branches
|
// todo hack for if expression: sometimes we not write properly type information for branches
|
||||||
val baseType = typeInfoForArgument.type?.unwrap() ?: onlyResolvedCall?.resultCallAtom?.freshReturnType ?: return null
|
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 =
|
||||||
|
ReceiverValueWithSmartCastInfo(expressionReceiver, emptySet(), isStable = true)
|
||||||
|
.prepareReceiverRegardingCaptureTypes()
|
||||||
|
|
||||||
|
return SubKotlinCallArgumentImpl(
|
||||||
|
valueArgument,
|
||||||
|
dataFlowInfoBeforeThisArgument,
|
||||||
|
typeInfoForArgument.dataFlowInfo,
|
||||||
|
capturedReceiver,
|
||||||
|
partiallyResolvedCall
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// we should use DFI after this argument, because there can be some useful smartcast. Popular case: if branches.
|
// we should use DFI after this argument, because there can be some useful smartcast. Popular case: if branches.
|
||||||
val receiverToCast = transformToReceiverWithSmartCastInfo(
|
val receiverToCast = transformToReceiverWithSmartCastInfo(
|
||||||
ownerDescriptor, bindingContext,
|
ownerDescriptor, bindingContext,
|
||||||
typeInfoForArgument.dataFlowInfo, // dataFlowInfoBeforeThisArgument cannot be used here, because of if() { if (x != null) return; x }
|
typeInfoForArgument.dataFlowInfo, // dataFlowInfoBeforeThisArgument cannot be used here, because of if() { if (x != null) return; x }
|
||||||
ExpressionReceiver.create(ktExpression, baseType, bindingContext),
|
expressionReceiver,
|
||||||
languageVersionSettings,
|
languageVersionSettings,
|
||||||
dataFlowValueFactory
|
dataFlowValueFactory
|
||||||
).prepareReceiverRegardingCaptureTypes()
|
).prepareReceiverRegardingCaptureTypes()
|
||||||
|
|
||||||
return if (onlyResolvedCall == null) {
|
return ExpressionKotlinCallArgumentImpl(valueArgument, dataFlowInfoBeforeThisArgument, typeInfoForArgument.dataFlowInfo, receiverToCast)
|
||||||
ExpressionKotlinCallArgumentImpl(valueArgument, dataFlowInfoBeforeThisArgument, typeInfoForArgument.dataFlowInfo, receiverToCast)
|
|
||||||
} else {
|
|
||||||
SubKotlinCallArgumentImpl(
|
|
||||||
valueArgument,
|
|
||||||
dataFlowInfoBeforeThisArgument,
|
|
||||||
typeInfoForArgument.dataFlowInfo,
|
|
||||||
receiverToCast,
|
|
||||||
onlyResolvedCall
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -579,37 +579,42 @@ class PSICallResolver(
|
|||||||
oldReceiver: Receiver?,
|
oldReceiver: Receiver?,
|
||||||
isSafeCall: Boolean,
|
isSafeCall: Boolean,
|
||||||
isForImplicitInvoke: Boolean
|
isForImplicitInvoke: Boolean
|
||||||
): ReceiverKotlinCallArgument? =
|
): ReceiverKotlinCallArgument? {
|
||||||
when (oldReceiver) {
|
return when (oldReceiver) {
|
||||||
null -> null
|
null -> null
|
||||||
is QualifierReceiver -> QualifierReceiverKotlinCallArgument(oldReceiver) // todo report warning if isSafeCall
|
|
||||||
is ReceiverValue -> {
|
|
||||||
val detailedReceiver = context.transformToReceiverWithSmartCastInfo(oldReceiver)
|
|
||||||
|
|
||||||
var subCallArgument: ReceiverKotlinCallArgument? = null
|
is QualifierReceiver -> QualifierReceiverKotlinCallArgument(oldReceiver) // todo report warning if isSafeCall
|
||||||
|
|
||||||
|
is ReceiverValue -> {
|
||||||
if (oldReceiver is ExpressionReceiver) {
|
if (oldReceiver is ExpressionReceiver) {
|
||||||
val ktExpression = KtPsiUtil.getLastElementDeparenthesized(oldReceiver.expression, context.statementFilter)
|
val ktExpression = KtPsiUtil.getLastElementDeparenthesized(oldReceiver.expression, context.statementFilter)
|
||||||
|
|
||||||
val bindingContext = context.trace.bindingContext
|
val bindingContext = context.trace.bindingContext
|
||||||
val call = bindingContext[BindingContext.DELEGATE_EXPRESSION_TO_PROVIDE_DELEGATE_CALL, ktExpression]
|
val call =
|
||||||
?: ktExpression?.getCall(bindingContext)
|
bindingContext[BindingContext.DELEGATE_EXPRESSION_TO_PROVIDE_DELEGATE_CALL, ktExpression]
|
||||||
|
?: ktExpression?.getCall(bindingContext)
|
||||||
|
|
||||||
val onlyResolvedCall = call?.let {
|
val partiallyResolvedCall = call?.let { bindingContext.get(BindingContext.ONLY_RESOLVED_CALL, it)?.result }
|
||||||
bindingContext.get(BindingContext.ONLY_RESOLVED_CALL, it)?.result
|
|
||||||
}
|
if (partiallyResolvedCall != null) {
|
||||||
if (onlyResolvedCall != null) {
|
val receiver = ReceiverValueWithSmartCastInfo(oldReceiver, emptySet(), isStable = true)
|
||||||
subCallArgument = SubKotlinCallArgumentImpl(
|
return SubKotlinCallArgumentImpl(
|
||||||
CallMaker.makeExternalValueArgument(oldReceiver.expression),
|
CallMaker.makeExternalValueArgument(oldReceiver.expression),
|
||||||
context.dataFlowInfo, context.dataFlowInfo, detailedReceiver, onlyResolvedCall
|
context.dataFlowInfo, context.dataFlowInfo, receiver, partiallyResolvedCall
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
subCallArgument ?: ReceiverExpressionKotlinCallArgument(detailedReceiver, isSafeCall, isForImplicitInvoke)
|
ReceiverExpressionKotlinCallArgument(
|
||||||
|
context.transformToReceiverWithSmartCastInfo(oldReceiver),
|
||||||
|
isSafeCall,
|
||||||
|
isForImplicitInvoke
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> error("Incorrect receiver: $oldReceiver")
|
else -> error("Incorrect receiver: $oldReceiver")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun resolveTypeArguments(context: BasicCallResolutionContext, typeArguments: List<KtTypeProjection>): List<TypeArgument> =
|
private fun resolveTypeArguments(context: BasicCallResolutionContext, typeArguments: List<KtTypeProjection>): List<TypeArgument> =
|
||||||
typeArguments.map { projection ->
|
typeArguments.map { projection ->
|
||||||
|
|||||||
Reference in New Issue
Block a user