From 98b70db0a72075da7e3d85581ab5033bf9ead40e Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 7 Jan 2013 11:45:25 +0100 Subject: [PATCH] extract method object: avoid element invalidation by batch update (IDEA-98365) --- .../ExtractMethodObjectHandler.java | 21 +++- .../BatchUpdateCausedByFormatter.java | 37 ++++++ .../BatchUpdateCausedByFormatter.java.after | 113 ++++++++++++++++++ ...ethodObjectWithMultipleExitPointsTest.java | 4 + 4 files changed, 170 insertions(+), 5 deletions(-) create mode 100644 java/java-tests/testData/refactoring/extractMethodObject/multipleExitPoints/BatchUpdateCausedByFormatter.java create mode 100644 java/java-tests/testData/refactoring/extractMethodObject/multipleExitPoints/BatchUpdateCausedByFormatter.java.after diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectHandler.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectHandler.java index 93b9a847d49f..d8fb3fd6ef87 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectHandler.java @@ -33,6 +33,7 @@ import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import com.intellij.psi.impl.source.PostprocessReformattingAspect; import com.intellij.refactoring.HelpID; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.RefactoringBundle; @@ -40,6 +41,7 @@ import com.intellij.refactoring.extractMethod.ExtractMethodHandler; import com.intellij.refactoring.extractMethod.PrepareFailedException; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.refactoring.util.duplicates.DuplicatesImpl; +import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; public class ExtractMethodObjectHandler implements RefactoringActionHandler { @@ -86,15 +88,24 @@ public class ExtractMethodObjectHandler implements RefactoringActionHandler { final RangeMarker marker = editor.getDocument().createRangeMarker(new TextRange(offset, offset)); CommandProcessor.getInstance().executeCommand(project, new Runnable() { public void run() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override + PostprocessReformattingAspect.getInstance(project).postponeFormattingInside(new Runnable() { public void run() { - extractProcessor.doRefactoring(); + try { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + extractProcessor.doRefactoring(); + } + }); + processor.run(); + processor.runChangeSignature(); + } + catch (IncorrectOperationException e) { + LOG.error(e); + } } }); - processor.run(); - processor.runChangeSignature(); PsiDocumentManager.getInstance(project).commitAllDocuments(); if (processor.isCreateInnerClass()) { processor.moveUsedMethodsToInner(); diff --git a/java/java-tests/testData/refactoring/extractMethodObject/multipleExitPoints/BatchUpdateCausedByFormatter.java b/java/java-tests/testData/refactoring/extractMethodObject/multipleExitPoints/BatchUpdateCausedByFormatter.java new file mode 100644 index 000000000000..f65828c09461 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodObject/multipleExitPoints/BatchUpdateCausedByFormatter.java @@ -0,0 +1,37 @@ +import java.util.*; + +public class ABug { + + private String drinkBear(String amount) { + String firstTime = "asdf"; + + if (firstTime == null) + return "loser"; + + ArrayList bottles = new ArrayList<>(); + bottles.add("asdf"); + + List errors = new ArrayList<>(); + + int money = 0; + int nCount = 0; + int rCount = 0; + int wCount = 0; + char[] tripel = new char[bottles.size()]; + boolean no33pr = false; + int first = 0; + int last = 0; + if (true) return null; + + boolean unhappy = no33pr && first || no33pr && last; + + String result = amount + Arrays.toString(tripel) + rCount + wCount + nCount + money + errors; + + if (!unhappy) + result += "happy"; + + + return result; + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractMethodObject/multipleExitPoints/BatchUpdateCausedByFormatter.java.after b/java/java-tests/testData/refactoring/extractMethodObject/multipleExitPoints/BatchUpdateCausedByFormatter.java.after new file mode 100644 index 000000000000..5b04adfb008c --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodObject/multipleExitPoints/BatchUpdateCausedByFormatter.java.after @@ -0,0 +1,113 @@ +import java.util.*; + +public class ABug { + + private String drinkBear(String amount) { + String firstTime = "asdf"; + + if (firstTime == null) + return "loser"; + + ArrayList bottles = new ArrayList<>(); + bottles.add("asdf"); + + Inner inner = new Inner(bottles).invoke(); + if (inner.is()) return null; + boolean no33pr = inner.isNo33pr(); + int first = inner.getFirst(); + int last = inner.getLast(); + char[] tripel = inner.getTripel(); + int rCount = inner.getrCount(); + int wCount = inner.getwCount(); + int nCount = inner.getnCount(); + int money = inner.getMoney(); + List errors = inner.getErrors(); + + boolean unhappy = no33pr && first || no33pr && last; + + String result = amount + Arrays.toString(tripel) + rCount + wCount + nCount + money + errors; + + if (!unhappy) + result += "happy"; + + + return result; + } + + private class Inner { + private boolean myResult; + private ArrayList bottles; + private List errors; + private int money; + private int nCount; + private int rCount; + private int wCount; + private char[] tripel; + private boolean no33pr; + private int first; + private int last; + + public Inner(ArrayList bottles) { + this.bottles = bottles; + } + + boolean is() { + return myResult; + } + + public List getErrors() { + return errors; + } + + public int getMoney() { + return money; + } + + public int getnCount() { + return nCount; + } + + public int getrCount() { + return rCount; + } + + public int getwCount() { + return wCount; + } + + public char[] getTripel() { + return tripel; + } + + public boolean isNo33pr() { + return no33pr; + } + + public int getFirst() { + return first; + } + + public int getLast() { + return last; + } + + public Inner invoke() { + errors = new ArrayList<>(); + + money = 0; + nCount = 0; + rCount = 0; + wCount = 0; + tripel = new char[bottles.size()]; + no33pr = false; + first = 0; + last = 0; + if (true) { + myResult = true; + return this; + } + myResult = false; + return this; + } + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodObjectWithMultipleExitPointsTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodObjectWithMultipleExitPointsTest.java index ea940e6691b0..62787cb68e52 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodObjectWithMultipleExitPointsTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodObjectWithMultipleExitPointsTest.java @@ -122,4 +122,8 @@ public class ExtractMethodObjectWithMultipleExitPointsTest extends LightRefactor public void testFromStaticContext() throws Exception { doTest(); } + + public void testBatchUpdateCausedByFormatter() throws Exception { + doTest(); + } }