diff --git a/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java b/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java index 74e5d54e5ec0..de28a65744ce 100644 --- a/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java +++ b/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java @@ -204,8 +204,9 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor { condition.accept(assertionEvaluator); } // Set the head as the last instruction of condition - Instruction head = getPrevInstruction(condition); - myBuilder.prevInstruction = head; + PyElement lastCondition = condition; + Instruction lastBranchingPoint = getPrevInstruction(condition); + myBuilder.prevInstruction = lastBranchingPoint; final PyStatementList thenStatements = ifPart.getStatementList(); if (thenStatements != null) { myBuilder.startConditionalNode(thenStatements, condition, true); @@ -224,16 +225,18 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor { myBuilder.addPendingEdge(node, myBuilder.prevInstruction); } for (PyIfPart part : node.getElifParts()) { - // restore head - myBuilder.prevInstruction = head; + // Set the head as the false branch + myBuilder.prevInstruction = lastBranchingPoint; + myBuilder.startConditionalNode(part, lastCondition, false); condition = part.getCondition(); if (condition != null) { + lastCondition = condition; + lastBranchingPoint = getPrevInstruction(lastCondition); condition.accept(this); } // Set the head as the last instruction of condition - head = getPrevInstruction(condition); - myBuilder.prevInstruction = head; - myBuilder.startConditionalNode(ifPart, condition, true); + myBuilder.prevInstruction = getPrevInstruction(lastCondition); + myBuilder.startConditionalNode(ifPart, lastCondition, true); final PyStatementList statementList = part.getStatementList(); if (statementList != null) { statementList.accept(this); @@ -250,15 +253,16 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor { }); myBuilder.addPendingEdge(node, myBuilder.prevInstruction); } - // restore head - myBuilder.prevInstruction = head; final PyElsePart elseBranch = node.getElsePart(); if (elseBranch != null) { - myBuilder.startConditionalNode(elseBranch, condition, false); + // Set the head as the false branch + myBuilder.prevInstruction = lastBranchingPoint; + myBuilder.startConditionalNode(elseBranch, lastCondition, false); elseBranch.accept(this); myBuilder.addPendingEdge(node, myBuilder.prevInstruction); + } else { + myBuilder.addPendingEdge(node, lastBranchingPoint); } - } @Override diff --git a/python/testData/codeInsight/controlflow/if.txt b/python/testData/codeInsight/controlflow/if.txt index a6589785062e..e79c69504093 100644 --- a/python/testData/codeInsight/controlflow/if.txt +++ b/python/testData/codeInsight/controlflow/if.txt @@ -4,12 +4,14 @@ 3(4,5) element: PyIfStatement 4(6) element: PyStatementList. Condition: 1:true 5(6) element: PyElsePart. Condition: 1:false -6(7,8,9) element: PyIfStatement -7(9) element: PyStatementList. Condition: 2:true -8(9) element: PyIfPartIf. Condition: 3:true -9(10,11,12) element: PyIfStatement -10(14) element: PyStatementList. Condition: 4:true -11(14) element: PyIfPartIf. Condition: 5:true -12(13) element: PyElsePart. Condition: 5:false -13(14) element: PyExpressionStatement -14() element: null \ No newline at end of file +6(7,8) element: PyIfStatement +7(10) element: PyStatementList. Condition: 2:true +8(9,10) element: PyIfPartElif. Condition: 2:false +9(10) element: PyIfPartIf. Condition: 3:true +10(11,12) element: PyIfStatement +11(16) element: PyStatementList. Condition: 4:true +12(13,14) element: PyIfPartElif. Condition: 4:false +13(16) element: PyIfPartIf. Condition: 5:true +14(15) element: PyElsePart. Condition: 5:false +15(16) element: PyExpressionStatement +16() element: null \ No newline at end of file diff --git a/python/testData/codeInsight/controlflow/manyifs.py b/python/testData/codeInsight/controlflow/manyifs.py new file mode 100644 index 000000000000..02813a53be2c --- /dev/null +++ b/python/testData/codeInsight/controlflow/manyifs.py @@ -0,0 +1,13 @@ +var = 1 +if a == b: + var = 2 +elif aa == bb: + bbb = same_changet_expression + + if bbb: + var = 3 # <--- this highlight bug (unused variable) + +else: + var = 4 + +return {'variable': var} \ No newline at end of file diff --git a/python/testData/codeInsight/controlflow/manyifs.txt b/python/testData/codeInsight/controlflow/manyifs.txt new file mode 100644 index 000000000000..524d984d9c3a --- /dev/null +++ b/python/testData/codeInsight/controlflow/manyifs.txt @@ -0,0 +1,27 @@ +0(1) element: null +1(2) element: PyAssignmentStatement +2(3) WRITE ACCESS: var +3(4) element: PyIfStatement +4(5) READ ACCESS: a +5(6,9) READ ACCESS: b +6(7) element: PyStatementList. Condition: a == b:true +7(8) element: PyAssignmentStatement +8(24) WRITE ACCESS: var +9(10,21) element: PyIfPartElif. Condition: a == b:false +10(11) READ ACCESS: aa +11(12) READ ACCESS: bb +12(13) element: PyIfPartIf. Condition: aa == bb:true +13(14) element: PyAssignmentStatement +14(15) READ ACCESS: same_changet_expression +15(16) WRITE ACCESS: bbb +16(17) element: PyIfStatement +17(18,21) READ ACCESS: bbb +18(19) element: PyStatementList. Condition: bbb:true +19(20) element: PyAssignmentStatement +20(21,24) WRITE ACCESS: var +21(22) element: PyElsePart. Condition: aa == bb:false +22(23) element: PyAssignmentStatement +23(24) WRITE ACCESS: var +24(25) element: PyReturnStatement +25(26) READ ACCESS: var +26() element: null \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PyControlFlowBuilderTest.java b/python/testSrc/com/jetbrains/python/PyControlFlowBuilderTest.java index ca9f13604e06..f33a468da477 100644 --- a/python/testSrc/com/jetbrains/python/PyControlFlowBuilderTest.java +++ b/python/testSrc/com/jetbrains/python/PyControlFlowBuilderTest.java @@ -144,6 +144,10 @@ public class PyControlFlowBuilderTest extends LightMarkedTestCase { doTest(); } + public void testManyIfs() throws Exception { + doTest(); + } + public void testQualifiedSelfReference() throws Exception { final String testName = getTestName(false).toLowerCase(); configureByFile(testName + ".py");