PY-1177 Fixed: Control flow analysis doesn't detect while/break

Handle control flow for statically true condition in while statement
This commit is contained in:
fitermay
2016-10-03 15:21:37 +03:00
committed by Semyon Proshev
parent a78ffde80b
commit 027fe9bb55
3 changed files with 21 additions and 12 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -404,26 +404,26 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
final Instruction instruction = myBuilder.startNode(node);
final PyWhilePart whilePart = node.getWhilePart();
final PyExpression condition = whilePart.getCondition();
boolean isStaticallyTrue = false;
if (condition != null) {
condition.accept(this);
isStaticallyTrue = (PyConstantExpressionEvaluator.evaluate(condition) == Boolean.TRUE);
}
final Instruction head = myBuilder.prevInstruction;
final PyElsePart elsePart = node.getElsePart();
if (elsePart == null) {
if (elsePart == null && !isStaticallyTrue) {
myBuilder.addPendingEdge(node, myBuilder.prevInstruction);
}
final PyStatementList list = whilePart.getStatementList();
if (list != null) {
myBuilder.startConditionalNode(list, condition, true);
list.accept(this);
// Loop edges
if (myBuilder.prevInstruction != null) {
myBuilder.addEdge(myBuilder.prevInstruction, instruction);
}
myBuilder.checkPending(instruction);
myBuilder.startConditionalNode(list, condition, true);
list.accept(this);
// Loop edges
if (myBuilder.prevInstruction != null) {
myBuilder.addEdge(myBuilder.prevInstruction, instruction);
}
myBuilder.checkPending(instruction);
myBuilder.prevInstruction = head;
if (elsePart != null) {
if (elsePart != null && !isStaticallyTrue) {
elsePart.accept(this);
myBuilder.addPendingEdge(node, myBuilder.prevInstruction);
}
@@ -0,0 +1,4 @@
while True:
a = 1
break
print(a) # pass
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -183,6 +183,11 @@ public class PyUnboundLocalVariableInspectionTest extends PyTestCase {
doTest();
}
// PY-1177
public void testWhileTrueBreak() {
doTest();
}
private void doTest() {
myFixture.configureByFile(TEST_DIRECTORY + getTestName(false) + ".py");
myFixture.enableInspections(PyUnboundLocalVariableInspection.class);