Extract Function: Merge initialized declarations on call site when possible

This commit is contained in:
Alexey Sedunov
2014-09-08 18:57:03 +04:00
parent dd78ed6d4a
commit feb393e4c8
7 changed files with 72 additions and 3 deletions
@@ -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<JetDeclaration>(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) {
@@ -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)
}
@@ -0,0 +1,7 @@
// WITH_RUNTIME
// SIBLING:
fun foo() {
<selection>var a = 1
var b = 2</selection>
println(a + b)
}
@@ -0,0 +1,12 @@
// WITH_RUNTIME
// SIBLING:
fun foo() {
var (a, b) = pair()
println(a + b)
}
private fun pair(): Pair<Int, Int> {
var a = 1
var b = 2
return Pair(a, b)
}
@@ -0,0 +1,7 @@
// WITH_RUNTIME
// SIBLING:
fun foo() {
<selection>val a = 1
var b = 2</selection>
println(a + b)
}
@@ -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<Int, Int> {
val a = 1
var b = 2
return Pair(a, b)
}
@@ -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");