From ec2d9c812393e736f4c928e6b61ed6c39e78efe4 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 4 Aug 2008 19:34:58 +0400 Subject: [PATCH] hairy fix for finding return statements via control flow in 'extract method' (IDEADEV-28830) --- .../com/intellij/refactoring/ExtractMethodTest.java | 4 ++++ .../psi/controlFlow/ControlFlowAnalyzer.java | 1 + .../intellij/psi/controlFlow/ControlFlowUtil.java | 3 ++- .../intellij/psi/controlFlow/ReturnInstruction.java | 9 +++++++++ .../refactoring/extractMethod/ReturnFromTry.java | 16 ++++++++++++++++ .../extractMethod/ReturnFromTry_after.java | 20 ++++++++++++++++++++ 6 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 testData/refactoring/extractMethod/ReturnFromTry.java create mode 100644 testData/refactoring/extractMethod/ReturnFromTry_after.java diff --git a/refactoring/tests/com/intellij/refactoring/ExtractMethodTest.java b/refactoring/tests/com/intellij/refactoring/ExtractMethodTest.java index 57bdcc7311..9b58ef6bfc 100644 --- a/refactoring/tests/com/intellij/refactoring/ExtractMethodTest.java +++ b/refactoring/tests/com/intellij/refactoring/ExtractMethodTest.java @@ -289,6 +289,10 @@ public class ExtractMethodTest extends LightCodeInsightTestCase { doChainedConstructorTest(true); } + public void testReturnFromTry() throws Exception { + doTest(); + } + public void testForceBraces() throws Exception { final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject()); int old = settings.IF_BRACE_FORCE; diff --git a/source/com/intellij/psi/controlFlow/ControlFlowAnalyzer.java b/source/com/intellij/psi/controlFlow/ControlFlowAnalyzer.java index 88e811cc29..5c3f9bb754 100644 --- a/source/com/intellij/psi/controlFlow/ControlFlowAnalyzer.java +++ b/source/com/intellij/psi/controlFlow/ControlFlowAnalyzer.java @@ -1085,6 +1085,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor { PsiElement catchBlock = unhandledExceptionCatchBlocks.get(i); final ReturnInstruction returnInstruction = new ReturnInstruction(0, myStack, callInstruction); + returnInstruction.setRethrowFromFinally(); myCurrentFlow.addInstruction(returnInstruction); if (catchBlock == null) { // dispatch to rethrowing exception code diff --git a/source/com/intellij/psi/controlFlow/ControlFlowUtil.java b/source/com/intellij/psi/controlFlow/ControlFlowUtil.java index 4328c5916f..09e4852787 100644 --- a/source/com/intellij/psi/controlFlow/ControlFlowUtil.java +++ b/source/com/intellij/psi/controlFlow/ControlFlowUtil.java @@ -595,7 +595,8 @@ public class ControlFlowUtil { @Override public void visitGoToInstruction(GoToInstruction instruction, int offset, int nextOffset) { if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); if (offset > endOffset) return; - boolean isNormal = !instruction.isReturn && isNormalCompletion[nextOffset]; + boolean isRethrowFromFinally = instruction instanceof ReturnInstruction && ((ReturnInstruction) instruction).isRethrowFromFinally(); + boolean isNormal = !instruction.isReturn && isNormalCompletion[nextOffset] && !isRethrowFromFinally; isNormalCompletion[offset] |= isNormal; } diff --git a/source/com/intellij/psi/controlFlow/ReturnInstruction.java b/source/com/intellij/psi/controlFlow/ReturnInstruction.java index 1b31484c4a..857a2ca965 100644 --- a/source/com/intellij/psi/controlFlow/ReturnInstruction.java +++ b/source/com/intellij/psi/controlFlow/ReturnInstruction.java @@ -9,6 +9,7 @@ public class ReturnInstruction extends GoToInstruction { private final ControlFlowStack myStack; private CallInstruction myCallInstruction; + private boolean myRethrowFromFinally = false; public ReturnInstruction(int offset, @NotNull ControlFlowStack stack, CallInstruction callInstruction) { super(offset, ControlFlow.JUMP_ROLE_GOTO_END, false); @@ -88,4 +89,12 @@ public class ReturnInstruction extends GoToInstruction { public ControlFlowStack getStack() { return myStack; } + + public void setRethrowFromFinally() { + myRethrowFromFinally = true; + } + + public boolean isRethrowFromFinally() { + return myRethrowFromFinally; + } } diff --git a/testData/refactoring/extractMethod/ReturnFromTry.java b/testData/refactoring/extractMethod/ReturnFromTry.java new file mode 100644 index 0000000000..c324de5954 --- /dev/null +++ b/testData/refactoring/extractMethod/ReturnFromTry.java @@ -0,0 +1,16 @@ +class A { + public String method() { + try { + try { + return ""; + } + finally { + System.out.println("f"); + } + } + catch (Error e) { + + } + return ""; + } +} \ No newline at end of file diff --git a/testData/refactoring/extractMethod/ReturnFromTry_after.java b/testData/refactoring/extractMethod/ReturnFromTry_after.java new file mode 100644 index 0000000000..4621ab2ba5 --- /dev/null +++ b/testData/refactoring/extractMethod/ReturnFromTry_after.java @@ -0,0 +1,20 @@ +class A { + public String method() { + try { + return newMethod(); + } + catch (Error e) { + + } + return ""; + } + + private String newMethod() { + try { + return ""; + } + finally { + System.out.println("f"); + } + } +} \ No newline at end of file -- 2.11.4.GIT