From 7da45fd74fda3cd9d38b849fbe429c234831a03c Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 8 Nov 2012 20:57:05 +0100 Subject: [PATCH] introduce variable: normalize declaration when necessary (IDEA-94494) --- .../IntroduceVariableBase.java | 34 +++++++++++++++++-- .../NormalizeDeclarations.after.java | 8 +++++ .../NormalizeDeclarations.java | 5 +++ .../refactoring/IntroduceVariableTest.java | 4 +++ 4 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 java/java-tests/testData/refactoring/introduceVariable/NormalizeDeclarations.after.java create mode 100644 java/java-tests/testData/refactoring/introduceVariable/NormalizeDeclarations.java diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java index eb9ed4817098..6f506022caf0 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java @@ -45,7 +45,10 @@ import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.WindowManager; import com.intellij.psi.*; -import com.intellij.psi.codeStyle.*; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; +import com.intellij.psi.codeStyle.SuggestedNameInfo; +import com.intellij.psi.codeStyle.VariableKind; import com.intellij.psi.impl.PsiDiamondTypeUtil; import com.intellij.psi.impl.source.jsp.jspJava.JspCodeBlock; import com.intellij.psi.impl.source.jsp.jspJava.JspHolderMethod; @@ -66,6 +69,7 @@ import com.intellij.refactoring.util.RefactoringUIUtil; import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.refactoring.util.occurrences.ExpressionOccurrenceManager; import com.intellij.refactoring.util.occurrences.NotInSuperCallOccurrenceFilter; +import com.intellij.util.ArrayUtilRt; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; @@ -784,7 +788,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { PsiDeclarationStatement declaration = JavaPsiFacade.getInstance(project).getElementFactory() .createVariableDeclarationStatement(settings.getEnteredName(), selectedType.getType(), initializer); if (!isInsideLoop) { - declaration = (PsiDeclarationStatement) container.addBefore(declaration, anchor); + declaration = addDeclaration(declaration, initializer); LOG.assertTrue(expr1.isValid()); if (deleteSelf) { // never true final PsiElement lastChild = statement.getLastChild(); @@ -842,6 +846,32 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { LOG.error(e); } } + + private PsiDeclarationStatement addDeclaration(PsiDeclarationStatement declaration, PsiExpression initializer) { + if (anchor instanceof PsiDeclarationStatement) { + final PsiElement[] declaredElements = ((PsiDeclarationStatement)anchor).getDeclaredElements(); + if (declaredElements.length > 1) { + final int [] usedFirstVar = new int[] {-1}; + initializer.accept(new JavaRecursiveElementWalkingVisitor() { + @Override + public void visitReferenceExpression(PsiReferenceExpression expression) { + final int i = ArrayUtilRt.find(declaredElements, expression.resolve()); + if (i > -1) { + usedFirstVar[0] = Math.max(i, usedFirstVar[0]); + } + super.visitReferenceExpression(expression); + } + }); + if (usedFirstVar[0] > -1) { + final PsiVariable psiVariable = (PsiVariable)declaredElements[usedFirstVar[0]]; + psiVariable.normalizeDeclaration(); + final PsiDeclarationStatement parDeclarationStatement = PsiTreeUtil.getParentOfType(psiVariable, PsiDeclarationStatement.class); + return (PsiDeclarationStatement)container.addAfter(declaration, parDeclarationStatement); + } + } + } + return (PsiDeclarationStatement) container.addBefore(declaration, anchor); + } }; } diff --git a/java/java-tests/testData/refactoring/introduceVariable/NormalizeDeclarations.after.java b/java/java-tests/testData/refactoring/introduceVariable/NormalizeDeclarations.after.java new file mode 100644 index 000000000000..55b388f329a2 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/NormalizeDeclarations.after.java @@ -0,0 +1,8 @@ +class X { + { + int i = 0; + int i3 = i; + int i1 = 0; + int i2 = i3; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/introduceVariable/NormalizeDeclarations.java b/java/java-tests/testData/refactoring/introduceVariable/NormalizeDeclarations.java new file mode 100644 index 000000000000..4549160eba2e --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/NormalizeDeclarations.java @@ -0,0 +1,5 @@ +class X { + { + int i = 0, i1 = 0, i2 = i; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java index 4bb84d7ba458..631e0c9468c6 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java @@ -388,6 +388,10 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase { doTest(new MockIntroduceVariableHandler("c", false, false, false, "int")); } + public void testNormalizeDeclarations() throws Exception { + doTest(new MockIntroduceVariableHandler("i3", false, false, false, "int")); + } + private void doTest(IntroduceVariableBase testMe) throws Exception { @NonNls String baseName = "/refactoring/introduceVariable/" + getTestName(false); configureByFile(baseName + ".java");