[FIR] Correctly insert FirImplicitInvokeCall expression when needed

Before that, implicit invoke call were inserted only for
double-brackets expressions (like `foo()()`)

In fact, it is intended to be present in every place where `invoke`
function is used as an operator:

`foo()` - `invoke` operator usage, should be `ImplicitInvokeCall`
`foo.invoke()` - `invoke` function used, should be simple `FunctionCall`

Also, handle implicit invokes in `FirDelegatedPropertyChecker`
This commit is contained in:
Roman Golyshev
2021-09-08 19:40:39 +03:00
committed by teamcityserver
parent f4a59de1c2
commit c7a6a77a04
3 changed files with 30 additions and 7 deletions
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.FirImplicitInvokeCall
import org.jetbrains.kotlin.fir.expressions.arguments
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError
@@ -55,6 +56,10 @@ object FirDelegatedPropertyChecker : FirPropertyChecker() {
checkFunctionCall(functionCall)
}
override fun visitImplicitInvokeCall(implicitInvokeCall: FirImplicitInvokeCall) {
checkFunctionCall(implicitInvokeCall)
}
private fun checkFunctionCall(functionCall: FirFunctionCall) {
val hasReferenceError = checkFunctionReferenceErrors(functionCall)
if (isGet && !hasReferenceError) checkReturnType(functionCall)
@@ -58,6 +58,25 @@ fun FirFunctionCall.copy(
return (builder as FirCallBuilder).build() as FirFunctionCall
}
internal fun FirFunctionCall.copyAsImplicitInvokeCall(
setupCopy: FirImplicitInvokeCallBuilder.() -> Unit
): FirImplicitInvokeCall {
val original = this
return buildImplicitInvokeCall {
source = original.source
annotations.addAll(original.annotations)
typeArguments.addAll(original.typeArguments)
explicitReceiver = original.explicitReceiver
dispatchReceiver = original.dispatchReceiver
extensionReceiver = original.extensionReceiver
argumentList = original.argumentList
calleeReference = original.calleeReference
setupCopy()
}
}
fun FirAnonymousFunction.copy(
receiverTypeRef: FirTypeRef? = this.receiverTypeRef,
source: FirSourceElement? = this.source,
@@ -44,7 +44,6 @@ import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
import org.jetbrains.kotlin.types.Variance
import java.lang.annotation.ElementType
class FirCallResolver(
private val components: FirAbstractBodyResolveTransformer.BodyResolveTransformerComponents,
@@ -115,12 +114,12 @@ class FirCallResolver(
// We need desugaring
val resultFunctionCall = if (candidate != null && candidate.callInfo != result.info) {
functionCall.copy(
explicitReceiver = candidate.callInfo.explicitReceiver,
dispatchReceiver = candidate.dispatchReceiverExpression(),
extensionReceiver = candidate.extensionReceiverExpression(),
argumentList = candidate.callInfo.argumentList,
)
functionCall.copyAsImplicitInvokeCall {
explicitReceiver = candidate.callInfo.explicitReceiver
dispatchReceiver = candidate.dispatchReceiverExpression()
extensionReceiver = candidate.extensionReceiverExpression()
argumentList = candidate.callInfo.argumentList
}
} else {
resultExpression
}