[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");
|
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
|
@Test
|
||||||
@TestMetadata("typeParameterAsValue.kt")
|
@TestMetadata("typeParameterAsValue.kt")
|
||||||
public void testTypeParameterAsValue() throws Exception {
|
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
|
// 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
|
// representation of this receiver. Caller can then use this PSI for further call resolution, which is implemented by the
|
||||||
// parameter `resolveCalleeExpressionOfFunctionCall` in `toKtCallInfo`.
|
// parameter `resolveCalleeExpressionOfFunctionCall` in `toKtCallInfo`.
|
||||||
val explicitReceiverPsi = when (psi) {
|
var explicitReceiverPsi = when (psi) {
|
||||||
is KtQualifiedExpression -> (psi.selectorExpression as KtCallExpression).calleeExpression
|
is KtQualifiedExpression -> {
|
||||||
is KtCallExpression -> psi.calleeExpression
|
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") {
|
else -> errorWithAttachment("unexpected PSI ${psi::class} for FirImplicitInvokeCall") {
|
||||||
withPsiEntry("psi", psi, analysisSession::getModule)
|
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
|
// Specially handle @ExtensionFunctionType
|
||||||
if (dispatchReceiver?.resolvedType?.isExtensionFunctionType == true) {
|
if (dispatchReceiver?.resolvedType?.isExtensionFunctionType == true) {
|
||||||
@@ -434,10 +443,14 @@ internal class KtFirCallResolver(
|
|||||||
}
|
}
|
||||||
dispatchReceiverValue =
|
dispatchReceiverValue =
|
||||||
KtExplicitReceiverValue(explicitReceiverPsi, dispatchReceiver.resolvedType.asKtType(), false, token)
|
KtExplicitReceiverValue(explicitReceiverPsi, dispatchReceiver.resolvedType.asKtType(), false, token)
|
||||||
if (firstArgIsExtensionReceiver) {
|
extensionReceiverValue = if (firstArgIsExtensionReceiver) {
|
||||||
extensionReceiverValue = (fir as FirFunctionCall).arguments.firstOrNull()?.toKtReceiverValue()
|
when (fir) {
|
||||||
|
is FirFunctionCall -> fir.arguments.firstOrNull()?.toKtReceiverValue()
|
||||||
|
is FirPropertyAccessExpression -> fir.explicitReceiver?.toKtReceiverValue()
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
extensionReceiverValue = extensionReceiver?.toKtReceiverValue()
|
extensionReceiver?.toKtReceiverValue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -557,7 +570,7 @@ internal class KtFirCallResolver(
|
|||||||
partiallyAppliedSymbol as KtPartiallyAppliedFunctionSymbol<KtFunctionLikeSymbol>,
|
partiallyAppliedSymbol as KtPartiallyAppliedFunctionSymbol<KtFunctionLikeSymbol>,
|
||||||
LinkedHashMap(),
|
LinkedHashMap(),
|
||||||
fir.toTypeArgumentsMapping(partiallyAppliedSymbol),
|
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");
|
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
|
@Test
|
||||||
@TestMetadata("typeParameterAsValue.kt")
|
@TestMetadata("typeParameterAsValue.kt")
|
||||||
public void testTypeParameterAsValue() throws Exception {
|
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");
|
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
|
@Test
|
||||||
@TestMetadata("typeParameterAsValue.kt")
|
@TestMetadata("typeParameterAsValue.kt")
|
||||||
public void testTypeParameterAsValue() throws Exception {
|
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