diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/MoveVariableDeclarationIntoWhenInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/MoveVariableDeclarationIntoWhenInspection.kt index b90df0a41f4..44d02d395a9 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/MoveVariableDeclarationIntoWhenInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/MoveVariableDeclarationIntoWhenInspection.kt @@ -60,10 +60,26 @@ private fun KtProperty.action(element: KtElement): Action = when (val elementUsa } private fun KtWhenExpression.findDeclarationNear(): KtProperty? { - val previousProperty = previousStatement() as? KtProperty ?: return null + val previousProperty = previousStatement() as? KtProperty + ?: previousPropertyFromParent() + ?: return null return previousProperty.takeIf { !it.isVar && it.hasInitializer() && it.nameIdentifier?.text == subjectExpression?.text } } +private tailrec fun KtExpression.previousPropertyFromParent(): KtProperty? { + val parentExpression = parent as? KtExpression ?: return null + if (this != when (parentExpression) { + is KtProperty -> parentExpression.initializer + is KtReturnExpression -> parentExpression.returnedExpression + is KtBinaryExpression -> parentExpression.left + is KtUnaryExpression -> parentExpression.baseExpression + else -> null + } + ) return null + + return parentExpression.previousStatement() as? KtProperty ?: parentExpression.previousPropertyFromParent() +} + private class VariableDeclarationIntoWhenFix( private val actionName: String, private val subjectExpressionPointer: SmartPsiElementPointer, diff --git a/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inBinaryExpression.kt b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inBinaryExpression.kt new file mode 100644 index 00000000000..36c987a6774 --- /dev/null +++ b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inBinaryExpression.kt @@ -0,0 +1,9 @@ +fun test() = true + +fun foo(): Int { + val a = test() + return when (a) { + true -> 42 + else -> null + } ?: 55 +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inBinaryExpression.kt.after b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inBinaryExpression.kt.after new file mode 100644 index 00000000000..827b11ec4bf --- /dev/null +++ b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inBinaryExpression.kt.after @@ -0,0 +1,8 @@ +fun test() = true + +fun foo(): Int { + return when (test()) { + true -> 42 + else -> null + } ?: 55 +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inProperty.kt b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inProperty.kt new file mode 100644 index 00000000000..5f9cc7a1b9c --- /dev/null +++ b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inProperty.kt @@ -0,0 +1,9 @@ +fun test() = 42 + +fun foo() { + val a = test() + val b = when (a) { + 1 -> a + else -> 24 + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inProperty.kt.after b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inProperty.kt.after new file mode 100644 index 00000000000..f0ec4ff2d2e --- /dev/null +++ b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inProperty.kt.after @@ -0,0 +1,8 @@ +fun test() = 42 + +fun foo() { + val b = when (val a = test()) { + 1 -> a + else -> 24 + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inReturnExpression.kt b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inReturnExpression.kt new file mode 100644 index 00000000000..156ec011a6a --- /dev/null +++ b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inReturnExpression.kt @@ -0,0 +1,9 @@ +fun test() = 42 + +fun foo(): Int { + val a = test() + return when (a) { + 1 -> a + else -> 24 + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inReturnExpression.kt.after b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inReturnExpression.kt.after new file mode 100644 index 00000000000..e0223fa91c4 --- /dev/null +++ b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inReturnExpression.kt.after @@ -0,0 +1,8 @@ +fun test() = 42 + +fun foo(): Int { + return when (val a = test()) { + 1 -> a + else -> 24 + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inUnaryAndProperty.kt b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inUnaryAndProperty.kt new file mode 100644 index 00000000000..7a6925f39ae --- /dev/null +++ b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inUnaryAndProperty.kt @@ -0,0 +1,9 @@ +fun test() = true + +fun foo() { + val a = test() + val b = !when (a) { + true -> true + else -> false + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inUnaryAndProperty.kt.after b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inUnaryAndProperty.kt.after new file mode 100644 index 00000000000..ea490fc9657 --- /dev/null +++ b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inUnaryAndProperty.kt.after @@ -0,0 +1,8 @@ +fun test() = true + +fun foo() { + val b = !when (test()) { + true -> true + else -> false + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableInBinaryExpression.kt b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableInBinaryExpression.kt new file mode 100644 index 00000000000..92bca71df78 --- /dev/null +++ b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableInBinaryExpression.kt @@ -0,0 +1,10 @@ +// PROBLEM: none +fun test() = true + +fun foo(): Int { + val a = test() + return null ?: when (a) { + true -> 42 + else -> 5 + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java index ad3432354f4..4b833afd7a6 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -4357,6 +4357,31 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true); } + @TestMetadata("inBinaryExpression.kt") + public void testInBinaryExpression() throws Exception { + runTest("idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inBinaryExpression.kt"); + } + + @TestMetadata("inProperty.kt") + public void testInProperty() throws Exception { + runTest("idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inProperty.kt"); + } + + @TestMetadata("inReturnExpression.kt") + public void testInReturnExpression() throws Exception { + runTest("idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inReturnExpression.kt"); + } + + @TestMetadata("inUnaryAndProperty.kt") + public void testInUnaryAndProperty() throws Exception { + runTest("idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inUnaryAndProperty.kt"); + } + + @TestMetadata("notApplicableInBinaryExpression.kt") + public void testNotApplicableInBinaryExpression() throws Exception { + runTest("idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableInBinaryExpression.kt"); + } + @TestMetadata("notApplicableOtherName.kt") public void testNotApplicableOtherName() throws Exception { runTest("idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableOtherName.kt");