From feb393e4c8b9052bc704a42e21f4a45e64f7c44d Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Mon, 8 Sep 2014 18:57:03 +0400 Subject: [PATCH] Extract Function: Merge initialized declarations on call site when possible --- .../extractFunction/extractorUtil.kt | 19 +++++++++++++++++++ ...irOfInitalizersWithNonLocalUsages.kt.after | 4 +--- .../pairOfVarInitalizersWithNonLocalUsages.kt | 7 +++++++ ...fVarInitalizersWithNonLocalUsages.kt.after | 12 ++++++++++++ .../valAndVarInitalizersWithNonLocalUsages.kt | 7 +++++++ ...dVarInitalizersWithNonLocalUsages.kt.after | 14 ++++++++++++++ .../JetExtractionTestGenerated.java | 12 ++++++++++++ 7 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 idea/testData/refactoring/extractFunction/controlFlow/outputValues/pairOfVarInitalizersWithNonLocalUsages.kt create mode 100644 idea/testData/refactoring/extractFunction/controlFlow/outputValues/pairOfVarInitalizersWithNonLocalUsages.kt.after create mode 100644 idea/testData/refactoring/extractFunction/controlFlow/outputValues/valAndVarInitalizersWithNonLocalUsages.kt create mode 100644 idea/testData/refactoring/extractFunction/controlFlow/outputValues/valAndVarInitalizersWithNonLocalUsages.kt.after diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/extractFunction/extractorUtil.kt b/idea/src/org/jetbrains/jet/plugin/refactoring/extractFunction/extractorUtil.kt index ded70c63f72..3016be27a94 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/extractFunction/extractorUtil.kt +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/extractFunction/extractorUtil.kt @@ -52,6 +52,7 @@ import org.jetbrains.jet.lang.psi.JetReturnExpression import org.jetbrains.jet.plugin.refactoring.JetNameValidatorImpl import org.jetbrains.jet.plugin.refactoring.JetNameSuggester import org.jetbrains.jet.plugin.refactoring.isMultiLine +import org.jetbrains.jet.plugin.refactoring.extractFunction.OutputValueBoxer.AsTuple fun ExtractableCodeDescriptor.getDeclarationText( options: ExtractionGeneratorOptions = ExtractionGeneratorOptions.DEFAULT, @@ -311,6 +312,24 @@ fun ExtractableCodeDescriptor.generateDeclaration(options: ExtractionGeneratorOp val newLine = psiFactory.createNewLine() + if (controlFlow.outputValueBoxer is AsTuple && controlFlow.outputValues.size > 1 && controlFlow.outputValues.all { it is Initializer }) { + val declarationsToMerge = controlFlow.outputValues.map { (it as Initializer).initializedDeclaration } + val isVar = declarationsToMerge.first().isVar() + if (declarationsToMerge.all { it.isVar() == isVar }) { + controlFlow.declarationsToCopy.subtract(declarationsToMerge).forEach { + block.addBefore(psiFactory.createDeclaration(it.getText()!!), anchorInBlock) as JetDeclaration + block.addBefore(newLine, anchorInBlock) + } + + val entries = declarationsToMerge.map { p -> p.getName() + (p.getTypeRef()?.let { ": ${it.getText()}" } ?: "") } + anchorInBlock?.replace( + psiFactory.createDeclaration("${if (isVar) "var" else "val"} (${entries.joinToString()}) = $callText") + ) + + return + } + } + val inlinableCall = controlFlow.outputValues.size <= 1 val unboxingExpressions = if (inlinableCall) { diff --git a/idea/testData/refactoring/extractFunction/controlFlow/outputValues/pairOfInitalizersWithNonLocalUsages.kt.after b/idea/testData/refactoring/extractFunction/controlFlow/outputValues/pairOfInitalizersWithNonLocalUsages.kt.after index df721a0addb..8f9bb8a5b72 100644 --- a/idea/testData/refactoring/extractFunction/controlFlow/outputValues/pairOfInitalizersWithNonLocalUsages.kt.after +++ b/idea/testData/refactoring/extractFunction/controlFlow/outputValues/pairOfInitalizersWithNonLocalUsages.kt.after @@ -1,9 +1,7 @@ // WITH_RUNTIME // SIBLING: fun foo() { - val pair = pair() - val a = pair.first - val b = pair.second + val (a, b) = pair() println(a + b) } diff --git a/idea/testData/refactoring/extractFunction/controlFlow/outputValues/pairOfVarInitalizersWithNonLocalUsages.kt b/idea/testData/refactoring/extractFunction/controlFlow/outputValues/pairOfVarInitalizersWithNonLocalUsages.kt new file mode 100644 index 00000000000..476e5c9d163 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/controlFlow/outputValues/pairOfVarInitalizersWithNonLocalUsages.kt @@ -0,0 +1,7 @@ +// WITH_RUNTIME +// SIBLING: +fun foo() { + var a = 1 + var b = 2 + println(a + b) +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/controlFlow/outputValues/pairOfVarInitalizersWithNonLocalUsages.kt.after b/idea/testData/refactoring/extractFunction/controlFlow/outputValues/pairOfVarInitalizersWithNonLocalUsages.kt.after new file mode 100644 index 00000000000..c2774f59985 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/controlFlow/outputValues/pairOfVarInitalizersWithNonLocalUsages.kt.after @@ -0,0 +1,12 @@ +// WITH_RUNTIME +// SIBLING: +fun foo() { + var (a, b) = pair() + println(a + b) +} + +private fun pair(): Pair { + var a = 1 + var b = 2 + return Pair(a, b) +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/controlFlow/outputValues/valAndVarInitalizersWithNonLocalUsages.kt b/idea/testData/refactoring/extractFunction/controlFlow/outputValues/valAndVarInitalizersWithNonLocalUsages.kt new file mode 100644 index 00000000000..c91fa5ab052 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/controlFlow/outputValues/valAndVarInitalizersWithNonLocalUsages.kt @@ -0,0 +1,7 @@ +// WITH_RUNTIME +// SIBLING: +fun foo() { + val a = 1 + var b = 2 + println(a + b) +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/controlFlow/outputValues/valAndVarInitalizersWithNonLocalUsages.kt.after b/idea/testData/refactoring/extractFunction/controlFlow/outputValues/valAndVarInitalizersWithNonLocalUsages.kt.after new file mode 100644 index 00000000000..c50dad9c2c5 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/controlFlow/outputValues/valAndVarInitalizersWithNonLocalUsages.kt.after @@ -0,0 +1,14 @@ +// WITH_RUNTIME +// SIBLING: +fun foo() { + val pair = pair() + val a = pair.first + var b = pair.second + println(a + b) +} + +private fun pair(): Pair { + val a = 1 + var b = 2 + return Pair(a, b) +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/JetExtractionTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/JetExtractionTestGenerated.java index 6a36fb9dfef..b13b463ed6b 100644 --- a/idea/tests/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/JetExtractionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/JetExtractionTestGenerated.java @@ -769,6 +769,12 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest { doExtractFunctionTest(fileName); } + @TestMetadata("pairOfVarInitalizersWithNonLocalUsages.kt") + public void testPairOfVarInitalizersWithNonLocalUsages() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/controlFlow/outputValues/pairOfVarInitalizersWithNonLocalUsages.kt"); + doExtractFunctionTest(fileName); + } + @TestMetadata("pairWithIf.kt") public void testPairWithIf() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/controlFlow/outputValues/pairWithIf.kt"); @@ -841,6 +847,12 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest { doExtractFunctionTest(fileName); } + @TestMetadata("valAndVarInitalizersWithNonLocalUsages.kt") + public void testValAndVarInitalizersWithNonLocalUsages() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/controlFlow/outputValues/valAndVarInitalizersWithNonLocalUsages.kt"); + doExtractFunctionTest(fileName); + } + @TestMetadata("valuesUsedInLambdaOnly.kt") public void testValuesUsedInLambdaOnly() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/controlFlow/outputValues/valuesUsedInLambdaOnly.kt");