diff --git a/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/PartialBodyResolveFilter.kt b/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/PartialBodyResolveFilter.kt index 655c2ad6a40..398c7137c90 100644 --- a/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/PartialBodyResolveFilter.kt +++ b/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/PartialBodyResolveFilter.kt @@ -208,7 +208,6 @@ class PartialBodyResolveFilter(elementToResolve: JetElement, private val body: J return result } - //TODO: more precise analysis private fun collectAlwaysExitPoints(expression: JetExpression?): Collection { val result = ArrayList() expression?.accept(object : ControlFlowVisitor() { @@ -222,6 +221,23 @@ class PartialBodyResolveFilter(elementToResolve: JetElement, private val body: J result.add(expression) } + override fun visitIfExpression(expression: JetIfExpression) { + expression.getCondition().accept(this) + + val thenBranch = expression.getThen() + val elseBranch = expression.getElse() + if (thenBranch != null && elseBranch != null) { // if we have only one branch it makes no sense to search exits in it + val thenExits = collectAlwaysExitPoints(thenBranch) + if (thenExits.isNotEmpty()) { + val elseExits = collectAlwaysExitPoints(elseBranch) + if (elseExits.isNotEmpty()) { + result.addAll(thenExits) + result.addAll(elseExits) + } + } + } + } + override fun visitForExpression(loop: JetForExpression) { loop.getLoopRange()?.accept(this) // do not make sense to search exits inside for as not necessary enter it at all diff --git a/idea/testData/resolve/partialBodyResolve/IfNullConditionalReturn.dump b/idea/testData/resolve/partialBodyResolve/IfNullConditionalReturn.dump new file mode 100644 index 00000000000..db31922fc1f --- /dev/null +++ b/idea/testData/resolve/partialBodyResolve/IfNullConditionalReturn.dump @@ -0,0 +1,3 @@ +Resolve target: val x: kotlin.Any? +Skipped statements: +if (x == null) { print(1) if (f()) return } diff --git a/idea/testData/resolve/partialBodyResolve/IfNullConditionalReturn.kt b/idea/testData/resolve/partialBodyResolve/IfNullConditionalReturn.kt new file mode 100644 index 00000000000..174cfc68202 --- /dev/null +++ b/idea/testData/resolve/partialBodyResolve/IfNullConditionalReturn.kt @@ -0,0 +1,13 @@ +fun foo() { + for (i in 1..10) { + val x = take() + if (x == null) { + print(1) + if (f()) return + } + x.hashCode() + } +} + +fun take(): Any? = null +fun f(): Boolean{} \ No newline at end of file diff --git a/idea/testData/resolve/partialBodyResolve/IfNullConditionalReturnWithElse.dump b/idea/testData/resolve/partialBodyResolve/IfNullConditionalReturnWithElse.dump new file mode 100644 index 00000000000..11dc1a74351 --- /dev/null +++ b/idea/testData/resolve/partialBodyResolve/IfNullConditionalReturnWithElse.dump @@ -0,0 +1,3 @@ +Resolve target: val x: kotlin.Any? +Skipped statements: +if (x == null) { print(1) if (f()) { return } else { print(2) } } diff --git a/idea/testData/resolve/partialBodyResolve/IfNullConditionalReturnWithElse.kt b/idea/testData/resolve/partialBodyResolve/IfNullConditionalReturnWithElse.kt new file mode 100644 index 00000000000..a9120e66e79 --- /dev/null +++ b/idea/testData/resolve/partialBodyResolve/IfNullConditionalReturnWithElse.kt @@ -0,0 +1,18 @@ +fun foo() { + for (i in 1..10) { + val x = take() + if (x == null) { + print(1) + if (f()) { + return + } + else { + print(2) + } + } + x.hashCode() + } +} + +fun take(): Any? = null +fun f(): Boolean{} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/resolve/PartialBodyResolveTestGenerated.java b/idea/tests/org/jetbrains/jet/resolve/PartialBodyResolveTestGenerated.java index 1980bda1ac1..2d149e1fa27 100644 --- a/idea/tests/org/jetbrains/jet/resolve/PartialBodyResolveTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/resolve/PartialBodyResolveTestGenerated.java @@ -19,7 +19,6 @@ package org.jetbrains.jet.resolve; import com.intellij.testFramework.TestDataPath; import org.jetbrains.jet.JUnit3RunnerWithInners; import org.jetbrains.jet.JetTestUtils; -import org.jetbrains.jet.test.InnerTestClasses; import org.jetbrains.jet.test.TestMetadata; import org.junit.runner.RunWith; @@ -126,6 +125,18 @@ public class PartialBodyResolveTestGenerated extends AbstractPartialBodyResolveT doTest(fileName); } + @TestMetadata("IfNullConditionalReturn.kt") + public void testIfNullConditionalReturn() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/resolve/partialBodyResolve/IfNullConditionalReturn.kt"); + doTest(fileName); + } + + @TestMetadata("IfNullConditionalReturnWithElse.kt") + public void testIfNullConditionalReturnWithElse() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/resolve/partialBodyResolve/IfNullConditionalReturnWithElse.kt"); + doTest(fileName); + } + @TestMetadata("IfNullContinue.kt") public void testIfNullContinue() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/resolve/partialBodyResolve/IfNullContinue.kt");