From 0cb64bd6aebd5b366b6958f74007632bec546d2d Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 29 Jul 2011 17:48:15 +0400 Subject: [PATCH] inplace introduce: append semicolon if needed (to avoid parsing assignment as local variable) --- .../BaseExpressionToFieldHandler.java | 3 +- .../AbstractJavaInplaceIntroducer.java | 26 +++++++++++++++-- .../beforeAssignment.java | 8 +++++ .../beforeAssignmentReplaceAll.java | 8 +++++ .../beforeAssignmentReplaceAllCall.java | 10 +++++++ .../beforeAssignmentReplaceAllCall_after.java | 11 +++++++ .../beforeAssignmentReplaceAll_after.java | 9 ++++++ .../beforeAssignment_after.java | 9 ++++++ .../InplaceIntroduceFieldTest.java | 29 +++++++++++++++++++ .../inplace/AbstractInplaceIntroducer.java | 6 ++-- 10 files changed, 113 insertions(+), 6 deletions(-) create mode 100644 java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignment.java create mode 100644 java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignmentReplaceAll.java create mode 100644 java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignmentReplaceAllCall.java create mode 100644 java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignmentReplaceAllCall_after.java create mode 100644 java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignmentReplaceAll_after.java create mode 100644 java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignment_after.java diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java index 4152e5140219..2177649fd736 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java @@ -721,7 +721,8 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase initializerPlace == InitializationPlace.IN_CONSTRUCTOR && enclosingConstructor != null && initializer != null) { if (myReplaceAll) { if (enclosingConstructor != null) { - final PsiElement anchorInConstructor = myOccurenceManager.getAnchorStatementForAllInScope(enclosingConstructor); + final PsiElement anchorInConstructor = RefactoringUtil.getAnchorElementForMultipleExpressions(mySettings.myOccurrences, + enclosingConstructor); anchorElementHere = anchorInConstructor != null ? anchorInConstructor : myAnchorStatementIfAll; } else { diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java index 49b2e6a5b73f..90dd609c1084 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/AbstractJavaInplaceIntroducer.java @@ -6,11 +6,13 @@ import com.intellij.codeInsight.template.Expression; import com.intellij.codeInsight.template.ExpressionContext; import com.intellij.codeInsight.template.Result; import com.intellij.codeInsight.template.TextResult; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Computable; import com.intellij.psi.*; import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.codeStyle.VariableKind; @@ -56,6 +58,19 @@ public abstract class AbstractJavaInplaceIntroducer extends AbstractInplaceIntro return createFieldToStartTemplateOn(names, getType()); } + @Override + protected void correctExpression() { + final PsiElement parent = getExpr().getParent(); + if (parent instanceof PsiExpressionStatement && parent.getLastChild() instanceof PsiErrorElement) { + myExpr = ((PsiExpressionStatement)ApplicationManager.getApplication().runWriteAction(new Computable() { + @Override + public PsiElement compute() { + return parent.replace(JavaPsiFacade.getElementFactory(myProject).createStatementFromText(parent.getText() + ";", parent)); + } + })).getExpression(); + } + } + @Override public PsiExpression restoreExpression(PsiFile containingFile, PsiVariable psiVariable, RangeMarker marker, String exprText) { return restoreExpression(containingFile, psiVariable, JavaPsiFacade.getElementFactory(myProject), marker, exprText); @@ -65,9 +80,14 @@ public abstract class AbstractJavaInplaceIntroducer extends AbstractInplaceIntro protected void restoreState(PsiVariable psiField) { final SmartTypePointer typePointer = SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(getType()); super.restoreState(psiField); - myTypeSelectorManager = myExpr != null - ? new TypeSelectorManagerImpl(myProject, typePointer.getType(), myExpr, myOccurrences) - : new TypeSelectorManagerImpl(myProject, typePointer.getType(), myOccurrences); + try { + myTypeSelectorManager = myExpr != null + ? new TypeSelectorManagerImpl(myProject, typePointer.getType(), myExpr, myOccurrences) + : new TypeSelectorManagerImpl(myProject, typePointer.getType(), myOccurrences); + } + catch (Exception e) { + LOG.error(e); + } } @Override diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignment.java b/java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignment.java new file mode 100644 index 000000000000..7e8caceb1a21 --- /dev/null +++ b/java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignment.java @@ -0,0 +1,8 @@ +class Test { + private String myTimer; + + Test() { + "" + myTimer = "abc"; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignmentReplaceAll.java b/java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignmentReplaceAll.java new file mode 100644 index 000000000000..4a35a0b591e4 --- /dev/null +++ b/java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignmentReplaceAll.java @@ -0,0 +1,8 @@ +class Test { + private String myTimer; + + Test() { + "" + myTimer = ""; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignmentReplaceAllCall.java b/java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignmentReplaceAllCall.java new file mode 100644 index 000000000000..e7377701ac66 --- /dev/null +++ b/java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignmentReplaceAllCall.java @@ -0,0 +1,10 @@ +class Test { + private Foo myFoo; + + Test() { + new Foo() + myFoo = new Foo(); + } +} + +class Foo{} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignmentReplaceAllCall_after.java b/java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignmentReplaceAllCall_after.java new file mode 100644 index 000000000000..f7d817a812a8 --- /dev/null +++ b/java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignmentReplaceAllCall_after.java @@ -0,0 +1,11 @@ +class Test { + private Foo myFoo; + private final Foo foo; + + Test() { + foo = new Foo(); + myFoo = foo; + } +} + +class Foo{} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignmentReplaceAll_after.java b/java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignmentReplaceAll_after.java new file mode 100644 index 000000000000..9d073f824f6d --- /dev/null +++ b/java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignmentReplaceAll_after.java @@ -0,0 +1,9 @@ +class Test { + private String myTimer; + private final String string; + + Test() { + string = ""; + myTimer = string; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignment_after.java b/java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignment_after.java new file mode 100644 index 000000000000..affd5251fc65 --- /dev/null +++ b/java/java-tests/testData/refactoring/inplaceIntroduceField/beforeAssignment_after.java @@ -0,0 +1,9 @@ +class Test { + private String myTimer; + private final String string; + + Test() { + string = ""; + myTimer = "abc"; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceFieldTest.java b/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceFieldTest.java index 6fa00cd20f1a..4d7be1f9fc3b 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceFieldTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceFieldTest.java @@ -41,6 +41,35 @@ public class InplaceIntroduceFieldTest extends AbstractInplaceIntroduceTest { }); } + public void testBeforeAssignment() throws Exception { + + doTest(new Pass() { + @Override + public void pass(AbstractInplaceIntroducer inplaceIntroduceFieldPopup) { + } + }); + } + + public void testBeforeAssignmentReplaceAll() throws Exception { + + doTest(new Pass() { + @Override + public void pass(AbstractInplaceIntroducer inplaceIntroduceFieldPopup) { + inplaceIntroduceFieldPopup.setReplaceAllOccurrences(true); + } + }); + } + + public void testBeforeAssignmentReplaceAllCall() throws Exception { + + doTest(new Pass() { + @Override + public void pass(AbstractInplaceIntroducer inplaceIntroduceFieldPopup) { + inplaceIntroduceFieldPopup.setReplaceAllOccurrences(true); + } + }); + } + public void testReplaceAll() throws Exception { doTest(new Pass() { diff --git a/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceIntroducer.java b/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceIntroducer.java index ea482c8fbea0..5821890d256f 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceIntroducer.java +++ b/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/AbstractInplaceIntroducer.java @@ -330,8 +330,8 @@ public abstract class AbstractInplaceIntroducercreate(expression, new TextRange(0, expression.getTextLength()))); } - } - else if (getExpr() != null) { + } else if (getExpr() != null) { + correctExpression(); stringUsages.add(Pair.create(getExpr(), new TextRange(0, getExpr().getTextLength()))); } @@ -345,6 +345,8 @@ public abstract class AbstractInplaceIntroducer rangesToHighlight, Collection> stringUsages,