Fixed loop-exit CFG edges in for-else loops (PY-4239)

This commit is contained in:
Andrey Vlasovskikh
2011-11-14 18:26:51 +04:00
parent 68d5c3a1f1
commit 783c421a55
3 changed files with 8 additions and 16 deletions
@@ -30,10 +30,6 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
private final ControlFlowBuilder myBuilder = new ControlFlowBuilder();
private List<Pair<PsiElement, Instruction>> myPendindBackup = null;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//// Control flow builder staff
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public ControlFlow buildControlFlow(@NotNull final ScopeOwner owner) {
return myBuilder.build(this, owner);
}
@@ -322,27 +318,23 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
if (elsePart == null) {
myBuilder.addPendingEdge(node, myBuilder.prevInstruction);
}
final PyStatementList list = forPart.getStatementList();
if (list != null) {
Instruction bodyInstruction = myBuilder.startNode(list);
final Instruction bodyInstruction = myBuilder.startNode(list);
final PyExpression target = forPart.getTarget();
if (target != null) {
target.accept(this);
}
list.accept(this);
if (myBuilder.prevInstruction != null) {
myBuilder.addEdge(myBuilder.prevInstruction, bodyInstruction); //loop
myBuilder.addPendingEdge(node, myBuilder.prevInstruction); // exit
myBuilder.addPendingEdge(list, myBuilder.prevInstruction); // exit
}
final Ref<Instruction> bodyInstRef = new Ref<Instruction>(bodyInstruction);
myBuilder.processPending(new ControlFlowBuilder.PendingProcessor() {
public void process(final PsiElement pendingScope, final Instruction instruction) {
if (pendingScope != null && PsiTreeUtil.isAncestor(list, pendingScope, false)) {
myBuilder.addEdge(instruction, bodyInstRef.get()); //loop
myBuilder.addPendingEdge(node, instruction); // exit
myBuilder.addEdge(instruction, bodyInstruction); //loop
myBuilder.addPendingEdge(list, instruction); // exit
}
else {
myBuilder.addPendingEdge(pendingScope, instruction);
@@ -1,4 +1,4 @@
for i in range(10)
for i in range(10):
print(i)
else
print "Something went wrong"
else:
print('for-loop executed 0 or more times, no break')
@@ -4,6 +4,6 @@
3(4) element: PyStatementList
4(5) WRITE ACCESS: i
5(6) element: PyPrintStatement
6(3,8) READ ACCESS: i
6(3,7) READ ACCESS: i
7(8) element: PyPrintStatement
8() element: null