diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/MoveVariableDeclarationIntoWhenInspection.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/MoveVariableDeclarationIntoWhenInspection.kt index 18150e971ac1..aba66c79738f 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/MoveVariableDeclarationIntoWhenInspection.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/MoveVariableDeclarationIntoWhenInspection.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.idea.core.moveCaret import org.jetbrains.kotlin.idea.intentions.loopToCallChain.countUsages import org.jetbrains.kotlin.idea.intentions.loopToCallChain.previousStatement import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.lexer.KtTokens.ELVIS import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.* @@ -31,10 +32,7 @@ class MoveVariableDeclarationIntoWhenInspection : AbstractKotlinInspection(), Cl val property = expression.findDeclarationNear() ?: return val identifier = property.nameIdentifier ?: return val initializer = property.initializer ?: return - if (!initializer.isOneLiner()) return - if (initializer.anyDescendantOfType { - it is KtThrowExpression || it is KtReturnExpression || it is KtBreakExpression || it is KtContinueExpression - }) return + if (initializer.isComplex()) return val action = property.action(expression) if (action == Action.NOTHING) return @@ -49,6 +47,17 @@ class MoveVariableDeclarationIntoWhenInspection : AbstractKotlinInspection(), Cl }) } +private fun KtExpression.isComplex(): Boolean { + if (!isOneLiner()) return true + return anyDescendantOfType { + it is KtThrowExpression || it is KtReturnExpression || it is KtBreakExpression || it is KtContinueExpression || + it is KtIfExpression || it is KtWhenExpression || it is KtTryExpression || it is KtLambdaExpression || it.isElvisExpression() + } +} + +private fun KtExpression.isElvisExpression(): Boolean = + this is KtBinaryExpression && operationToken == ELVIS + private enum class Action { NOTHING, MOVE, diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java index 3dc192fc302c..d39daaf6768e 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -7677,11 +7677,31 @@ public abstract class LocalInspectionTestGenerated extends AbstractLocalInspecti runTest("testData/inspectionsLocal/moveVariableDeclarationIntoWhen/multiLineWithOneLineInitializer.kt"); } + @TestMetadata("notApplicableElvis.kt") + public void testNotApplicableElvis() throws Exception { + runTest("testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableElvis.kt"); + } + + @TestMetadata("notApplicableIf.kt") + public void testNotApplicableIf() throws Exception { + runTest("testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableIf.kt"); + } + + @TestMetadata("notApplicableIf2.kt") + public void testNotApplicableIf2() throws Exception { + runTest("testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableIf2.kt"); + } + @TestMetadata("notApplicableInBinaryExpression.kt") public void testNotApplicableInBinaryExpression() throws Exception { runTest("testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableInBinaryExpression.kt"); } + @TestMetadata("notApplicableLambda.kt") + public void testNotApplicableLambda() throws Exception { + runTest("testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableLambda.kt"); + } + @TestMetadata("notApplicableMultiLineWithOneLineInitializer.kt") public void testNotApplicableMultiLineWithOneLineInitializer() throws Exception { runTest("testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableMultiLineWithOneLineInitializer.kt"); @@ -7702,6 +7722,11 @@ public abstract class LocalInspectionTestGenerated extends AbstractLocalInspecti runTest("testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableSideEffect.kt"); } + @TestMetadata("notApplicableTry.kt") + public void testNotApplicableTry() throws Exception { + runTest("testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableTry.kt"); + } + @TestMetadata("notApplicableUsedInOtherScope.kt") public void testNotApplicableUsedInOtherScope() throws Exception { runTest("testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableUsedInOtherScope.kt"); @@ -7712,6 +7737,11 @@ public abstract class LocalInspectionTestGenerated extends AbstractLocalInspecti runTest("testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableVar.kt"); } + @TestMetadata("notApplicableWhen.kt") + public void testNotApplicableWhen() throws Exception { + runTest("testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableWhen.kt"); + } + @TestMetadata("simple.kt") public void testSimple() throws Exception { runTest("testData/inspectionsLocal/moveVariableDeclarationIntoWhen/simple.kt"); diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableElvis.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableElvis.kt new file mode 100644 index 000000000000..12fd073eb8af --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableElvis.kt @@ -0,0 +1,10 @@ +// PROBLEM: none +fun foo() { + val a = 1 ?: 2 ?: 3 + when (a) { + 1 -> { + } + else -> { + } + } +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableIf.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableIf.kt new file mode 100644 index 000000000000..c02ddfb5de0b --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableIf.kt @@ -0,0 +1,10 @@ +// PROBLEM: none +fun foo() { + val a = if (true) 0 else 1 + when (a) { + 1 -> { + } + else -> { + } + } +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableIf2.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableIf2.kt new file mode 100644 index 000000000000..bd004d9aae05 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableIf2.kt @@ -0,0 +1,10 @@ +// PROBLEM: none +fun foo() { + val a = ((if (true) 0 else 1)) + when (a) { + 1 -> { + } + else -> { + } + } +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableLambda.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableLambda.kt new file mode 100644 index 000000000000..817e440c5804 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableLambda.kt @@ -0,0 +1,11 @@ +// PROBLEM: none +// WITH_STDLIB +fun foo() { + val a = listOf(1).filter { it > 0 }.max() + when (a) { + 1 -> { + } + else -> { + } + } +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableTry.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableTry.kt new file mode 100644 index 000000000000..260686542301 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableTry.kt @@ -0,0 +1,10 @@ +// PROBLEM: none +fun foo() { + val a = try { 1 } catch (e: Exception) { 2 } + when (a) { + 1 -> { + } + else -> { + } + } +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableWhen.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableWhen.kt new file mode 100644 index 000000000000..56cc389bbb6d --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/notApplicableWhen.kt @@ -0,0 +1,10 @@ +// PROBLEM: none +fun foo() { + val a = when { true -> { 0 } else -> { 1 } } + when (a) { + 1 -> { + } + else -> { + } + } +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/withComment2.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/withComment2.kt index 29682e19ff6c..a3f7cb84f607 100644 --- a/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/withComment2.kt +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/withComment2.kt @@ -1,5 +1,5 @@ -fun foo(style: Int?): Int { - val a = style ?: 0 // comment +fun foo(style: Int): Int { + val a = style // comment return when (a) { 0 -> 0 else -> a diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/withComment2.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/withComment2.kt.after index 54bbe40c9aee..af2605b95f66 100644 --- a/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/withComment2.kt.after +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/withComment2.kt.after @@ -1,5 +1,5 @@ -fun foo(style: Int?): Int { - return when (val a = style ?: 0) { // comment +fun foo(style: Int): Int { + return when (val a = style) { // comment 0 -> 0 else -> a } diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/withComment3.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/withComment3.kt index 3dd0c797ff8f..0b726af786e1 100644 --- a/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/withComment3.kt +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/withComment3.kt @@ -1,5 +1,5 @@ -fun foo(style: Int?): Int { - val a = style ?: 0 // comment +fun foo(style: Int): Int { + val a = style // comment return when (a) { 0 -> 0 else -> a } diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/withComment3.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/withComment3.kt.after index 54bbe40c9aee..af2605b95f66 100644 --- a/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/withComment3.kt.after +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/withComment3.kt.after @@ -1,5 +1,5 @@ -fun foo(style: Int?): Int { - return when (val a = style ?: 0) { // comment +fun foo(style: Int): Int { + return when (val a = style) { // comment 0 -> 0 else -> a } diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/withComment4.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/withComment4.kt index a92815b87476..7fbff3349b2e 100644 --- a/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/withComment4.kt +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/withComment4.kt @@ -1,5 +1,5 @@ fun foo(style: Int?) { - val a = style ?: 0 // comment + val a = style // comment when (a) { 0 -> {} else -> {} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/withComment4.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/withComment4.kt.after index 9baa0faa331d..4c0559f090e4 100644 --- a/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/withComment4.kt.after +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/withComment4.kt.after @@ -1,5 +1,5 @@ fun foo(style: Int?) { - when (style ?: 0) { // comment + when (style) { // comment 0 -> {} else -> {} }