Incorrect "code is unreachable" warning
This commit is contained in:
Oleg Shpynov
2010-02-19 17:19:51 +03:00
parent 139529ac2d
commit 28e27205c4
5 changed files with 41 additions and 8 deletions
@@ -3,6 +3,8 @@ package com.jetbrains.python.codeInsight.controlflow;
import com.intellij.codeInsight.controlflow.ControlFlowBuilder;
import com.intellij.codeInsight.controlflow.ControlFlow;
import com.intellij.codeInsight.controlflow.Instruction;
import com.intellij.codeInsight.controlflow.impl.InstructionImpl;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
@@ -12,6 +14,7 @@ import com.jetbrains.python.psi.impl.PyImportStatementNavigator;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* @author oleg
@@ -259,10 +262,7 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
myBuilder.prevInstruction = head;
if (elsePart != null) {
elsePart.accept(this);
myBuilder.addPendingEdge(node, myBuilder.prevInstruction); // exit
}
else {
myBuilder.addPendingEdge(null, myBuilder.prevInstruction);
myBuilder.addPendingEdge(node, myBuilder.prevInstruction);
}
myBuilder.flowAbrupted();
}
@@ -346,14 +346,21 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
}
final ArrayList<Instruction> exceptInstructions = new ArrayList<Instruction>();
// Store pending and clear it
final List<Pair<PsiElement, Instruction>> myPending = myBuilder.pending;
myBuilder.pending = new ArrayList<Pair<PsiElement, Instruction>>();
for (PyExceptPart exceptPart : node.getExceptParts()) {
myBuilder.prevInstruction = lastBlockInstruction;
final Instruction exceptInstruction = myBuilder.startNode(exceptPart);
final Instruction exceptInstruction = new InstructionImpl(myBuilder, exceptPart);
myBuilder.addNode(exceptInstruction);
exceptInstructions.add(exceptInstruction);
exceptPart.accept(this);
myBuilder.addPendingEdge(node, myBuilder.prevInstruction);
}
// Restore pending
for (Pair<PsiElement, Instruction> pair : myPending) {
myBuilder.addPendingEdge(pair.first, pair.second);
}
final PyFinallyPart finallyPart = node.getFinallyPart();
Instruction finallyInstruction = null;
Instruction lastFinallyInstruction = null;
@@ -22,8 +22,7 @@ import org.jetbrains.annotations.Nullable;
/**
* The 'for/else' statement.
*/
public interface PyForStatement extends PyStatement, NameDefiner {
public interface PyForStatement extends PyLoopStatement, NameDefiner {
@NotNull PyForPart getForPart();
@Nullable PyElsePart getElsePart();
}
@@ -0,0 +1,7 @@
def foo():
try:
for i in bar:
break
except:
raise Exception()
return 3
@@ -0,0 +1,12 @@
0(1) element: null
1(2) element: PyTryExceptStatement
2(3) element: PyTryPart
3(4) element: PyForStatement
4(5,10) READ ACCESS: bar
5(6) element: PyStatementList
6(7) WRITE ACCESS: i
7(10) element: PyBreakStatement
8(9) element: PyExceptPart
9(11) element: PyRaiseStatement
10(11) element: PyReturnStatement
11() element: null
@@ -82,6 +82,14 @@ public class PyControlFlowBuilderTest extends LightMarkedTestCase {
doTest();
}
public void testTryBreak() throws Exception {
final String testName = getTestName(false).toLowerCase();
configureByFile(testName + ".py");
final ControlFlow flow = ((PyFunction)((PyFile)myFile).getStatements().get(0)).getControlFlow();
final String fullPath = getTestDataPath() + testName + ".txt";
check(fullPath, flow);
}
public void testFunction() throws Exception {
final String testName = getTestName(false).toLowerCase();
configureByFile(testName + ".py");