Lambda to reference: correct handling of named arguments using resolved call #KT-14550 Fixed
This commit is contained in:
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.idea.util.approximateFlexibleTypes
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.FUNCTION
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.REFERENCE_TARGET
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
|
||||
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
|
||||
import org.jetbrains.kotlin.types.isDynamic
|
||||
@@ -130,10 +131,13 @@ class ConvertLambdaToReferenceIntention : SelfTargetingOffsetIndependentIntentio
|
||||
// Same lambda / references function parameter order
|
||||
if (callableExpression is KtCallExpression) {
|
||||
if (lambdaValueParameters.size < receiverShift + callableExpression.valueArguments.size) return false
|
||||
callableExpression.valueArguments.forEachIndexed { i, argument ->
|
||||
val argumentExpression = argument.getArgumentExpression() as? KtNameReferenceExpression ?: return false
|
||||
val resolvedCall = callableExpression.getResolvedCall(context) ?: return false
|
||||
resolvedCall.valueArguments.entries.forEach { (valueParameter, resolvedArgument) ->
|
||||
val argumentExpression =
|
||||
resolvedArgument.arguments.singleOrNull()?.getArgumentExpression() as? KtNameReferenceExpression
|
||||
?: return false
|
||||
val argumentTarget = context[REFERENCE_TARGET, argumentExpression] as? ValueParameterDescriptor ?: return false
|
||||
if (argumentTarget != lambdaValueParameters[i + receiverShift]) return false
|
||||
if (argumentTarget != lambdaValueParameters[valueParameter.index + receiverShift]) return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
fun foo(x: Int, y: Int) = x + y
|
||||
|
||||
val x = { y: Int, x: Int <caret>-> foo(y = x, x = y) }
|
||||
@@ -0,0 +1,3 @@
|
||||
fun foo(x: Int, y: Int) = x + y
|
||||
|
||||
val x = ::foo
|
||||
@@ -0,0 +1,5 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
fun foo(x: Int, y: Int) = x + y
|
||||
|
||||
val x = { x: Int, y: Int <caret>-> foo(y = x, x = y) }
|
||||
@@ -4087,6 +4087,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("goodNamedOrder.kt")
|
||||
public void testGoodNamedOrder() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/goodNamedOrder.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inner.kt")
|
||||
public void testInner() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/inner.kt");
|
||||
@@ -4213,6 +4219,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("wrongNamedOrder.kt")
|
||||
public void testWrongNamedOrder() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/wrongNamedOrder.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("wrongParameterNumber.kt")
|
||||
public void testWrongParameterNumber() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/wrongParameterNumber.kt");
|
||||
|
||||
Reference in New Issue
Block a user