diff --git a/java/java-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java b/java/java-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java index a751630b5bb5..d85b2e576931 100644 --- a/java/java-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java +++ b/java/java-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java @@ -264,7 +264,7 @@ public class ControlFlowUtil { } @Override public void visitBranchingInstruction(BranchingInstruction instruction, int offset, int nextOffset) { - processGoto(flow, start, end, exitPoints, exitStatements, instruction.offset, classesFilter, findStatement(flow, offset)); + processGoto(flow, start, end, exitPoints, exitStatements, instruction, classesFilter, findStatement(flow, offset)); } // call/return do not incur exit points @@ -297,8 +297,9 @@ public class ControlFlowUtil { private static void processGoto(ControlFlow flow, int start, int end, IntArrayList exitPoints, - Collection exitStatements, int gotoOffset, Class[] classesFilter, final PsiStatement statement) { + Collection exitStatements, BranchingInstruction instruction, Class[] classesFilter, final PsiStatement statement) { if (statement == null) return; + int gotoOffset = instruction.offset; if (start > gotoOffset || gotoOffset >= end || isElementOfClass(statement, classesFilter)) { // process chain of goto's gotoOffset = promoteThroughGotoChain(flow, gotoOffset); @@ -306,7 +307,16 @@ public class ControlFlowUtil { if (!exitPoints.contains(gotoOffset) && (gotoOffset >= end || gotoOffset < start)) { exitPoints.add(gotoOffset); } - processGotoStatement(classesFilter, exitStatements, statement); + if (gotoOffset >= end || gotoOffset < start) { + processGotoStatement(classesFilter, exitStatements, statement); + } else { + boolean isReturn = instruction instanceof GoToInstruction && ((GoToInstruction)instruction).isReturn; + final Instruction gotoInstruction = flow.getInstructions().get(gotoOffset); + isReturn |= gotoInstruction instanceof GoToInstruction && ((GoToInstruction)gotoInstruction).isReturn; + if (isReturn) { + processGotoStatement(classesFilter, exitStatements, statement); + } + } } } diff --git a/java/java-tests/testData/refactoring/extractMethod/ContinueInside.java b/java/java-tests/testData/refactoring/extractMethod/ContinueInside.java new file mode 100644 index 000000000000..892e22d93a9c --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/ContinueInside.java @@ -0,0 +1,12 @@ +class Test { + String foo(String[] args) { + + for(String arg : args) { + if (arg == null) continue; + System.out.println(arg); + } + if (args.length == 0) return null; + + return null; + } +} diff --git a/java/java-tests/testData/refactoring/extractMethod/ContinueInside_after.java b/java/java-tests/testData/refactoring/extractMethod/ContinueInside_after.java new file mode 100644 index 000000000000..a8e17f76c123 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethod/ContinueInside_after.java @@ -0,0 +1,17 @@ +class Test { + String foo(String[] args) { + + if (newMethod(args)) return null; + + return null; + } + + private boolean newMethod(String[] args) { + for(String arg : args) { + if (arg == null) continue; + System.out.println(arg); + } + if (args.length == 0) return true; + return false; + } +} diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java index 6602b68e390b..7a39171d37ce 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java @@ -74,6 +74,10 @@ public class ExtractMethodTest extends LightCodeInsightTestCase { doExitPointsTest(false); } + public void testContinueInside() throws Exception { + doTest(); + } + public void testBooleanExpression() throws Exception { doTest(); } @@ -496,4 +500,4 @@ public class ExtractMethodTest extends LightCodeInsightTestCase { return true; } -} \ No newline at end of file +}