diff --git a/idea/resources/inspectionDescriptions/LiftReturnOrAssignment.html b/idea/resources/inspectionDescriptions/LiftReturnOrAssignment.html index 4f10ebf98d8..bb5754fb7a3 100644 --- a/idea/resources/inspectionDescriptions/LiftReturnOrAssignment.html +++ b/idea/resources/inspectionDescriptions/LiftReturnOrAssignment.html @@ -1,6 +1,6 @@
-This inspection reports if and when statements that can be converted to expressions +This inspection reports if, when and try statements that can be converted to expressions by lifting return or assignment out. Typical example:
fun foo(arg: Boolean): String {
diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/LiftReturnOrAssignmentInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/LiftReturnOrAssignmentInspection.kt
index fff89647eeb..5446fb84ed0 100644
--- a/idea/src/org/jetbrains/kotlin/idea/inspections/LiftReturnOrAssignmentInspection.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/inspections/LiftReturnOrAssignmentInspection.kt
@@ -30,7 +30,7 @@ class LiftReturnOrAssignmentInspection : AbstractKotlinInspection() {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession) =
object : KtVisitorVoid() {
- private fun visitIfOrWhen(expression: KtExpression, keyword: PsiElement) {
+ private fun visitIfOrWhenOrTry(expression: KtExpression, keyword: PsiElement) {
if (expression.lineCount() > LINES_LIMIT) return
if (expression.isElseIf()) return
@@ -60,12 +60,19 @@ class LiftReturnOrAssignmentInspection : AbstractKotlinInspection() {
override fun visitIfExpression(expression: KtIfExpression) {
super.visitIfExpression(expression)
- visitIfOrWhen(expression, expression.ifKeyword)
+ visitIfOrWhenOrTry(expression, expression.ifKeyword)
}
override fun visitWhenExpression(expression: KtWhenExpression) {
super.visitWhenExpression(expression)
- visitIfOrWhen(expression, expression.whenKeyword)
+ visitIfOrWhenOrTry(expression, expression.whenKeyword)
+ }
+
+ override fun visitTryExpression(expression: KtTryExpression) {
+ super.visitTryExpression(expression)
+ expression.tryKeyword?.let {
+ visitIfOrWhenOrTry(expression, it)
+ }
}
}
diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/BranchedFoldingUtils.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/BranchedFoldingUtils.kt
index dc13095d2fd..3f094c0976f 100644
--- a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/BranchedFoldingUtils.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/BranchedFoldingUtils.kt
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.idea.intentions.branches
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
+import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.lastBlockStatementOrThis
import org.jetbrains.kotlin.types.typeUtil.isNothing
@@ -75,6 +76,12 @@ object BranchedFoldingUtils {
assignment != null || collectAssignmentsAndCheck(branch?.lastBlockStatementOrThis())
}
}
+ is KtTryExpression -> {
+ e.tryBlockAndCatchBodies().all {
+ val assignment = getFoldableBranchedAssignment(it)?.run { assignments.add(this) }
+ assignment != null || collectAssignmentsAndCheck(it?.lastBlockStatementOrThis())
+ }
+ }
is KtCallExpression -> {
e.analyze().getType(e)?.isNothing() ?: false
}
@@ -83,13 +90,19 @@ object BranchedFoldingUtils {
else -> false
}
if (!collectAssignmentsAndCheck(expression)) return -1
- val firstAssignment = assignments.firstOrNull()
- if (firstAssignment != null && assignments.any { !BranchedFoldingUtils.checkAssignmentsMatch(it, firstAssignment) }) {
+ val firstAssignment = assignments.firstOrNull() ?: return 0
+ if (assignments.any { !BranchedFoldingUtils.checkAssignmentsMatch(it, firstAssignment) }) {
return -1
}
if (expression.anyDescendantOfType(
predicate = {
- it.operationToken in KtTokens.ALL_ASSIGNMENTS && it !in assignments
+ if (it.operationToken in KtTokens.ALL_ASSIGNMENTS)
+ if (it.getNonStrictParentOfType() != null)
+ BranchedFoldingUtils.checkAssignmentsMatch(it, firstAssignment)
+ else
+ it !in assignments
+ else
+ false
}
)) {
return -1
@@ -128,6 +141,12 @@ object BranchedFoldingUtils {
else -> getFoldableReturns(branches)
}
}
+ is KtTryExpression -> {
+ if (expression.finallyBlock?.finalExpression?.let { getFoldableReturns(listOf(it)) }?.isNotEmpty() == true)
+ null
+ else
+ getFoldableReturns(expression.tryBlockAndCatchBodies())
+ }
is KtCallExpression -> {
if (expression.analyze().getType(expression)?.isNothing() == true) emptyList() else null
}
@@ -157,6 +176,9 @@ object BranchedFoldingUtils {
is KtIfExpression -> e.branches.forEach { branch ->
getFoldableBranchedAssignment(branch)?.replaceWithRHS() ?: lift(branch?.lastBlockStatementOrThis())
}
+ is KtTryExpression -> e.tryBlockAndCatchBodies().forEach {
+ getFoldableBranchedAssignment(it)?.replaceWithRHS() ?: lift(it?.lastBlockStatementOrThis())
+ }
}
}
lift(expression)
@@ -177,9 +199,16 @@ object BranchedFoldingUtils {
getFoldableBranchedReturn(branch)?.replaceWithReturned() ?:
lift(branch?.lastBlockStatementOrThis())
}
+ is KtTryExpression -> e.tryBlockAndCatchBodies().forEach {
+ getFoldableBranchedReturn(it)?.replaceWithReturned() ?:
+ lift(it?.lastBlockStatementOrThis())
+ }
}
}
lift(expression)
expression.replace(KtPsiFactory(expression).createExpressionByPattern("return $0", expression))
}
+
+ private fun KtTryExpression.tryBlockAndCatchBodies(): List = listOf(tryBlock) + catchClauses.map { it.catchBody }
+
}
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToAssignment/.inspection b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/.inspection
new file mode 100644
index 00000000000..6440b445789
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/.inspection
@@ -0,0 +1 @@
+org.jetbrains.kotlin.idea.inspections.LiftReturnOrAssignmentInspection
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToAssignment/basic.kt b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/basic.kt
new file mode 100644
index 00000000000..7abac1510c4
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/basic.kt
@@ -0,0 +1,11 @@
+// HIGHLIGHT: INFORMATION
+
+fun test() {
+ var res: String? = null
+
+ try {
+ res = "success"
+ } catch (e: Exception) {
+ throw e
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToAssignment/basic.kt.after b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/basic.kt.after
new file mode 100644
index 00000000000..42a8620149d
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/basic.kt.after
@@ -0,0 +1,11 @@
+// HIGHLIGHT: INFORMATION
+
+fun test() {
+ var res: String? = null
+
+ res = try {
+ "success"
+ } catch (e: Exception) {
+ throw e
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToAssignment/block.kt b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/block.kt
new file mode 100644
index 00000000000..ebe301b9d96
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/block.kt
@@ -0,0 +1,15 @@
+// HIGHLIGHT: GENERIC_ERROR_OR_WARNING
+
+fun doSomething() {}
+
+fun test() {
+ var res: String? = null
+
+ try {
+ doSomething()
+ res = "success"
+ } catch (e: Exception) {
+ doSomething()
+ res = "failure"
+ }
+}
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToAssignment/block.kt.after b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/block.kt.after
new file mode 100644
index 00000000000..3d210c002cf
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/block.kt.after
@@ -0,0 +1,15 @@
+// HIGHLIGHT: GENERIC_ERROR_OR_WARNING
+
+fun doSomething() {}
+
+fun test() {
+ var res: String? = null
+
+ res = try {
+ doSomething()
+ "success"
+ } catch (e: Exception) {
+ doSomething()
+ "failure"
+ }
+}
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToAssignment/cascade.kt b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/cascade.kt
new file mode 100644
index 00000000000..4f33dd59753
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/cascade.kt
@@ -0,0 +1,18 @@
+// WITH_RUNTIME
+fun test() {
+ var res: String? = null
+
+ try {
+ try {
+ res = "success"
+ } catch (e: Exception) {
+ TODO()
+ }
+ } catch (e: Exception) {
+ try {
+ TODO()
+ } catch (e: Exception) {
+ res = "failure"
+ }
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToAssignment/cascade.kt.after b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/cascade.kt.after
new file mode 100644
index 00000000000..f68d5353080
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/cascade.kt.after
@@ -0,0 +1,18 @@
+// WITH_RUNTIME
+fun test() {
+ var res: String? = null
+
+ res = try {
+ try {
+ "success"
+ } catch (e: Exception) {
+ TODO()
+ }
+ } catch (e: Exception) {
+ try {
+ TODO()
+ } catch (e: Exception) {
+ "failure"
+ }
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToAssignment/finally.kt b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/finally.kt
new file mode 100644
index 00000000000..1409e5684fa
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/finally.kt
@@ -0,0 +1,13 @@
+fun doSomething() {}
+
+fun test() {
+ var res: String? = null
+
+ try {
+ res = "success"
+ } catch (e: Exception) {
+ res = "failure"
+ } finally {
+ doSomething()
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToAssignment/finally.kt.after b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/finally.kt.after
new file mode 100644
index 00000000000..919c27e80f5
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/finally.kt.after
@@ -0,0 +1,13 @@
+fun doSomething() {}
+
+fun test() {
+ var res: String? = null
+
+ res = try {
+ "success"
+ } catch (e: Exception) {
+ "failure"
+ } finally {
+ doSomething()
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToAssignment/finallyWithAssignment.kt b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/finallyWithAssignment.kt
new file mode 100644
index 00000000000..7fc088c7e94
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/finallyWithAssignment.kt
@@ -0,0 +1,12 @@
+// PROBLEM: none
+fun test() {
+ var res: String? = null
+
+ try {
+ res = "success"
+ } catch (e: Exception) {
+ res = "failure"
+ } finally {
+ res = "finally"
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToAssignment/finallyWithCascadeAssignment.kt b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/finallyWithCascadeAssignment.kt
new file mode 100644
index 00000000000..ae4816aa4c1
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/finallyWithCascadeAssignment.kt
@@ -0,0 +1,17 @@
+// PROBLEM: none
+fun doSomething() {}
+
+fun test(n: Int) {
+ var res: String? = null
+
+ try {
+ res = "success"
+ } catch (e: Exception) {
+ throw e
+ } finally {
+ if (n == 1)
+ doSomething()
+ else
+ res = "finally"
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToAssignment/finallyWithCascadeUnmatchedAssignment.kt b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/finallyWithCascadeUnmatchedAssignment.kt
new file mode 100644
index 00000000000..b2b659d3a38
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/finallyWithCascadeUnmatchedAssignment.kt
@@ -0,0 +1,17 @@
+fun doSomething() {}
+
+fun test(n: Int) {
+ var res: String? = null
+ var foo: String? = null
+
+ try {
+ res = "success"
+ } catch (e: Exception) {
+ throw e
+ } finally {
+ if (n == 1)
+ doSomething()
+ else
+ foo = "finally"
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToAssignment/finallyWithCascadeUnmatchedAssignment.kt.after b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/finallyWithCascadeUnmatchedAssignment.kt.after
new file mode 100644
index 00000000000..2a288f6b0cc
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/finallyWithCascadeUnmatchedAssignment.kt.after
@@ -0,0 +1,17 @@
+fun doSomething() {}
+
+fun test(n: Int) {
+ var res: String? = null
+ var foo: String? = null
+
+ res = try {
+ "success"
+ } catch (e: Exception) {
+ throw e
+ } finally {
+ if (n == 1)
+ doSomething()
+ else
+ foo = "finally"
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToAssignment/finallyWithUnmatchedAssignments.kt b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/finallyWithUnmatchedAssignments.kt
new file mode 100644
index 00000000000..ecc7b4d34fe
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/finallyWithUnmatchedAssignments.kt
@@ -0,0 +1,12 @@
+fun test() {
+ var res: String? = null
+ var foo: String? = null
+
+ try {
+ res = "success"
+ } catch (e: Exception) {
+ res = "failure"
+ } finally {
+ foo = "finally"
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToAssignment/finallyWithUnmatchedAssignments.kt.after b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/finallyWithUnmatchedAssignments.kt.after
new file mode 100644
index 00000000000..b659a76aa87
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/finallyWithUnmatchedAssignments.kt.after
@@ -0,0 +1,12 @@
+fun test() {
+ var res: String? = null
+ var foo: String? = null
+
+ res = try {
+ "success"
+ } catch (e: Exception) {
+ "failure"
+ } finally {
+ foo = "finally"
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToAssignment/inner.kt b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/inner.kt
new file mode 100644
index 00000000000..53fec80dfbf
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/inner.kt
@@ -0,0 +1,14 @@
+fun test(n: Int) {
+ var res: String? = null
+
+ if (n == 1) {
+ try {
+ res = "success"
+ } catch (e: Exception) {
+ throw e
+ }
+ }
+ else {
+ res = "else"
+ }
+}
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToAssignment/inner.kt.after b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/inner.kt.after
new file mode 100644
index 00000000000..7552979c131
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/inner.kt.after
@@ -0,0 +1,14 @@
+fun test(n: Int) {
+ var res: String? = null
+
+ if (n == 1) {
+ res = try {
+ "success"
+ } catch (e: Exception) {
+ throw e
+ }
+ }
+ else {
+ res = "else"
+ }
+}
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToAssignment/withUnmatchedAssignments.kt b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/withUnmatchedAssignments.kt
new file mode 100644
index 00000000000..26440dff32a
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/withUnmatchedAssignments.kt
@@ -0,0 +1,11 @@
+// PROBLEM: none
+fun test() {
+ var res: String? = null
+ var foo: String? = null
+
+ try {
+ res = "success"
+ } catch (e: Exception) {
+ foo = "exception"
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToAssignment/withoutTerminatingAssignment.kt b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/withoutTerminatingAssignment.kt
new file mode 100644
index 00000000000..a4ab7eb3fbc
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToAssignment/withoutTerminatingAssignment.kt
@@ -0,0 +1,13 @@
+// PROBLEM: none
+fun doSomething() {}
+
+fun test() {
+ var res: String? = null
+
+ try {
+ res = "success"
+ } catch (e: Exception) {
+ res = "failure"
+ doSomething()
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToReturn/.inspection b/idea/testData/inspectionsLocal/liftOut/tryToReturn/.inspection
new file mode 100644
index 00000000000..6440b445789
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToReturn/.inspection
@@ -0,0 +1 @@
+org.jetbrains.kotlin.idea.inspections.LiftReturnOrAssignmentInspection
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToReturn/basic.kt b/idea/testData/inspectionsLocal/liftOut/tryToReturn/basic.kt
new file mode 100644
index 00000000000..36cc2a70eb7
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToReturn/basic.kt
@@ -0,0 +1,9 @@
+// HIGHLIGHT: INFORMATION
+
+fun test(): String {
+ try {
+ return "success"
+ } catch (e: Exception) {
+ throw e
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToReturn/basic.kt.after b/idea/testData/inspectionsLocal/liftOut/tryToReturn/basic.kt.after
new file mode 100644
index 00000000000..a149d62093a
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToReturn/basic.kt.after
@@ -0,0 +1,9 @@
+// HIGHLIGHT: INFORMATION
+
+fun test(): String {
+ return try {
+ "success"
+ } catch (e: Exception) {
+ throw e
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToReturn/block.kt b/idea/testData/inspectionsLocal/liftOut/tryToReturn/block.kt
new file mode 100644
index 00000000000..15a33efef2c
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToReturn/block.kt
@@ -0,0 +1,13 @@
+// HIGHLIGHT: GENERIC_ERROR_OR_WARNING
+
+fun doSomething() {}
+
+fun test(): String {
+ try {
+ doSomething()
+ return "success"
+ } catch (e: Exception) {
+ doSomething()
+ return "failure"
+ }
+}
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToReturn/block.kt.after b/idea/testData/inspectionsLocal/liftOut/tryToReturn/block.kt.after
new file mode 100644
index 00000000000..4ae23d81b6a
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToReturn/block.kt.after
@@ -0,0 +1,13 @@
+// HIGHLIGHT: GENERIC_ERROR_OR_WARNING
+
+fun doSomething() {}
+
+fun test(): String {
+ return try {
+ doSomething()
+ "success"
+ } catch (e: Exception) {
+ doSomething()
+ "failure"
+ }
+}
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToReturn/cascade.kt b/idea/testData/inspectionsLocal/liftOut/tryToReturn/cascade.kt
new file mode 100644
index 00000000000..3a3ad993910
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToReturn/cascade.kt
@@ -0,0 +1,16 @@
+// WITH_RUNTIME
+fun test(): String {
+ try {
+ try {
+ return "success"
+ } catch (e: Exception) {
+ TODO()
+ }
+ } catch (e: Exception) {
+ try {
+ TODO()
+ } catch (e: Exception) {
+ return "failure"
+ }
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToReturn/cascade.kt.after b/idea/testData/inspectionsLocal/liftOut/tryToReturn/cascade.kt.after
new file mode 100644
index 00000000000..0b6a1789058
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToReturn/cascade.kt.after
@@ -0,0 +1,16 @@
+// WITH_RUNTIME
+fun test(): String {
+ return try {
+ try {
+ "success"
+ } catch (e: Exception) {
+ TODO()
+ }
+ } catch (e: Exception) {
+ try {
+ TODO()
+ } catch (e: Exception) {
+ "failure"
+ }
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToReturn/finally.kt b/idea/testData/inspectionsLocal/liftOut/tryToReturn/finally.kt
new file mode 100644
index 00000000000..ecee03fc466
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToReturn/finally.kt
@@ -0,0 +1,11 @@
+fun doSomething() {}
+
+fun test(): String {
+ try {
+ return "success"
+ } catch (e: Exception) {
+ return "failure"
+ } finally {
+ doSomething()
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToReturn/finally.kt.after b/idea/testData/inspectionsLocal/liftOut/tryToReturn/finally.kt.after
new file mode 100644
index 00000000000..8f333970227
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToReturn/finally.kt.after
@@ -0,0 +1,11 @@
+fun doSomething() {}
+
+fun test(): String {
+ return try {
+ "success"
+ } catch (e: Exception) {
+ "failure"
+ } finally {
+ doSomething()
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToReturn/finallyWithCascadeReturn.kt b/idea/testData/inspectionsLocal/liftOut/tryToReturn/finallyWithCascadeReturn.kt
new file mode 100644
index 00000000000..37444b1248c
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToReturn/finallyWithCascadeReturn.kt
@@ -0,0 +1,14 @@
+fun doSomething() {}
+
+fun test(n: Int): String {
+ try {
+ return "success"
+ } catch (e: Exception) {
+ throw e
+ } finally {
+ if (n == 1)
+ doSomething()
+ else
+ return "finally"
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToReturn/finallyWithCascadeReturn.kt.after b/idea/testData/inspectionsLocal/liftOut/tryToReturn/finallyWithCascadeReturn.kt.after
new file mode 100644
index 00000000000..bde085ac45d
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToReturn/finallyWithCascadeReturn.kt.after
@@ -0,0 +1,14 @@
+fun doSomething() {}
+
+fun test(n: Int): String {
+ return try {
+ "success"
+ } catch (e: Exception) {
+ throw e
+ } finally {
+ if (n == 1)
+ doSomething()
+ else
+ return "finally"
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToReturn/finallyWithReturn.kt b/idea/testData/inspectionsLocal/liftOut/tryToReturn/finallyWithReturn.kt
new file mode 100644
index 00000000000..8163a7c29bb
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToReturn/finallyWithReturn.kt
@@ -0,0 +1,10 @@
+// PROBLEM: none
+fun test(): String {
+ try {
+ return "success"
+ } catch (e: Exception) {
+ return "failure"
+ } finally {
+ return "finally"
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToReturn/inner.kt b/idea/testData/inspectionsLocal/liftOut/tryToReturn/inner.kt
new file mode 100644
index 00000000000..b43768d433f
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToReturn/inner.kt
@@ -0,0 +1,12 @@
+fun test(n: Int): String {
+ if (n == 1) {
+ try {
+ return "success"
+ } catch (e: Exception) {
+ throw e
+ }
+ }
+ else {
+ return "else"
+ }
+}
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToReturn/inner.kt.after b/idea/testData/inspectionsLocal/liftOut/tryToReturn/inner.kt.after
new file mode 100644
index 00000000000..ee6417d68b0
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToReturn/inner.kt.after
@@ -0,0 +1,12 @@
+fun test(n: Int): String {
+ if (n == 1) {
+ return try {
+ "success"
+ } catch (e: Exception) {
+ throw e
+ }
+ }
+ else {
+ return "else"
+ }
+}
diff --git a/idea/testData/inspectionsLocal/liftOut/tryToReturn/withoutReturn.kt b/idea/testData/inspectionsLocal/liftOut/tryToReturn/withoutReturn.kt
new file mode 100644
index 00000000000..7c850582b10
--- /dev/null
+++ b/idea/testData/inspectionsLocal/liftOut/tryToReturn/withoutReturn.kt
@@ -0,0 +1,11 @@
+// ERROR: A 'return' expression required in a function with a block body ('{...}')
+// PROBLEM: none
+fun doSomething() {}
+
+fun test(): String {
+ try {
+ return "success"
+ } catch (e: Exception) {
+ doSomething()
+ }
+}
\ 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 1f25bc0bae9..9d6ce6195bb 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java
+++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java
@@ -629,6 +629,138 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
}
}
+ @TestMetadata("idea/testData/inspectionsLocal/liftOut/tryToAssignment")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class TryToAssignment extends AbstractLocalInspectionTest {
+ public void testAllFilesPresentInTryToAssignment() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/liftOut/tryToAssignment"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
+ }
+
+ @TestMetadata("basic.kt")
+ public void testBasic() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/liftOut/tryToAssignment/basic.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("block.kt")
+ public void testBlock() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/liftOut/tryToAssignment/block.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("cascade.kt")
+ public void testCascade() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/liftOut/tryToAssignment/cascade.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("finally.kt")
+ public void testFinally() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/liftOut/tryToAssignment/finally.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("finallyWithAssignment.kt")
+ public void testFinallyWithAssignment() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/liftOut/tryToAssignment/finallyWithAssignment.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("finallyWithCascadeAssignment.kt")
+ public void testFinallyWithCascadeAssignment() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/liftOut/tryToAssignment/finallyWithCascadeAssignment.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("finallyWithCascadeUnmatchedAssignment.kt")
+ public void testFinallyWithCascadeUnmatchedAssignment() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/liftOut/tryToAssignment/finallyWithCascadeUnmatchedAssignment.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("finallyWithUnmatchedAssignments.kt")
+ public void testFinallyWithUnmatchedAssignments() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/liftOut/tryToAssignment/finallyWithUnmatchedAssignments.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("inner.kt")
+ public void testInner() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/liftOut/tryToAssignment/inner.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("withUnmatchedAssignments.kt")
+ public void testWithUnmatchedAssignments() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/liftOut/tryToAssignment/withUnmatchedAssignments.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("withoutTerminatingAssignment.kt")
+ public void testWithoutTerminatingAssignment() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/liftOut/tryToAssignment/withoutTerminatingAssignment.kt");
+ doTest(fileName);
+ }
+ }
+
+ @TestMetadata("idea/testData/inspectionsLocal/liftOut/tryToReturn")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class TryToReturn extends AbstractLocalInspectionTest {
+ public void testAllFilesPresentInTryToReturn() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/liftOut/tryToReturn"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
+ }
+
+ @TestMetadata("basic.kt")
+ public void testBasic() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/liftOut/tryToReturn/basic.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("block.kt")
+ public void testBlock() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/liftOut/tryToReturn/block.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("cascade.kt")
+ public void testCascade() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/liftOut/tryToReturn/cascade.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("finally.kt")
+ public void testFinally() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/liftOut/tryToReturn/finally.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("finallyWithCascadeReturn.kt")
+ public void testFinallyWithCascadeReturn() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/liftOut/tryToReturn/finallyWithCascadeReturn.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("finallyWithReturn.kt")
+ public void testFinallyWithReturn() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/liftOut/tryToReturn/finallyWithReturn.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("inner.kt")
+ public void testInner() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/liftOut/tryToReturn/inner.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("withoutReturn.kt")
+ public void testWithoutReturn() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/liftOut/tryToReturn/withoutReturn.kt");
+ doTest(fileName);
+ }
+ }
+
@TestMetadata("idea/testData/inspectionsLocal/liftOut/whenToAssignment")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)