Partial body resolve: more efficient handling if-statements
This commit is contained in:
+17
-1
@@ -208,7 +208,6 @@ class PartialBodyResolveFilter(elementToResolve: JetElement, private val body: J
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: more precise analysis
|
|
||||||
private fun collectAlwaysExitPoints(expression: JetExpression?): Collection<JetExpression> {
|
private fun collectAlwaysExitPoints(expression: JetExpression?): Collection<JetExpression> {
|
||||||
val result = ArrayList<JetExpression>()
|
val result = ArrayList<JetExpression>()
|
||||||
expression?.accept(object : ControlFlowVisitor() {
|
expression?.accept(object : ControlFlowVisitor() {
|
||||||
@@ -222,6 +221,23 @@ class PartialBodyResolveFilter(elementToResolve: JetElement, private val body: J
|
|||||||
result.add(expression)
|
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) {
|
override fun visitForExpression(loop: JetForExpression) {
|
||||||
loop.getLoopRange()?.accept(this)
|
loop.getLoopRange()?.accept(this)
|
||||||
// do not make sense to search exits inside for as not necessary enter it at all
|
// do not make sense to search exits inside for as not necessary enter it at all
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Resolve target: val x: kotlin.Any?
|
||||||
|
Skipped statements:
|
||||||
|
if (x == null) { print(1) if (f()) return }
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
fun foo() {
|
||||||
|
for (i in 1..10) {
|
||||||
|
val x = take()
|
||||||
|
if (x == null) {
|
||||||
|
print(1)
|
||||||
|
if (f()) return
|
||||||
|
}
|
||||||
|
<caret>x.hashCode()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun take(): Any? = null
|
||||||
|
fun f(): Boolean{}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Resolve target: val x: kotlin.Any?
|
||||||
|
Skipped statements:
|
||||||
|
if (x == null) { print(1) if (f()) { return } else { print(2) } }
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<caret>x.hashCode()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun take(): Any? = null
|
||||||
|
fun f(): Boolean{}
|
||||||
@@ -19,7 +19,6 @@ package org.jetbrains.jet.resolve;
|
|||||||
import com.intellij.testFramework.TestDataPath;
|
import com.intellij.testFramework.TestDataPath;
|
||||||
import org.jetbrains.jet.JUnit3RunnerWithInners;
|
import org.jetbrains.jet.JUnit3RunnerWithInners;
|
||||||
import org.jetbrains.jet.JetTestUtils;
|
import org.jetbrains.jet.JetTestUtils;
|
||||||
import org.jetbrains.jet.test.InnerTestClasses;
|
|
||||||
import org.jetbrains.jet.test.TestMetadata;
|
import org.jetbrains.jet.test.TestMetadata;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
@@ -126,6 +125,18 @@ public class PartialBodyResolveTestGenerated extends AbstractPartialBodyResolveT
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("IfNullContinue.kt")
|
||||||
public void testIfNullContinue() throws Exception {
|
public void testIfNullContinue() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/resolve/partialBodyResolve/IfNullContinue.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/resolve/partialBodyResolve/IfNullContinue.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user