From 877e583a96c355e366c1fdd28bacc004c6104898 Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Thu, 19 Sep 2019 09:25:40 +0900 Subject: [PATCH] Move variable declaration into `when`: don't report when property has 'return' or 'throw' #KT-31999 Fixed --- ...veVariableDeclarationIntoWhenInspection.kt | 6 ++++++ .../hasReturn.kt | 8 ++++++++ .../hasReturn2.kt | 8 ++++++++ .../hasThrow.kt | 8 ++++++++ .../hasThrow2.kt | 8 ++++++++ .../LocalInspectionTestGenerated.java | 20 +++++++++++++++++++ 6 files changed, 58 insertions(+) create mode 100644 idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/hasReturn.kt create mode 100644 idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/hasReturn2.kt create mode 100644 idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/hasThrow.kt create mode 100644 idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/hasThrow2.kt diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/MoveVariableDeclarationIntoWhenInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/MoveVariableDeclarationIntoWhenInspection.kt index 22bbcfd9de1..c308b3eaf05 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/MoveVariableDeclarationIntoWhenInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/MoveVariableDeclarationIntoWhenInspection.kt @@ -21,6 +21,7 @@ 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.psi.* +import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer import org.jetbrains.kotlin.psi.psiUtil.siblings import org.jetbrains.kotlin.psi.psiUtil.startOffset @@ -31,6 +32,7 @@ class MoveVariableDeclarationIntoWhenInspection : AbstractKotlinInspection(), Cl val subjectExpression = expression.subjectExpression ?: return val property = expression.findDeclarationNear() ?: return if (!property.isOneLiner()) return + if (property.hasReturnOrThrowExpression()) return val action = property.action(expression) if (action == Action.NOTHING) return @@ -75,6 +77,10 @@ private fun KtWhenExpression.findDeclarationNear(): KtProperty? { return previousProperty.takeIf { !it.isVar && it.hasInitializer() && it.nameIdentifier?.text == subjectExpression?.text } } +private fun KtProperty.hasReturnOrThrowExpression(): Boolean { + return this.initializer?.anyDescendantOfType { it is KtReturnExpression || it is KtThrowExpression } == true +} + private tailrec fun KtExpression.previousPropertyFromParent(): KtProperty? { val parentExpression = parent as? KtExpression ?: return null if (this != when (parentExpression) { diff --git a/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/hasReturn.kt b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/hasReturn.kt new file mode 100644 index 00000000000..1fac75b1dc0 --- /dev/null +++ b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/hasReturn.kt @@ -0,0 +1,8 @@ +// PROBLEM: none +fun test(str: String?): String? { + val some = str ?: return null + return when (some) { + "some" -> some + else -> "" + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/hasReturn2.kt b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/hasReturn2.kt new file mode 100644 index 00000000000..6ae2d84a2af --- /dev/null +++ b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/hasReturn2.kt @@ -0,0 +1,8 @@ +// PROBLEM: none +fun test(str: String?): String? { + val some = if (str != null) str + str else return null + return when (some) { + "some" -> some + else -> "" + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/hasThrow.kt b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/hasThrow.kt new file mode 100644 index 00000000000..e5e9d1fc28e --- /dev/null +++ b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/hasThrow.kt @@ -0,0 +1,8 @@ +// PROBLEM: none +fun test(str: String?): String? { + val some = str ?: throw Exception() + return when (some) { + "some" -> some + else -> "" + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/hasThrow2.kt b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/hasThrow2.kt new file mode 100644 index 00000000000..07d5c502222 --- /dev/null +++ b/idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/hasThrow2.kt @@ -0,0 +1,8 @@ +// PROBLEM: none +fun test(str: String?): String? { + val some = if (str != null) str + str else throw Exception() + return when (some) { + "some" -> some + else -> "" + } +} \ 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 2d12a360b9e..21d8342dc3e 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -6093,6 +6093,26 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true); } + @TestMetadata("hasReturn.kt") + public void testHasReturn() throws Exception { + runTest("idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/hasReturn.kt"); + } + + @TestMetadata("hasReturn2.kt") + public void testHasReturn2() throws Exception { + runTest("idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/hasReturn2.kt"); + } + + @TestMetadata("hasThrow.kt") + public void testHasThrow() throws Exception { + runTest("idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/hasThrow.kt"); + } + + @TestMetadata("hasThrow2.kt") + public void testHasThrow2() throws Exception { + runTest("idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/hasThrow2.kt"); + } + @TestMetadata("inBinaryExpression.kt") public void testInBinaryExpression() throws Exception { runTest("idea/testData/inspectionsLocal/moveVariableDeclarationIntoWhen/inBinaryExpression.kt");