diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirCallResolver.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirCallResolver.kt index 8870bc082f2..ca1ecb94d8d 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirCallResolver.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirCallResolver.kt @@ -180,10 +180,10 @@ internal class KtFirCallResolver( val ktArgumentMapping = LinkedHashMap() argumentMapping?.let { fun FirExpression.findKtExpression(): KtExpression? { - // For spread and named arguments, the source is the KtValueArgument. + // For spread, named, and lambda arguments, the source is the KtValueArgument. // For other arguments (including array indices), the source is the KtExpression. return when (this) { - is FirNamedArgumentExpression, is FirSpreadArgumentExpression -> + is FirNamedArgumentExpression, is FirSpreadArgumentExpression, is FirLambdaArgumentExpression -> realPsi.safeAs()?.getArgumentExpression() else -> realPsi as? KtExpression } diff --git a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithLambdaArgument.kt b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithLambdaArgument.kt new file mode 100644 index 00000000000..68ca0505ffb --- /dev/null +++ b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithLambdaArgument.kt @@ -0,0 +1,7 @@ +fun function(a: Int, b: (String) -> Boolean) {} + +fun call() { + function(1) { s -> true } +} + +// CALL: KtFunctionCall: targetFunction = /function(a: kotlin.Int, b: (kotlin.String) -> kotlin.Boolean): kotlin.Unit \ No newline at end of file diff --git a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithLambdaArgument.txt b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithLambdaArgument.txt new file mode 100644 index 00000000000..c436fa4c52c --- /dev/null +++ b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithLambdaArgument.txt @@ -0,0 +1,3 @@ +KtFunctionCall: +argumentMapping = { 1 -> (a: kotlin.Int), { s -> true } -> (b: kotlin.Function1) } +targetFunction = /function(a: kotlin.Int, b: kotlin.Function1): kotlin.Unit \ No newline at end of file diff --git a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithNamedArgument.kt b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithNamedArgument.kt new file mode 100644 index 00000000000..c46bca5b477 --- /dev/null +++ b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithNamedArgument.kt @@ -0,0 +1,7 @@ +fun function(a: Int, b: String) {} + +fun call() { + function(b = "foo", a = 1) +} + +// CALL: KtFunctionCall: targetFunction = /function(a: kotlin.Int, b: kotlin.String): kotlin.Unit \ No newline at end of file diff --git a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithNamedArgument.txt b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithNamedArgument.txt new file mode 100644 index 00000000000..250c5189ddd --- /dev/null +++ b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithNamedArgument.txt @@ -0,0 +1,3 @@ +KtFunctionCall: +argumentMapping = { "foo" -> (b: kotlin.String), 1 -> (a: kotlin.Int) } +targetFunction = /function(a: kotlin.Int, b: kotlin.String): kotlin.Unit \ No newline at end of file diff --git a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithNonTrailingLambdaArgument.kt b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithNonTrailingLambdaArgument.kt new file mode 100644 index 00000000000..73d704818d5 --- /dev/null +++ b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithNonTrailingLambdaArgument.kt @@ -0,0 +1,7 @@ +fun function(a: Int, b: (String) -> Boolean) {} + +fun call() { + function(1, { s -> true }) +} + +// CALL: KtFunctionCall: targetFunction = /function(a: kotlin.Int, b: (String) -> Boolean): kotlin.Unit \ No newline at end of file diff --git a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithNonTrailingLambdaArgument.txt b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithNonTrailingLambdaArgument.txt new file mode 100644 index 00000000000..c436fa4c52c --- /dev/null +++ b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithNonTrailingLambdaArgument.txt @@ -0,0 +1,3 @@ +KtFunctionCall: +argumentMapping = { 1 -> (a: kotlin.Int), { s -> true } -> (b: kotlin.Function1) } +targetFunction = /function(a: kotlin.Int, b: kotlin.Function1): kotlin.Unit \ No newline at end of file diff --git a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithSpreadArgument.kt b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithSpreadArgument.kt new file mode 100644 index 00000000000..cca491e3f41 --- /dev/null +++ b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithSpreadArgument.kt @@ -0,0 +1,8 @@ +fun function(vararg a: Int) {} + +fun call() { + val args = intArrayOf(1, 2, 3) + function(*args) +} + +// CALL: KtFunctionCall: targetFunction = /function(vararg a: kotlin.IntArray): kotlin.Unit \ No newline at end of file diff --git a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithSpreadArgument.txt b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithSpreadArgument.txt new file mode 100644 index 00000000000..1d9df90e365 --- /dev/null +++ b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithSpreadArgument.txt @@ -0,0 +1,3 @@ +KtFunctionCall: +argumentMapping = { args -> (vararg a: kotlin.IntArray) } +targetFunction = /function(vararg a: kotlin.IntArray): kotlin.Unit \ No newline at end of file diff --git a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithVarargArgument.kt b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithVarargArgument.kt new file mode 100644 index 00000000000..f59177ae2af --- /dev/null +++ b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithVarargArgument.kt @@ -0,0 +1,7 @@ +fun function(vararg a: Int) {} + +fun call() { + function(1, 2, 3) +} + +// CALL: KtFunctionCall: targetFunction = /function(vararg a: kotlin.IntArray): kotlin.Unit \ No newline at end of file diff --git a/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithVarargArgument.txt b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithVarargArgument.txt new file mode 100644 index 00000000000..5dc3bdaea10 --- /dev/null +++ b/idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithVarargArgument.txt @@ -0,0 +1,3 @@ +KtFunctionCall: +argumentMapping = { 1 -> (vararg a: kotlin.IntArray), 2 -> (vararg a: kotlin.IntArray), 3 -> (vararg a: kotlin.IntArray) } +targetFunction = /function(vararg a: kotlin.IntArray): kotlin.Unit \ No newline at end of file diff --git a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/fir/frontend/api/fir/AbstractResolveCallTest.kt b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/fir/frontend/api/fir/AbstractResolveCallTest.kt index 0a8e686b258..fe5be4b0787 100644 --- a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/fir/frontend/api/fir/AbstractResolveCallTest.kt +++ b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/fir/frontend/api/fir/AbstractResolveCallTest.kt @@ -61,13 +61,11 @@ private fun KtCall.stringRepresentation(): String { append(": ${receiver.type.render()}") if (valueParameters.isNotEmpty()) append(", ") } - valueParameters.joinTo(this) { parameter -> - "${parameter.name}: ${parameter.annotatedType.type.render()}" - } + valueParameters.joinTo(this) { it.stringValue() } append(")") append(": ${annotatedType.type.render()}") } - is KtValueParameterSymbol -> "$name: ${annotatedType.type.render()}" + is KtValueParameterSymbol -> "${if (isVararg) "vararg " else ""}$name: ${annotatedType.type.render()}" is KtSuccessCallTarget -> symbol.stringValue() is KtErrorCallTarget -> "ERR<${this.diagnostic.defaultMessage}, [${candidates.joinToString { it.stringValue() }}]>" is Boolean -> toString() diff --git a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/fir/frontend/api/fir/ResolveCallTestGenerated.java b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/fir/frontend/api/fir/ResolveCallTestGenerated.java index b7d5432e48d..a4d0d231135 100644 --- a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/fir/frontend/api/fir/ResolveCallTestGenerated.java +++ b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/fir/frontend/api/fir/ResolveCallTestGenerated.java @@ -54,6 +54,36 @@ public class ResolveCallTestGenerated extends AbstractResolveCallTest { runTest("idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallInTheSameFile.kt"); } + @Test + @TestMetadata("functionCallWithLambdaArgument.kt") + public void testFunctionCallWithLambdaArgument() throws Exception { + runTest("idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithLambdaArgument.kt"); + } + + @Test + @TestMetadata("functionCallWithNamedArgument.kt") + public void testFunctionCallWithNamedArgument() throws Exception { + runTest("idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithNamedArgument.kt"); + } + + @Test + @TestMetadata("functionCallWithNonTrailingLambdaArgument.kt") + public void testFunctionCallWithNonTrailingLambdaArgument() throws Exception { + runTest("idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithNonTrailingLambdaArgument.kt"); + } + + @Test + @TestMetadata("functionCallWithSpreadArgument.kt") + public void testFunctionCallWithSpreadArgument() throws Exception { + runTest("idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithSpreadArgument.kt"); + } + + @Test + @TestMetadata("functionCallWithVarargArgument.kt") + public void testFunctionCallWithVarargArgument() throws Exception { + runTest("idea/idea-frontend-fir/testData/analysisSession/resolveCall/functionCallWithVarargArgument.kt"); + } + @Test @TestMetadata("functionWithReceiverCall.kt") public void testFunctionWithReceiverCall() throws Exception {