mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
inplace introduce api extracted
This commit is contained in:
@@ -73,4 +73,8 @@ public class TypeExpression extends Expression {
|
||||
return result.toArray(new LookupElement[result.size()]);
|
||||
}
|
||||
|
||||
public boolean hasSuggestions() {
|
||||
return myItems.size() > 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
package com.intellij.refactoring.introduceField;
|
||||
|
||||
import com.intellij.ide.ui.ListCellRendererWrapper;
|
||||
import com.intellij.ide.ui.UISettings;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.wm.ToolWindowManager;
|
||||
import com.intellij.psi.PsiBundle;
|
||||
import com.intellij.psi.PsiModifier;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
*/
|
||||
public class InplaceCombosUtil {
|
||||
public static JComboBox createVisibilityCombo(final JPanel left,
|
||||
final GridBagConstraints lgc,
|
||||
final Project project,
|
||||
@NotNull final String initialVisibility) {
|
||||
|
||||
final JLabel label = new JLabel("Visibility:");
|
||||
label.setDisplayedMnemonic('V');
|
||||
left.add(label, lgc);
|
||||
final JComboBox visibilityCombo = new JComboBox(new String[]{PsiModifier.PUBLIC, PsiModifier.PACKAGE_LOCAL, PsiModifier.PROTECTED, PsiModifier.PRIVATE});
|
||||
visibilityCombo.setRenderer(new ListCellRendererWrapper<String>(visibilityCombo.getRenderer()) {
|
||||
@Override
|
||||
public void customize(JList list, String value, int index, boolean selected, boolean hasFocus) {
|
||||
if (value == null) return;
|
||||
setText(PsiBundle.visibilityPresentation(value));
|
||||
}
|
||||
});
|
||||
label.setLabelFor(visibilityCombo);
|
||||
visibilityCombo.setSelectedItem(initialVisibility);
|
||||
|
||||
appendActions(visibilityCombo, project);
|
||||
lgc.gridx++;
|
||||
lgc.insets.top = 2;
|
||||
lgc.insets.left = 2;
|
||||
left.add(visibilityCombo, lgc);
|
||||
return visibilityCombo;
|
||||
}
|
||||
|
||||
public static void appendActions(final JComboBox comboBox, final Project project) {
|
||||
final boolean toggleStrategy = !UIUtil.isUnderAquaLookAndFeel();
|
||||
final boolean[] moveFocusBack = new boolean[] {true};
|
||||
comboBox.addFocusListener(new FocusAdapter() {
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
if (!moveFocusBack[0]) {
|
||||
moveFocusBack[0] = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (toggleStrategy) {
|
||||
final int size = comboBox.getModel().getSize();
|
||||
int next = comboBox.getSelectedIndex() + 1;
|
||||
if (next < 0 || next >= size) {
|
||||
if (!UISettings.getInstance().CYCLE_SCROLLING) {
|
||||
return;
|
||||
}
|
||||
next = (next + size) % size;
|
||||
}
|
||||
comboBox.setSelectedIndex(next);
|
||||
ToolWindowManager.getInstance(project).activateEditorComponent();
|
||||
}
|
||||
else {
|
||||
JBPopupFactory popupFactory = JBPopupFactory.getInstance();
|
||||
boolean fromTheSameBalloon = popupFactory.getParentBalloonFor(e.getComponent()) == popupFactory.getParentBalloonFor(e.getOppositeComponent());
|
||||
if (!fromTheSameBalloon) {
|
||||
comboBox.showPopup();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
comboBox.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
moveFocusBack[0] = false;
|
||||
}
|
||||
});
|
||||
comboBox.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
moveFocusBack[0] = true;
|
||||
if (!toggleStrategy && e.getKeyCode() == KeyEvent.VK_ESCAPE && e.getModifiers() == 0) {
|
||||
ToolWindowManager.getInstance(project).activateEditorComponent();
|
||||
}
|
||||
}
|
||||
});
|
||||
comboBox.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
moveFocusBack[0] = true;
|
||||
ToolWindowManager.getInstance(project).activateEditorComponent();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+146
-399
@@ -16,77 +16,49 @@
|
||||
package com.intellij.refactoring.introduceField;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.intention.impl.TypeExpression;
|
||||
import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
|
||||
import com.intellij.codeInsight.template.impl.TemplateState;
|
||||
import com.intellij.ide.ui.ListCellRendererWrapper;
|
||||
import com.intellij.ide.ui.UISettings;
|
||||
import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.wm.ToolWindowManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.refactoring.JavaRefactoringSettings;
|
||||
import com.intellij.refactoring.introduceParameter.AbstractInplaceIntroducer;
|
||||
import com.intellij.refactoring.introduceParameter.AbstractJavaInplaceIntroducer;
|
||||
import com.intellij.refactoring.introduceParameter.VisibilityListener;
|
||||
import com.intellij.refactoring.move.moveMembers.MoveMembersImpl;
|
||||
import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer;
|
||||
import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
|
||||
import com.intellij.refactoring.util.occurences.OccurenceManager;
|
||||
import com.intellij.ui.StateRestoringCheckBox;
|
||||
import com.intellij.ui.TitlePanel;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
* Date: 3/18/11
|
||||
*/
|
||||
public class InplaceIntroduceConstantPopup {
|
||||
private final Project myProject;
|
||||
private final PsiClass myParentClass;
|
||||
private PsiExpression myExpr;
|
||||
private final PsiLocalVariable myLocalVariable;
|
||||
private final PsiExpression[] myOccurrences;
|
||||
private TypeSelectorManagerImpl myTypeSelectorManager;
|
||||
public class InplaceIntroduceConstantPopup extends AbstractJavaInplaceIntroducer {
|
||||
private PsiElement myAnchorElement;
|
||||
private int myAnchorIdx = -1;
|
||||
private PsiElement myAnchorElementIfAll;
|
||||
private int myAnchorIdxIfAll = -1;
|
||||
private final OccurenceManager myOccurenceManager;
|
||||
|
||||
private Editor myEditor;
|
||||
private String myConstantName;
|
||||
private List<RangeMarker> myOccurrenceMarkers;
|
||||
private final String myExprText;
|
||||
private final String myInitializerText;
|
||||
private final String myLocalName;
|
||||
private RangeMarker myExprMarker;
|
||||
|
||||
private boolean myInitListeners = false;
|
||||
|
||||
private JCheckBox myReplaceAllCb;
|
||||
private JCheckBox myAnnotateNonNls;
|
||||
private StateRestoringCheckBox myCbDeleteVariable;
|
||||
@@ -96,6 +68,7 @@ public class InplaceIntroduceConstantPopup {
|
||||
private JComboBox myVisibilityCombo;
|
||||
|
||||
private JPanel myWholePanel;
|
||||
private final PsiClass myParentClass;
|
||||
|
||||
public InplaceIntroduceConstantPopup(Project project,
|
||||
Editor editor,
|
||||
@@ -106,12 +79,8 @@ public class InplaceIntroduceConstantPopup {
|
||||
TypeSelectorManagerImpl typeSelectorManager,
|
||||
PsiElement anchorElement,
|
||||
PsiElement anchorElementIfAll, OccurenceManager occurenceManager) {
|
||||
myProject = project;
|
||||
myEditor = editor;
|
||||
super(project, editor, expr, localVariable, occurrences, typeSelectorManager.getDefaultType(), typeSelectorManager, IntroduceConstantHandler.REFACTORING_NAME);
|
||||
myParentClass = parentClass;
|
||||
myExpr = expr;
|
||||
myLocalVariable = localVariable;
|
||||
myOccurrences = occurrences;
|
||||
myTypeSelectorManager = typeSelectorManager;
|
||||
myAnchorElement = anchorElement;
|
||||
myAnchorElementIfAll = anchorElementIfAll;
|
||||
@@ -127,13 +96,12 @@ public class InplaceIntroduceConstantPopup {
|
||||
}
|
||||
myOccurenceManager = occurenceManager;
|
||||
|
||||
myExprMarker = expr != null && expr.isPhysical() ? myEditor.getDocument().createRangeMarker(expr.getTextRange()) : null;
|
||||
myExprText = expr != null ? expr.getText() : null;
|
||||
myInitializerText = getExprText(expr, localVariable);
|
||||
myLocalName = localVariable != null ? localVariable.getName() : null;
|
||||
|
||||
|
||||
myWholePanel = new JPanel(new GridBagLayout());
|
||||
GridBagConstraints gc = new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0 , 0, 0), 0, 0);
|
||||
GridBagConstraints gc =
|
||||
new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0);
|
||||
|
||||
gc.gridwidth = 1;
|
||||
gc.gridy = 1;
|
||||
@@ -142,7 +110,6 @@ public class InplaceIntroduceConstantPopup {
|
||||
gc.gridx = 1;
|
||||
gc.insets.left = 6;
|
||||
myWholePanel.add(createRightPanel(), gc);
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -159,7 +126,9 @@ public class InplaceIntroduceConstantPopup {
|
||||
|
||||
private JPanel createRightPanel() {
|
||||
final JPanel right = new JPanel(new GridBagLayout());
|
||||
final GridBagConstraints rgc = new GridBagConstraints(0, GridBagConstraints.RELATIVE,1,1,0,0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(1,0,0,0), 0, 0);
|
||||
final GridBagConstraints rgc =
|
||||
new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
|
||||
new Insets(1, 0, 0, 0), 0, 0);
|
||||
myReplaceAllCb = new JCheckBox("Replace all occurrences");
|
||||
myReplaceAllCb.setMnemonic('a');
|
||||
myReplaceAllCb.setFocusable(false);
|
||||
@@ -176,7 +145,8 @@ public class InplaceIntroduceConstantPopup {
|
||||
myCbDeleteVariable.setSelected(true);
|
||||
myCbDeleteVariable.setEnabled(false);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
myCbDeleteVariable.setVisible(false);
|
||||
}
|
||||
right.add(myCbDeleteVariable, rgc);
|
||||
@@ -185,7 +155,7 @@ public class InplaceIntroduceConstantPopup {
|
||||
myAnnotateNonNls.setMnemonic('f');
|
||||
myAnnotateNonNls.setFocusable(false);
|
||||
if ((myTypeSelectorManager.isSuggestedType("java.lang.String") || (myLocalVariable != null && AnnotationUtil
|
||||
.isAnnotated(myLocalVariable, AnnotationUtil.NON_NLS, false)))&&
|
||||
.isAnnotated(myLocalVariable, AnnotationUtil.NON_NLS, false))) &&
|
||||
LanguageLevelProjectExtension.getInstance(myProject).getLanguageLevel().hasEnumKeywordAndAutoboxing() &&
|
||||
JavaPsiFacade.getInstance(myProject).findClass(AnnotationUtil.NON_NLS, myParentClass.getResolveScope()) != null) {
|
||||
final PropertiesComponent component = PropertiesComponent.getInstance(myProject);
|
||||
@@ -195,7 +165,8 @@ public class InplaceIntroduceConstantPopup {
|
||||
component.setValue(IntroduceConstantDialog.NONNLS_SELECTED_PROPERTY, Boolean.toString(myAnnotateNonNls.isSelected()));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
myAnnotateNonNls.setVisible(false);
|
||||
}
|
||||
right.add(myAnnotateNonNls, rgc);
|
||||
@@ -208,156 +179,38 @@ public class InplaceIntroduceConstantPopup {
|
||||
if (initialVisibility == null) {
|
||||
initialVisibility = PsiModifier.PUBLIC;
|
||||
}
|
||||
myVisibilityCombo = createVisibilityCombo(left, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0, 0, GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, new Insets(6,5,0,0), 0, 0),
|
||||
myProject, initialVisibility);
|
||||
myVisibilityCombo = InplaceCombosUtil.createVisibilityCombo(left, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0, 0,
|
||||
GridBagConstraints.NORTHEAST,
|
||||
GridBagConstraints.NONE,
|
||||
new Insets(6, 5, 0, 0), 0, 0),
|
||||
myProject, initialVisibility);
|
||||
myMoveToAnotherClassCb = new JCheckBox("Move to another class");
|
||||
myMoveToAnotherClassCb.setMnemonic('m');
|
||||
myMoveToAnotherClassCb.setFocusable(false);
|
||||
left.add(myMoveToAnotherClassCb, new GridBagConstraints(0, 1, 2, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
|
||||
left.add(myMoveToAnotherClassCb,
|
||||
new GridBagConstraints(0, 1, 2, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0),
|
||||
0, 0));
|
||||
return left;
|
||||
}
|
||||
|
||||
public static JComboBox createVisibilityCombo(final JPanel left,
|
||||
final GridBagConstraints lgc,
|
||||
final Project project,
|
||||
@NotNull final String initialVisibility) {
|
||||
|
||||
final JLabel label = new JLabel("Visibility:");
|
||||
label.setDisplayedMnemonic('V');
|
||||
left.add(label, lgc);
|
||||
final JComboBox visibilityCombo = new JComboBox(new String[]{PsiModifier.PUBLIC, PsiModifier.PACKAGE_LOCAL, PsiModifier.PROTECTED, PsiModifier.PRIVATE});
|
||||
visibilityCombo.setRenderer(new ListCellRendererWrapper<String>(visibilityCombo.getRenderer()) {
|
||||
@Override
|
||||
public void customize(JList list, String value, int index, boolean selected, boolean hasFocus) {
|
||||
if (value == null) return;
|
||||
setText(PsiBundle.visibilityPresentation(value));
|
||||
}
|
||||
});
|
||||
label.setLabelFor(visibilityCombo);
|
||||
visibilityCombo.setSelectedItem(initialVisibility);
|
||||
|
||||
appendActions(visibilityCombo, project);
|
||||
lgc.gridx++;
|
||||
lgc.insets.top = 2;
|
||||
lgc.insets.left = 2;
|
||||
left.add(visibilityCombo, lgc);
|
||||
return visibilityCombo;
|
||||
private String getSelectedVisibility() {
|
||||
return (String)myVisibilityCombo.getSelectedItem();
|
||||
}
|
||||
|
||||
public static void appendActions(final JComboBox comboBox, final Project project) {
|
||||
final boolean toggleStrategy = !UIUtil.isUnderAquaLookAndFeel();
|
||||
final boolean[] moveFocusBack = new boolean[] {true};
|
||||
comboBox.addFocusListener(new FocusAdapter() {
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
if (!moveFocusBack[0]) {
|
||||
moveFocusBack[0] = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (toggleStrategy) {
|
||||
final int size = comboBox.getModel().getSize();
|
||||
int next = comboBox.getSelectedIndex() + 1;
|
||||
if (next < 0 || next >= size) {
|
||||
if (!UISettings.getInstance().CYCLE_SCROLLING) {
|
||||
return;
|
||||
}
|
||||
next = (next + size) % size;
|
||||
}
|
||||
comboBox.setSelectedIndex(next);
|
||||
ToolWindowManager.getInstance(project).activateEditorComponent();
|
||||
}
|
||||
else {
|
||||
JBPopupFactory popupFactory = JBPopupFactory.getInstance();
|
||||
boolean fromTheSameBalloon = popupFactory.getParentBalloonFor(e.getComponent()) == popupFactory.getParentBalloonFor(e.getOppositeComponent());
|
||||
if (!fromTheSameBalloon) {
|
||||
comboBox.showPopup();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
comboBox.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
moveFocusBack[0] = false;
|
||||
}
|
||||
});
|
||||
comboBox.addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
moveFocusBack[0] = true;
|
||||
if (!toggleStrategy && e.getKeyCode() == KeyEvent.VK_ESCAPE && e.getModifiers() == 0) {
|
||||
ToolWindowManager.getInstance(project).activateEditorComponent();
|
||||
}
|
||||
}
|
||||
});
|
||||
comboBox.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
moveFocusBack[0] = true;
|
||||
ToolWindowManager.getInstance(project).activateEditorComponent();
|
||||
}
|
||||
});
|
||||
}
|
||||
private RangeMarker myFieldRangeStart;
|
||||
|
||||
public boolean performInplaceIntroduce() {
|
||||
return startIntroduceTemplate(false, null);
|
||||
}
|
||||
|
||||
private boolean startIntroduceTemplate(final boolean replaceAllOccurrences, @Nullable final PsiType fieldDefaultType) {
|
||||
final Ref<Boolean> result = new Ref<Boolean>();
|
||||
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
|
||||
public void run() {
|
||||
myTypeSelectorManager.setAllOccurences(replaceAllOccurrences);
|
||||
PsiType defaultType = myTypeSelectorManager.getTypeSelector().getSelectedType();
|
||||
if (fieldDefaultType != null) {
|
||||
if (replaceAllOccurrences) {
|
||||
if (ArrayUtil.find(myTypeSelectorManager.getTypesForAll(), fieldDefaultType) != -1) {
|
||||
defaultType = fieldDefaultType;
|
||||
}
|
||||
}
|
||||
else if (ArrayUtil.find(myTypeSelectorManager.getTypesForOne(), fieldDefaultType) != -1) {
|
||||
defaultType = fieldDefaultType;
|
||||
}
|
||||
}
|
||||
final String propName = myLocalVariable != null ? JavaCodeStyleManager
|
||||
.getInstance(myProject).variableNameToPropertyName(myLocalVariable.getName(), VariableKind.LOCAL_VARIABLE) : null;
|
||||
final String[] names =
|
||||
IntroduceConstantDialog.createNameSuggestionGenerator(propName, myExpr, JavaCodeStyleManager.getInstance(myProject))
|
||||
.getSuggestedNameInfo(defaultType).names;
|
||||
final PsiField field = createFieldToStartTemplateOn(names, defaultType);
|
||||
boolean started = false;
|
||||
if (field != null) {
|
||||
myEditor.getCaretModel().moveToOffset(field.getTextOffset());
|
||||
myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
|
||||
final LinkedHashSet<String> nameSuggestions = new LinkedHashSet<String>();
|
||||
nameSuggestions.add(field.getName());
|
||||
nameSuggestions.addAll(Arrays.asList(names));
|
||||
final VariableInplaceRenamer renamer = new FieldInplaceIntroducer(field);
|
||||
started = renamer.performInplaceRename(false, nameSuggestions);
|
||||
}
|
||||
result.set(started);
|
||||
if (!started && field != null) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
field.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}, IntroduceConstantHandler.REFACTORING_NAME, IntroduceConstantHandler.REFACTORING_NAME);
|
||||
return result.get();
|
||||
}
|
||||
|
||||
private PsiField createFieldToStartTemplateOn(final String[] names, final PsiType psiType) {
|
||||
@Override
|
||||
protected PsiVariable createFieldToStartTemplateOn(final String[] names, final PsiType psiType) {
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
|
||||
return ApplicationManager.getApplication().runWriteAction(new Computable<PsiField>() {
|
||||
@Override
|
||||
public PsiField compute() {
|
||||
|
||||
PsiField field = elementFactory.createFieldFromText(
|
||||
psiType.getCanonicalText() + " " + (myConstantName != null ? myConstantName : names[0]) + " = " + myInitializerText + ";",
|
||||
psiType.getCanonicalText() + " " + (getInputName() != null ? getInputName() : names[0]) + " = " + myInitializerText + ";",
|
||||
myParentClass);
|
||||
PsiUtil.setModifierProperty(field, PsiModifier.FINAL, true);
|
||||
PsiUtil.setModifierProperty(field, PsiModifier.STATIC, true);
|
||||
@@ -365,243 +218,137 @@ public class InplaceIntroduceConstantPopup {
|
||||
if (visibility != null) {
|
||||
PsiUtil.setModifierProperty(field, visibility, true);
|
||||
}
|
||||
return BaseExpressionToFieldHandler.ConvertToFieldRunnable
|
||||
field = BaseExpressionToFieldHandler.ConvertToFieldRunnable
|
||||
.appendField(myExpr, BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION, myParentClass, myParentClass,
|
||||
myAnchorElementIfAll, field);
|
||||
myFieldRangeStart = myEditor.getDocument().createRangeMarker(field.getTextRange());
|
||||
return field;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private String getSelectedVisibility() {
|
||||
return (String)myVisibilityCombo.getSelectedItem();
|
||||
@Override
|
||||
protected String[] suggestNames(PsiType defaultType, String propName) {
|
||||
return IntroduceConstantDialog.createNameSuggestionGenerator(propName, myExpr, JavaCodeStyleManager.getInstance(myProject))
|
||||
.getSuggestedNameInfo(defaultType).names;
|
||||
}
|
||||
|
||||
public List<RangeMarker> getOccurrenceMarkers() {
|
||||
if (myOccurrenceMarkers == null) {
|
||||
myOccurrenceMarkers = new ArrayList<RangeMarker>();
|
||||
for (PsiExpression occurrence : myOccurrences) {
|
||||
myOccurrenceMarkers.add(myEditor.getDocument().createRangeMarker(occurrence.getTextRange()));
|
||||
}
|
||||
}
|
||||
return myOccurrenceMarkers;
|
||||
@Override
|
||||
protected boolean isReplaceAllOccurrences() {
|
||||
return myReplaceAllCb.isSelected();
|
||||
}
|
||||
|
||||
private void updateCbDeleteVariable() {
|
||||
if (!myReplaceAllCb.isSelected()) {
|
||||
myCbDeleteVariable.makeUnselectable(false);
|
||||
}
|
||||
else {
|
||||
myCbDeleteVariable.makeSelectable();
|
||||
}
|
||||
@Override
|
||||
protected PsiElement checkLocalScope() {
|
||||
return myParentClass;
|
||||
}
|
||||
|
||||
private class FieldInplaceIntroducer extends AbstractInplaceIntroducer {
|
||||
private RangeMarker myFieldRangeStart;
|
||||
@Override
|
||||
protected void saveSettings(PsiVariable psiVariable) {
|
||||
super.saveSettings(psiVariable);
|
||||
JavaRefactoringSettings.getInstance().INTRODUCE_CONSTANT_VISIBILITY = getSelectedVisibility();
|
||||
}
|
||||
|
||||
|
||||
private SmartTypePointer myDefaultParameterTypePointer;
|
||||
|
||||
private SmartTypePointer myFieldTypePointer;
|
||||
|
||||
public FieldInplaceIntroducer(PsiField field) {
|
||||
super(myProject, new TypeExpression(myProject, myReplaceAllCb.isSelected() ? myTypeSelectorManager.getTypesForAll() : myTypeSelectorManager.getTypesForOne()),
|
||||
myEditor, field, false,
|
||||
myTypeSelectorManager.getTypesForAll().length > 1,
|
||||
myExpr != null && myExpr.isPhysical() ? myEditor.getDocument().createRangeMarker(myExpr.getTextRange()) : null, InplaceIntroduceConstantPopup.this.getOccurrenceMarkers(),
|
||||
IntroduceConstantHandler.REFACTORING_NAME, IntroduceConstantHandler.REFACTORING_NAME);
|
||||
|
||||
myDefaultParameterTypePointer =
|
||||
SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(myTypeSelectorManager.getDefaultType());
|
||||
myFieldRangeStart = myEditor.getDocument().createRangeMarker(field.getTextRange());
|
||||
@Override
|
||||
protected PsiVariable getVariable() {
|
||||
PsiElement element = myParentClass.getContainingFile().findElementAt(myFieldRangeStart.getStartOffset());
|
||||
if (element instanceof PsiWhiteSpace) {
|
||||
element = PsiTreeUtil.skipSiblingsForward(element, PsiWhiteSpace.class);
|
||||
}
|
||||
return PsiTreeUtil.getParentOfType(element, PsiField.class, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isReplaceAllOccurrences() {
|
||||
return myReplaceAllCb.isSelected();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiExpression getExpr() {
|
||||
return myExpr != null && myExpr.isValid() && myExpr.isPhysical() ? myExpr : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiExpression[] getOccurrences() {
|
||||
return myOccurrences;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<RangeMarker> getOccurrenceMarkers() {
|
||||
return InplaceIntroduceConstantPopup.this.getOccurrenceMarkers();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiElement checkLocalScope() {
|
||||
return myParentClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RangeMarker getExprMarker() {
|
||||
return myExprMarker;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveSettings(PsiVariable psiVariable) {
|
||||
TypeSelectorManagerImpl.typeSelected(psiVariable.getType(), myDefaultParameterTypePointer.getType());
|
||||
JavaRefactoringSettings.getInstance().INTRODUCE_CONSTANT_VISIBILITY = getSelectedVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiVariable getVariable() {
|
||||
PsiElement element = myParentClass.getContainingFile().findElementAt(myFieldRangeStart.getStartOffset());
|
||||
if (element instanceof PsiWhiteSpace) {
|
||||
element = PsiTreeUtil.skipSiblingsForward(element, PsiWhiteSpace.class);
|
||||
}
|
||||
return PsiTreeUtil.getParentOfType(element, PsiField.class, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void moveOffsetAfter(boolean success) {
|
||||
if (success) {
|
||||
if (myLocalVariable == null && myExpr == null || myConstantName == null) {
|
||||
super.moveOffsetAfter(false);
|
||||
return;
|
||||
}
|
||||
final BaseExpressionToFieldHandler.Settings settings =
|
||||
new BaseExpressionToFieldHandler.Settings(myConstantName,
|
||||
isReplaceAllOccurrences(), true,
|
||||
true,
|
||||
BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION,
|
||||
getSelectedVisibility(), myLocalVariable,
|
||||
myFieldTypePointer.getType(),
|
||||
isDeleteVariable(),
|
||||
myParentClass, isAnnotateNonNls(), false);
|
||||
final Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
if (myLocalVariable != null) {
|
||||
final LocalToFieldHandler.IntroduceFieldRunnable fieldRunnable =
|
||||
new LocalToFieldHandler.IntroduceFieldRunnable(false, myLocalVariable, myParentClass, settings, true, myOccurrences);
|
||||
fieldRunnable.run();
|
||||
}
|
||||
else {
|
||||
final BaseExpressionToFieldHandler.ConvertToFieldRunnable convertToFieldRunnable =
|
||||
new BaseExpressionToFieldHandler.ConvertToFieldRunnable(myExpr, settings, settings.getForcedType(),
|
||||
myOccurrences, myOccurenceManager,
|
||||
myAnchorElementIfAll, myAnchorElement, myEditor, myParentClass);
|
||||
convertToFieldRunnable.run();
|
||||
}
|
||||
}
|
||||
};
|
||||
ApplicationManager.getApplication().runWriteAction(runnable);
|
||||
}
|
||||
super.moveOffsetAfter(success);
|
||||
if (myLocalVariable != null && myLocalVariable.isValid()) {
|
||||
myEditor.getCaretModel().moveToOffset(myLocalVariable.getTextOffset());
|
||||
myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
|
||||
}
|
||||
if (myMoveToAnotherClassCb.isSelected()) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
MoveMembersImpl.doMove(myProject, new PsiElement[]{myParentClass.findFieldByName(myConstantName, false)}, null, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
super.finish();
|
||||
final PsiField psiField = (PsiField)getVariable();
|
||||
if (psiField == null) {
|
||||
return;
|
||||
}
|
||||
myFieldTypePointer = SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(psiField.getType());
|
||||
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
|
||||
myConstantName = psiField.getName();
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
protected void performPostIntroduceTasks() {
|
||||
if (myMoveToAnotherClassCb.isSelected()) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final PsiFile containingFile = myParentClass.getContainingFile();
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
|
||||
final RangeMarker exprMarker = getExprMarker();
|
||||
if (exprMarker != null) {
|
||||
myExpr = restoreExpression(containingFile, psiField, elementFactory, exprMarker, myExprText);
|
||||
if (myExpr != null && myExpr.isPhysical()) {
|
||||
myExprMarker = myEditor.getDocument().createRangeMarker(myExpr.getTextRange());
|
||||
}
|
||||
}
|
||||
final List<RangeMarker> occurrenceMarkers = getOccurrenceMarkers();
|
||||
for (int i = 0, occurrenceMarkersSize = occurrenceMarkers.size(); i < occurrenceMarkersSize; i++) {
|
||||
RangeMarker marker = occurrenceMarkers.get(i);
|
||||
if (getExprMarker() != null && marker.getStartOffset() == getExprMarker().getStartOffset()) {
|
||||
myOccurrences[i] = myExpr;
|
||||
continue;
|
||||
}
|
||||
final PsiExpression psiExpression =
|
||||
restoreExpression(containingFile, psiField, elementFactory, marker, myLocalVariable != null ? myLocalName : myExprText);
|
||||
if (psiExpression != null) {
|
||||
myOccurrences[i] = psiExpression;
|
||||
}
|
||||
}
|
||||
|
||||
if (myAnchorIdxIfAll != -1 && myOccurrences[myAnchorIdxIfAll] != null) {
|
||||
myAnchorElementIfAll = myOccurrences[myAnchorIdxIfAll].getParent();
|
||||
}
|
||||
|
||||
if (myAnchorIdx != -1 && myOccurrences[myAnchorIdx] != null) {
|
||||
myAnchorElement = myOccurrences[myAnchorIdx].getParent();
|
||||
}
|
||||
myOccurrenceMarkers = null;
|
||||
if (psiField.isValid()) {
|
||||
psiField.delete();
|
||||
}
|
||||
MoveMembersImpl.doMove(myProject, new PsiElement[]{myParentClass.findFieldByName(getInputName(), false)}, null, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent getComponent() {
|
||||
if (!myInitListeners) {
|
||||
myInitListeners = true;
|
||||
final VisibilityListener visibilityListener = new VisibilityListener(myProject, IntroduceConstantHandler.REFACTORING_NAME, myEditor) {
|
||||
@Override
|
||||
protected String getVisibility() {
|
||||
return getSelectedVisibility();
|
||||
}
|
||||
};
|
||||
myVisibilityCombo.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
visibilityListener.stateChanged(null);
|
||||
}
|
||||
});
|
||||
myReplaceAllCb.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
Runnable restartTemplateRunnable = new Runnable() {
|
||||
public void run() {
|
||||
final TemplateState templateState = TemplateManagerImpl.getTemplateState(myEditor);
|
||||
if (templateState != null) {
|
||||
templateState.gotoEnd(true);
|
||||
myTypeSelectorManager = new TypeSelectorManagerImpl(myProject, myDefaultParameterTypePointer.getType(), null, myExpr, myOccurrences);
|
||||
startIntroduceTemplate(isReplaceAllOccurrences(), myFieldTypePointer.getType());
|
||||
}
|
||||
}
|
||||
};
|
||||
CommandProcessor.getInstance().executeCommand(myProject, restartTemplateRunnable, IntroduceConstantHandler.REFACTORING_NAME, IntroduceConstantHandler.REFACTORING_NAME);
|
||||
}
|
||||
});
|
||||
|
||||
myAnnotateNonNls.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
//todo it is unresolved; import here is not a good idea new FinalListener(myProject).perform(myAnnotateNonNls.isSelected(), "@NonNls");
|
||||
}
|
||||
});
|
||||
@Override
|
||||
protected void performIntroduce() {
|
||||
final BaseExpressionToFieldHandler.Settings settings =
|
||||
new BaseExpressionToFieldHandler.Settings(getInputName(),
|
||||
isReplaceAllOccurrences(), true,
|
||||
true,
|
||||
BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION,
|
||||
getSelectedVisibility(), (PsiLocalVariable)myLocalVariable,
|
||||
myTypePointer.getType(),
|
||||
isDeleteVariable(),
|
||||
myParentClass, isAnnotateNonNls(), false);
|
||||
new WriteCommandAction(myProject, getCommandName(), getCommandName()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
if (myLocalVariable != null) {
|
||||
final LocalToFieldHandler.IntroduceFieldRunnable fieldRunnable =
|
||||
new LocalToFieldHandler.IntroduceFieldRunnable(false, (PsiLocalVariable)myLocalVariable, myParentClass, settings, true, myOccurrences);
|
||||
fieldRunnable.run();
|
||||
}
|
||||
else {
|
||||
final BaseExpressionToFieldHandler.ConvertToFieldRunnable convertToFieldRunnable =
|
||||
new BaseExpressionToFieldHandler.ConvertToFieldRunnable(myExpr, settings, settings.getForcedType(),
|
||||
myOccurrences, myOccurenceManager,
|
||||
myAnchorElementIfAll, myAnchorElement, myEditor, myParentClass);
|
||||
convertToFieldRunnable.run();
|
||||
}
|
||||
}
|
||||
return myWholePanel;
|
||||
}.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void restoreAnchors() {
|
||||
if (myAnchorIdxIfAll != -1 && myOccurrences[myAnchorIdxIfAll] != null) {
|
||||
myAnchorElementIfAll = myOccurrences[myAnchorIdxIfAll].getParent();
|
||||
}
|
||||
|
||||
if (myAnchorIdx != -1 && myOccurrences[myAnchorIdx] != null) {
|
||||
myAnchorElement = myOccurrences[myAnchorIdx].getParent();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent getComponent() {
|
||||
final VisibilityListener visibilityListener = new VisibilityListener(myEditor) {
|
||||
@Override
|
||||
protected String getVisibility() {
|
||||
return getSelectedVisibility();
|
||||
}
|
||||
};
|
||||
myVisibilityCombo.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
new WriteCommandAction(myProject, IntroduceConstantHandler.REFACTORING_NAME, IntroduceConstantHandler.REFACTORING_NAME) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
PsiDocumentManager.getInstance(myProject).commitDocument(myEditor.getDocument());
|
||||
visibilityListener.perform(getVariable());
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
});
|
||||
myReplaceAllCb.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
restartTemplate();
|
||||
}
|
||||
});
|
||||
|
||||
myAnnotateNonNls.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
//todo it is unresolved; import here is not a good idea new FinalListener(myProject).perform(myAnnotateNonNls.isSelected(), "@NonNls");
|
||||
}
|
||||
});
|
||||
return myWholePanel;
|
||||
}
|
||||
|
||||
public String getCommandName() {
|
||||
return IntroduceConstantHandler.REFACTORING_NAME;
|
||||
}
|
||||
|
||||
private boolean isAnnotateNonNls() {
|
||||
|
||||
+99
-250
@@ -15,73 +15,52 @@
|
||||
*/
|
||||
package com.intellij.refactoring.introduceField;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.codeInsight.intention.impl.TypeExpression;
|
||||
import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
|
||||
import com.intellij.codeInsight.template.impl.TemplateState;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.SuggestedNameInfo;
|
||||
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.refactoring.JavaRefactoringSettings;
|
||||
import com.intellij.refactoring.introduceParameter.AbstractInplaceIntroducer;
|
||||
import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer;
|
||||
import com.intellij.refactoring.introduceParameter.AbstractJavaInplaceIntroducer;
|
||||
import com.intellij.refactoring.introduceParameter.VisibilityListener;
|
||||
import com.intellij.refactoring.introduceVariable.FinalListener;
|
||||
import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
|
||||
import com.intellij.refactoring.util.occurences.OccurenceManager;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
* Date: 3/15/11
|
||||
*/
|
||||
public class InplaceIntroduceFieldPopup {
|
||||
public class InplaceIntroduceFieldPopup extends AbstractJavaInplaceIntroducer {
|
||||
|
||||
private PsiLocalVariable myLocalVariable;
|
||||
private PsiClass myParentClass;
|
||||
private boolean myStatic;
|
||||
private PsiExpression[] myOccurrences;
|
||||
private PsiExpression myInitializerExpression;
|
||||
private final Editor myEditor;
|
||||
private Project myProject;
|
||||
|
||||
private TypeSelectorManagerImpl myTypeSelectorManager;
|
||||
private final PsiElement myAnchorElement;
|
||||
private PsiElement myAnchorElement;
|
||||
private int myAnchorIdx = -1;
|
||||
private final PsiElement myAnchorElementIfAll;
|
||||
private PsiElement myAnchorElementIfAll;
|
||||
private int myAnchorIdxIfAll = -1;
|
||||
private final OccurenceManager myOccurenceManager;
|
||||
private List<RangeMarker> myOccurrenceMarkers;
|
||||
|
||||
private final IntroduceFieldCentralPanel myIntroduceFieldPanel;
|
||||
|
||||
private JPanel myWholePanel;
|
||||
private String myExprText;
|
||||
private String myLocalName;
|
||||
private RangeMarker myExprMarker;
|
||||
private String myFieldName;
|
||||
|
||||
private boolean myInitListeners = false;
|
||||
static BaseExpressionToFieldHandler.InitializationPlace ourLastInitializerPlace;
|
||||
|
||||
public InplaceIntroduceFieldPopup(PsiLocalVariable localVariable,
|
||||
@@ -94,16 +73,13 @@ public class InplaceIntroduceFieldPopup {
|
||||
final boolean allowInitInMethod,
|
||||
boolean allowInitInMethodIfAll, final PsiElement anchorElement,
|
||||
final PsiElement anchorElementIfAll,
|
||||
final OccurenceManager occurenceManager) {
|
||||
final OccurenceManager occurenceManager, Project project) {
|
||||
super(project, editor, initializerExpression, localVariable, occurrences, typeSelectorManager.getDefaultType(), typeSelectorManager,
|
||||
IntroduceFieldHandler.REFACTORING_NAME);
|
||||
myLocalVariable = localVariable;
|
||||
myParentClass = parentClass;
|
||||
myStatic = aStatic;
|
||||
myOccurrences = occurrences;
|
||||
myInitializerExpression = initializerExpression;
|
||||
myExprText = myInitializerExpression != null ? myInitializerExpression.getText() : null;
|
||||
myLocalName = localVariable != null ? localVariable.getName() : null;
|
||||
myExprMarker = myInitializerExpression != null && myInitializerExpression.isPhysical() ? editor.getDocument().createRangeMarker(myInitializerExpression.getTextRange()) : null;
|
||||
myTypeSelectorManager = typeSelectorManager;
|
||||
myAnchorElement = anchorElement;
|
||||
myAnchorElementIfAll = anchorElementIfAll;
|
||||
for (int i = 0, occurrencesLength = occurrences.length; i < occurrencesLength; i++) {
|
||||
@@ -117,7 +93,7 @@ public class InplaceIntroduceFieldPopup {
|
||||
}
|
||||
}
|
||||
myOccurenceManager = occurenceManager;
|
||||
myProject = myLocalVariable != null ? myLocalVariable.getProject() : myInitializerExpression.getProject();
|
||||
myProject = myLocalVariable != null ? myLocalVariable.getProject() : initializerExpression.getProject();
|
||||
myEditor = editor;
|
||||
|
||||
myIntroduceFieldPanel =
|
||||
@@ -141,85 +117,31 @@ public class InplaceIntroduceFieldPopup {
|
||||
|
||||
}
|
||||
|
||||
public List<RangeMarker> getOccurrenceMarkers() {
|
||||
if (myOccurrenceMarkers == null) {
|
||||
myOccurrenceMarkers = new ArrayList<RangeMarker>();
|
||||
for (PsiExpression occurrence : myOccurrences) {
|
||||
myOccurrenceMarkers.add(myEditor.getDocument().createRangeMarker(occurrence.getTextRange()));
|
||||
}
|
||||
}
|
||||
return myOccurrenceMarkers;
|
||||
}
|
||||
|
||||
public boolean startTemplate() {
|
||||
return startTemplate(false, null);
|
||||
}
|
||||
|
||||
public boolean startTemplate(final boolean replaceAllOccurrences, @Nullable final PsiType fieldDefaultType) {
|
||||
final Ref<Boolean> result = new Ref<Boolean>();
|
||||
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
|
||||
public void run() {
|
||||
myTypeSelectorManager.setAllOccurences(replaceAllOccurrences);
|
||||
|
||||
PsiType defaultType = myTypeSelectorManager.getTypeSelector().getSelectedType();
|
||||
if (fieldDefaultType != null) {
|
||||
if (replaceAllOccurrences) {
|
||||
if (ArrayUtil.find(myTypeSelectorManager.getTypesForAll(), fieldDefaultType) != -1) {
|
||||
defaultType = fieldDefaultType;
|
||||
}
|
||||
}
|
||||
else if (ArrayUtil.find(myTypeSelectorManager.getTypesForOne(), fieldDefaultType) != -1) {
|
||||
defaultType = fieldDefaultType;
|
||||
}
|
||||
}
|
||||
|
||||
final SuggestedNameInfo suggestedNameInfo =
|
||||
IntroduceFieldDialog.createGenerator(myStatic, myLocalVariable, myInitializerExpression, myLocalVariable != null)
|
||||
.getSuggestedNameInfo(defaultType);
|
||||
|
||||
boolean started = false;
|
||||
final PsiField field = createFieldToStartTemplateOn(suggestedNameInfo.names, defaultType);
|
||||
if (field != null) {
|
||||
myEditor.getCaretModel().moveToOffset(field.getTextOffset());
|
||||
myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
|
||||
final LinkedHashSet<String> nameSuggestions = new LinkedHashSet<String>();
|
||||
nameSuggestions.add(field.getName());
|
||||
nameSuggestions.addAll(Arrays.asList(suggestedNameInfo.names));
|
||||
final VariableInplaceRenamer renamer = new FieldInplaceIntroducer(field);
|
||||
started = renamer.performInplaceRename(false, nameSuggestions);
|
||||
}
|
||||
result.set(started);
|
||||
if (!started && field != null) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
field.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}, IntroduceFieldHandler.REFACTORING_NAME, IntroduceFieldHandler.REFACTORING_NAME);
|
||||
return result.get();
|
||||
}
|
||||
|
||||
private PsiField createFieldToStartTemplateOn(final String[] names,
|
||||
protected PsiField createFieldToStartTemplateOn(final String[] names,
|
||||
final PsiType defaultType) {
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
|
||||
return ApplicationManager.getApplication().runWriteAction(new Computable<PsiField>() {
|
||||
@Override
|
||||
public PsiField compute() {
|
||||
PsiField field = elementFactory.createField(myFieldName != null ? myFieldName : names[0], defaultType);
|
||||
PsiField field = elementFactory.createField(getInputName() != null ? getInputName() : names[0], defaultType);
|
||||
field = (PsiField)myParentClass.add(field);
|
||||
PsiUtil.setModifierProperty(field, PsiModifier.FINAL, myIntroduceFieldPanel.isDeclareFinal());
|
||||
final String visibility = myIntroduceFieldPanel.getFieldVisibility();
|
||||
if (visibility != null) {
|
||||
PsiUtil.setModifierProperty(field, visibility, true);
|
||||
}
|
||||
myFieldRangeStart = myEditor.getDocument().createRangeMarker(field.getTextRange());
|
||||
return field;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] suggestNames(PsiType defaultType, String propName) {
|
||||
return IntroduceFieldDialog.createGenerator(myStatic, myLocalVariable, myExpr, myLocalVariable != null)
|
||||
.getSuggestedNameInfo(defaultType).names;
|
||||
}
|
||||
|
||||
public void setReplaceAllOccurrences(boolean replaceAllOccurrences) {
|
||||
myIntroduceFieldPanel.setReplaceAllOccurrences(replaceAllOccurrences);
|
||||
}
|
||||
@@ -240,54 +162,17 @@ public class InplaceIntroduceFieldPopup {
|
||||
ourLastInitializerPlace = place;
|
||||
}
|
||||
|
||||
class FieldInplaceIntroducer extends AbstractInplaceIntroducer {
|
||||
|
||||
private RangeMarker myFieldRangeStart;
|
||||
|
||||
|
||||
private SmartTypePointer myDefaultParameterTypePointer;
|
||||
|
||||
private SmartTypePointer myFieldTypePointer;
|
||||
|
||||
public FieldInplaceIntroducer(PsiVariable psiVariable) {
|
||||
super(myProject, new TypeExpression(myProject, myIntroduceFieldPanel.isReplaceAllOccurrences() ? myTypeSelectorManager.getTypesForAll() : myTypeSelectorManager.getTypesForOne()),
|
||||
myEditor, psiVariable, false,
|
||||
myTypeSelectorManager.getTypesForAll().length > 1,
|
||||
myInitializerExpression != null && myInitializerExpression.isPhysical() ? myEditor.getDocument().createRangeMarker(myInitializerExpression.getTextRange()) : null, InplaceIntroduceFieldPopup.this.getOccurrenceMarkers(),
|
||||
IntroduceFieldHandler.REFACTORING_NAME, IntroduceFieldHandler.REFACTORING_NAME);
|
||||
myDefaultParameterTypePointer =
|
||||
SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(myTypeSelectorManager.getDefaultType());
|
||||
myFieldRangeStart = myEditor.getDocument().createRangeMarker(psiVariable.getTextRange());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isReplaceAllOccurrences() {
|
||||
return myIntroduceFieldPanel.isReplaceAllOccurrences();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiExpression getExpr() {
|
||||
return myInitializerExpression != null && myInitializerExpression.isValid() && myInitializerExpression.isPhysical() ? myInitializerExpression : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiExpression[] getOccurrences() {
|
||||
return myOccurrences;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<RangeMarker> getOccurrenceMarkers() {
|
||||
return InplaceIntroduceFieldPopup.this.getOccurrenceMarkers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RangeMarker getExprMarker() {
|
||||
return myExprMarker;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveSettings(PsiVariable psiVariable) {
|
||||
TypeSelectorManagerImpl.typeSelected(psiVariable.getType(), myDefaultParameterTypePointer.getType());
|
||||
super.saveSettings(psiVariable);
|
||||
JavaRefactoringSettings.getInstance().INTRODUCE_FIELD_VISIBILITY = myIntroduceFieldPanel.getFieldVisibility();
|
||||
}
|
||||
|
||||
@@ -298,46 +183,52 @@ public class InplaceIntroduceFieldPopup {
|
||||
|
||||
@Override
|
||||
protected JComponent getComponent() {
|
||||
if (!myInitListeners) {
|
||||
myInitListeners = true;
|
||||
myIntroduceFieldPanel.addVisibilityListener(new VisibilityListener(myProject, IntroduceFieldHandler.REFACTORING_NAME, myEditor){
|
||||
@Override
|
||||
protected String getVisibility() {
|
||||
return myIntroduceFieldPanel.getFieldVisibility();
|
||||
}
|
||||
});
|
||||
final FinalListener finalListener = new FinalListener(myProject, IntroduceFieldHandler.REFACTORING_NAME);
|
||||
myIntroduceFieldPanel.addFinalListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
finalListener.perform(myIntroduceFieldPanel.isDeclareFinal());
|
||||
}
|
||||
});
|
||||
myIntroduceFieldPanel.addOccurrenceListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
final Runnable restartTemplate = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final TemplateState templateState =
|
||||
TemplateManagerImpl.getTemplateState(myEditor);
|
||||
if (templateState != null) {
|
||||
templateState.gotoEnd(true);
|
||||
myTypeSelectorManager = new TypeSelectorManagerImpl(myProject, myDefaultParameterTypePointer.getType(), null, myInitializerExpression, myOccurrences);
|
||||
startTemplate(myIntroduceFieldPanel.isReplaceAllOccurrences(), myFieldTypePointer.getType());
|
||||
}
|
||||
}
|
||||
};
|
||||
CommandProcessor.getInstance().executeCommand(myProject, restartTemplate,
|
||||
IntroduceFieldHandler.REFACTORING_NAME,
|
||||
IntroduceFieldHandler.REFACTORING_NAME);
|
||||
}
|
||||
});
|
||||
}
|
||||
final VisibilityListener visibilityListener = new VisibilityListener(myEditor) {
|
||||
@Override
|
||||
protected String getVisibility() {
|
||||
return myIntroduceFieldPanel.getFieldVisibility();
|
||||
}
|
||||
};
|
||||
myIntroduceFieldPanel.addVisibilityListener(new ChangeListener() {
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
new WriteCommandAction(myProject, getCommandName(), getCommandName()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
PsiDocumentManager.getInstance(myProject).commitDocument(myEditor.getDocument());
|
||||
visibilityListener.perform(getVariable());
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
});
|
||||
final FinalListener finalListener = new FinalListener(myEditor);
|
||||
myIntroduceFieldPanel.addFinalListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
new WriteCommandAction(myProject, getCommandName(), getCommandName()){
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
PsiDocumentManager.getInstance(myProject).commitDocument(myEditor.getDocument());
|
||||
finalListener.perform(myIntroduceFieldPanel.isDeclareFinal(), getVariable());
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
});
|
||||
myIntroduceFieldPanel.addOccurrenceListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
restartTemplate();
|
||||
}
|
||||
});
|
||||
|
||||
return myWholePanel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCommandName() {
|
||||
return IntroduceFieldHandler.REFACTORING_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiVariable getVariable() {
|
||||
PsiElement element = myParentClass.getContainingFile().findElementAt(myFieldRangeStart.getStartOffset());
|
||||
@@ -352,89 +243,47 @@ public class InplaceIntroduceFieldPopup {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void moveOffsetAfter(boolean success) {
|
||||
if (success) {
|
||||
if (myLocalVariable == null && myInitializerExpression == null || myFieldName == null) {
|
||||
super.moveOffsetAfter(false);
|
||||
return;
|
||||
}
|
||||
ourLastInitializerPlace = myIntroduceFieldPanel.getInitializerPlace();
|
||||
myIntroduceFieldPanel.saveFinalState();
|
||||
final BaseExpressionToFieldHandler.Settings settings =
|
||||
new BaseExpressionToFieldHandler.Settings(myFieldName, myIntroduceFieldPanel.isReplaceAllOccurrences(), myStatic,
|
||||
myIntroduceFieldPanel.isDeclareFinal(),
|
||||
myIntroduceFieldPanel.getInitializerPlace(),
|
||||
myIntroduceFieldPanel.getFieldVisibility(), myLocalVariable,
|
||||
myFieldTypePointer.getType(),
|
||||
myIntroduceFieldPanel.isDeleteVariable(),
|
||||
myParentClass, false, false);
|
||||
final Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
if (myLocalVariable != null) {
|
||||
final LocalToFieldHandler.IntroduceFieldRunnable fieldRunnable =
|
||||
new LocalToFieldHandler.IntroduceFieldRunnable(false, myLocalVariable, myParentClass, settings, myStatic, myOccurrences);
|
||||
fieldRunnable.run();
|
||||
}
|
||||
else {
|
||||
final BaseExpressionToFieldHandler.ConvertToFieldRunnable convertToFieldRunnable =
|
||||
new BaseExpressionToFieldHandler.ConvertToFieldRunnable(myInitializerExpression, settings, settings.getForcedType(),
|
||||
myOccurrences, myOccurenceManager,
|
||||
myAnchorIdxIfAll != -1 && myOccurrences[myAnchorIdxIfAll] != null ? myOccurrences[myAnchorIdxIfAll].getParent() : myAnchorElementIfAll,
|
||||
myAnchorIdx != -1 && myOccurrences[myAnchorIdx] != null ? myOccurrences[myAnchorIdx].getParent() : myAnchorElement, myEditor,
|
||||
myParentClass);
|
||||
convertToFieldRunnable.run();
|
||||
}
|
||||
}
|
||||
};
|
||||
ApplicationManager.getApplication().runWriteAction(runnable);
|
||||
protected void restoreAnchors() {
|
||||
if (myAnchorIdxIfAll != -1 && myOccurrences[myAnchorIdxIfAll] != null) {
|
||||
myAnchorElementIfAll = myOccurrences[myAnchorIdxIfAll].getParent();
|
||||
}
|
||||
super.moveOffsetAfter(success);
|
||||
if (myLocalVariable != null && myLocalVariable.isValid()) {
|
||||
myEditor.getCaretModel().moveToOffset(myLocalVariable.getTextOffset());
|
||||
myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
|
||||
|
||||
if (myAnchorIdx != -1 && myOccurrences[myAnchorIdx] != null) {
|
||||
myAnchorElement = myOccurrences[myAnchorIdx].getParent();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
super.finish();
|
||||
final PsiField psiField = (PsiField)getVariable();
|
||||
if (psiField == null) {
|
||||
return;
|
||||
}
|
||||
myFieldTypePointer = SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(psiField.getType());
|
||||
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
|
||||
myFieldName = psiField.getName();
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
final PsiFile containingFile = myParentClass.getContainingFile();
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
|
||||
if (getExprMarker() != null) {
|
||||
myInitializerExpression = restoreExpression(containingFile, psiField, elementFactory, getExprMarker(), myExprText);
|
||||
if (myInitializerExpression != null) {
|
||||
myExprMarker = myEditor.getDocument().createRangeMarker(myInitializerExpression.getTextRange());
|
||||
}
|
||||
protected void performIntroduce() {
|
||||
ourLastInitializerPlace = myIntroduceFieldPanel.getInitializerPlace();
|
||||
myIntroduceFieldPanel.saveFinalState();
|
||||
final BaseExpressionToFieldHandler.Settings settings =
|
||||
new BaseExpressionToFieldHandler.Settings(getInputName(), myIntroduceFieldPanel.isReplaceAllOccurrences(), myStatic,
|
||||
myIntroduceFieldPanel.isDeclareFinal(),
|
||||
myIntroduceFieldPanel.getInitializerPlace(),
|
||||
myIntroduceFieldPanel.getFieldVisibility(), myLocalVariable,
|
||||
myTypePointer.getType(),
|
||||
myIntroduceFieldPanel.isDeleteVariable(),
|
||||
myParentClass, false, false);
|
||||
new WriteCommandAction(myProject, getCommandName(), getCommandName()){
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
if (myLocalVariable != null) {
|
||||
final LocalToFieldHandler.IntroduceFieldRunnable fieldRunnable =
|
||||
new LocalToFieldHandler.IntroduceFieldRunnable(false, myLocalVariable, myParentClass, settings, myStatic, myOccurrences);
|
||||
fieldRunnable.run();
|
||||
}
|
||||
final List<RangeMarker> occurrenceMarkers = getOccurrenceMarkers();
|
||||
for (int i = 0, occurrenceMarkersSize = occurrenceMarkers.size(); i < occurrenceMarkersSize; i++) {
|
||||
RangeMarker marker = occurrenceMarkers.get(i);
|
||||
if (getExprMarker() != null && marker.getStartOffset() == getExprMarker().getStartOffset()) {
|
||||
myOccurrences[i] = myInitializerExpression;
|
||||
continue;
|
||||
}
|
||||
final PsiExpression psiExpression =
|
||||
restoreExpression(containingFile, psiField, elementFactory, marker, myLocalVariable != null ? myLocalName : myExprText);
|
||||
if (psiExpression != null) {
|
||||
myOccurrences[i] = psiExpression;
|
||||
}
|
||||
}
|
||||
myOccurrenceMarkers = null;
|
||||
if (psiField.isValid()) {
|
||||
psiField.delete();
|
||||
else {
|
||||
final BaseExpressionToFieldHandler.ConvertToFieldRunnable convertToFieldRunnable =
|
||||
new BaseExpressionToFieldHandler.ConvertToFieldRunnable(myExpr, settings, settings.getForcedType(),
|
||||
myOccurrences, myOccurenceManager,
|
||||
myAnchorIdxIfAll != -1 && myOccurrences[myAnchorIdxIfAll] != null ? myOccurrences[myAnchorIdxIfAll].getParent() : myAnchorElementIfAll,
|
||||
myAnchorIdx != -1 && myOccurrences[myAnchorIdx] != null ? myOccurrences[myAnchorIdx].getParent() : myAnchorElement, myEditor,
|
||||
myParentClass);
|
||||
convertToFieldRunnable.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
}.execute();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+1
-2
@@ -17,7 +17,6 @@ package com.intellij.refactoring.introduceField;
|
||||
|
||||
import com.intellij.codeInsight.highlighting.HighlightManager;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.application.ex.ApplicationManagerEx;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.colors.EditorColors;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
@@ -149,7 +148,7 @@ public class IntroduceConstantHandler extends BaseExpressionToFieldHandler {
|
||||
if (editor != null && editor.getSettings().isVariableInplaceRenameEnabled()) {
|
||||
if (new InplaceIntroduceConstantPopup(project, editor, parentClass, expr, localVariable, occurences, typeSelectorManager,
|
||||
anchorElement, anchorElementIfAll,
|
||||
expr != null ? createOccurenceManager(expr, parentClass) : null).performInplaceIntroduce() ){
|
||||
expr != null ? createOccurenceManager(expr, parentClass) : null).startInplaceIntroduceTemplate() ){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-4
@@ -16,8 +16,6 @@
|
||||
package com.intellij.refactoring.introduceField;
|
||||
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ex.ApplicationManagerEx;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.wm.WindowManager;
|
||||
@@ -108,8 +106,9 @@ public class IntroduceFieldHandler extends BaseExpressionToFieldHandler {
|
||||
if (editor != null && editor.getSettings().isVariableInplaceRenameEnabled()) {
|
||||
myInplaceIntroduceFieldPopup =
|
||||
new InplaceIntroduceFieldPopup(localVariable, parentClass, declareStatic, currentMethodConstructor, occurences, expr, typeSelectorManager, editor,
|
||||
allowInitInMethod, allowInitInMethodIfAll, anchorElement, anchorElementIfAll, expr != null ? createOccurenceManager(expr, parentClass) : null);
|
||||
if (myInplaceIntroduceFieldPopup.startTemplate()) {
|
||||
allowInitInMethod, allowInitInMethodIfAll, anchorElement, anchorElementIfAll, expr != null ? createOccurenceManager(expr, parentClass) : null,
|
||||
project);
|
||||
if (myInplaceIntroduceFieldPopup.startInplaceIntroduceTemplate()) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -134,7 +134,7 @@ public class IntroduceFieldPopupPanel extends IntroduceFieldCentralPanel {
|
||||
initLabel.setDisplayedMnemonic('i');
|
||||
groupPanel.add(initLabel, gridBagConstraints);
|
||||
JComboBox initializersCombo = new JComboBox(myInitialisersPlaceModel);
|
||||
InplaceIntroduceConstantPopup.appendActions(initializersCombo, myParentClass.getProject());
|
||||
InplaceCombosUtil.appendActions(initializersCombo, myParentClass.getProject());
|
||||
initLabel.setLabelFor(initializersCombo);
|
||||
initializersCombo.setRenderer(new ListCellRendererWrapper<BaseExpressionToFieldHandler.InitializationPlace>(initializersCombo) {
|
||||
@Override
|
||||
@@ -176,8 +176,8 @@ public class IntroduceFieldPopupPanel extends IntroduceFieldCentralPanel {
|
||||
if (visibility == null) {
|
||||
visibility = PsiModifier.PRIVATE;
|
||||
}
|
||||
myVisibilityCombo = InplaceIntroduceConstantPopup.createVisibilityCombo(groupPanel, gridBagConstraints, myParentClass.getProject(),
|
||||
visibility);
|
||||
myVisibilityCombo = InplaceCombosUtil.createVisibilityCombo(groupPanel, gridBagConstraints, myParentClass.getProject(),
|
||||
visibility);
|
||||
|
||||
mainPanel.add(groupPanel, BorderLayout.CENTER);
|
||||
|
||||
|
||||
+169
-100
@@ -16,64 +16,129 @@
|
||||
package com.intellij.refactoring.introduceParameter;
|
||||
|
||||
import com.intellij.codeInsight.highlighting.HighlightManager;
|
||||
import com.intellij.codeInsight.intention.impl.TypeExpression;
|
||||
import com.intellij.codeInsight.lookup.LookupManager;
|
||||
import com.intellij.codeInsight.lookup.impl.LookupImpl;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
|
||||
import com.intellij.codeInsight.template.impl.TemplateState;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.editor.colors.EditorColors;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.markup.RangeHighlighter;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.introduceVariable.VariableInplaceIntroducer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.swing.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
* Date: 3/15/11
|
||||
*/
|
||||
public abstract class AbstractInplaceIntroducer extends VariableInplaceIntroducer {
|
||||
public abstract class AbstractInplaceIntroducer<V extends PsiNamedElement, E extends PsiElement> extends AbstractInplaceVariableIntroducer<E> {
|
||||
protected final V myLocalVariable;
|
||||
|
||||
private final String myExprText;
|
||||
private final String myLocalName;
|
||||
|
||||
protected String myConstantName;
|
||||
|
||||
public AbstractInplaceIntroducer(Project project,
|
||||
TypeExpression expression,
|
||||
Editor editor,
|
||||
PsiVariable elementToRename,
|
||||
boolean cantChangeFinalModifier,
|
||||
boolean hasTypeSuggestion,
|
||||
RangeMarker exprMarker,
|
||||
List<RangeMarker> occurrenceMarkers, String commandName, String title) {
|
||||
super(project, expression, editor, elementToRename, cantChangeFinalModifier, hasTypeSuggestion, exprMarker, occurrenceMarkers, commandName, title);
|
||||
E expr,
|
||||
V localVariable,
|
||||
E[] occurrences,
|
||||
String title) {
|
||||
super(null, editor, project, title, occurrences, expr);
|
||||
myLocalVariable = localVariable;
|
||||
myExprText = expr != null ? expr.getText() : null;
|
||||
myLocalName = localVariable != null ? localVariable.getName() : null;
|
||||
}
|
||||
|
||||
protected abstract String getCommandName();
|
||||
|
||||
protected abstract V createFieldToStartTemplateOn(boolean replaceAll, String[] names);
|
||||
protected abstract String[] suggestNames(boolean replaceAll, V variable);
|
||||
|
||||
protected abstract void performIntroduce();
|
||||
protected void performPostIntroduceTasks() {}
|
||||
|
||||
public abstract E restoreExpression(PsiFile containingFile, V variable, RangeMarker marker, String exprText);
|
||||
|
||||
protected abstract boolean isReplaceAllOccurrences();
|
||||
|
||||
protected abstract PsiExpression getExpr();
|
||||
|
||||
protected abstract PsiExpression[] getOccurrences();
|
||||
protected abstract JComponent getComponent();
|
||||
|
||||
|
||||
protected void restoreAnchors() {}
|
||||
|
||||
protected abstract List<RangeMarker> getOccurrenceMarkers();
|
||||
protected abstract void saveSettings(V variable);
|
||||
protected abstract V getVariable();
|
||||
|
||||
public boolean startInplaceIntroduceTemplate() {
|
||||
final boolean replaceAllOccurrences = isReplaceAllOccurrences();
|
||||
final Ref<Boolean> result = new Ref<Boolean>();
|
||||
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
|
||||
public void run() {
|
||||
final String[] names = suggestNames(replaceAllOccurrences, myLocalVariable);
|
||||
final V variable = createFieldToStartTemplateOn(replaceAllOccurrences, names);
|
||||
boolean started = false;
|
||||
if (variable != null) {
|
||||
myEditor.getCaretModel().moveToOffset(variable.getTextOffset());
|
||||
myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
|
||||
|
||||
final LinkedHashSet<String> nameSuggestions = new LinkedHashSet<String>();
|
||||
nameSuggestions.add(variable.getName());
|
||||
nameSuggestions.addAll(Arrays.asList(names));
|
||||
initOccurrencesMarkers();
|
||||
setElementToRename(variable);
|
||||
started = AbstractInplaceIntroducer.super.performInplaceRename(false, nameSuggestions);
|
||||
}
|
||||
result.set(started);
|
||||
if (!started && variable != null) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
variable.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}, getCommandName(), getCommandName());
|
||||
return result.get();
|
||||
}
|
||||
|
||||
protected String getInputName() {
|
||||
return myConstantName;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean performAutomaticRename() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
super.finish();
|
||||
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
|
||||
final V variable = getVariable();
|
||||
if (variable == null) {
|
||||
return;
|
||||
}
|
||||
restoreState(variable);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addReferenceAtCaret(Collection<PsiReference> refs) {
|
||||
final PsiVariable variable = getVariable();
|
||||
final V variable = getVariable();
|
||||
if (variable != null) {
|
||||
for (PsiReference reference : ReferencesSearch.search(variable)) {
|
||||
refs.remove(reference);
|
||||
@@ -89,7 +154,7 @@ public abstract class AbstractInplaceIntroducer extends VariableInplaceIntroduce
|
||||
@Override
|
||||
protected void collectAdditionalElementsToRename(boolean processTextOccurrences, List<Pair<PsiElement, TextRange>> stringUsages) {
|
||||
if (isReplaceAllOccurrences()) {
|
||||
for (PsiExpression expression : getOccurrences()) {
|
||||
for (E expression : getOccurrences()) {
|
||||
stringUsages.add(Pair.<PsiElement, TextRange>create(expression, new TextRange(0, expression.getTextLength())));
|
||||
}
|
||||
}
|
||||
@@ -125,80 +190,84 @@ public abstract class AbstractInplaceIntroducer extends VariableInplaceIntroduce
|
||||
super.addHighlights(ranges, editor, highlighters, highlightManager);
|
||||
}
|
||||
|
||||
protected abstract class VisibilityListener implements ChangeListener {
|
||||
private Project myProject;
|
||||
private final String myCommandName;
|
||||
private Editor myEditor;
|
||||
|
||||
protected VisibilityListener(Project project, String commandName, Editor editor) {
|
||||
myProject = project;
|
||||
myCommandName = commandName;
|
||||
myEditor = editor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
new WriteCommandAction(myProject, myCommandName, myCommandName) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
final Document document = myEditor.getDocument();
|
||||
PsiDocumentManager.getInstance(getProject()).commitDocument(document);
|
||||
final PsiVariable variable = getVariable();
|
||||
LOG.assertTrue(variable != null);
|
||||
final PsiModifierList modifierList = variable.getModifierList();
|
||||
LOG.assertTrue(modifierList != null);
|
||||
int textOffset = modifierList.getTextOffset();
|
||||
final String modifierListText = modifierList.getText();
|
||||
|
||||
int length = PsiModifier.PUBLIC.length();
|
||||
int idx = modifierListText.indexOf(PsiModifier.PUBLIC);
|
||||
|
||||
if (idx == -1) {
|
||||
idx = modifierListText.indexOf(PsiModifier.PROTECTED);
|
||||
length = PsiModifier.PROTECTED.length();
|
||||
protected void restoreState(final V psiField) {
|
||||
myConstantName = psiField.getName();
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
final PsiFile containingFile = psiField.getContainingFile();
|
||||
final RangeMarker exprMarker = getExprMarker();
|
||||
if (exprMarker != null) {
|
||||
myExpr = restoreExpression(containingFile, psiField, exprMarker, myExprText);
|
||||
if (myExpr != null && myExpr.isPhysical()) {
|
||||
myExprMarker = myEditor.getDocument().createRangeMarker(myExpr.getTextRange());
|
||||
}
|
||||
|
||||
if (idx == -1) {
|
||||
idx = modifierListText.indexOf(PsiModifier.PRIVATE);
|
||||
length = PsiModifier.PRIVATE.length();
|
||||
}
|
||||
final List<RangeMarker> occurrenceMarkers = getOccurrenceMarkers();
|
||||
for (int i = 0, occurrenceMarkersSize = occurrenceMarkers.size(); i < occurrenceMarkersSize; i++) {
|
||||
RangeMarker marker = occurrenceMarkers.get(i);
|
||||
if (getExprMarker() != null && marker.getStartOffset() == getExprMarker().getStartOffset()) {
|
||||
myOccurrences[i] = myExpr;
|
||||
continue;
|
||||
}
|
||||
|
||||
String visibility = getVisibility();
|
||||
if (visibility == PsiModifier.PACKAGE_LOCAL) {
|
||||
visibility = "";
|
||||
}
|
||||
|
||||
final boolean wasPackageLocal = idx == -1;
|
||||
final boolean isPackageLocal = visibility.isEmpty();
|
||||
|
||||
final int startOffset = textOffset + (wasPackageLocal ? 0 : idx);
|
||||
final int endOffset;
|
||||
if (wasPackageLocal) {
|
||||
endOffset = startOffset;
|
||||
}
|
||||
else {
|
||||
endOffset = textOffset + length + (isPackageLocal ? 1 : 0);
|
||||
}
|
||||
|
||||
final String finalVisibility = visibility + (wasPackageLocal ? " " : "");
|
||||
|
||||
Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
document.replaceString(startOffset, endOffset, finalVisibility);
|
||||
}
|
||||
};
|
||||
|
||||
final LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(myEditor);
|
||||
if (lookup != null) {
|
||||
lookup.performGuardedChange(runnable);
|
||||
} else {
|
||||
runnable.run();
|
||||
final E psiExpression =
|
||||
restoreExpression(containingFile, psiField, marker, myLocalVariable != null ? myLocalName : myExprText);
|
||||
if (psiExpression != null) {
|
||||
myOccurrences[i] = psiExpression;
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
protected abstract String getVisibility();
|
||||
restoreAnchors();
|
||||
myOccurrenceMarkers = null;
|
||||
if (psiField.isValid()) {
|
||||
psiField.delete();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void moveOffsetAfter(boolean success) {
|
||||
if (success) {
|
||||
if (myLocalVariable == null && myExpr == null ||
|
||||
getInputName() == null ||
|
||||
myLocalVariable != null && !myLocalVariable.isValid() ||
|
||||
myExpr != null && !myExpr.isValid()) {
|
||||
super.moveOffsetAfter(false);
|
||||
return;
|
||||
}
|
||||
performIntroduce();
|
||||
saveSettings(getVariable());
|
||||
}
|
||||
if (myLocalVariable != null && myLocalVariable.isValid()) {
|
||||
myEditor.getCaretModel().moveToOffset(myLocalVariable.getTextOffset());
|
||||
myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
|
||||
}
|
||||
else if (getExprMarker() != null) {
|
||||
myEditor.getCaretModel().moveToOffset(getExprMarker().getStartOffset());
|
||||
myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
|
||||
}
|
||||
super.moveOffsetAfter(success);
|
||||
if (success) {
|
||||
performPostIntroduceTasks();
|
||||
}
|
||||
}
|
||||
|
||||
protected void restartTemplate() {
|
||||
Runnable restartTemplateRunnable = new Runnable() {
|
||||
public void run() {
|
||||
final TemplateState templateState = TemplateManagerImpl.getTemplateState(myEditor);
|
||||
if (templateState != null) {
|
||||
myEditor.putUserData(INTRODUCE_RESTART, true);
|
||||
try {
|
||||
templateState.gotoEnd(true);
|
||||
startInplaceIntroduceTemplate();
|
||||
}
|
||||
finally {
|
||||
myEditor.putUserData(INTRODUCE_RESTART, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
CommandProcessor.getInstance().executeCommand(myProject, restartTemplateRunnable, getCommandName(), getCommandName());
|
||||
}
|
||||
}
|
||||
|
||||
+190
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.refactoring.introduceParameter;
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||
import com.intellij.codeInsight.template.TextResult;
|
||||
import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
|
||||
import com.intellij.codeInsight.template.impl.TemplateState;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.editor.SelectionModel;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.Balloon;
|
||||
import com.intellij.openapi.ui.popup.BalloonBuilder;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiNamedElement;
|
||||
import com.intellij.refactoring.rename.NameSuggestionProvider;
|
||||
import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
* Date: 3/15/11
|
||||
*/
|
||||
public abstract class AbstractInplaceVariableIntroducer<E extends PsiElement> extends VariableInplaceRenamer {
|
||||
public static final Key<Boolean> INTRODUCE_RESTART = Key.create("INTRODUCE_RESTART");
|
||||
|
||||
protected List<RangeMarker> myOccurrenceMarkers;
|
||||
protected RangeMarker myExprMarker;
|
||||
protected E myExpr;
|
||||
protected E[] myOccurrences;
|
||||
protected Balloon myBalloon;
|
||||
protected String myTitle;
|
||||
|
||||
public AbstractInplaceVariableIntroducer(PsiNamedElement elementToRename,
|
||||
Editor editor,
|
||||
Project project,
|
||||
String title, E[] occurrences, E expr) {
|
||||
super(elementToRename, editor, project);
|
||||
myTitle = title;
|
||||
myOccurrences = occurrences;
|
||||
myExpr = expr;
|
||||
myExprMarker = myExpr != null && myExpr.isPhysical() ? myEditor.getDocument().createRangeMarker(myExpr.getTextRange()) : null;
|
||||
initOccurrencesMarkers();
|
||||
}
|
||||
|
||||
protected abstract JComponent getComponent();
|
||||
protected abstract String getCommandName();
|
||||
|
||||
public void setOccurrenceMarkers(List<RangeMarker> occurrenceMarkers) {
|
||||
myOccurrenceMarkers = occurrenceMarkers;
|
||||
}
|
||||
|
||||
public void setExprMarker(RangeMarker exprMarker) {
|
||||
myExprMarker = exprMarker;
|
||||
}
|
||||
|
||||
protected E getExpr() {
|
||||
return myExpr != null && myExpr.isValid() && myExpr.isPhysical() ? myExpr : null;
|
||||
}
|
||||
|
||||
protected E[] getOccurrences() {
|
||||
return myOccurrences;
|
||||
}
|
||||
|
||||
public List<RangeMarker> getOccurrenceMarkers() {
|
||||
if (myOccurrenceMarkers == null) {
|
||||
initOccurrencesMarkers();
|
||||
}
|
||||
return myOccurrenceMarkers;
|
||||
}
|
||||
|
||||
protected void initOccurrencesMarkers() {
|
||||
if (myOccurrenceMarkers != null) return;
|
||||
myOccurrenceMarkers = new ArrayList<RangeMarker>();
|
||||
for (E occurrence : myOccurrences) {
|
||||
myOccurrenceMarkers.add(myEditor.getDocument().createRangeMarker(occurrence.getTextRange()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public RangeMarker getExprMarker() {
|
||||
return myExprMarker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performInplaceRename(boolean processTextOccurrences, LinkedHashSet<String> nameSuggestions) {
|
||||
final boolean result = super.performInplaceRename(processTextOccurrences, nameSuggestions);
|
||||
if (result) {
|
||||
if (myBalloon == null) {
|
||||
showBalloon();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void showBalloon() {
|
||||
final JComponent component = getComponent();
|
||||
if (component == null) return;
|
||||
if (ApplicationManager.getApplication().isHeadlessEnvironment()) return;
|
||||
final BalloonBuilder balloonBuilder = JBPopupFactory.getInstance().createBalloonBuilder(component);
|
||||
balloonBuilder.setFadeoutTime(0)
|
||||
.setFillColor(UIManager.getColor("Panel.background"))
|
||||
.setAnimationCycle(100)
|
||||
.setHideOnClickOutside(false)
|
||||
.setHideOnKeyOutside(false)
|
||||
.setHideOnAction(false)
|
||||
.setCloseButtonEnabled(true)
|
||||
.setTitle(myTitle);
|
||||
|
||||
final RelativePoint target = JBPopupFactory.getInstance().guessBestPopupLocation(myEditor);
|
||||
final Point screenPoint = target.getScreenPoint();
|
||||
myBalloon = balloonBuilder.createBalloon();
|
||||
int y = screenPoint.y;
|
||||
if (target.getPoint().getY() > myEditor.getLineHeight() + myBalloon.getPreferredSize().getHeight()) {
|
||||
y -= myEditor.getLineHeight();
|
||||
}
|
||||
myBalloon.show(new RelativePoint(new Point(screenPoint.x, y)), Balloon.Position.above);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
super.finish();
|
||||
if (myBalloon != null) {
|
||||
final Boolean isRestart = myEditor.getUserData(INTRODUCE_RESTART);
|
||||
if (isRestart == null || !isRestart.booleanValue()) {
|
||||
myBalloon.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LookupElement[] createLookupItems(LookupElement[] lookupItems, String name) {
|
||||
TemplateState templateState = TemplateManagerImpl.getTemplateState(myEditor);
|
||||
final PsiNamedElement psiVariable = getVariable();
|
||||
if (psiVariable != null) {
|
||||
final TextResult insertedValue =
|
||||
templateState != null ? templateState.getVariableValue(PRIMARY_VARIABLE_NAME) : null;
|
||||
if (insertedValue != null) {
|
||||
final String text = insertedValue.getText();
|
||||
if (!text.isEmpty() && !Comparing.strEqual(text, name)) {
|
||||
final LinkedHashSet<String> names = new LinkedHashSet<String>();
|
||||
names.add(text);
|
||||
for (NameSuggestionProvider provider : Extensions.getExtensions(NameSuggestionProvider.EP_NAME)) {
|
||||
provider.getSuggestedNames(psiVariable, psiVariable, names);
|
||||
}
|
||||
final LookupElement[] items = new LookupElement[names.size()];
|
||||
final Iterator<String> iterator = names.iterator();
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
items[i] = LookupElementBuilder.create(iterator.next());
|
||||
}
|
||||
return items;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.createLookupItems(lookupItems, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TextRange preserveSelectedRange(SelectionModel selectionModel) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
package com.intellij.refactoring.introduceParameter;
|
||||
|
||||
import com.intellij.codeInsight.intention.impl.TypeExpression;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.template.*;
|
||||
import com.intellij.openapi.actionSystem.Shortcut;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.keymap.Keymap;
|
||||
import com.intellij.openapi.keymap.KeymapManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
*/
|
||||
public abstract class AbstractJavaInplaceIntroducer extends AbstractInplaceIntroducer<PsiVariable, PsiExpression> {
|
||||
protected SmartTypePointer myTypePointer;
|
||||
protected TypeSelectorManagerImpl myTypeSelectorManager;
|
||||
protected final SmartTypePointer myDefaultType;
|
||||
protected final TypeExpression myExpression;
|
||||
|
||||
|
||||
public AbstractJavaInplaceIntroducer(Project project,
|
||||
Editor editor,
|
||||
PsiExpression expr,
|
||||
PsiVariable localVariable,
|
||||
PsiExpression[] occurrences,
|
||||
PsiType defaultType, TypeSelectorManagerImpl typeSelectorManager, String title) {
|
||||
super(project, editor, expr, localVariable, occurrences, title);
|
||||
myTypeSelectorManager = typeSelectorManager;
|
||||
myExpression = new TypeExpression(project, typeSelectorManager.getTypesForOne());
|
||||
myDefaultType = SmartTypePointerManager.getInstance(project).createSmartTypePointer(defaultType);
|
||||
setAdvertisementText(getAdvertisementText(myExpression.hasSuggestions()));
|
||||
}
|
||||
|
||||
protected abstract PsiVariable createFieldToStartTemplateOn(String[] names, PsiType psiType);
|
||||
protected abstract String[] suggestNames(PsiType defaultType, String propName);
|
||||
|
||||
|
||||
@Override
|
||||
protected String[] suggestNames(boolean replaceAll, PsiVariable variable) {
|
||||
myTypeSelectorManager.setAllOccurences(replaceAll);
|
||||
final PsiType defaultType = myTypeSelectorManager.getTypeSelector().getSelectedType();
|
||||
final String propertyName = variable != null
|
||||
? JavaCodeStyleManager.getInstance(myProject).variableNameToPropertyName(variable.getName(), VariableKind.LOCAL_VARIABLE)
|
||||
: null;
|
||||
return suggestNames(defaultType, propertyName);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected PsiVariable createFieldToStartTemplateOn(boolean replaceAll, String[] names) {
|
||||
final PsiType fieldDefaultType = myTypePointer != null ? myTypePointer.getType() : null;
|
||||
|
||||
myTypeSelectorManager.setAllOccurences(replaceAll);
|
||||
PsiType defaultType = myTypeSelectorManager.getTypeSelector().getSelectedType();
|
||||
if (fieldDefaultType != null) {
|
||||
if (replaceAll) {
|
||||
if (ArrayUtil.find(myTypeSelectorManager.getTypesForAll(), fieldDefaultType) != -1) {
|
||||
defaultType = fieldDefaultType;
|
||||
}
|
||||
}
|
||||
else if (ArrayUtil.find(myTypeSelectorManager.getTypesForOne(), fieldDefaultType) != -1) {
|
||||
defaultType = fieldDefaultType;
|
||||
}
|
||||
}
|
||||
return createFieldToStartTemplateOn(names, defaultType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiExpression restoreExpression(PsiFile containingFile, PsiVariable psiVariable, RangeMarker marker, String exprText) {
|
||||
return restoreExpression(containingFile, psiVariable, JavaPsiFacade.getElementFactory(myProject), marker, exprText);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void restoreState(PsiVariable psiField) {
|
||||
myTypePointer = SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(psiField.getType());
|
||||
super.restoreState(psiField);
|
||||
myTypeSelectorManager = new TypeSelectorManagerImpl(myProject, myDefaultType.getType(), null, myExpr, myOccurrences);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveSettings(PsiVariable psiVariable) {
|
||||
TypeSelectorManagerImpl.typeSelected(psiVariable.getType(), myDefaultType.getType());
|
||||
}
|
||||
|
||||
protected void addAdditionalVariables(TemplateBuilderImpl builder) {
|
||||
final PsiTypeElement typeElement = getVariable().getTypeElement();
|
||||
builder.replaceElement(typeElement, "Variable_Type", createExpression(myExpression, typeElement.getText()), true, true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiExpression restoreExpression(PsiFile containingFile,
|
||||
PsiVariable psiVariable,
|
||||
PsiElementFactory elementFactory,
|
||||
RangeMarker marker, String exprText) {
|
||||
if (exprText == null) return null;
|
||||
if (psiVariable == null || !psiVariable.isValid()) return null;
|
||||
final PsiElement refVariableElement = containingFile.findElementAt(marker.getStartOffset());
|
||||
PsiExpression expression = PsiTreeUtil.getParentOfType(refVariableElement, PsiReferenceExpression.class);
|
||||
if (expression instanceof PsiReferenceExpression && (((PsiReferenceExpression)expression).resolve() == psiVariable ||
|
||||
Comparing.strEqual(psiVariable.getName(),
|
||||
((PsiReferenceExpression)expression).getReferenceName()))) {
|
||||
return (PsiExpression)expression.replace(elementFactory.createExpressionFromText(exprText, psiVariable));
|
||||
}
|
||||
if (expression == null) {
|
||||
expression = PsiTreeUtil.getParentOfType(refVariableElement, PsiExpression.class);
|
||||
}
|
||||
return expression != null && expression.isValid() && expression.getText().equals(exprText) ? expression : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getAdvertisementText(final boolean hasTypeSuggestion) {
|
||||
final Keymap keymap = KeymapManager.getInstance().getActiveKeymap();
|
||||
if (hasTypeSuggestion) {
|
||||
final Shortcut[] shortcuts = keymap.getShortcuts("PreviousTemplateVariable");
|
||||
if (shortcuts.length > 0) {
|
||||
return "Press " + shortcuts[0] + " to change type";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Expression createExpression(final TypeExpression expression, final String defaultType) {
|
||||
return new Expression() {
|
||||
@Override
|
||||
public Result calculateResult(ExpressionContext context) {
|
||||
return new TextResult(defaultType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result calculateQuickResult(ExpressionContext context) {
|
||||
return new TextResult(defaultType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LookupElement[] calculateLookupItems(ExpressionContext context) {
|
||||
return expression.calculateLookupItems(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAdvertisingText() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
+103
-392
@@ -15,76 +15,43 @@
|
||||
*/
|
||||
package com.intellij.refactoring.introduceParameter;
|
||||
|
||||
import com.intellij.codeInsight.intention.impl.TypeExpression;
|
||||
import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
|
||||
import com.intellij.codeInsight.template.impl.TemplateState;
|
||||
import com.intellij.ide.ui.ListCellRendererWrapper;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.LabeledComponent;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.refactoring.IntroduceParameterRefactoring;
|
||||
import com.intellij.refactoring.JavaRefactoringSettings;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.inline.InlineParameterHandler;
|
||||
import com.intellij.refactoring.introduceField.InplaceIntroduceConstantPopup;
|
||||
import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer;
|
||||
import com.intellij.refactoring.ui.TypeSelectorManager;
|
||||
import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
import com.intellij.ui.NonFocusableCheckBox;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import gnu.trove.TIntArrayList;
|
||||
import gnu.trove.TIntProcedure;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
* Date: 2/25/11
|
||||
*/
|
||||
class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
class InplaceIntroduceParameterPopup extends AbstractJavaInplaceIntroducer {
|
||||
private static final Logger LOG = Logger.getInstance("#" + InplaceIntroduceParameterPopup.class.getName());
|
||||
|
||||
private final Project myProject;
|
||||
private final Editor myEditor;
|
||||
private final TypeSelectorManagerImpl myTypeSelectorManager;
|
||||
private PsiExpression myExpr;
|
||||
private final PsiLocalVariable myLocalVar;
|
||||
private final PsiMethod myMethod;
|
||||
private final PsiMethod myMethodToSearchFor;
|
||||
private final PsiExpression[] myOccurrences;
|
||||
private final boolean myMustBeFinal;
|
||||
private RangeMarker myExprMarker;
|
||||
private List<RangeMarker> myOccurrenceMarkers;
|
||||
|
||||
private final JPanel myWholePanel;
|
||||
private int myParameterIndex = -1;
|
||||
private String myParameterName;
|
||||
private final String myExprText;
|
||||
private InplaceIntroduceParameterUI myPanel;
|
||||
|
||||
private JComboBox myReplaceFieldsCb;
|
||||
private boolean myInitialized = false;
|
||||
private static final Logger LOG = Logger.getInstance("#" + InplaceIntroduceParameterPopup.class.getName());
|
||||
|
||||
private JCheckBox myFinalCb;
|
||||
private boolean myHasWriteAccess = false;
|
||||
|
||||
InplaceIntroduceParameterPopup(final Project project,
|
||||
final Editor editor,
|
||||
@@ -97,152 +64,58 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
final PsiExpression[] occurrences,
|
||||
final TIntArrayList parametersToRemove,
|
||||
final boolean mustBeFinal) {
|
||||
super(project, localVar, expr, method, parametersToRemove);
|
||||
super(project, editor, expr, localVar, occurrences, typeSelectorManager.getDefaultType(), typeSelectorManager, IntroduceParameterHandler.REFACTORING_NAME
|
||||
);
|
||||
myProject = project;
|
||||
myEditor = editor;
|
||||
myTypeSelectorManager = typeSelectorManager;
|
||||
myExpr = expr;
|
||||
myLocalVar = localVar;
|
||||
myMethod = method;
|
||||
myMethodToSearchFor = methodToSearchFor;
|
||||
myOccurrences = occurrences;
|
||||
myMustBeFinal = mustBeFinal;
|
||||
myExprMarker = expr != null && expr.isPhysical() ? myEditor.getDocument().createRangeMarker(expr.getTextRange()) : null;
|
||||
myExprText = myExpr != null ? myExpr.getText() : null;
|
||||
|
||||
myWholePanel = new JPanel(new GridBagLayout());
|
||||
myWholePanel.setBorder(null);
|
||||
final GridBagConstraints gc =
|
||||
new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0);
|
||||
|
||||
gc.insets = new Insets(0, 5, 0, 0);
|
||||
gc.gridwidth = 1;
|
||||
gc.fill = GridBagConstraints.NONE;
|
||||
if (myOccurrences.length > 1 && !myIsInvokedOnDeclaration) {
|
||||
gc.gridy++;
|
||||
createOccurrencesCb(gc, myWholePanel, myOccurrences.length);
|
||||
}
|
||||
gc.gridy++;
|
||||
gc.insets.left = 5;
|
||||
createDelegateCb(gc, myWholePanel);
|
||||
|
||||
|
||||
final JavaRefactoringSettings settings = JavaRefactoringSettings.getInstance();
|
||||
final JPanel rightPanel = new JPanel(new GridBagLayout());
|
||||
final GridBagConstraints rgc = new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0,0,0,5), 0, 0);
|
||||
createLocalVariablePanel(rgc, rightPanel, settings);
|
||||
createRemoveParamsPanel(rgc, rightPanel);
|
||||
if (Util.anyFieldsWithGettersPresent(classMemberRefs)) {
|
||||
rgc.gridy++;
|
||||
rightPanel.add(createReplaceFieldsWithGettersPanel(), rgc);
|
||||
}
|
||||
|
||||
gc.gridx = 1;
|
||||
gc.gridheight = myCbReplaceAllOccurences != null ? 3 : 2;
|
||||
gc.gridy = 1;
|
||||
myWholePanel.add(rightPanel, gc);
|
||||
|
||||
for (PsiExpression occurrence : occurrences) {
|
||||
if (PsiUtil.isAccessedForWriting(occurrence)) {
|
||||
myHasWriteAccess = true;
|
||||
break;
|
||||
myPanel = new InplaceIntroduceParameterUI(project, localVar, expr, method, parametersToRemove, typeSelectorManager,
|
||||
myEditor, myOccurrences, classMemberRefs, myMustBeFinal) {
|
||||
@Override
|
||||
protected PsiParameter getParameter() {
|
||||
return InplaceIntroduceParameterPopup.this.getParameter();
|
||||
}
|
||||
}
|
||||
|
||||
if (!myMustBeFinal) {
|
||||
myFinalCb = new NonFocusableCheckBox("Declare final");
|
||||
myFinalCb.setMnemonic('f');
|
||||
myWholePanel.add(myFinalCb,
|
||||
new GridBagConstraints(0, myCbReplaceAllOccurences == null ? 2 : 3, 1, 1, 0, 0, GridBagConstraints.NORTHWEST,
|
||||
GridBagConstraints.NONE, new Insets(0, 5, 2, 5), 0, 0));
|
||||
}
|
||||
@Override
|
||||
protected void updateControls(JCheckBox[] removeParamsCb) {
|
||||
super.updateControls(removeParamsCb);
|
||||
if (myParameterIndex < 0) return;
|
||||
restartTemplate();
|
||||
}
|
||||
};
|
||||
myPanel.append2MainPanel(myWholePanel);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected JPanel createReplaceFieldsWithGettersPanel() {
|
||||
final LabeledComponent<JComboBox> component = new LabeledComponent<JComboBox>();
|
||||
myReplaceFieldsCb = new JComboBox(new Integer[] {IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_ALL,
|
||||
IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE});
|
||||
myReplaceFieldsCb.setRenderer(new ListCellRendererWrapper<Integer>(myReplaceFieldsCb) {
|
||||
protected PsiVariable createFieldToStartTemplateOn(final String[] names, final PsiType defaultType) {
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myMethod.getProject());
|
||||
return ApplicationManager.getApplication().runWriteAction(new Computable<PsiParameter>() {
|
||||
@Override
|
||||
public void customize(JList list, Integer value, int index, boolean selected, boolean hasFocus) {
|
||||
switch (value) {
|
||||
case IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE:
|
||||
setText(UIUtil.removeMnemonic(RefactoringBundle.message("do.not.replace")));
|
||||
break;
|
||||
case IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE:
|
||||
setText(UIUtil.removeMnemonic(RefactoringBundle.message("replace.fields.inaccessible.in.usage.context")));
|
||||
break;
|
||||
default:
|
||||
setText(UIUtil.removeMnemonic(RefactoringBundle.message("replace.all.fields")));
|
||||
}
|
||||
public PsiParameter compute() {
|
||||
final String name = getInputName() != null ? getInputName() : names[0];
|
||||
final PsiParameter anchor = JavaIntroduceParameterMethodUsagesProcessor.getAnchorParameter(myMethod);
|
||||
final PsiParameter psiParameter = (PsiParameter)myMethod.getParameterList()
|
||||
.addAfter(elementFactory.createParameter(name, defaultType), anchor);
|
||||
PsiUtil.setModifierProperty(psiParameter, PsiModifier.FINAL, myPanel.hasFinalModifier());
|
||||
myParameterIndex = myMethod.getParameterList().getParameterIndex(psiParameter);
|
||||
return psiParameter;
|
||||
}
|
||||
});
|
||||
myReplaceFieldsCb.setSelectedItem(JavaRefactoringSettings.getInstance().INTRODUCE_PARAMETER_REPLACE_FIELDS_WITH_GETTERS);
|
||||
InplaceIntroduceConstantPopup.appendActions(myReplaceFieldsCb, myProject);
|
||||
component.setComponent(myReplaceFieldsCb);
|
||||
component.setText(RefactoringBundle.message("replace.fields.used.in.expressions.with.their.getters"));
|
||||
component.getLabel().setDisplayedMnemonic('u');
|
||||
component.setLabelLocation(BorderLayout.NORTH);
|
||||
component.setBorder(IdeBorderFactory.createEmptyBorder(3, 3, 2, 2));
|
||||
return component;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getReplaceFieldsWithGetters() {
|
||||
return myReplaceFieldsCb!= null ? (Integer)myReplaceFieldsCb.getSelectedItem() : IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE;
|
||||
protected String[] suggestNames(PsiType defaultType, String propName) {
|
||||
return IntroduceParameterHandler.createNameSuggestionGenerator(myExpr, propName, myProject)
|
||||
.getSuggestedNameInfo(defaultType).names;
|
||||
}
|
||||
|
||||
boolean inplaceIntroduceParameter() {
|
||||
return startIntroduceTemplate(false);
|
||||
}
|
||||
|
||||
private boolean startIntroduceTemplate(final boolean replaceAllOccurrences) {
|
||||
return startIntroduceTemplate(replaceAllOccurrences, hasFinalModifier());
|
||||
}
|
||||
|
||||
private boolean startIntroduceTemplate(final boolean replaceAllOccurrences,
|
||||
final boolean hasFinalModifier) {
|
||||
final Ref<Boolean> result = new Ref<Boolean>();
|
||||
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
|
||||
public void run() {
|
||||
myTypeSelectorManager.setAllOccurences(replaceAllOccurrences);
|
||||
final PsiType defaultType = myTypeSelectorManager.getTypeSelector().getSelectedType();
|
||||
final String propName = myLocalVar != null ? JavaCodeStyleManager
|
||||
.getInstance(myProject).variableNameToPropertyName(myLocalVar.getName(), VariableKind.LOCAL_VARIABLE) : null;
|
||||
final String[] names = IntroduceParameterHandler.createNameSuggestionGenerator(myExpr, propName, myProject)
|
||||
.getSuggestedNameInfo(defaultType).names;
|
||||
final PsiParameter parameter = createParameterToStartTemplateOn(names, defaultType, hasFinalModifier);
|
||||
boolean started = false;
|
||||
if (parameter != null) {
|
||||
myParameterIndex = myMethod.getParameterList().getParameterIndex(parameter);
|
||||
myEditor.getCaretModel().moveToOffset(parameter.getTextOffset());
|
||||
myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
|
||||
final LinkedHashSet<String> nameSuggestions = new LinkedHashSet<String>();
|
||||
nameSuggestions.add(parameter.getName());
|
||||
nameSuggestions.addAll(Arrays.asList(names));
|
||||
final VariableInplaceRenamer renamer = new ParameterInplaceIntroducer(parameter);
|
||||
LOG.assertTrue(parameter.isPhysical());
|
||||
started = renamer.performInplaceRename(false, nameSuggestions);
|
||||
}
|
||||
result.set(started);
|
||||
if (!started && parameter != null) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
parameter.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}, IntroduceParameterHandler.REFACTORING_NAME, IntroduceParameterHandler.REFACTORING_NAME);
|
||||
return result.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TypeSelectorManager getTypeSelectionManager() {
|
||||
return myTypeSelectorManager;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiParameter getParameter() {
|
||||
@@ -251,247 +124,85 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
return parameters.length > myParameterIndex ? parameters[myParameterIndex] : null;
|
||||
}
|
||||
|
||||
public List<RangeMarker> getOccurrenceMarkers() {
|
||||
if (myOccurrenceMarkers == null) {
|
||||
myOccurrenceMarkers = new ArrayList<RangeMarker>();
|
||||
for (PsiExpression occurrence : myOccurrences) {
|
||||
myOccurrenceMarkers.add(myEditor.getDocument().createRangeMarker(occurrence.getTextRange()));
|
||||
}
|
||||
}
|
||||
return myOccurrenceMarkers;
|
||||
}
|
||||
|
||||
private class ParameterInplaceIntroducer extends AbstractInplaceIntroducer {
|
||||
|
||||
private SmartTypePointer myParameterTypePointer;
|
||||
private SmartTypePointer myDefaultParameterTypePointer;
|
||||
|
||||
private boolean myFinal;
|
||||
|
||||
public ParameterInplaceIntroducer(PsiParameter parameter) {
|
||||
super(myProject, new TypeExpression(myProject, myTypeSelectorManager.getTypesForAll()),
|
||||
myEditor, parameter, myMustBeFinal,
|
||||
myTypeSelectorManager.getTypesForAll().length > 1, myExprMarker, InplaceIntroduceParameterPopup.this.getOccurrenceMarkers(),
|
||||
IntroduceParameterHandler.REFACTORING_NAME, IntroduceParameterHandler.REFACTORING_NAME);
|
||||
myDefaultParameterTypePointer = SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(parameter.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent getComponent() {
|
||||
if (!myInitialized) {
|
||||
myInitialized = true;
|
||||
if (myFinalCb != null) {
|
||||
myFinalCb.setSelected(createFinals());
|
||||
final FinalListener finalListener = new FinalListener(myProject, InlineParameterHandler.REFACTORING_NAME);
|
||||
myFinalCb.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
finalListener.perform(myFinalCb.isSelected());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return myWholePanel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isReplaceAllOccurrences() {
|
||||
return InplaceIntroduceParameterPopup.this.isReplaceAllOccurences();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiExpression getExpr() {
|
||||
return myExpr != null && myExpr.isValid() && myExpr.isPhysical() ? myExpr : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiExpression[] getOccurrences() {
|
||||
return myOccurrences;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<RangeMarker> getOccurrenceMarkers() {
|
||||
return InplaceIntroduceParameterPopup.this.getOccurrenceMarkers();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiVariable getVariable() {
|
||||
return getParameter();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void saveSettings(PsiVariable psiVariable) {
|
||||
final JavaRefactoringSettings settings = JavaRefactoringSettings.getInstance();
|
||||
InplaceIntroduceParameterPopup.super.saveSettings(settings);
|
||||
if (myFinalCb != null && myFinalCb.isEnabled()) {
|
||||
settings.INTRODUCE_PARAMETER_CREATE_FINALS = psiVariable.hasModifierProperty(PsiModifier.FINAL);
|
||||
}
|
||||
TypeSelectorManagerImpl.typeSelected(psiVariable.getType(), myDefaultParameterTypePointer.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void moveOffsetAfter(boolean success) {
|
||||
if (success) {
|
||||
boolean isDeleteLocalVariable = false;
|
||||
|
||||
PsiExpression parameterInitializer = myExpr;
|
||||
if (myLocalVar != null) {
|
||||
if (isUseInitializer()) {
|
||||
parameterInitializer = myLocalVar.getInitializer();
|
||||
}
|
||||
isDeleteLocalVariable = isDeleteLocalVariable();
|
||||
}
|
||||
|
||||
if (!myMethod.isValid() || myParameterName == null || myLocalVar == null && myExpr == null) {
|
||||
super.moveOffsetAfter(false);
|
||||
return;
|
||||
}
|
||||
|
||||
final TIntArrayList parametersToRemove = getParametersToRemove();
|
||||
|
||||
final IntroduceParameterProcessor processor =
|
||||
new IntroduceParameterProcessor(myProject, myMethod,
|
||||
myMethodToSearchFor, parameterInitializer, myExpr,
|
||||
myLocalVar, isDeleteLocalVariable, myParameterName,
|
||||
isReplaceAllOccurences(),
|
||||
getReplaceFieldsWithGetters(), myMustBeFinal || myFinal, isGenerateDelegate(),
|
||||
myParameterTypePointer.getType(),
|
||||
parametersToRemove);
|
||||
final Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
final boolean [] conflictsFound = new boolean[] {true};
|
||||
processor.setPrepareSuccessfulSwingThreadCallback(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
conflictsFound[0] = processor.hasConflicts();
|
||||
}
|
||||
});
|
||||
processor.run();
|
||||
normalizeParameterIdxAccordingToRemovedParams(parametersToRemove);
|
||||
ParameterInplaceIntroducer.super.moveOffsetAfter(!conflictsFound[0]);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
CommandProcessor.getInstance().executeCommand(myProject, runnable, IntroduceParameterHandler.REFACTORING_NAME, null);
|
||||
}
|
||||
super.moveOffsetAfter(false);
|
||||
if (myLocalVar != null && myLocalVar.isValid()) {
|
||||
myEditor.getCaretModel().moveToOffset(myLocalVar.getTextOffset());
|
||||
myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
super.finish();
|
||||
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
|
||||
final PsiParameter psiParameter = (PsiParameter)getVariable();
|
||||
if (psiParameter == null) {
|
||||
return;
|
||||
}
|
||||
myFinal = psiParameter.hasModifierProperty(PsiModifier.FINAL);
|
||||
myParameterTypePointer = SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(psiParameter.getType());
|
||||
|
||||
myParameterName = psiParameter.getName();
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
final PsiFile containingFile = myMethod.getContainingFile();
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
|
||||
if (myExprMarker != null) {
|
||||
myExpr = restoreExpression(containingFile, psiParameter, elementFactory, myExprMarker, myExprText);
|
||||
if (myExpr != null) {
|
||||
myExprMarker = myEditor.getDocument().createRangeMarker(myExpr.getTextRange());
|
||||
}
|
||||
}
|
||||
final List<RangeMarker> occurrenceMarkers = getOccurrenceMarkers();
|
||||
for (int i = 0, occurrenceMarkersSize = occurrenceMarkers.size(); i < occurrenceMarkersSize; i++) {
|
||||
RangeMarker marker = occurrenceMarkers.get(i);
|
||||
if (myExprMarker != null && marker.getStartOffset() == myExprMarker.getStartOffset()) {
|
||||
myOccurrences[i] = myExpr;
|
||||
continue;
|
||||
}
|
||||
final PsiExpression psiExpression = restoreExpression(containingFile, psiParameter, elementFactory, marker, myExprText);
|
||||
if (psiExpression != null) {
|
||||
myOccurrences[i] = psiExpression;
|
||||
}
|
||||
}
|
||||
myOccurrenceMarkers = null;
|
||||
if (psiParameter.isValid()) {
|
||||
psiParameter.delete();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void normalizeParameterIdxAccordingToRemovedParams(TIntArrayList parametersToRemove) {
|
||||
parametersToRemove.forEach(new TIntProcedure() {
|
||||
@Override
|
||||
public boolean execute(int value) {
|
||||
if (myParameterIndex >= value) {
|
||||
myParameterIndex--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean createFinals() {
|
||||
return hasFinalModifier();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasFinalModifier() {
|
||||
if (myHasWriteAccess) return false;
|
||||
final Boolean createFinals = JavaRefactoringSettings.getInstance().INTRODUCE_PARAMETER_CREATE_FINALS;
|
||||
return createFinals == null ? CodeStyleSettingsManager.getSettings(myProject).GENERATE_FINAL_PARAMETERS : createFinals.booleanValue();
|
||||
@Override
|
||||
protected JComponent getComponent() {
|
||||
return myWholePanel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateControls(JCheckBox[] removeParamsCb) {
|
||||
super.updateControls(removeParamsCb);
|
||||
if (myParameterIndex < 0) return;
|
||||
final boolean writeUsageWouldBeReplaced = myHasWriteAccess && isReplaceAllOccurences();
|
||||
Runnable restartTemplateRunnable = new Runnable() {
|
||||
public void run() {
|
||||
final TemplateState templateState = TemplateManagerImpl.getTemplateState(myEditor);
|
||||
if (templateState != null) {
|
||||
PsiDocumentManager.getInstance(myProject).commitDocument(myEditor.getDocument());
|
||||
final PsiParameter parameter = getParameter();
|
||||
boolean hasFinalModifier = parameter.hasModifierProperty(PsiModifier.FINAL) && !writeUsageWouldBeReplaced;
|
||||
templateState.gotoEnd(true);
|
||||
startIntroduceTemplate(isReplaceAllOccurences(), hasFinalModifier);
|
||||
}
|
||||
}
|
||||
};
|
||||
CommandProcessor.getInstance().executeCommand(myProject, restartTemplateRunnable, IntroduceParameterHandler.REFACTORING_NAME,
|
||||
IntroduceParameterHandler.REFACTORING_NAME);
|
||||
if (myFinalCb != null) {
|
||||
if (writeUsageWouldBeReplaced) {
|
||||
myFinalCb.setSelected(false);
|
||||
}
|
||||
myFinalCb.setEnabled(!writeUsageWouldBeReplaced);
|
||||
}
|
||||
protected boolean isReplaceAllOccurrences() {
|
||||
return myPanel.isReplaceAllOccurences();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiVariable getVariable() {
|
||||
return getParameter();
|
||||
}
|
||||
|
||||
|
||||
private PsiParameter createParameterToStartTemplateOn(final String[] names,
|
||||
final PsiType defaultType, final boolean hasFinalModifier) {
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myMethod.getProject());
|
||||
return ApplicationManager.getApplication().runWriteAction(new Computable<PsiParameter>() {
|
||||
@Override
|
||||
protected void saveSettings(PsiVariable psiVariable) {
|
||||
myPanel.saveSettings(JavaRefactoringSettings.getInstance());
|
||||
}
|
||||
|
||||
protected void performIntroduce() {
|
||||
boolean isDeleteLocalVariable = false;
|
||||
|
||||
PsiExpression parameterInitializer = myExpr;
|
||||
if (myLocalVar != null) {
|
||||
if (myPanel.isUseInitializer()) {
|
||||
parameterInitializer = myLocalVar.getInitializer();
|
||||
}
|
||||
isDeleteLocalVariable = myPanel.isDeleteLocalVariable();
|
||||
}
|
||||
|
||||
final TIntArrayList parametersToRemove = myPanel.getParametersToRemove();
|
||||
|
||||
final IntroduceParameterProcessor processor =
|
||||
new IntroduceParameterProcessor(myProject, myMethod,
|
||||
myMethodToSearchFor, parameterInitializer, myExpr,
|
||||
myLocalVar, isDeleteLocalVariable, getInputName(),
|
||||
myPanel.isReplaceAllOccurences(),
|
||||
myPanel.getReplaceFieldsWithGetters(), myMustBeFinal || myPanel.isGenerateFinal(),
|
||||
myPanel.isGenerateDelegate(),
|
||||
myTypePointer.getType(),
|
||||
parametersToRemove);
|
||||
final Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
final boolean[] conflictsFound = new boolean[]{true};
|
||||
processor.setPrepareSuccessfulSwingThreadCallback(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
conflictsFound[0] = processor.hasConflicts();
|
||||
}
|
||||
});
|
||||
processor.run();
|
||||
normalizeParameterIdxAccordingToRemovedParams(parametersToRemove);
|
||||
InplaceIntroduceParameterPopup.super.moveOffsetAfter(!conflictsFound[0]);
|
||||
InplaceIntroduceParameterPopup.super.saveSettings(getParameter());
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
CommandProcessor.getInstance().executeCommand(myProject, runnable, getCommandName(), null);
|
||||
}
|
||||
|
||||
public String getCommandName() {
|
||||
return IntroduceParameterHandler.REFACTORING_NAME;
|
||||
}
|
||||
|
||||
private void normalizeParameterIdxAccordingToRemovedParams(TIntArrayList parametersToRemove) {
|
||||
parametersToRemove.forEach(new TIntProcedure() {
|
||||
@Override
|
||||
public PsiParameter compute() {
|
||||
final String name = myParameterName != null ? myParameterName : names[0];
|
||||
final PsiParameter anchor = JavaIntroduceParameterMethodUsagesProcessor.getAnchorParameter(myMethod);
|
||||
final PsiParameter psiParameter = (PsiParameter)myMethod.getParameterList()
|
||||
.addAfter(elementFactory.createParameter(name, defaultType), anchor);
|
||||
PsiUtil.setModifierProperty(psiParameter, PsiModifier.FINAL, hasFinalModifier);
|
||||
return psiParameter;
|
||||
public boolean execute(int value) {
|
||||
if (myParameterIndex >= value) {
|
||||
myParameterIndex--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
package com.intellij.refactoring.introduceParameter;
|
||||
|
||||
import com.intellij.ide.ui.ListCellRendererWrapper;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.LabeledComponent;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.refactoring.IntroduceParameterRefactoring;
|
||||
import com.intellij.refactoring.JavaRefactoringSettings;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.introduceField.InplaceCombosUtil;
|
||||
import com.intellij.refactoring.introduceVariable.FinalListener;
|
||||
import com.intellij.refactoring.ui.TypeSelectorManager;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
import com.intellij.ui.NonFocusableCheckBox;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import gnu.trove.TIntArrayList;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
*/
|
||||
public abstract class InplaceIntroduceParameterUI extends IntroduceParameterSettingsUI {
|
||||
private JComboBox myReplaceFieldsCb;
|
||||
private JCheckBox myFinalCb;
|
||||
private boolean myHasWriteAccess = false;
|
||||
private Project myProject;
|
||||
private TypeSelectorManager myTypeSelectorManager;
|
||||
private Editor myEditor;
|
||||
private PsiExpression[] myOccurrences;
|
||||
private List<UsageInfo> myClassMemberRefs;
|
||||
private boolean myMustBeFinal;
|
||||
|
||||
public InplaceIntroduceParameterUI(Project project,
|
||||
PsiLocalVariable onLocalVariable,
|
||||
PsiExpression onExpression,
|
||||
PsiMethod methodToReplaceIn,
|
||||
TIntArrayList parametersToRemove,
|
||||
TypeSelectorManager typeSelectorManager,
|
||||
Editor editor,
|
||||
PsiExpression[] occurrences, List<UsageInfo> classMemberRefs, boolean mustBeFinal) {
|
||||
super(project, onLocalVariable, onExpression, methodToReplaceIn, parametersToRemove);
|
||||
myProject = project;
|
||||
myTypeSelectorManager = typeSelectorManager;
|
||||
myEditor = editor;
|
||||
myOccurrences = occurrences;
|
||||
myClassMemberRefs = classMemberRefs;
|
||||
myMustBeFinal = mustBeFinal;
|
||||
|
||||
for (PsiExpression occurrence : myOccurrences) {
|
||||
if (PsiUtil.isAccessedForWriting(occurrence)) {
|
||||
myHasWriteAccess = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract PsiParameter getParameter();
|
||||
|
||||
@Override
|
||||
protected JPanel createReplaceFieldsWithGettersPanel() {
|
||||
final LabeledComponent<JComboBox> component = new LabeledComponent<JComboBox>();
|
||||
myReplaceFieldsCb = new JComboBox(new Integer[]{IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_ALL,
|
||||
IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE,
|
||||
IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE});
|
||||
myReplaceFieldsCb.setRenderer(new ListCellRendererWrapper<Integer>(myReplaceFieldsCb) {
|
||||
@Override
|
||||
public void customize(JList list, Integer value, int index, boolean selected, boolean hasFocus) {
|
||||
switch (value) {
|
||||
case IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE:
|
||||
setText(UIUtil.removeMnemonic(RefactoringBundle.message("do.not.replace")));
|
||||
break;
|
||||
case IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE:
|
||||
setText(UIUtil.removeMnemonic(RefactoringBundle.message("replace.fields.inaccessible.in.usage.context")));
|
||||
break;
|
||||
default:
|
||||
setText(UIUtil.removeMnemonic(RefactoringBundle.message("replace.all.fields")));
|
||||
}
|
||||
}
|
||||
});
|
||||
myReplaceFieldsCb.setSelectedItem(JavaRefactoringSettings.getInstance().INTRODUCE_PARAMETER_REPLACE_FIELDS_WITH_GETTERS);
|
||||
InplaceCombosUtil.appendActions(myReplaceFieldsCb, myProject);
|
||||
component.setComponent(myReplaceFieldsCb);
|
||||
component.setText(RefactoringBundle.message("replace.fields.used.in.expressions.with.their.getters"));
|
||||
component.getLabel().setDisplayedMnemonic('u');
|
||||
component.setLabelLocation(BorderLayout.NORTH);
|
||||
component.setBorder(IdeBorderFactory.createEmptyBorder(3, 3, 2, 2));
|
||||
return component;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getReplaceFieldsWithGetters() {
|
||||
return myReplaceFieldsCb != null
|
||||
? (Integer)myReplaceFieldsCb.getSelectedItem()
|
||||
: IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TypeSelectorManager getTypeSelectionManager() {
|
||||
return myTypeSelectorManager;
|
||||
}
|
||||
|
||||
public boolean isGenerateFinal() {
|
||||
return myFinalCb == null || myFinalCb.isSelected();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateControls(JCheckBox[] removeParamsCb) {
|
||||
super.updateControls(removeParamsCb);
|
||||
final boolean writeUsageWouldBeReplaced = writeUsageWouldBeReplaced();
|
||||
if (myFinalCb != null) {
|
||||
if (writeUsageWouldBeReplaced) {
|
||||
myFinalCb.setSelected(false);
|
||||
}
|
||||
myFinalCb.setEnabled(!writeUsageWouldBeReplaced);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean writeUsageWouldBeReplaced() {
|
||||
return myHasWriteAccess && isReplaceAllOccurences();
|
||||
}
|
||||
|
||||
public void append2MainPanel(JPanel myWholePanel) {
|
||||
final GridBagConstraints gc =
|
||||
new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0);
|
||||
|
||||
gc.insets = new Insets(0, 5, 0, 0);
|
||||
gc.gridwidth = 1;
|
||||
gc.fill = GridBagConstraints.NONE;
|
||||
if (myOccurrences.length > 1 && !myIsInvokedOnDeclaration) {
|
||||
gc.gridy++;
|
||||
createOccurrencesCb(gc, myWholePanel, myOccurrences.length);
|
||||
}
|
||||
gc.gridy++;
|
||||
gc.insets.left = 5;
|
||||
createDelegateCb(gc, myWholePanel);
|
||||
|
||||
|
||||
final JavaRefactoringSettings settings = JavaRefactoringSettings.getInstance();
|
||||
final JPanel rightPanel = new JPanel(new GridBagLayout());
|
||||
final GridBagConstraints rgc =
|
||||
new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
|
||||
new Insets(0, 0, 0, 5), 0, 0);
|
||||
createLocalVariablePanel(rgc, rightPanel, settings);
|
||||
createRemoveParamsPanel(rgc, rightPanel);
|
||||
if (Util.anyFieldsWithGettersPresent(myClassMemberRefs)) {
|
||||
rgc.gridy++;
|
||||
rightPanel.add(createReplaceFieldsWithGettersPanel(), rgc);
|
||||
}
|
||||
|
||||
gc.gridx = 1;
|
||||
gc.gridheight = myCbReplaceAllOccurences != null ? 3 : 2;
|
||||
gc.gridy = 1;
|
||||
myWholePanel.add(rightPanel, gc);
|
||||
|
||||
if (!myMustBeFinal) {
|
||||
myFinalCb = new NonFocusableCheckBox("Declare final");
|
||||
myFinalCb.setMnemonic('f');
|
||||
myFinalCb.setSelected(hasFinalModifier());
|
||||
final FinalListener finalListener = new FinalListener(myEditor);
|
||||
myFinalCb.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
new WriteCommandAction(myProject, IntroduceParameterHandler.REFACTORING_NAME, IntroduceParameterHandler.REFACTORING_NAME) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
PsiDocumentManager.getInstance(myProject).commitDocument(myEditor.getDocument());
|
||||
finalListener.perform(myFinalCb.isSelected(), getParameter());
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
});
|
||||
myWholePanel.add(myFinalCb,
|
||||
new GridBagConstraints(0, myCbReplaceAllOccurences == null ? 2 : 3, 1, 1, 0, 0, GridBagConstraints.NORTHWEST,
|
||||
GridBagConstraints.NONE, new Insets(0, 5, 2, 5), 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveSettings(JavaRefactoringSettings settings) {
|
||||
super.saveSettings(settings);
|
||||
if (myFinalCb != null && myFinalCb.isEnabled()) {
|
||||
settings.INTRODUCE_PARAMETER_CREATE_FINALS = myFinalCb.isSelected();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasFinalModifier() {
|
||||
if (myHasWriteAccess) return false;
|
||||
final Boolean createFinals = JavaRefactoringSettings.getInstance().INTRODUCE_PARAMETER_CREATE_FINALS;
|
||||
return createFinals == null ? CodeStyleSettingsManager.getSettings(myProject).GENERATE_FINAL_PARAMETERS : createFinals.booleanValue();
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -53,7 +53,6 @@ import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.refactoring.util.occurences.ExpressionOccurenceManager;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
@@ -423,7 +422,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R
|
||||
typeSelectorManager,
|
||||
myExpr, myLocalVar, method, methodToSearchFor, occurences,
|
||||
parametersToRemove,
|
||||
mustBeFinal).inplaceIntroduceParameter()) {
|
||||
mustBeFinal).startInplaceIntroduceTemplate()) {
|
||||
return;
|
||||
}
|
||||
if (myEditor != null) {
|
||||
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
package com.intellij.refactoring.introduceParameter;
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupManager;
|
||||
import com.intellij.codeInsight.lookup.impl.LookupImpl;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.psi.PsiModifier;
|
||||
import com.intellij.psi.PsiModifierList;
|
||||
import com.intellij.psi.PsiVariable;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
*/
|
||||
public abstract class VisibilityListener {
|
||||
private Editor myEditor;
|
||||
private static final Logger LOG = Logger.getInstance("#" + VisibilityListener.class.getName());
|
||||
|
||||
protected VisibilityListener(Editor editor) {
|
||||
myEditor = editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* to be performed in write action
|
||||
*/
|
||||
public void perform(final PsiVariable variable) {
|
||||
ApplicationManager.getApplication().assertWriteAccessAllowed();
|
||||
|
||||
final Document document = myEditor.getDocument();
|
||||
LOG.assertTrue(variable != null);
|
||||
final PsiModifierList modifierList = variable.getModifierList();
|
||||
LOG.assertTrue(modifierList != null);
|
||||
int textOffset = modifierList.getTextOffset();
|
||||
final String modifierListText = modifierList.getText();
|
||||
|
||||
int length = PsiModifier.PUBLIC.length();
|
||||
int idx = modifierListText.indexOf(PsiModifier.PUBLIC);
|
||||
|
||||
if (idx == -1) {
|
||||
idx = modifierListText.indexOf(PsiModifier.PROTECTED);
|
||||
length = PsiModifier.PROTECTED.length();
|
||||
}
|
||||
|
||||
if (idx == -1) {
|
||||
idx = modifierListText.indexOf(PsiModifier.PRIVATE);
|
||||
length = PsiModifier.PRIVATE.length();
|
||||
}
|
||||
|
||||
String visibility = getVisibility();
|
||||
if (visibility == PsiModifier.PACKAGE_LOCAL) {
|
||||
visibility = "";
|
||||
}
|
||||
|
||||
final boolean wasPackageLocal = idx == -1;
|
||||
final boolean isPackageLocal = visibility.isEmpty();
|
||||
|
||||
final int startOffset = textOffset + (wasPackageLocal ? 0 : idx);
|
||||
final int endOffset;
|
||||
if (wasPackageLocal) {
|
||||
endOffset = startOffset;
|
||||
}
|
||||
else {
|
||||
endOffset = textOffset + length + (isPackageLocal ? 1 : 0);
|
||||
}
|
||||
|
||||
final String finalVisibility = visibility + (wasPackageLocal ? " " : "");
|
||||
|
||||
Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
document.replaceString(startOffset, endOffset, finalVisibility);
|
||||
}
|
||||
};
|
||||
|
||||
final LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(myEditor);
|
||||
if (lookup != null) {
|
||||
lookup.performGuardedChange(runnable);
|
||||
} else {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract String getVisibility();
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.intellij.refactoring.introduceVariable;
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupManager;
|
||||
import com.intellij.codeInsight.lookup.impl.LookupImpl;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.psi.PsiModifier;
|
||||
import com.intellij.psi.PsiModifierList;
|
||||
import com.intellij.psi.PsiTypeElement;
|
||||
import com.intellij.psi.PsiVariable;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
*/
|
||||
public class FinalListener {
|
||||
private final Editor myEditor;
|
||||
private static final Logger LOG = Logger.getInstance("#" + FinalListener.class.getName());
|
||||
|
||||
public FinalListener(Editor editor) {
|
||||
myEditor = editor;
|
||||
}
|
||||
|
||||
public void perform(final boolean generateFinal, PsiVariable variable) {
|
||||
perform(generateFinal, PsiModifier.FINAL, variable);
|
||||
}
|
||||
|
||||
public void perform(final boolean generateFinal, final String modifier, final PsiVariable variable) {
|
||||
final Document document = myEditor.getDocument();
|
||||
LOG.assertTrue(variable != null);
|
||||
final PsiModifierList modifierList = variable.getModifierList();
|
||||
LOG.assertTrue(modifierList != null);
|
||||
final int textOffset = modifierList.getTextOffset();
|
||||
|
||||
final Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
if (generateFinal) {
|
||||
final PsiTypeElement typeElement = variable.getTypeElement();
|
||||
final int typeOffset = typeElement != null ? typeElement.getTextOffset() : textOffset;
|
||||
document.insertString(typeOffset, modifier + " ");
|
||||
}
|
||||
else {
|
||||
final int idx = modifierList.getText().indexOf(modifier);
|
||||
document.deleteString(textOffset + idx, textOffset + idx + modifier.length() + 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
final LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(myEditor);
|
||||
if (lookup != null) {
|
||||
lookup.performGuardedChange(runnable);
|
||||
} else {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -49,7 +49,6 @@ import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.PsiUtilBase;
|
||||
import com.intellij.refactoring.*;
|
||||
import com.intellij.refactoring.introduceField.ElementToWorkOn;
|
||||
import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer;
|
||||
import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.refactoring.util.FieldConflictsResolver;
|
||||
@@ -531,7 +530,8 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme
|
||||
final boolean cantChangeFinalModifier = (hasWriteAccess || inFinalContext) && choice == OccurrencesChooser.ReplaceChoice.ALL;
|
||||
final VariableInplaceIntroducer renamer =
|
||||
new VariableInplaceIntroducer(project, expression, editor, elementToRename, cantChangeFinalModifier,
|
||||
typeSelectorManager.getTypesForAll().length > 1, exprMarker, occurrenceMarkers, IntroduceVariableBase.REFACTORING_NAME, IntroduceVariableBase.REFACTORING_NAME);
|
||||
typeSelectorManager.getTypesForAll().length > 1, exprMarker, occurrenceMarkers,
|
||||
IntroduceVariableBase.REFACTORING_NAME);
|
||||
renamer.initInitialText(expressionText);
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument());
|
||||
renamer.performInplaceRename(false, new LinkedHashSet<String>(Arrays.asList(suggestedName.names)));
|
||||
|
||||
+87
-247
@@ -16,27 +16,17 @@
|
||||
package com.intellij.refactoring.introduceVariable;
|
||||
|
||||
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.lookup.impl.LookupImpl;
|
||||
import com.intellij.codeInsight.template.*;
|
||||
import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
|
||||
import com.intellij.codeInsight.template.impl.TemplateState;
|
||||
import com.intellij.ide.IdeTooltipManager;
|
||||
import com.intellij.codeInsight.template.TemplateBuilderImpl;
|
||||
import com.intellij.openapi.actionSystem.Shortcut;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.*;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.keymap.Keymap;
|
||||
import com.intellij.openapi.keymap.KeymapManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.Balloon;
|
||||
import com.intellij.openapi.ui.popup.BalloonBuilder;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
@@ -44,73 +34,63 @@ import com.intellij.psi.scope.processor.VariablesProcessor;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.refactoring.JavaRefactoringSettings;
|
||||
import com.intellij.refactoring.rename.NameSuggestionProvider;
|
||||
import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer;
|
||||
import com.intellij.refactoring.introduceParameter.AbstractInplaceVariableIntroducer;
|
||||
import com.intellij.refactoring.introduceParameter.AbstractJavaInplaceIntroducer;
|
||||
import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
|
||||
import com.intellij.ui.NonFocusableCheckBox;
|
||||
import com.intellij.ui.TitlePanel;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
* Date: 12/8/10
|
||||
*/
|
||||
public class VariableInplaceIntroducer extends VariableInplaceRenamer {
|
||||
private final PsiVariable myElementToRename;
|
||||
private final Editor myEditor;
|
||||
private final TypeExpression myExpression;
|
||||
private final Project myProject;
|
||||
public class VariableInplaceIntroducer extends AbstractInplaceVariableIntroducer<PsiExpression> {
|
||||
protected final Editor myEditor;
|
||||
|
||||
protected final Project myProject;
|
||||
private final SmartPsiElementPointer<PsiDeclarationStatement> myPointer;
|
||||
private final RangeMarker myExprMarker;
|
||||
private final List<RangeMarker> myOccurrenceMarkers;
|
||||
private final SmartTypePointer myDefaultType;
|
||||
|
||||
private JCheckBox myCanBeFinalCb;
|
||||
private Balloon myBalloon;
|
||||
|
||||
private boolean myCantChangeFinalModifier;
|
||||
private String myCommandName;
|
||||
private String myTitle;
|
||||
private String myExpressionText;
|
||||
protected final SmartTypePointer myDefaultType;
|
||||
protected final TypeExpression myExpression;
|
||||
|
||||
public VariableInplaceIntroducer(final Project project,
|
||||
final TypeExpression expression,
|
||||
final Editor editor,
|
||||
final PsiVariable elementToRename,
|
||||
final @NotNull PsiVariable elementToRename,
|
||||
final boolean cantChangeFinalModifier,
|
||||
final boolean hasTypeSuggestion,
|
||||
final RangeMarker exprMarker,
|
||||
final List<RangeMarker> occurrenceMarkers,
|
||||
final String commandName,
|
||||
final String title) {
|
||||
super(elementToRename, editor);
|
||||
super(elementToRename, editor, project, title, new PsiExpression[0], null);
|
||||
myProject = project;
|
||||
myEditor = editor;
|
||||
myElementToRename = elementToRename;
|
||||
myExpression = expression;
|
||||
myCantChangeFinalModifier = cantChangeFinalModifier;
|
||||
myCommandName = commandName;
|
||||
myTitle = title;
|
||||
|
||||
myExprMarker = exprMarker;
|
||||
myOccurrenceMarkers = occurrenceMarkers;
|
||||
|
||||
final PsiType defaultType = elementToRename.getType();
|
||||
myDefaultType = SmartTypePointerManager.getInstance(project).createSmartTypePointer(defaultType);
|
||||
|
||||
setExprMarker(exprMarker);
|
||||
setOccurrenceMarkers(occurrenceMarkers);
|
||||
final PsiDeclarationStatement declarationStatement = PsiTreeUtil.getParentOfType(elementToRename, PsiDeclarationStatement.class);
|
||||
myPointer = declarationStatement != null ? SmartPointerManager.getInstance(project).createSmartPsiElementPointer(declarationStatement) : null;
|
||||
editor.putUserData(ReassignVariableUtil.DECLARATION_KEY, myPointer);
|
||||
editor.putUserData(ReassignVariableUtil.OCCURRENCES_KEY,
|
||||
occurrenceMarkers.toArray(new RangeMarker[occurrenceMarkers.size()]));
|
||||
if (occurrenceMarkers != null) {
|
||||
editor.putUserData(ReassignVariableUtil.OCCURRENCES_KEY,
|
||||
occurrenceMarkers.toArray(new RangeMarker[occurrenceMarkers.size()]));
|
||||
}
|
||||
myExpression = expression;
|
||||
final PsiType defaultType = elementToRename.getType();
|
||||
myDefaultType = SmartTypePointerManager.getInstance(project).createSmartTypePointer(defaultType);
|
||||
setAdvertisementText(getAdvertisementText(declarationStatement, defaultType, hasTypeSuggestion));
|
||||
}
|
||||
|
||||
@@ -118,39 +98,6 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer {
|
||||
myExpressionText = text;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addAdditionalVariables(TemplateBuilderImpl builder) {
|
||||
final PsiTypeElement typeElement = myElementToRename.getTypeElement();
|
||||
builder.replaceElement(typeElement, "Variable_Type", createExpression(myExpression, typeElement.getText()), true, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LookupElement[] createLookupItems(LookupElement[] lookupItems, String name) {
|
||||
TemplateState templateState = TemplateManagerImpl.getTemplateState(myEditor);
|
||||
final PsiVariable psiVariable = getVariable();
|
||||
if (psiVariable != null) {
|
||||
final TextResult insertedValue =
|
||||
templateState != null ? templateState.getVariableValue(PRIMARY_VARIABLE_NAME) : null;
|
||||
if (insertedValue != null) {
|
||||
final String text = insertedValue.getText();
|
||||
if (!text.isEmpty() && !Comparing.strEqual(text, name)) {
|
||||
final LinkedHashSet<String> names = new LinkedHashSet<String>();
|
||||
names.add(text);
|
||||
for (NameSuggestionProvider provider : Extensions.getExtensions(NameSuggestionProvider.EP_NAME)) {
|
||||
provider.getSuggestedNames(psiVariable, psiVariable, names);
|
||||
}
|
||||
final LookupElement[] items = new LookupElement[names.size()];
|
||||
final Iterator<String> iterator = names.iterator();
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
items[i] = LookupElementBuilder.create(iterator.next());
|
||||
}
|
||||
return items;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.createLookupItems(lookupItems, name);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected PsiVariable getVariable() {
|
||||
final PsiDeclarationStatement declarationStatement = myPointer.getElement();
|
||||
@@ -161,29 +108,6 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TextRange preserveSelectedRange(SelectionModel selectionModel) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performInplaceRename(boolean processTextOccurrences, LinkedHashSet<String> nameSuggestions) {
|
||||
final boolean result = super.performInplaceRename(processTextOccurrences, nameSuggestions);
|
||||
if (result) {
|
||||
showBalloon();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public RangeMarker getExprMarker() {
|
||||
return myExprMarker;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean performAutomaticRename() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void moveOffsetAfter(boolean success) {
|
||||
try {
|
||||
@@ -196,7 +120,8 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer {
|
||||
LOG.assertTrue(psiVariable.isValid());
|
||||
saveSettings(psiVariable);
|
||||
adjustLine(psiVariable, document);
|
||||
int startOffset = myExprMarker != null && myExprMarker.isValid() ? myExprMarker.getStartOffset() : psiVariable.getTextOffset();
|
||||
|
||||
int startOffset = getExprMarker() != null && getExprMarker().isValid() ? getExprMarker().getStartOffset() : psiVariable.getTextOffset();
|
||||
final PsiFile file = psiVariable.getContainingFile();
|
||||
final PsiReference referenceAt = file.findReferenceAt(startOffset);
|
||||
if (referenceAt != null && referenceAt.resolve() instanceof PsiVariable) {
|
||||
@@ -213,13 +138,13 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer {
|
||||
if (psiVariable.getInitializer() != null) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
appendTypeCasts(myOccurrenceMarkers, file, myProject, psiVariable);
|
||||
appendTypeCasts(getOccurrenceMarkers(), file, myProject, psiVariable);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (myExprMarker != null) {
|
||||
myEditor.getCaretModel().moveToOffset(myExprMarker.getStartOffset());
|
||||
if (getExprMarker() != null) {
|
||||
myEditor.getCaretModel().moveToOffset(getExprMarker().getStartOffset());
|
||||
myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
|
||||
}
|
||||
if (myExpressionText != null) {
|
||||
@@ -231,8 +156,9 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer {
|
||||
if (vars.length > 0 && vars[0] instanceof PsiVariable) {
|
||||
final PsiFile containingFile = element.getContainingFile();
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
|
||||
for (RangeMarker occurrenceMarker : myOccurrenceMarkers) {
|
||||
if (restoreExpression(containingFile, (PsiVariable)vars[0], elementFactory, occurrenceMarker, myExpressionText) == null) return;
|
||||
for (RangeMarker occurrenceMarker : getOccurrenceMarkers()) {
|
||||
if (AbstractJavaInplaceIntroducer
|
||||
.restoreExpression(containingFile, (PsiVariable)vars[0], elementFactory, occurrenceMarker, myExpressionText) == null) return;
|
||||
}
|
||||
element.delete();
|
||||
}
|
||||
@@ -244,23 +170,17 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer {
|
||||
}
|
||||
finally {
|
||||
myEditor.putUserData(ReassignVariableUtil.DECLARATION_KEY, null);
|
||||
for (RangeMarker occurrenceMarker : myOccurrenceMarkers) {
|
||||
for (RangeMarker occurrenceMarker : getOccurrenceMarkers()) {
|
||||
occurrenceMarker.dispose();
|
||||
}
|
||||
myEditor.putUserData(ReassignVariableUtil.OCCURRENCES_KEY, null);
|
||||
if (myExprMarker != null) myExprMarker.dispose();
|
||||
if (getExprMarker() != null) getExprMarker().dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
super.finish();
|
||||
if (myBalloon != null) myBalloon.hide();
|
||||
}
|
||||
|
||||
protected void saveSettings(PsiVariable psiVariable) {
|
||||
JavaRefactoringSettings.getInstance().INTRODUCE_LOCAL_CREATE_FINALS = psiVariable.hasModifierProperty(PsiModifier.FINAL);
|
||||
TypeSelectorManagerImpl.typeSelected(psiVariable.getType(), myDefaultType.getType());
|
||||
JavaRefactoringSettings.getInstance().INTRODUCE_LOCAL_CREATE_FINALS = psiVariable.hasModifierProperty(PsiModifier.FINAL);
|
||||
}
|
||||
|
||||
|
||||
@@ -270,7 +190,19 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer {
|
||||
myCanBeFinalCb = new NonFocusableCheckBox("Declare final");
|
||||
myCanBeFinalCb.setSelected(createFinals());
|
||||
myCanBeFinalCb.setMnemonic('f');
|
||||
myCanBeFinalCb.addActionListener(new FinalListener(myProject, myCommandName));
|
||||
final FinalListener finalListener = new FinalListener(myEditor);
|
||||
myCanBeFinalCb.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
new WriteCommandAction(myProject, IntroduceVariableBase.REFACTORING_NAME, IntroduceVariableBase.REFACTORING_NAME) {
|
||||
@Override
|
||||
protected void run(com.intellij.openapi.application.Result result) throws Throwable {
|
||||
PsiDocumentManager.getInstance(myProject).commitDocument(myEditor.getDocument());
|
||||
finalListener.perform(myCanBeFinalCb.isSelected(), getVariable());
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@@ -286,27 +218,39 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer {
|
||||
return panel;
|
||||
}
|
||||
|
||||
protected void addAdditionalVariables(TemplateBuilderImpl builder) {
|
||||
final PsiTypeElement typeElement = getVariable().getTypeElement();
|
||||
builder.replaceElement(typeElement, "Variable_Type", AbstractJavaInplaceIntroducer.createExpression(myExpression, typeElement.getText()), true, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCommandName() {
|
||||
return IntroduceVariableBase.REFACTORING_NAME;
|
||||
}
|
||||
|
||||
private static void appendTypeCasts(List<RangeMarker> occurrenceMarkers,
|
||||
PsiFile file,
|
||||
Project project,
|
||||
@Nullable PsiVariable psiVariable) {
|
||||
for (RangeMarker occurrenceMarker : occurrenceMarkers) {
|
||||
final PsiElement refVariableElement = file.findElementAt(occurrenceMarker.getStartOffset());
|
||||
final PsiReferenceExpression referenceExpression = PsiTreeUtil.getParentOfType(refVariableElement, PsiReferenceExpression.class);
|
||||
if (referenceExpression != null) {
|
||||
final PsiElement parent = referenceExpression.getParent();
|
||||
if (parent instanceof PsiVariable) {
|
||||
createCastInVariableDeclaration(project, (PsiVariable)parent);
|
||||
}
|
||||
else if (parent instanceof PsiReferenceExpression && psiVariable != null) {
|
||||
final PsiExpression initializer = psiVariable.getInitializer();
|
||||
LOG.assertTrue(initializer != null);
|
||||
final PsiType type = initializer.getType();
|
||||
if (((PsiReferenceExpression)parent).resolve() == null && type != null) {
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
|
||||
final PsiExpression castedExpr =
|
||||
elementFactory.createExpressionFromText("((" + type.getCanonicalText() + ")" + referenceExpression.getText() + ")", parent);
|
||||
JavaCodeStyleManager.getInstance(project).shortenClassReferences(referenceExpression.replace(castedExpr));
|
||||
if (occurrenceMarkers != null) {
|
||||
for (RangeMarker occurrenceMarker : occurrenceMarkers) {
|
||||
final PsiElement refVariableElement = file.findElementAt(occurrenceMarker.getStartOffset());
|
||||
final PsiReferenceExpression referenceExpression = PsiTreeUtil.getParentOfType(refVariableElement, PsiReferenceExpression.class);
|
||||
if (referenceExpression != null) {
|
||||
final PsiElement parent = referenceExpression.getParent();
|
||||
if (parent instanceof PsiVariable) {
|
||||
createCastInVariableDeclaration(project, (PsiVariable)parent);
|
||||
}
|
||||
else if (parent instanceof PsiReferenceExpression && psiVariable != null) {
|
||||
final PsiExpression initializer = psiVariable.getInitializer();
|
||||
LOG.assertTrue(initializer != null);
|
||||
final PsiType type = initializer.getType();
|
||||
if (((PsiReferenceExpression)parent).resolve() == null && type != null) {
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
|
||||
final PsiExpression castedExpr =
|
||||
elementFactory.createExpressionFromText("((" + type.getCanonicalText() + ")" + referenceExpression.getText() + ")", parent);
|
||||
JavaCodeStyleManager.getInstance(project).shortenClassReferences(referenceExpression.replace(castedExpr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -350,29 +294,6 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Expression createExpression(final TypeExpression expression, final String defaultType) {
|
||||
return new Expression() {
|
||||
@Override
|
||||
public Result calculateResult(ExpressionContext context) {
|
||||
return new TextResult(defaultType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result calculateQuickResult(ExpressionContext context) {
|
||||
return new TextResult(defaultType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LookupElement[] calculateLookupItems(ExpressionContext context) {
|
||||
return expression.calculateLookupItems(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAdvertisingText() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected boolean createFinals() {
|
||||
return IntroduceVariableBase.createFinals(myProject);
|
||||
@@ -396,97 +317,16 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer {
|
||||
return myTitle;
|
||||
}
|
||||
|
||||
private void showBalloon() {
|
||||
final JComponent component = getComponent();
|
||||
if (component == null) return;
|
||||
if (ApplicationManager.getApplication().isHeadlessEnvironment()) return;
|
||||
final BalloonBuilder balloonBuilder = JBPopupFactory.getInstance().createBalloonBuilder(component);
|
||||
balloonBuilder.setFadeoutTime(0)
|
||||
.setFillColor(UIManager.getColor("Panel.background"))
|
||||
.setAnimationCycle(100)
|
||||
.setHideOnClickOutside(false)
|
||||
.setHideOnKeyOutside(false)
|
||||
.setHideOnAction(false)
|
||||
.setCloseButtonEnabled(true)
|
||||
.setTitle(getTitle());
|
||||
|
||||
final RelativePoint target = JBPopupFactory.getInstance().guessBestPopupLocation(myEditor);
|
||||
final Point screenPoint = target.getScreenPoint();
|
||||
myBalloon = balloonBuilder.createBalloon();
|
||||
int y = screenPoint.y;
|
||||
if (target.getPoint().getY() > myEditor.getLineHeight() + myBalloon.getPreferredSize().getHeight()) {
|
||||
y -= myEditor.getLineHeight();
|
||||
}
|
||||
myBalloon.show(new RelativePoint(new Point(screenPoint.x, y)), Balloon.Position.above);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected static PsiExpression restoreExpression(PsiFile containingFile,
|
||||
PsiVariable psiVariable,
|
||||
PsiElementFactory elementFactory,
|
||||
RangeMarker marker, String exprText) {
|
||||
if (exprText == null) return null;
|
||||
if (psiVariable == null || !psiVariable.isValid()) return null;
|
||||
final PsiElement refVariableElement = containingFile.findElementAt(marker.getStartOffset());
|
||||
final PsiExpression expression = PsiTreeUtil.getParentOfType(refVariableElement, PsiReferenceExpression.class);
|
||||
if (expression instanceof PsiReferenceExpression && (((PsiReferenceExpression)expression).resolve() == psiVariable ||
|
||||
Comparing.strEqual(psiVariable.getName(), ((PsiReferenceExpression)expression).getReferenceName()))) {
|
||||
return (PsiExpression)expression.replace(elementFactory.createExpressionFromText(exprText, psiVariable));
|
||||
}
|
||||
return expression != null && expression.isValid() && expression.getText().equals(exprText) ? expression : null;
|
||||
}
|
||||
|
||||
public class FinalListener implements ActionListener {
|
||||
private final Project myProject;
|
||||
private final String myCommandName;
|
||||
|
||||
public FinalListener(Project project, String commandName) {
|
||||
myProject = project;
|
||||
myCommandName = commandName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
perform(myCanBeFinalCb.isSelected());
|
||||
}
|
||||
|
||||
public void perform(final boolean generateFinal) {
|
||||
perform(generateFinal, PsiModifier.FINAL);
|
||||
}
|
||||
|
||||
public void perform(final boolean generateFinal, final String modifier) {
|
||||
new WriteCommandAction(myProject, myCommandName, myCommandName){
|
||||
@Override
|
||||
protected void run(com.intellij.openapi.application.Result result) throws Throwable {
|
||||
final Document document = myEditor.getDocument();
|
||||
PsiDocumentManager.getInstance(getProject()).commitDocument(document);
|
||||
final PsiVariable variable = getVariable();
|
||||
LOG.assertTrue(variable != null);
|
||||
final PsiModifierList modifierList = variable.getModifierList();
|
||||
LOG.assertTrue(modifierList != null);
|
||||
final int textOffset = modifierList.getTextOffset();
|
||||
|
||||
final Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
if (generateFinal) {
|
||||
final PsiTypeElement typeElement = variable.getTypeElement();
|
||||
final int typeOffset = typeElement != null ? typeElement.getTextOffset() : textOffset;
|
||||
document.insertString(typeOffset, modifier + " ");
|
||||
}
|
||||
else {
|
||||
final int idx = modifierList.getText().indexOf(modifier);
|
||||
document.deleteString(textOffset + idx, textOffset + idx + modifier.length() + 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
final LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(myEditor);
|
||||
if (lookup != null) {
|
||||
lookup.performGuardedChange(runnable);
|
||||
} else {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
private static String getAdvertisementText(final boolean hasTypeSuggestion) {
|
||||
final Keymap keymap = KeymapManager.getInstance().getActiveKeymap();
|
||||
if (hasTypeSuggestion) {
|
||||
final Shortcut[] shortcuts = keymap.getShortcuts("PreviousTemplateVariable");
|
||||
if (shortcuts.length > 0) {
|
||||
return "Press " + shortcuts[0] + " to change type";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
class Test {
|
||||
void simpleMethod() {
|
||||
System.out.println("<caret>");
|
||||
System.out.println("");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class Test {
|
||||
void simpleMethod() {
|
||||
boolean b<caret>b;
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
class Test {
|
||||
|
||||
void simpleMethod() {
|
||||
boolean <caret>bb;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
class Test {
|
||||
|
||||
void simpleMethod() {
|
||||
System.out.println(<caret>"");
|
||||
System.out.println("");
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,6 @@ import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
|
||||
import com.intellij.codeInsight.template.impl.TemplateState;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
|
||||
import com.intellij.openapi.util.Pass;
|
||||
import com.intellij.psi.PsiExpression;
|
||||
import com.intellij.psi.PsiLocalVariable;
|
||||
@@ -92,6 +91,46 @@ public class InplaceIntroduceFieldTest extends LightCodeInsightTestCase {
|
||||
});
|
||||
}
|
||||
|
||||
public void testEscapePosition() throws Exception {
|
||||
doTestEscape();
|
||||
}
|
||||
|
||||
public void testEscapePositionOnLocal() throws Exception {
|
||||
doTestEscape();
|
||||
}
|
||||
|
||||
private void doTestEscape() throws Exception {
|
||||
String name = getTestName(true);
|
||||
configureByFile(BASE_PATH + name + ".java");
|
||||
final boolean enabled = getEditor().getSettings().isVariableInplaceRenameEnabled();
|
||||
TemplateManagerImpl templateManager = (TemplateManagerImpl)TemplateManager.getInstance(getProject());
|
||||
try {
|
||||
templateManager.setTemplateTesting(true);
|
||||
getEditor().getSettings().setVariableInplaceRenameEnabled(true);
|
||||
|
||||
final MyIntroduceFieldHandler introduceFieldHandler = new MyIntroduceFieldHandler();
|
||||
final PsiExpression expression =
|
||||
PsiTreeUtil.getParentOfType(getFile().findElementAt(getEditor().getCaretModel().getOffset()), PsiExpression.class);
|
||||
if (expression != null) {
|
||||
introduceFieldHandler.invokeImpl(getProject(), expression, getEditor());
|
||||
} else {
|
||||
final PsiLocalVariable localVariable =
|
||||
PsiTreeUtil.getParentOfType(getFile().findElementAt(getEditor().getCaretModel().getOffset()), PsiLocalVariable.class);
|
||||
assertNotNull(localVariable);
|
||||
introduceFieldHandler.invokeImpl(getProject(), localVariable, getEditor());
|
||||
}
|
||||
TemplateState state = TemplateManagerImpl.getTemplateState(getEditor());
|
||||
assert state != null;
|
||||
state.gotoEnd(true);
|
||||
checkResultByFile(BASE_PATH + name + "_after.java");
|
||||
}
|
||||
finally {
|
||||
myEditor.getSettings().setVariableInplaceRenameEnabled(enabled);
|
||||
templateManager.setTemplateTesting(false);
|
||||
InplaceIntroduceFieldPopup.setInitializationPlace(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void doTest(final Pass<InplaceIntroduceFieldPopup> pass) throws Exception {
|
||||
String name = getTestName(true);
|
||||
|
||||
+15
-5
@@ -90,12 +90,12 @@ public class VariableInplaceRenamer {
|
||||
"com.intellij.rename.inplace.resolveSnapshotProvider"
|
||||
);
|
||||
|
||||
private final PsiNamedElement myElementToRename;
|
||||
private PsiNamedElement myElementToRename;
|
||||
@NonNls protected static final String PRIMARY_VARIABLE_NAME = "PrimaryVariable";
|
||||
@NonNls private static final String OTHER_VARIABLE_NAME = "OtherVariable";
|
||||
private ArrayList<RangeHighlighter> myHighlighters;
|
||||
private final Editor myEditor;
|
||||
private final Project myProject;
|
||||
protected final Editor myEditor;
|
||||
protected final Project myProject;
|
||||
private RangeMarker myRenameOffset;
|
||||
|
||||
public void setAdvertisementText(String advertisementText) {
|
||||
@@ -107,10 +107,16 @@ public class VariableInplaceRenamer {
|
||||
private static final Stack<VariableInplaceRenamer> ourRenamersStack = new Stack<VariableInplaceRenamer>();
|
||||
|
||||
public VariableInplaceRenamer(@NotNull PsiNamedElement elementToRename, Editor editor) {
|
||||
this(elementToRename, editor, elementToRename.getProject());
|
||||
}
|
||||
|
||||
public VariableInplaceRenamer(PsiNamedElement elementToRename,
|
||||
Editor editor,
|
||||
Project project) {
|
||||
myElementToRename = elementToRename;
|
||||
myEditor = /*(editor instanceof EditorWindow)? ((EditorWindow)editor).getDelegate() : */editor;
|
||||
myProject = myElementToRename.getProject();
|
||||
myRenameOffset = myEditor.getDocument().createRangeMarker(myElementToRename.getTextRange());
|
||||
myProject = project;
|
||||
myRenameOffset = myElementToRename != null ? myEditor.getDocument().createRangeMarker(myElementToRename.getTextRange()) : null;
|
||||
}
|
||||
|
||||
public boolean performInplaceRename() {
|
||||
@@ -393,6 +399,10 @@ public class VariableInplaceRenamer {
|
||||
}
|
||||
}
|
||||
|
||||
public void setElementToRename(PsiNamedElement elementToRename) {
|
||||
myElementToRename = elementToRename;
|
||||
}
|
||||
|
||||
private static VirtualFile getTopLevelVirtualFile(final FileViewProvider fileViewProvider) {
|
||||
VirtualFile file = fileViewProvider.getVirtualFile();
|
||||
if (file instanceof VirtualFileWindow) file = ((VirtualFileWindow)file).getDelegate();
|
||||
|
||||
Reference in New Issue
Block a user