diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInsight/surroundWith/MoveDeclarationsOutHelper.kt b/idea/src/org/jetbrains/kotlin/idea/codeInsight/surroundWith/MoveDeclarationsOutHelper.kt index 74c8f9e35d5..2c1a6f7976c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInsight/surroundWith/MoveDeclarationsOutHelper.kt +++ b/idea/src/org/jetbrains/kotlin/idea/codeInsight/surroundWith/MoveDeclarationsOutHelper.kt @@ -50,17 +50,22 @@ fun move(container: PsiElement, statements: Array, generateDefaultIn val scope = LocalSearchScope(container) val lastStatementOffset = statements[statements.size - 1].textRange.endOffset - for (statement in statements) { + statements.forEachIndexed { i, statement -> if (needToDeclareOut(statement, lastStatementOffset, scope)) { val property = statement as? KtProperty if (property?.initializer != null) { - var declaration = createVariableDeclaration(property, generateDefaultInitializers) - declaration = container.addBefore(declaration, dummyFirstStatement) as KtProperty - propertiesDeclarations.add(declaration) - container.addAfter(psiFactory.createNewLine(), declaration) - - val assignment = createVariableAssignment(property) - resultStatements.add(property.replace(assignment)) + if (i == statements.size - 1) { + kotlinStyleDeclareOut(container, dummyFirstStatement, resultStatements, propertiesDeclarations, property) + } else { + declareOut( + container, + dummyFirstStatement, + generateDefaultInitializers, + resultStatements, + propertiesDeclarations, + property + ) + } } else { val newStatement = container.addBefore(statement, dummyFirstStatement) container.addAfter(psiFactory.createNewLine(), newStatement) @@ -79,6 +84,38 @@ fun move(container: PsiElement, statements: Array, generateDefaultIn return PsiUtilCore.toPsiElementArray(resultStatements) } +private fun kotlinStyleDeclareOut( + container: PsiElement, + dummyFirstStatement: PsiElement, + resultStatements: ArrayList, + propertiesDeclarations: ArrayList, + property: KtProperty +) { + val name = property.name ?: return + var declaration = KtPsiFactory(property).createProperty(name, property.typeReference?.text, property.isVar, null) + declaration = container.addBefore(declaration, dummyFirstStatement) as KtProperty + container.addAfter(KtPsiFactory(declaration).createEQ(), declaration) + propertiesDeclarations.add(declaration) + property.initializer?.let { + resultStatements.add(property.replace(it)) + } +} + +private fun declareOut( + container: PsiElement, + dummyFirstStatement: PsiElement, + generateDefaultInitializers: Boolean, + resultStatements: ArrayList, + propertiesDeclarations: ArrayList, + property: KtProperty +) { + var declaration = createVariableDeclaration(property, generateDefaultInitializers) + declaration = container.addBefore(declaration, dummyFirstStatement) as KtProperty + propertiesDeclarations.add(declaration) + val assignment = createVariableAssignment(property) + resultStatements.add(property.replace(assignment)) +} + private fun createVariableAssignment(property: KtProperty): KtBinaryExpression { val propertyName = property.name ?: error("Property should have a name " + property.text) val assignment = KtPsiFactory(property).createExpression("$propertyName = x") as KtBinaryExpression @@ -105,11 +142,10 @@ private fun getPropertyType(property: KtProperty): KotlinType { private fun createProperty(property: KtProperty, propertyType: KotlinType, initializer: String?): KtProperty { val typeRef = property.typeReference - var typeString: String? = null - if (typeRef != null) { - typeString = typeRef.text - } else if (!propertyType.isError) { - typeString = IdeDescriptorRenderers.SOURCE_CODE.renderType(propertyType) + val typeString = when { + typeRef != null -> typeRef.text + !propertyType.isError -> IdeDescriptorRenderers.SOURCE_CODE.renderType(propertyType) + else -> null } return KtPsiFactory(property).createProperty(property.name!!, typeString, property.isVar, initializer) diff --git a/idea/testData/codeInsight/surroundWith/functionLiteral/moveDeclarationsOut.kt.after b/idea/testData/codeInsight/surroundWith/functionLiteral/moveDeclarationsOut.kt.after index a434fcd3681..8557bf32892 100644 --- a/idea/testData/codeInsight/surroundWith/functionLiteral/moveDeclarationsOut.kt.after +++ b/idea/testData/codeInsight/surroundWith/functionLiteral/moveDeclarationsOut.kt.after @@ -1,9 +1,8 @@ fun foo() { val a: String - val b: String - run { + val b = run { a = "aaa" - b = "aaa" + "aaa" } a.charAt(1) diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valAndClass.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valAndClass.kt.after index 75cb35e6969..863644f2b77 100644 --- a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valAndClass.kt.after +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valAndClass.kt.after @@ -3,9 +3,9 @@ fun foo() { fun test() {} } - val d: A + val d: A = if () { - d = A() + A() } d.test() diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valOrder.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valOrder.kt.after index bf17f1d8f79..748048932d9 100644 --- a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valOrder.kt.after +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/order/valOrder.kt.after @@ -1,9 +1,8 @@ fun foo() { val a: String - val b: String - if () { + val b = if () { a = "aaa" - b = a + a } a.charAt(1) diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedType.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedType.kt.after index 946c3be5637..dd371649f35 100644 --- a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedType.kt.after +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedType.kt.after @@ -1,7 +1,6 @@ fun foo() { - val a: kotlin.test.Asserter? - if () { - a = null + val a: kotlin.test.Asserter? = if () { + null } a?.charAt(1) diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedTypeWithoutTypeRef.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedTypeWithoutTypeRef.kt.after index 73b04f16dc9..247a4048596 100644 --- a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedTypeWithoutTypeRef.kt.after +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/fullQualifiedTypeWithoutTypeRef.kt.after @@ -3,9 +3,8 @@ package test class A {} fun foo() { - val a: A - if () { - a = test.A() + val a = if () { + test.A() } a.hashCode() diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWithTypeWithInitializer.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWithTypeWithInitializer.kt.after index f9be01d644a..e2b4853b287 100644 --- a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWithTypeWithInitializer.kt.after +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWithTypeWithInitializer.kt.after @@ -1,7 +1,6 @@ fun foo() { - val a: String - if () { - a = "aaa" + val a: String = if () { + "aaa" } a.charAt(1) diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWoTypeWithInitializer.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWoTypeWithInitializer.kt.after index f9be01d644a..6fc8f9060db 100644 --- a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWoTypeWithInitializer.kt.after +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/val/valWoTypeWithInitializer.kt.after @@ -1,7 +1,6 @@ fun foo() { - val a: String - if () { - a = "aaa" + val a = if () { + "aaa" } a.charAt(1) diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/boolean.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/boolean.kt.after index 5cebb06fe79..2e7508b9f79 100644 --- a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/boolean.kt.after +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/boolean.kt.after @@ -1,7 +1,6 @@ fun foo() { - var a: Boolean = false - if () { - a = true + var a: Boolean = if () { + true } a = true } \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/nullable.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/nullable.kt.after index b6b1166c945..ca9b40dcb21 100644 --- a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/nullable.kt.after +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/nullable.kt.after @@ -1,7 +1,6 @@ fun foo() { - var a: String? = null - if () { - a = "aaa" + var a: String? = if () { + "aaa" } a = "bbb" } \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/primitiveNumbers.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/primitiveNumbers.kt.after index 30408915140..34c548b946e 100644 --- a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/primitiveNumbers.kt.after +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/defaultValue/primitiveNumbers.kt.after @@ -5,15 +5,14 @@ fun foo() { var d: Long = 0 var e: Short = 0 var f: Double = 0.0 - var g: Float = 0.0f - if () { + var g: Float = if () { a = 1 b = 1 c = 1 d = 1 e = 1 f = 1 - g = 1 + 1 } a = 2 b = 2 diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWithNotNullableTypeWithInitializer.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWithNotNullableTypeWithInitializer.kt.after index 26ed7edb07e..bd27cd09f51 100644 --- a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWithNotNullableTypeWithInitializer.kt.after +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWithNotNullableTypeWithInitializer.kt.after @@ -1,7 +1,6 @@ fun foo() { - var a: String = "" - if () { - a = "aaa" + var a: String = if () { + "aaa" } a.charAt(1) diff --git a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWoTypeWithInitializer.kt.after b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWoTypeWithInitializer.kt.after index 26ed7edb07e..4f39174ac51 100644 --- a/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWoTypeWithInitializer.kt.after +++ b/idea/testData/codeInsight/surroundWith/if/moveDeclarationsOut/var/varWoTypeWithInitializer.kt.after @@ -1,7 +1,6 @@ fun foo() { - var a: String = "" - if () { - a = "aaa" + var a = if () { + "aaa" } a.charAt(1) diff --git a/idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVal.kt.after b/idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVal.kt.after index 4168020cbe3..d6029ad661f 100644 --- a/idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVal.kt.after +++ b/idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVal.kt.after @@ -1,7 +1,6 @@ fun foo() { - val a: String? - if () { - a = "aaa" + val a: String? = if () { + "aaa" } else { } a.toString() diff --git a/idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVar.kt.after b/idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVar.kt.after index 9de6df4a8bf..fd38816403d 100644 --- a/idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVar.kt.after +++ b/idea/testData/codeInsight/surroundWith/ifElse/moveDeclarationsOutVar.kt.after @@ -1,7 +1,6 @@ fun foo() { - var a: String? - if () { - a = "aaa" + var a: String? = if () { + "aaa" } else { } a = "bbb" diff --git a/idea/testData/codeInsight/surroundWith/tryCatch/moveDeclarationsOut.kt.after b/idea/testData/codeInsight/surroundWith/tryCatch/moveDeclarationsOut.kt.after index e0215c4ccea..38ca9b2b04d 100644 --- a/idea/testData/codeInsight/surroundWith/tryCatch/moveDeclarationsOut.kt.after +++ b/idea/testData/codeInsight/surroundWith/tryCatch/moveDeclarationsOut.kt.after @@ -1,9 +1,8 @@ fun foo() { val a: String - val b: String - try { + val b = try { a = "aaa" - b = "aaa" + "aaa" } catch (e: Exception) { } diff --git a/idea/testData/codeInsight/surroundWith/tryCatch/moveDeclarationsOutSingleStatement.kt b/idea/testData/codeInsight/surroundWith/tryCatch/moveDeclarationsOutSingleStatement.kt new file mode 100644 index 00000000000..7218e0f750f --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/tryCatch/moveDeclarationsOutSingleStatement.kt @@ -0,0 +1,5 @@ +fun foo() { + val a = "aaa" + + a.charAt(1) +} \ No newline at end of file diff --git a/idea/testData/codeInsight/surroundWith/tryCatch/moveDeclarationsOutSingleStatement.kt.after b/idea/testData/codeInsight/surroundWith/tryCatch/moveDeclarationsOutSingleStatement.kt.after new file mode 100644 index 00000000000..3b5b3799e4e --- /dev/null +++ b/idea/testData/codeInsight/surroundWith/tryCatch/moveDeclarationsOutSingleStatement.kt.after @@ -0,0 +1,8 @@ +fun foo() { + val a = try { + "aaa" + } catch (e: Exception) { + } + + a.charAt(1) +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/surroundWith/SurroundWithTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/surroundWith/SurroundWithTestGenerated.java index 4d064af1272..b8232eeea8b 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/surroundWith/SurroundWithTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/surroundWith/SurroundWithTestGenerated.java @@ -587,6 +587,11 @@ public class SurroundWithTestGenerated extends AbstractSurroundWithTest { runTest("idea/testData/codeInsight/surroundWith/tryCatch/moveDeclarationsOut.kt"); } + @TestMetadata("moveDeclarationsOutSingleStatement.kt") + public void testMoveDeclarationsOutSingleStatement() throws Exception { + runTest("idea/testData/codeInsight/surroundWith/tryCatch/moveDeclarationsOutSingleStatement.kt"); + } + @TestMetadata("multiExpression.kt") public void testMultiExpression() throws Exception { runTest("idea/testData/codeInsight/surroundWith/tryCatch/multiExpression.kt");