Groovy: in-place introduce constant from local var reference

This commit is contained in:
Max Medvedev
2014-01-31 16:04:18 +04:00
parent 3d07be5709
commit cee821f7cb
7 changed files with 99 additions and 63 deletions
@@ -752,7 +752,7 @@ public abstract class GrIntroduceHandlerBase<Settings extends GrIntroduceSetting
}
@Nullable
private static GrVariable resolveLocalVar(@Nullable GrExpression expression) {
public static GrVariable resolveLocalVar(@Nullable GrExpression expression) {
if (expression instanceof GrReferenceExpression) {
final GrReferenceExpression ref = (GrReferenceExpression)expression;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -58,6 +58,7 @@ import org.jetbrains.plugins.groovy.refactoring.GroovyNamesUtil;
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle;
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContext;
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceDialog;
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceHandlerBase;
import org.jetbrains.plugins.groovy.refactoring.introduce.StringPartInfo;
import org.jetbrains.plugins.groovy.refactoring.introduce.field.GrFieldNameSuggester;
import org.jetbrains.plugins.groovy.refactoring.introduce.variable.GroovyVariableValidator;
@@ -135,7 +136,7 @@ public class GrIntroduceConstantDialog extends DialogWrapper
initializeName();
initializeTargetClassEditor();
if (myContext.getVar() != null) {
if (GrIntroduceHandlerBase.resolveLocalVar(myContext) != null) {
myReplaceAllOccurrences.setEnabled(false);
myReplaceAllOccurrences.setSelected(true);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -53,7 +53,13 @@ public class GrIntroduceConstantHandler extends GrIntroduceFieldHandlerBase<GrIn
@Override
protected void checkExpression(@NotNull GrExpression selectedExpr) {
selectedExpr.accept(new ConstantChecker(selectedExpr, selectedExpr));
GrVariable variable = GrIntroduceHandlerBase.resolveLocalVar(selectedExpr);
if (variable != null) {
checkVariable(variable);
}
else {
selectedExpr.accept(new ConstantChecker(selectedExpr, selectedExpr));
}
}
@Override
@@ -73,10 +73,17 @@ public class GrIntroduceConstantProcessor {
final GrVariableDeclaration declaration = addDeclaration(targetClass);
final GrField field = (GrField)declaration.getVariables()[0];
if (context.getVar() != null) {
GrVariable var = context.getVar();
replaceOccurrence(field, var.getInitializerGroovy(), isEscalateVisibility());
deleteLocalVar(var);
GrVariable localVar = GrIntroduceHandlerBase.resolveLocalVar(context);
if (localVar != null) {
assert localVar.getInitializerGroovy() != null : "initializer should exist: " + localVar.getText();
deleteLocalVar(localVar);
if (settings.replaceAllOccurrences()) {
processOccurrences(field);
}
else {
replaceOccurrence(field, localVar.getInitializerGroovy(), isEscalateVisibility());
}
}
else if (context.getStringPart() != null) {
final GrExpression ref = processLiteral(field.getName(), context.getStringPart(), context.getProject());
@@ -85,11 +92,7 @@ public class GrIntroduceConstantProcessor {
}
else if (context.getExpression() != null) {
if (settings.replaceAllOccurrences()) {
final PsiElement[] occurrences = context.getOccurrences();
GroovyRefactoringUtil.sortOccurrences(occurrences);
for (PsiElement occurrence : occurrences) {
replaceOccurrence(field, occurrence, isEscalateVisibility());
}
processOccurrences(field);
}
else {
replaceOccurrence(field, context.getExpression(), isEscalateVisibility());
@@ -98,6 +101,14 @@ public class GrIntroduceConstantProcessor {
return field;
}
private void processOccurrences(GrField field) {
final PsiElement[] occurrences = context.getOccurrences();
GroovyRefactoringUtil.sortOccurrences(occurrences);
for (PsiElement occurrence : occurrences) {
replaceOccurrence(field, occurrence, isEscalateVisibility());
}
}
private void updateCaretPosition(PsiElement element) {
context.getEditor().getCaretModel().moveToOffset(element.getTextRange().getEndOffset());
context.getEditor().getSelectionModel().removeSelection();
@@ -206,15 +217,15 @@ public class GrIntroduceConstantProcessor {
@NotNull
protected GrExpression getInitializer() {
GrVariable var = GrIntroduceHandlerBase.resolveLocalVar(context);
GrExpression expression = context.getExpression();
GrVariable var = context.getVar();
if (expression != null) {
return expression;
}
else if (var != null) {
if (var != null) {
return var.getInitializerGroovy();
}
else if (expression != null) {
return expression;
}
else {
return GrIntroduceHandlerBase.generateExpressionFromStringPart(context.getStringPart(), context.getProject());
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,24 +13,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.refactoring.introduce;
package org.jetbrains.plugins.groovy.refactoring.introduce
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiType;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import com.intellij.util.VisibilityUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.refactoring.introduce.constant.GrIntroduceConstantHandler;
import org.jetbrains.plugins.groovy.refactoring.introduce.constant.GrIntroduceConstantSettings;
import org.jetbrains.plugins.groovy.util.TestUtils;
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.editor.Editor
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiModifier
import com.intellij.psi.PsiType
import com.intellij.psi.impl.source.PostprocessReformattingAspect
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import com.intellij.util.VisibilityUtil
import org.jetbrains.annotations.NotNull
import org.jetbrains.annotations.Nullable
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression
import org.jetbrains.plugins.groovy.refactoring.introduce.constant.GrIntroduceConstantHandler
import org.jetbrains.plugins.groovy.refactoring.introduce.constant.GrIntroduceConstantSettings
import org.jetbrains.plugins.groovy.util.TestUtils
/**
* @author Maxim.Medvedev
@@ -38,7 +38,7 @@ import org.jetbrains.plugins.groovy.util.TestUtils;
public class IntroduceConstantTest extends LightCodeInsightFixtureTestCase {
@Override
protected String getBasePath() {
return TestUtils.getTestDataPath() + "refactoring/introduceConstant/";
TestUtils.testDataPath + "refactoring/introduceConstant/"
}
public void testSimple() {
@@ -62,7 +62,7 @@ public class IntroduceConstantTest extends LightCodeInsightFixtureTestCase {
}
public void testTupleDeclaration() {
doTest("Test", false, false, PsiModifier.PUBLIC);
doTest("Test", true, false, PsiModifier.PUBLIC);
}
public void testStringPart() {
@@ -77,11 +77,15 @@ public class IntroduceConstantTest extends LightCodeInsightFixtureTestCase {
doTest();
}
void testLocalVarRef() {
doTest()
}
private void doTest() {
doTest(null, true, true, PsiModifier.PUBLIC);
}
private void doTest(@Nullable String targetClassName, boolean replaceAllOccurences, boolean useExplicitType, String modifier) {
private void doTest(@Nullable String targetClassName, boolean replaceAllOccurrences, boolean useExplicitType, String modifier) {
myFixture.configureByFile(getTestName(false) + ".groovy");
@@ -95,25 +99,17 @@ public class IntroduceConstantTest extends LightCodeInsightFixtureTestCase {
PsiElement[] scopes = handler.findPossibleScopes(expression, variable, stringPart, editor);
final GrIntroduceContext context = handler.getContext(getProject(), editor, expression, variable, stringPart, scopes[0]);
PsiClass targetClass;
if (targetClassName == null) {
targetClass = GrIntroduceConstantHandler.findContainingClass(context);
}
else {
targetClass = myFixture.findClass(targetClassName);
}
PsiClass targetClass = targetClassName == null ? GrIntroduceConstantHandler.findContainingClass(context)
: myFixture.findClass(targetClassName);
assertNotNull("target class is null", targetClass);
final GrIntroduceConstantSettings settings =
new MockIntroduceConstantSettings(targetClass, replaceAllOccurences, getType(useExplicitType, expression, variable, stringPart), modifier);
def type = getType(useExplicitType, expression, variable, stringPart)
final GrIntroduceConstantSettings settings = new MockIntroduceConstantSettings(targetClass, replaceAllOccurrences, type, modifier);
WriteCommandAction.runWriteCommandAction(null, new Runnable() {
@Override
public void run() {
handler.runRefactoring(context, settings);
PostprocessReformattingAspect.getInstance(getProject()).doPostponedFormatting();
}
});
WriteCommandAction.runWriteCommandAction(null) {
handler.runRefactoring(context, settings);
PostprocessReformattingAspect.getInstance(project).doPostponedFormatting();
}
myFixture.checkResultByFile(getTestName(false) + "_after.groovy", true);
}
@@ -122,8 +118,8 @@ public class IntroduceConstantTest extends LightCodeInsightFixtureTestCase {
return null;
}
return expression != null ? expression.getType() :
variable != null ? variable.getType() :
stringPart.getLiteral().getType();
variable != null ? variable.getType() :
stringPart.getLiteral().getType();
}
@Nullable
@@ -151,10 +147,10 @@ public class IntroduceConstantTest extends LightCodeInsightFixtureTestCase {
}
private static class MockIntroduceConstantSettings implements GrIntroduceConstantSettings {
private PsiClass myTargetClass;
private boolean myReplaceAllOccurrences;
private PsiType mySelectedType;
private String myModifier;
private final PsiClass myTargetClass;
private final boolean myReplaceAllOccurrences;
private final PsiType mySelectedType;
private final String myModifier;
private MockIntroduceConstantSettings(@NotNull PsiClass targetClass,
boolean replaceAllOccurrences,
@@ -168,7 +164,6 @@ public class IntroduceConstantTest extends LightCodeInsightFixtureTestCase {
@Override
public String getVisibilityModifier() {
return myModifier;
}
@@ -0,0 +1,11 @@
class X {
def foo() {
def ad = 6
print <selection>ad</selection>
print ad
print "abc"
print 5
}
}
@@ -0,0 +1,12 @@
class X {
public static final int CONST = 6
def foo() {
print CONST
print CONST
print "abc"
print 5
}
}