Convert lambda to reference: handle named arguments more precisely

For trailing lambda intention inserts parameter names for all arguments
if at least one argument used default value.
Otherwise it just keeps existing named arguments.

So #KT-20349 Fixed
This commit is contained in:
Toshiaki Kameyama
2017-10-10 12:38:56 +03:00
committed by Mikhail Glukhikh
parent 4c4427c280
commit fa03632197
11 changed files with 88 additions and 8 deletions
@@ -178,16 +178,16 @@ open class ConvertLambdaToReferenceIntention(text: String) :
// Parameters with default value
val valueParameters = outerCalleeDescriptor.valueParameters
val arguments = outerCallExpression.valueArguments.filter { it !is KtLambdaArgument }
val useNamedArguments = valueParameters.any { it.hasDefaultValue() } || arguments.any { it.getArgumentName() != null }
val hadDefaultValues = valueParameters.size - 1 > arguments.size
val useNamedArguments = valueParameters.any { it.hasDefaultValue() } && hadDefaultValues
|| arguments.any { it.getArgumentName() != null }
if (useNamedArguments && arguments.size > valueParameters.size) return
val newArgumentList = factory.buildValueArgumentList {
appendFixedText("(")
arguments.forEachIndexed { i, argument ->
if (useNamedArguments) {
val argumentName = argument.getArgumentName()?.asName
val name = argumentName ?: valueParameters[i].name
appendName(name)
arguments.forEach { argument ->
val argumentName = argument.getArgumentName()
if (useNamedArguments && argumentName != null) {
appendName(argumentName.asName)
appendFixedText(" = ")
}
appendExpression(argument.getArgumentExpression())
@@ -0,0 +1,7 @@
class Transformer {
fun transform(x: Int = 0, y: Int = 1, f: (Int) -> Int) = f(x + y)
}
fun bar(x: Int) = x * x
val y = Transformer().transform(2, y = 3) { <caret>bar(it) }
@@ -0,0 +1,7 @@
class Transformer {
fun transform(x: Int = 0, y: Int = 1, f: (Int) -> Int) = f(x + y)
}
fun bar(x: Int) = x * x
val y = Transformer().transform(2, y = 3, f = ::bar)
@@ -0,0 +1,7 @@
class Transformer {
fun transform(x: Int = 0, y: Int = 1, f: (Int) -> Int) = f(x + y)
}
fun bar(x: Int) = x * x
val y = Transformer().transform(x = 2, y = 3) { <caret>bar(it) }
@@ -0,0 +1,7 @@
class Transformer {
fun transform(x: Int = 0, y: Int = 1, f: (Int) -> Int) = f(x + y)
}
fun bar(x: Int) = x * x
val y = Transformer().transform(x = 2, y = 3, f = ::bar)
@@ -4,4 +4,4 @@ class Transformer {
fun bar(x: Int) = x * x
val y = Transformer().transform(x = 2, f = ::bar)
val y = Transformer().transform(2, f = ::bar)
@@ -0,0 +1,7 @@
class Transformer {
fun transform(x: Int = 0, y: Int = 1, f: (Int) -> Int) = f(x + y)
}
fun bar(x: Int) = x * x
val y = Transformer().transform { <caret>bar(it) }
@@ -0,0 +1,7 @@
class Transformer {
fun transform(x: Int = 0, y: Int = 1, f: (Int) -> Int) = f(x + y)
}
fun bar(x: Int) = x * x
val y = Transformer().transform(f = ::bar)
@@ -0,0 +1,7 @@
class Transformer {
fun transform(x: Int = 0, y: Int = 1, f: (Int) -> Int) = f(x + y)
}
fun bar(x: Int) = x * x
val y = Transformer().transform(2, 3) { <caret>bar(it) }
@@ -0,0 +1,7 @@
class Transformer {
fun transform(x: Int = 0, y: Int = 1, f: (Int) -> Int) = f(x + y)
}
fun bar(x: Int) = x * x
val y = Transformer().transform(2, 3, ::bar)
@@ -5036,6 +5036,18 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
doTest(fileName);
}
@TestMetadata("defaultNamed2.kt")
public void testDefaultNamed2() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/defaultNamed2.kt");
doTest(fileName);
}
@TestMetadata("defaultNamed3.kt")
public void testDefaultNamed3() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/defaultNamed3.kt");
doTest(fileName);
}
@TestMetadata("defaultOverridden.kt")
public void testDefaultOverridden() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/defaultOverridden.kt");
@@ -5048,6 +5060,18 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
doTest(fileName);
}
@TestMetadata("defaultUnnamed2.kt")
public void testDefaultUnnamed2() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/defaultUnnamed2.kt");
doTest(fileName);
}
@TestMetadata("defaultUnnamed3.kt")
public void testDefaultUnnamed3() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/defaultUnnamed3.kt");
doTest(fileName);
}
@TestMetadata("emptyBrackets.kt")
public void testEmptyBrackets() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/emptyBrackets.kt");