From 12be50787349c5ee2792da5cee8f939324a762b1 Mon Sep 17 00:00:00 2001 From: Oleg Shpynov Date: Mon, 24 May 2010 19:08:52 +0400 Subject: [PATCH] PY-992 Cannot perform refactoring when execution flow is interrupted --- .../codeFragment/PyCodeFragmentUtil.java | 16 +--------- .../codeInsight/codefragment/forifreturn.test | 4 +++ .../codeInsight/controlflow/forreturn.py | 2 ++ .../codeInsight/controlflow/forreturn.txt | 16 ++++++++++ .../python/PyControlFlowBuilderTest.java | 4 +++ .../refactoring/PyCodeFragmentTest.java | 32 ++++++++++++------- 6 files changed, 48 insertions(+), 26 deletions(-) create mode 100644 python/testData/codeInsight/codefragment/forifreturn.test create mode 100644 python/testData/codeInsight/controlflow/forreturn.py create mode 100644 python/testData/codeInsight/controlflow/forreturn.txt diff --git a/python/src/com/jetbrains/python/codeInsight/codeFragment/PyCodeFragmentUtil.java b/python/src/com/jetbrains/python/codeInsight/codeFragment/PyCodeFragmentUtil.java index 883a62326091..ca1c502f430b 100644 --- a/python/src/com/jetbrains/python/codeInsight/codeFragment/PyCodeFragmentUtil.java +++ b/python/src/com/jetbrains/python/codeInsight/codeFragment/PyCodeFragmentUtil.java @@ -92,23 +92,9 @@ public class PyCodeFragmentUtil { } // If we see more than 1 outer instruction, controlflow is interrupted - if (outerInstructions.size() > 2){ + if (outerInstructions.size() > 1){ throw new CannotCreateCodeFragmentException(PyBundle.message("refactoring.extract.method.error.cannot.perform.refactoring.when.execution.flow.is.interrupted")); } - if (outerInstructions.size() == 2){ - boolean errorFound = true; - for (Instruction outerInstruction : outerInstructions) { - // Here we check control flow when for statement content is beeing extracted - if (outerInstruction instanceof ReadWriteInstruction && - PyForStatementNavigator.getPyForStatementByIterable(outerInstruction.getElement())!=null){ - errorFound = false; - break; - } - } - if (errorFound){ - throw new CannotCreateCodeFragmentException(PyBundle.message("refactoring.extract.method.error.cannot.perform.refactoring.when.execution.flow.is.interrupted")); - } - } // Building code fragment final PyCodeFragmentBuilder builder = new PyCodeFragmentBuilder(owner, start, end); diff --git a/python/testData/codeInsight/codefragment/forifreturn.test b/python/testData/codeInsight/codefragment/forifreturn.test new file mode 100644 index 000000000000..8d9b29717818 --- /dev/null +++ b/python/testData/codeInsight/codefragment/forifreturn.test @@ -0,0 +1,4 @@ +for start, end, name in self.talks: + if hour >= start and hour < end: return name + +Cannot perform refactoring when execution flow is interrupted \ No newline at end of file diff --git a/python/testData/codeInsight/controlflow/forreturn.py b/python/testData/codeInsight/controlflow/forreturn.py new file mode 100644 index 000000000000..674cbe32e047 --- /dev/null +++ b/python/testData/codeInsight/controlflow/forreturn.py @@ -0,0 +1,2 @@ +for start, end, name in self.talks: + if hour >= start and hour < end: return name \ No newline at end of file diff --git a/python/testData/codeInsight/controlflow/forreturn.txt b/python/testData/codeInsight/controlflow/forreturn.txt new file mode 100644 index 000000000000..42218407ada7 --- /dev/null +++ b/python/testData/codeInsight/controlflow/forreturn.txt @@ -0,0 +1,16 @@ +0(1) element: null +1(2) element: PyForStatement +2(3,15) READ ACCESS: self +3(4) element: PyStatementList +4(5) WRITE ACCESS: start +5(6) WRITE ACCESS: end +6(7) WRITE ACCESS: name +7(8) element: PyIfStatement +8(9) READ ACCESS: hour +9(10) READ ACCESS: start +10(11) READ ACCESS: hour +11(12,3,15) READ ACCESS: end +12(13) element: PyStatementList. Condition: hour >= start and hour < end:true +13(14) element: PyReturnStatement +14(15) READ ACCESS: name +15() 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 c05c381fbe25..fb0daad7ca70 100644 --- a/python/testSrc/com/jetbrains/python/PyControlFlowBuilderTest.java +++ b/python/testSrc/com/jetbrains/python/PyControlFlowBuilderTest.java @@ -103,6 +103,10 @@ public class PyControlFlowBuilderTest extends LightMarkedTestCase { doTest(); } + public void testForReturn() throws Exception { + doTest(); + } + public void testForTryContinue() throws Exception { doTest(); } diff --git a/python/testSrc/com/jetbrains/python/refactoring/PyCodeFragmentTest.java b/python/testSrc/com/jetbrains/python/refactoring/PyCodeFragmentTest.java index 320ecb3c701e..03fdb9bae802 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/PyCodeFragmentTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/PyCodeFragmentTest.java @@ -1,5 +1,6 @@ package com.jetbrains.python.refactoring; +import com.intellij.codeInsight.codeFragment.CannotCreateCodeFragmentException; import com.intellij.codeInsight.codeFragment.CodeFragment; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; @@ -67,19 +68,24 @@ public class PyCodeFragmentTest extends LightMarkedTestCase { context = PsiTreeUtil.getParentOfType(context, ScopeOwner.class); } final StringBuffer buffer = new StringBuffer(); - final CodeFragment fragment = PyCodeFragmentUtil.createCodeFragment((ScopeOwner)context, startElement, endElement); - if (fragment.isReturnInstructonInside()) { - buffer.append("Return instruction inside found").append("\n"); + try { + final CodeFragment fragment = PyCodeFragmentUtil.createCodeFragment((ScopeOwner)context, startElement, endElement); + if (fragment.isReturnInstructonInside()) { + buffer.append("Return instruction inside found").append("\n"); + } + buffer.append("In:\n"); + for (String inputVariable : new TreeSet(fragment.getInputVariables())) { + buffer.append(inputVariable).append('\n'); + } + buffer.append("Out:\n"); + for (String outputVariable : new TreeSet(fragment.getOutputVariables())) { + buffer.append(outputVariable).append('\n'); + } } - buffer.append("In:\n"); - for (String inputVariable : new TreeSet(fragment.getInputVariables())) { - buffer.append(inputVariable).append('\n'); + catch (CannotCreateCodeFragmentException e) { + assertEquals(result.trim(), e.getMessage()); + return; } - buffer.append("Out:\n"); - for (String outputVariable : new TreeSet(fragment.getOutputVariables())) { - buffer.append(outputVariable).append('\n'); - } - assertEquals(result.trim(), buffer.toString().trim()); } @@ -144,5 +150,9 @@ public class PyCodeFragmentTest extends LightMarkedTestCase { public void testClass() throws Exception { doTest(); } + + public void testForIfReturn() throws Exception { + doTest(); + } }