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 739e0682c837..d6d76b960c4b 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java @@ -62,6 +62,7 @@ import com.intellij.util.IncorrectOperationException; import com.intellij.util.Processor; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -162,7 +163,9 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { if (!selectionModel.hasSelection()) { final List expressions = ContainerUtil - .filter(collectExpressions(file, editor, offset), expression -> RefactoringUtil.getParentStatement(expression, false) != null); + .filter(collectExpressions(file, editor, offset), expression -> + RefactoringUtil.getParentStatement(expression, false) != null || + PsiTreeUtil.getParentOfType(expression, PsiField.class, true, PsiStatement.class) != null); if (expressions.isEmpty()) { selectionModel.selectLineAtCaret(); } else if (!isChooserNeeded(expressions)) { @@ -612,7 +615,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { final PsiElement physicalElement = expr.getUserData(ElementToWorkOn.PARENT); - final PsiElement anchorStatement = RefactoringUtil.getParentStatement(physicalElement != null ? physicalElement : expr, false); + final PsiElement anchorStatement = getAnchor(physicalElement != null ? physicalElement : expr); PsiElement tempContainer = checkAnchorStatement(project, editor, anchorStatement); if (tempContainer == null) return false; @@ -756,6 +759,19 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase { return wasSucceed[0]; } + @Nullable + private static PsiElement getAnchor(PsiElement place) { + PsiElement anchorStatement = RefactoringUtil.getParentStatement(place, false); + if (anchorStatement == null) { + PsiField field = PsiTreeUtil.getParentOfType(place, PsiField.class, true, PsiStatement.class); + if (field != null) { + anchorStatement = field.getInitializer(); + } + } + return anchorStatement; + } + + @Contract("_, _, null -> null") protected PsiElement checkAnchorStatement(Project project, Editor editor, PsiElement anchorStatement) { if (anchorStatement == null) { String message = RefactoringBundle.message("refactoring.is.not.supported.in.the.current.context", REFACTORING_NAME); diff --git a/java/java-impl/src/com/intellij/refactoring/util/occurrences/BaseOccurrenceManager.java b/java/java-impl/src/com/intellij/refactoring/util/occurrences/BaseOccurrenceManager.java index 797b5c39566f..5a4f72dd5219 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/occurrences/BaseOccurrenceManager.java +++ b/java/java-impl/src/com/intellij/refactoring/util/occurrences/BaseOccurrenceManager.java @@ -78,7 +78,8 @@ public abstract class BaseOccurrenceManager implements OccurrenceManager { } @Override public PsiElement getAnchorStatementForAllInScope(PsiElement scope) { - return RefactoringUtil.getAnchorElementForMultipleExpressions(myOccurrences, scope); + PsiElement anchor = RefactoringUtil.getAnchorElementForMultipleExpressions(myOccurrences, scope); + return anchor instanceof PsiField ? ((PsiField)anchor).getInitializer() : anchor; } private static boolean needToDeclareFinal(PsiExpression[] occurrences) { diff --git a/java/java-tests/testData/refactoring/introduceVariable/Field.after.java b/java/java-tests/testData/refactoring/introduceVariable/Field.after.java new file mode 100644 index 000000000000..04a40e263cae --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/Field.after.java @@ -0,0 +1,8 @@ +class Test { + private static final String STRING; + + static { + String temp = "foo".trim(); + STRING = temp +"foo".trim(); + } +} diff --git a/java/java-tests/testData/refactoring/introduceVariable/Field.java b/java/java-tests/testData/refactoring/introduceVariable/Field.java new file mode 100644 index 000000000000..529e3f85b5c5 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/Field.java @@ -0,0 +1,3 @@ +class Test { + private static final String STRING = "foo".trim()+"foo".trim(); +} diff --git a/java/java-tests/testData/refactoring/introduceVariable/FieldAll.after.java b/java/java-tests/testData/refactoring/introduceVariable/FieldAll.after.java new file mode 100644 index 000000000000..d25869f9e7bd --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/FieldAll.after.java @@ -0,0 +1,8 @@ +class Test { + private static final String STRING; + + static { + String temp = "foo".trim(); + STRING = temp + temp; + } +} diff --git a/java/java-tests/testData/refactoring/introduceVariable/FieldAll.java b/java/java-tests/testData/refactoring/introduceVariable/FieldAll.java new file mode 100644 index 000000000000..529e3f85b5c5 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/FieldAll.java @@ -0,0 +1,3 @@ +class Test { + private static final String STRING = "foo".trim()+"foo".trim(); +} diff --git a/java/java-tests/testSrc/com/intellij/java/refactoring/IntroduceVariableTest.java b/java/java-tests/testSrc/com/intellij/java/refactoring/IntroduceVariableTest.java index 855fabefcc04..2ee6f7ecb9fd 100644 --- a/java/java-tests/testSrc/com/intellij/java/refactoring/IntroduceVariableTest.java +++ b/java/java-tests/testSrc/com/intellij/java/refactoring/IntroduceVariableTest.java @@ -203,6 +203,14 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase { public void testWhileCondition2() { doTest(new MockIntroduceVariableHandler("temp", true, false, false, "Node")); } + + public void testField() { + doTest(new MockIntroduceVariableHandler("temp", false, false, false, CommonClassNames.JAVA_LANG_STRING)); + } + + public void testFieldAll() { + doTest(new MockIntroduceVariableHandler("temp", true, false, false, CommonClassNames.JAVA_LANG_STRING)); + } public void testCaseLabel() { doTest(new MockIntroduceVariableHandler("temp", true, false, false, "int"));