From 42e496419160d6711d46bf5c066c89bb9dcd8d19 Mon Sep 17 00:00:00 2001 From: Semyon Proshev Date: Tue, 20 Mar 2018 15:47:38 +0300 Subject: [PATCH] Visit `else` in `while` in any case even if condition is `True` (PY-28972) But when condition is `True`, edge to `else` is not created. --- .../codeInsight/controlflow/PyControlFlowBuilder.java | 6 ++++-- .../testData/codeInsight/controlflow/whiletrueelse.py | 4 ++++ .../testData/codeInsight/controlflow/whiletrueelse.txt | 6 ++++++ .../extractmethod/InterruptedOuterLoop.before.py | 7 +++++++ .../com/jetbrains/python/PyControlFlowBuilderTest.java | 5 +++++ .../inspections/PyUnreachableCodeInspectionTest.java | 10 ++++++++++ .../python/refactoring/PyExtractMethodTest.java | 5 +++++ 7 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 python/testData/codeInsight/controlflow/whiletrueelse.py create mode 100644 python/testData/codeInsight/controlflow/whiletrueelse.txt create mode 100644 python/testData/refactoring/extractmethod/InterruptedOuterLoop.before.py diff --git a/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java b/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java index 5329e87297ec..eadc9865422d 100644 --- a/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java +++ b/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java @@ -489,11 +489,13 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor { myBuilder.addEdge(myBuilder.prevInstruction, instruction); } myBuilder.checkPending(instruction); - myBuilder.prevInstruction = head; - if (elsePart != null && !isStaticallyTrue) { + + if (elsePart != null) { + myBuilder.prevInstruction = !isStaticallyTrue ? head : null; elsePart.accept(this); myBuilder.addPendingEdge(node, myBuilder.prevInstruction); } + myBuilder.flowAbrupted(); } diff --git a/python/testData/codeInsight/controlflow/whiletrueelse.py b/python/testData/codeInsight/controlflow/whiletrueelse.py new file mode 100644 index 000000000000..66aebac4804f --- /dev/null +++ b/python/testData/codeInsight/controlflow/whiletrueelse.py @@ -0,0 +1,4 @@ +while True: + pass +else: + print("ok") \ No newline at end of file diff --git a/python/testData/codeInsight/controlflow/whiletrueelse.txt b/python/testData/codeInsight/controlflow/whiletrueelse.txt new file mode 100644 index 000000000000..cbe98737cb19 --- /dev/null +++ b/python/testData/codeInsight/controlflow/whiletrueelse.txt @@ -0,0 +1,6 @@ +0(1) element: null +1(2) element: PyWhileStatement +2(3) READ ACCESS: True +3(1) element: PyStatementList. Condition: True:true +4(5) element: PyPrintStatement +5() element: null \ No newline at end of file diff --git a/python/testData/refactoring/extractmethod/InterruptedOuterLoop.before.py b/python/testData/refactoring/extractmethod/InterruptedOuterLoop.before.py new file mode 100644 index 000000000000..937a2e121790 --- /dev/null +++ b/python/testData/refactoring/extractmethod/InterruptedOuterLoop.before.py @@ -0,0 +1,7 @@ +while True: + + while True: + pass + else: + break + \ 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 7f63515f4c87..98a11f56aade 100644 --- a/python/testSrc/com/jetbrains/python/PyControlFlowBuilderTest.java +++ b/python/testSrc/com/jetbrains/python/PyControlFlowBuilderTest.java @@ -274,6 +274,11 @@ public class PyControlFlowBuilderTest extends LightMarkedTestCase { doTest(); } + // PY-28972 + public void testWhileTrueElse() { + doTest(); + } + private void doTestFirstStatement() { final String testName = getTestName(false).toLowerCase(); configureByFile(testName + ".py"); diff --git a/python/testSrc/com/jetbrains/python/inspections/PyUnreachableCodeInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyUnreachableCodeInspectionTest.java index 78c7cda03dac..d6f409cf4b9e 100644 --- a/python/testSrc/com/jetbrains/python/inspections/PyUnreachableCodeInspectionTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/PyUnreachableCodeInspectionTest.java @@ -117,6 +117,16 @@ public class PyUnreachableCodeInspectionTest extends PyInspectionTestCase { ); } + // PY-28972 + public void testWhileTrueElse() { + doTestByText( + "while True:\n" + + " pass\n" + + "else:\n" + + " print(\"ok\")" + ); + } + @NotNull @Override protected Class getInspectionClass() { diff --git a/python/testSrc/com/jetbrains/python/refactoring/PyExtractMethodTest.java b/python/testSrc/com/jetbrains/python/refactoring/PyExtractMethodTest.java index 1b6a87ec44bb..84af949916d4 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/PyExtractMethodTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/PyExtractMethodTest.java @@ -270,4 +270,9 @@ public class PyExtractMethodTest extends LightMarkedTestCase { public void testCommentsPrecedingSourceStatement() { doTest("func"); } + + // PY-28972 + public void testInterruptedOuterLoop() { + doFail("foo", "Cannot perform refactoring when execution flow is interrupted"); + } }