[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? {
|
||||
|
||||
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
|
||||
}
|
||||
// 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.
|
||||
val receiverToCast = transformToReceiverWithSmartCastInfo(
|
||||
ownerDescriptor, bindingContext,
|
||||
typeInfoForArgument.dataFlowInfo, // dataFlowInfoBeforeThisArgument cannot be used here, because of if() { if (x != null) return; x }
|
||||
ExpressionReceiver.create(ktExpression, baseType, bindingContext),
|
||||
expressionReceiver,
|
||||
languageVersionSettings,
|
||||
dataFlowValueFactory
|
||||
).prepareReceiverRegardingCaptureTypes()
|
||||
|
||||
return if (onlyResolvedCall == null) {
|
||||
ExpressionKotlinCallArgumentImpl(valueArgument, dataFlowInfoBeforeThisArgument, typeInfoForArgument.dataFlowInfo, receiverToCast)
|
||||
} else {
|
||||
SubKotlinCallArgumentImpl(
|
||||
valueArgument,
|
||||
dataFlowInfoBeforeThisArgument,
|
||||
typeInfoForArgument.dataFlowInfo,
|
||||
receiverToCast,
|
||||
onlyResolvedCall
|
||||
)
|
||||
}
|
||||
return ExpressionKotlinCallArgumentImpl(valueArgument, dataFlowInfoBeforeThisArgument, typeInfoForArgument.dataFlowInfo, receiverToCast)
|
||||
}
|
||||
|
||||
@@ -579,37 +579,42 @@ class PSICallResolver(
|
||||
oldReceiver: Receiver?,
|
||||
isSafeCall: Boolean,
|
||||
isForImplicitInvoke: Boolean
|
||||
): ReceiverKotlinCallArgument? =
|
||||
when (oldReceiver) {
|
||||
): ReceiverKotlinCallArgument? {
|
||||
return when (oldReceiver) {
|
||||
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) {
|
||||
val ktExpression = KtPsiUtil.getLastElementDeparenthesized(oldReceiver.expression, context.statementFilter)
|
||||
|
||||
val bindingContext = context.trace.bindingContext
|
||||
val call = bindingContext[BindingContext.DELEGATE_EXPRESSION_TO_PROVIDE_DELEGATE_CALL, ktExpression]
|
||||
?: ktExpression?.getCall(bindingContext)
|
||||
val call =
|
||||
bindingContext[BindingContext.DELEGATE_EXPRESSION_TO_PROVIDE_DELEGATE_CALL, ktExpression]
|
||||
?: ktExpression?.getCall(bindingContext)
|
||||
|
||||
val onlyResolvedCall = call?.let {
|
||||
bindingContext.get(BindingContext.ONLY_RESOLVED_CALL, it)?.result
|
||||
}
|
||||
if (onlyResolvedCall != null) {
|
||||
subCallArgument = SubKotlinCallArgumentImpl(
|
||||
val partiallyResolvedCall = call?.let { bindingContext.get(BindingContext.ONLY_RESOLVED_CALL, it)?.result }
|
||||
|
||||
if (partiallyResolvedCall != null) {
|
||||
val receiver = ReceiverValueWithSmartCastInfo(oldReceiver, emptySet(), isStable = true)
|
||||
return SubKotlinCallArgumentImpl(
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveTypeArguments(context: BasicCallResolutionContext, typeArguments: List<KtTypeProjection>): List<TypeArgument> =
|
||||
typeArguments.map { projection ->
|
||||
|
||||
Reference in New Issue
Block a user