[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:
+6
@@ -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 {
|
||||
|
||||
+23
-10
@@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
// IGNORE_FE10
|
||||
fun f(s: String, action: (String.() -> Unit)?) {
|
||||
<expr>s.action</expr>?.let { it() }
|
||||
}
|
||||
+30
@@ -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.>
|
||||
Reference in New Issue
Block a user