[FIR] Correctly process invalid implicit invoke

^KT-60170 fixed


Merge-request: KT-MR-12926
Merged-by: Egor Kulikov <Egor.Kulikov@jetbrains.com>
This commit is contained in:
Egor Kulikov
2023-11-15 11:43:48 +00:00
committed by Space Team
parent 061b1238fc
commit c0a05e435c
6 changed files with 75 additions and 10 deletions
@@ -1019,6 +1019,12 @@ public class Fe10IdeNormalAnalysisSourceModuleResolveCallTestGenerated extends A
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode/incorrectCodeJavaDeclaration.kt");
}
@Test
@TestMetadata("invalidImplicitInvoke.kt")
public void testInvalidImplicitInvoke() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode/invalidImplicitInvoke.kt");
}
@Test
@TestMetadata("typeParameterAsValue.kt")
public void testTypeParameterAsValue() throws Exception {
@@ -404,16 +404,25 @@ internal class KtFirCallResolver(
// the `invoke` member function. In this case, we use the `calleeExpression` in the `KtCallExpression` as the PSI
// representation of this receiver. Caller can then use this PSI for further call resolution, which is implemented by the
// parameter `resolveCalleeExpressionOfFunctionCall` in `toKtCallInfo`.
val explicitReceiverPsi = when (psi) {
is KtQualifiedExpression -> (psi.selectorExpression as KtCallExpression).calleeExpression
is KtCallExpression -> psi.calleeExpression
var explicitReceiverPsi = when (psi) {
is KtQualifiedExpression -> {
psi.selectorExpression
?: errorWithAttachment("missing selectorExpression in PSI ${psi::class} for FirImplicitInvokeCall") {
withPsiEntry("psi", psi, analysisSession::getModule)
}
}
is KtExpression -> psi
else -> errorWithAttachment("unexpected PSI ${psi::class} for FirImplicitInvokeCall") {
withPsiEntry("psi", psi, analysisSession::getModule)
}
}
?: errorWithAttachment("missing calleeExpression in PSI ${psi::class} for FirImplicitInvokeCall") {
withPsiEntry("psi", psi, analysisSession::getModule)
}
if (explicitReceiverPsi is KtCallExpression) {
explicitReceiverPsi = explicitReceiverPsi.calleeExpression
?: errorWithAttachment("missing calleeExpression in PSI ${psi::class} for FirImplicitInvokeCall") {
withPsiEntry("psi", psi, analysisSession::getModule)
}
}
// Specially handle @ExtensionFunctionType
if (dispatchReceiver?.resolvedType?.isExtensionFunctionType == true) {
@@ -434,10 +443,14 @@ internal class KtFirCallResolver(
}
dispatchReceiverValue =
KtExplicitReceiverValue(explicitReceiverPsi, dispatchReceiver.resolvedType.asKtType(), false, token)
if (firstArgIsExtensionReceiver) {
extensionReceiverValue = (fir as FirFunctionCall).arguments.firstOrNull()?.toKtReceiverValue()
extensionReceiverValue = if (firstArgIsExtensionReceiver) {
when (fir) {
is FirFunctionCall -> fir.arguments.firstOrNull()?.toKtReceiverValue()
is FirPropertyAccessExpression -> fir.explicitReceiver?.toKtReceiverValue()
else -> null
}
} else {
extensionReceiverValue = extensionReceiver?.toKtReceiverValue()
extensionReceiver?.toKtReceiverValue()
}
}
@@ -557,7 +570,7 @@ internal class KtFirCallResolver(
partiallyAppliedSymbol as KtPartiallyAppliedFunctionSymbol<KtFunctionLikeSymbol>,
LinkedHashMap(),
fir.toTypeArgumentsMapping(partiallyAppliedSymbol),
_isImplicitInvoke = false,
isImplicitInvoke,
)
}
}
@@ -1019,6 +1019,12 @@ public class FirIdeNormalAnalysisSourceModuleResolveCallTestGenerated extends Ab
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode/incorrectCodeJavaDeclaration.kt");
}
@Test
@TestMetadata("invalidImplicitInvoke.kt")
public void testInvalidImplicitInvoke() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode/invalidImplicitInvoke.kt");
}
@Test
@TestMetadata("typeParameterAsValue.kt")
public void testTypeParameterAsValue() throws Exception {
@@ -1019,6 +1019,12 @@ public class FirStandaloneNormalAnalysisSourceModuleResolveCallTestGenerated ext
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode/incorrectCodeJavaDeclaration.kt");
}
@Test
@TestMetadata("invalidImplicitInvoke.kt")
public void testInvalidImplicitInvoke() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/invalidCode/invalidImplicitInvoke.kt");
}
@Test
@TestMetadata("typeParameterAsValue.kt")
public void testTypeParameterAsValue() throws Exception {
@@ -0,0 +1,4 @@
// IGNORE_FE10
fun f(s: String, action: (String.() -> Unit)?) {
<expr>s.action</expr>?.let { it() }
}
@@ -0,0 +1,30 @@
KtErrorCallInfo:
candidateCalls = [
KtSimpleFunctionCall:
isImplicitInvoke = true
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = KtExplicitReceiverValue:
expression = action
isSafeNavigation = false
type = @ExtensionFunctionType kotlin.Function1<kotlin.String, kotlin.Unit>?
extensionReceiver = KtExplicitReceiverValue:
expression = s
isSafeNavigation = false
type = kotlin.String
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = kotlin/Function1.invoke(<dispatch receiver>: kotlin.Function1<P1, R>, p1: P1): R
valueParameters = [
KtVariableLikeSignature:
name = p1
receiverType = null
returnType = kotlin.String
symbol = p1: P1
callableIdIfNonLocal = null
]
callableIdIfNonLocal = kotlin/Function1.invoke
typeArgumentsMapping = {}
argumentMapping = {}
]
diagnostic = ERROR<FUNCTION_CALL_EXPECTED: Function invocation 'action(...)' expected.>