inplace introduce: adjust final: local setting

This commit is contained in:
anna
2010-11-13 18:13:09 +03:00
parent 4c57d286a7
commit 83ed87001f
2 changed files with 79 additions and 7 deletions
@@ -28,8 +28,11 @@ import com.intellij.codeInsight.completion.JavaCompletionUtil;
import com.intellij.codeInsight.highlighting.HighlightManager;
import com.intellij.codeInsight.intention.impl.TypeExpression;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.codeInsight.lookup.LookupManager;
import com.intellij.codeInsight.template.*;
import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
import com.intellij.codeInsight.template.impl.TextExpression;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.lang.LanguageRefactoringSupport;
@@ -49,6 +52,8 @@ 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.impl.PsiVariableEx;
import com.intellij.psi.impl.java.stubs.PsiModifierListStub;
import com.intellij.psi.impl.source.tree.java.ReplaceExpressionUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
@@ -487,26 +492,37 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme
editor.putUserData(ReassignVariableUtil.DECLARATION_KEY, declarationStatement);
editor.putUserData(ReassignVariableUtil.OCCURRENCES_KEY,
occurrenceMarkers.toArray(new RangeMarker[occurrenceMarkers.size()]));
final boolean cantChangeFinalModifier = hasWriteAccess || (inFinalContext && choice == OccurrencesChooser.ReplaceChoice.ALL);
final VariableInplaceRenamer renamer = new VariableInplaceRenamer(elementToRename, editor){
@Override
protected void addAdditionalVariables(TemplateBuilderImpl builder) {
final PsiTypeElement typeElement = elementToRename.getTypeElement();
builder.replaceElement(typeElement, "Variable_Type",
ReassignVariableUtil.createExpression(expression, typeElement.getText()), false, true);
ReassignVariableUtil.createExpression(expression, typeElement.getText(), !cantChangeFinalModifier), false, true);
if (!cantChangeFinalModifier) {
builder.replaceElement(elementToRename.getModifierList(), "_FINAL_", new FinalExpression(project), false, true);
}
}
};
renamer.setAdvertisementText(
ReassignVariableUtil.getAdvertisementText(editor, declarationStatement, elementToRename.getType(), typeSelectorManager.getTypesForAll()));
ReassignVariableUtil.getAdvertisementText(editor, declarationStatement, elementToRename.getType(), typeSelectorManager.getTypesForAll(), !cantChangeFinalModifier));
renamer.performInplaceRename(false, new LinkedHashSet<String>(Arrays.asList(suggestedName.names)), new Consumer<Boolean>() {
@Override
public void consume(Boolean apply) {
if (apply) {
final Document document = editor.getDocument();
final PsiVariable psiVariable =
PsiTreeUtil.getParentOfType(file.findElementAt(editor.getCaretModel().getOffset()), PsiVariable.class);
if (psiVariable != null) {
JavaRefactoringSettings.getInstance().INTRODUCE_LOCAL_CREATE_FINALS = psiVariable.hasModifierProperty(PsiModifier.FINAL);
FinalExpression.adjustLine(psiVariable, document);
}
int startOffset = exprMarker.getStartOffset();
final PsiReference referenceAt = file.findReferenceAt(startOffset);
if (referenceAt != null && referenceAt.resolve() instanceof PsiLocalVariable) {
startOffset = referenceAt.getElement().getTextRange().getEndOffset();
} else {
startOffset = editor.getDocument().getLineEndOffset(editor.getDocument().getLineNumber(startOffset));
startOffset = document.getLineEndOffset(document.getLineNumber(startOffset));
}
editor.getCaretModel().moveToOffset(startOffset);
typeSelectorManager.typeSelected(ReassignVariableUtil.getVariableType(declarationStatement));
@@ -803,8 +819,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme
replaceChoice == OccurrencesChooser.ReplaceChoice.ALL || replaceChoice == OccurrencesChooser.ReplaceChoice.NO_WRITE;
final boolean declareFinal =
!anyAssignmentLHS && (replaceAll &&
declareFinalIfAll ||
CodeStyleSettingsManager.getSettings(project).GENERATE_FINAL_LOCALS);
declareFinalIfAll || createFinals(project));
final boolean replaceWrite = anyAssignmentLHS && replaceChoice == OccurrencesChooser.ReplaceChoice.ALL;
return new IntroduceVariableSettings() {
@Override
@@ -840,6 +855,11 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme
};
}
private static boolean createFinals(Project project) {
final Boolean createFinals = JavaRefactoringSettings.getInstance().INTRODUCE_LOCAL_CREATE_FINALS;
return createFinals == null ? CodeStyleSettingsManager.getSettings(project).GENERATE_FINAL_LOCALS : createFinals.booleanValue();
}
public interface Validator {
boolean isOK(IntroduceVariableSettings dialog);
}
@@ -863,4 +883,40 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme
conflicts.putValue(occurence, RefactoringBundle.message("introducing.variable.may.break.code.logic"));
}
}
private static class FinalExpression extends Expression {
private final Project myProject;
public FinalExpression(Project project) {
myProject = project;
}
@Override
public Result calculateResult(ExpressionContext context) {
return new TextResult(createFinals(myProject) ? PsiKeyword.FINAL : "");
}
@Override
public Result calculateQuickResult(ExpressionContext context) {
return calculateResult(context);
}
@Override
public LookupElement[] calculateLookupItems(ExpressionContext context) {
LookupElement[] lookupElements = new LookupElement[2];
lookupElements[0] = LookupElementBuilder.create("");
lookupElements[1] = LookupElementBuilder.create(PsiModifier.FINAL + " ");
return lookupElements;
}
public static void adjustLine(final PsiVariable psiVariable, final Document document) {
final int modifierListOffset = psiVariable.getTextRange().getStartOffset();
final int varLineNumber = document.getLineNumber(modifierListOffset);
ApplicationManager.getApplication().runWriteAction(new Runnable() { //adjust line indent if final was inserted and then deleted
public void run() {
CodeStyleManager.getInstance(psiVariable.getProject()).adjustLineIndent(document, document.getLineStartOffset(varLineNumber));
}
});
}
}
}
@@ -174,7 +174,7 @@ public class ReassignVariableUtil {
}
@Nullable
static String getAdvertisementText(Editor editor, PsiDeclarationStatement declaration, PsiType type, PsiType[] typesForAll) {
static String getAdvertisementText(Editor editor, PsiDeclarationStatement declaration, PsiType type, PsiType[] typesForAll, boolean canAdjustFinal) {
final VariablesProcessor processor = findVariablesOfType(editor, declaration, type);
final Keymap keymap = KeymapManager.getInstance().getActiveKeymap();
if (processor.size() > 0) {
@@ -189,10 +189,21 @@ public class ReassignVariableUtil {
return "Press " + shortcuts[0] + " to change type";
}
}
return adjustFinalText(canAdjustFinal);
}
@Nullable
private static String adjustFinalText(boolean canBeFinalAdjusted) {
if (canBeFinalAdjusted) {
final Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts("PreviousTemplateVariable");
if (shortcuts.length > 0) {
return "Press " + shortcuts[0] + " to adjust final modifier";
}
}
return null;
}
public static Expression createExpression(final TypeExpression expression, final String defaultType) {
public static Expression createExpression(final TypeExpression expression, final String defaultType, final boolean canBeFinalAdjusted) {
return new Expression() {
@Override
public com.intellij.codeInsight.template.Result calculateResult(ExpressionContext context) {
@@ -208,6 +219,11 @@ public class ReassignVariableUtil {
public LookupElement[] calculateLookupItems(ExpressionContext context) {
return expression.calculateLookupItems(context);
}
@Override
public String getAdvertisingText() {
return adjustFinalText(canBeFinalAdjusted);
}
};
}
}