From fa0363219722a6a51a507f75894e705168a0959e Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Tue, 10 Oct 2017 12:38:56 +0300 Subject: [PATCH] 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 --- .../ConvertLambdaToReferenceIntention.kt | 14 +++++------ .../convertLambdaToReference/defaultNamed2.kt | 7 ++++++ .../defaultNamed2.kt.after | 7 ++++++ .../convertLambdaToReference/defaultNamed3.kt | 7 ++++++ .../defaultNamed3.kt.after | 7 ++++++ .../defaultUnnamed.kt.after | 2 +- .../defaultUnnamed2.kt | 7 ++++++ .../defaultUnnamed2.kt.after | 7 ++++++ .../defaultUnnamed3.kt | 7 ++++++ .../defaultUnnamed3.kt.after | 7 ++++++ .../intentions/IntentionTestGenerated.java | 24 +++++++++++++++++++ 11 files changed, 88 insertions(+), 8 deletions(-) create mode 100644 idea/testData/intentions/convertLambdaToReference/defaultNamed2.kt create mode 100644 idea/testData/intentions/convertLambdaToReference/defaultNamed2.kt.after create mode 100644 idea/testData/intentions/convertLambdaToReference/defaultNamed3.kt create mode 100644 idea/testData/intentions/convertLambdaToReference/defaultNamed3.kt.after create mode 100644 idea/testData/intentions/convertLambdaToReference/defaultUnnamed2.kt create mode 100644 idea/testData/intentions/convertLambdaToReference/defaultUnnamed2.kt.after create mode 100644 idea/testData/intentions/convertLambdaToReference/defaultUnnamed3.kt create mode 100644 idea/testData/intentions/convertLambdaToReference/defaultUnnamed3.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertLambdaToReferenceIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertLambdaToReferenceIntention.kt index 48dbce51ca1..7f8fcdea7c6 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertLambdaToReferenceIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertLambdaToReferenceIntention.kt @@ -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()) diff --git a/idea/testData/intentions/convertLambdaToReference/defaultNamed2.kt b/idea/testData/intentions/convertLambdaToReference/defaultNamed2.kt new file mode 100644 index 00000000000..5aee00375e9 --- /dev/null +++ b/idea/testData/intentions/convertLambdaToReference/defaultNamed2.kt @@ -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) { bar(it) } diff --git a/idea/testData/intentions/convertLambdaToReference/defaultNamed2.kt.after b/idea/testData/intentions/convertLambdaToReference/defaultNamed2.kt.after new file mode 100644 index 00000000000..e0d410b5bec --- /dev/null +++ b/idea/testData/intentions/convertLambdaToReference/defaultNamed2.kt.after @@ -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) diff --git a/idea/testData/intentions/convertLambdaToReference/defaultNamed3.kt b/idea/testData/intentions/convertLambdaToReference/defaultNamed3.kt new file mode 100644 index 00000000000..0dcc0c5493f --- /dev/null +++ b/idea/testData/intentions/convertLambdaToReference/defaultNamed3.kt @@ -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) { bar(it) } diff --git a/idea/testData/intentions/convertLambdaToReference/defaultNamed3.kt.after b/idea/testData/intentions/convertLambdaToReference/defaultNamed3.kt.after new file mode 100644 index 00000000000..0b628489b66 --- /dev/null +++ b/idea/testData/intentions/convertLambdaToReference/defaultNamed3.kt.after @@ -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) diff --git a/idea/testData/intentions/convertLambdaToReference/defaultUnnamed.kt.after b/idea/testData/intentions/convertLambdaToReference/defaultUnnamed.kt.after index 425a8787169..d319aaa7d7c 100644 --- a/idea/testData/intentions/convertLambdaToReference/defaultUnnamed.kt.after +++ b/idea/testData/intentions/convertLambdaToReference/defaultUnnamed.kt.after @@ -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) diff --git a/idea/testData/intentions/convertLambdaToReference/defaultUnnamed2.kt b/idea/testData/intentions/convertLambdaToReference/defaultUnnamed2.kt new file mode 100644 index 00000000000..2b9924045dc --- /dev/null +++ b/idea/testData/intentions/convertLambdaToReference/defaultUnnamed2.kt @@ -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 { bar(it) } diff --git a/idea/testData/intentions/convertLambdaToReference/defaultUnnamed2.kt.after b/idea/testData/intentions/convertLambdaToReference/defaultUnnamed2.kt.after new file mode 100644 index 00000000000..03dbedf005e --- /dev/null +++ b/idea/testData/intentions/convertLambdaToReference/defaultUnnamed2.kt.after @@ -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) diff --git a/idea/testData/intentions/convertLambdaToReference/defaultUnnamed3.kt b/idea/testData/intentions/convertLambdaToReference/defaultUnnamed3.kt new file mode 100644 index 00000000000..93b9b304eea --- /dev/null +++ b/idea/testData/intentions/convertLambdaToReference/defaultUnnamed3.kt @@ -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(it) } diff --git a/idea/testData/intentions/convertLambdaToReference/defaultUnnamed3.kt.after b/idea/testData/intentions/convertLambdaToReference/defaultUnnamed3.kt.after new file mode 100644 index 00000000000..9c027cb9caa --- /dev/null +++ b/idea/testData/intentions/convertLambdaToReference/defaultUnnamed3.kt.after @@ -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) \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index bade2b9b37c..a4a4edf5459 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -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");