From 5436cbad013bc0542b53f82391613df6915e26f8 Mon Sep 17 00:00:00 2001 From: anna Date: Tue, 1 Mar 2011 16:58:08 +0100 Subject: [PATCH 1/4] inplace introduce parameter: move occurrences chooser to balloon --- .../InplaceIntroduceParameterPopup.java | 170 +++++++++++------- .../IntroduceParameterDialog.java | 62 +------ .../IntroduceParameterHandler.java | 26 +-- .../IntroduceParameterSettingsUI.java | 66 ++++++- 4 files changed, 196 insertions(+), 128 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java index 895aa80e2892..cce7d69e081a 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java @@ -17,6 +17,8 @@ package com.intellij.refactoring.introduceParameter; import com.intellij.codeInsight.highlighting.HighlightManager; 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.IdeTooltipManager; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; @@ -33,17 +35,17 @@ import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.*; 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.search.searches.ReferencesSearch; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.JavaRefactoringSettings; -import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.introduceVariable.OccurrencesChooser; import com.intellij.refactoring.introduceVariable.VariableInplaceIntroducer; import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer; -import com.intellij.refactoring.ui.NameSuggestionsGenerator; +import com.intellij.refactoring.ui.TypeSelectorManager; import com.intellij.refactoring.ui.TypeSelectorManagerImpl; -import com.intellij.ui.NonFocusableCheckBox; import com.intellij.ui.awt.RelativePoint; import com.intellij.usageView.UsageInfo; import gnu.trove.TIntArrayList; @@ -61,30 +63,30 @@ import java.util.List; * Date: 2/25/11 */ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { - private JCheckBox myDelegateCb; private Balloon myBalloon; private final Project myProject; private final Editor myEditor; private final TypeSelectorManagerImpl myTypeSelectorManager; - private final NameSuggestionsGenerator myNameSuggestionsGenerator; - private final PsiExpression myExpr; + private PsiExpression myExpr; private final PsiLocalVariable myLocalVar; private final PsiMethod myMethod; private final PsiMethod myMethodToSearchFor; private final PsiExpression[] myOccurrences; private final boolean myMustBeFinal; - private final RangeMarker myExprMarker; - private final List myOccurrenceMarkers; + private RangeMarker myExprMarker; + private List myOccurrenceMarkers; private final JPanel myWholePanel; + private int myParameterIndex = -1; + private String myParameterName; + private final String myExprText; InplaceIntroduceParameterPopup(final Project project, final Editor editor, final List classMemberRefs, final TypeSelectorManagerImpl typeSelectorManager, - final NameSuggestionsGenerator nameSuggestionsGenerator, final PsiExpression expr, final PsiLocalVariable localVar, final PsiMethod method, @@ -96,7 +98,6 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { myProject = project; myEditor = editor; myTypeSelectorManager = typeSelectorManager; - myNameSuggestionsGenerator = nameSuggestionsGenerator; myExpr = expr; myLocalVar = localVar; myMethod = method; @@ -104,14 +105,17 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { myOccurrences = occurrences; myMustBeFinal = mustBeFinal; myExprMarker = expr != null ? myEditor.getDocument().createRangeMarker(myExpr.getTextRange()) : null; - myOccurrenceMarkers = new ArrayList(); + myExprText = myExpr != null ? myExpr.getText() : null; myWholePanel = new JPanel(new GridBagLayout()); myWholePanel.setBorder(BorderFactory.createTitledBorder(IntroduceParameterHandler.REFACTORING_NAME)); - myDelegateCb = new NonFocusableCheckBox(RefactoringBundle.message("delegation.panel.delegate.via.overloading.method")); final GridBagConstraints gc = new GridBagConstraints(0, 0, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 0), 0, 0); - myWholePanel.add(myDelegateCb, gc); + + if (myOccurrences.length > 1 && !myIsInvokedOnDeclaration) { + gc.gridy++; + createOccurrencesCb(gc, myWholePanel, myOccurrences.length); + } final JavaRefactoringSettings settings = JavaRefactoringSettings.getInstance(); createLocalVariablePanel(gc, myWholePanel, settings); createRemoveParamsPanel(gc, myWholePanel); @@ -119,52 +123,51 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { gc.gridy++; myWholePanel.add(createReplaceFieldsWithGettersPanel(), gc); } + gc.gridy++; + createDelegateCb(gc, myWholePanel); } void inplaceIntroduceParameter() { - final LinkedHashMap occurrencesMap = - new LinkedHashMap(); - - for (PsiExpression occurrence : myOccurrences) { - myOccurrenceMarkers.add(myEditor.getDocument().createRangeMarker(occurrence.getTextRange())); - } - - OccurrencesChooser.fillChoices(myExpr, myOccurrences, occurrencesMap); - new OccurrencesChooser(myEditor).showChooser(new IntroduceParameterPass(), occurrencesMap); + new IntroduceParameterPass().pass(OccurrencesChooser.ReplaceChoice.NO); } @Override - protected void updateControls(JCheckBox[] removeParamsCb) { + protected TypeSelectorManager getTypeSelectionManager() { + return myTypeSelectorManager; + } + + private PsiParameter getParameter() { + return myMethod.getParameterList().getParameters()[myParameterIndex]; + } + + public List getOccurrenceMarkers() { + if (myOccurrenceMarkers == null) { + myOccurrenceMarkers = new ArrayList(); + for (PsiExpression occurrence : myOccurrences) { + myOccurrenceMarkers.add(myEditor.getDocument().createRangeMarker(occurrence.getTextRange())); + } + } + return myOccurrenceMarkers; } private class ParameterInplaceIntroducer extends VariableInplaceIntroducer { - private String myParameterName; + private SmartTypePointer myParameterTypePointer; private SmartTypePointer myDefaultParameterTypePointer; - private final PsiParameter myParameter; - private int myParameterIndex; - private PsiExpression myExpression; - private final OccurrencesChooser.ReplaceChoice myReplaceChoice; private boolean myFinal; - private final String myExprText; - public ParameterInplaceIntroducer(PsiParameter parameter, - OccurrencesChooser.ReplaceChoice replaceChoice) { + public ParameterInplaceIntroducer(PsiParameter parameter) { super(myProject, new TypeExpression(myProject, myTypeSelectorManager.getTypesForAll()), myEditor, parameter, myMustBeFinal, - myTypeSelectorManager.getTypesForAll().length > 1, myExprMarker, myOccurrenceMarkers); - myParameter = parameter; - myReplaceChoice = replaceChoice; - myExprText = myExpr != null ? myExpr.getText() : null; - myParameterIndex = myMethod.getParameterList().getParameterIndex(myParameter); + myTypeSelectorManager.getTypesForAll().length > 1, myExprMarker, getOccurrenceMarkers()); myDefaultParameterTypePointer = SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(parameter.getType()); } @Override protected PsiVariable getVariable() { - return myMethod.getParameterList().getParameters()[myParameterIndex]; + return getParameter(); } @Override @@ -184,8 +187,12 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { @Override protected void collectAdditionalElementsToRename(boolean processTextOccurrences, List> stringUsages) { - for (PsiExpression expression : myOccurrences) { - stringUsages.add(Pair.create(expression, new TextRange(0, expression.getTextLength()))); + if (isReplaceAllOccurences()) { + for (PsiExpression expression : myOccurrences) { + stringUsages.add(Pair.create(expression, new TextRange(0, expression.getTextLength()))); + } + } else if (myExpr != null){ + stringUsages.add(Pair.create(myExpr, new TextRange(0, myExpr.getTextLength()))); } } @@ -202,9 +209,15 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { @NotNull HighlightManager highlightManager) { final TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES); - for (RangeMarker marker : myOccurrenceMarkers) { - final int startOffset = marker.getStartOffset(); - highlightManager.addOccurrenceHighlight(editor, startOffset, startOffset + myParameter.getName().length(), attributes, 0, highlighters, null); + final int variableNameLength = getVariable().getName().length(); + if (isReplaceAllOccurences()) { + for (RangeMarker marker : getOccurrenceMarkers()) { + final int startOffset = marker.getStartOffset(); + highlightManager.addOccurrenceHighlight(editor, startOffset, startOffset + variableNameLength, attributes, 0, highlighters, null); + } + } else if (myExpr != null) { + final int startOffset = myExprMarker.getStartOffset(); + highlightManager.addOccurrenceHighlight(editor, startOffset, startOffset + variableNameLength, attributes, 0, highlighters, null); } super.addHighlights(ranges, editor, highlighters, highlightManager); } @@ -222,7 +235,7 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { if (success) { boolean isDeleteLocalVariable = false; - PsiExpression parameterInitializer = myExpression; + PsiExpression parameterInitializer = myExpr; if (myLocalVar != null) { if (isUseInitializer()) { parameterInitializer = myLocalVar.getInitializer(); @@ -233,10 +246,10 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { final IntroduceParameterProcessor processor = new IntroduceParameterProcessor(myProject, myMethod, - myMethodToSearchFor, parameterInitializer, myExpression, + myMethodToSearchFor, parameterInitializer, myExpr, myLocalVar, isDeleteLocalVariable, myParameterName, - myReplaceChoice == OccurrencesChooser.ReplaceChoice.ALL, - getReplaceFieldsWithGetters(), myMustBeFinal || myFinal, myDelegateCb.isSelected(), + isReplaceAllOccurences(), + getReplaceFieldsWithGetters(), myMustBeFinal || myFinal, isGenerateDelegate(), myParameterTypePointer.getType(), parametersToRemove); processor.setPrepareSuccessfulSwingThreadCallback(new Runnable() { @@ -268,35 +281,50 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { public void finish() { super.finish(); myBalloon.hide(); - final PsiParameter psiParameter = myMethod.getParameterList().getParameters()[myParameterIndex]; - myParameterName = psiParameter.getName(); + final PsiParameter psiParameter = (PsiParameter)getVariable(); + LOG.assertTrue(psiParameter != null); myFinal = psiParameter.hasModifierProperty(PsiModifier.FINAL); myParameterTypePointer = SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(psiParameter.getType()); PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + myParameterName = psiParameter.getName(); ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { final PsiFile containingFile = myMethod.getContainingFile(); final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject); - myExpression = restoreExpression(containingFile, elementFactory, myExprMarker); - for (RangeMarker marker : myOccurrenceMarkers) { - if (myExprMarker != null && marker.getStartOffset() == myExprMarker.getStartOffset()) continue; - restoreExpression(containingFile, elementFactory, marker); + myExpr = restoreExpression(containingFile, psiParameter, elementFactory, myExprMarker); + if (myExpr != null) { + myExprMarker = myEditor.getDocument().createRangeMarker(myExpr.getTextRange()); } + final List 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); + if (psiExpression != null) { + myOccurrences[i] = psiExpression; + } + } + myOccurrenceMarkers = null; if (psiParameter.isValid()) { psiParameter.delete(); } } }); - } @Nullable - private PsiExpression restoreExpression(PsiFile containingFile, PsiElementFactory elementFactory, RangeMarker marker) { + private PsiExpression restoreExpression(PsiFile containingFile, + PsiParameter psiParameter, + PsiElementFactory elementFactory, + RangeMarker marker) { if (myExprText == null) return null; - if (myParameter == null || !myParameter.isValid()) return null; + if (psiParameter == null || !psiParameter.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() == myParameter) { + if (expression instanceof PsiReferenceExpression && ((PsiReferenceExpression)expression).resolve() == psiParameter) { return (PsiExpression)expression.replace(elementFactory.createExpressionFromText(myExprText, myMethod)); } return null; @@ -313,6 +341,17 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { return createFinals == null ? CodeStyleSettingsManager.getSettings(myProject).GENERATE_FINAL_PARAMETERS : createFinals.booleanValue(); } + @Override + protected void updateControls(JCheckBox[] removeParamsCb) { + super.updateControls(removeParamsCb); + if (myParameterIndex < 0) return; + final TemplateState templateState = TemplateManagerImpl.getTemplateState(myEditor); + if (templateState != null) { + templateState.gotoEnd(true); + new IntroduceParameterPass().pass(isReplaceAllOccurences() ? OccurrencesChooser.ReplaceChoice.ALL : OccurrencesChooser.ReplaceChoice.NO); + } + } + private class IntroduceParameterPass extends Pass { @Override @@ -321,14 +360,20 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { public void run() { myTypeSelectorManager.setAllOccurences(replaceChoice != OccurrencesChooser.ReplaceChoice.NO); final PsiType defaultType = myTypeSelectorManager.getTypeSelector().getSelectedType(); - final String[] names = myNameSuggestionsGenerator.getSuggestedNameInfo(defaultType).names; + final String propName = myLocalVar != null ? JavaCodeStyleManager + .getInstance(myProject).variableNameToPropertyName(myLocalVar.getName(), VariableKind.LOCAL_VARIABLE) : null; + final String[] names = IntroduceParameterHandler.createNameSuggestionGenerator(myExpr, propName) + .getSuggestedNameInfo(defaultType).names; final PsiParameter parameter = createParameterToStartTemplateOn(names, defaultType); if (parameter != null) { + myParameterIndex = myMethod.getParameterList().getParameterIndex(parameter); myEditor.getCaretModel().moveToOffset(parameter.getTextOffset()); showSettingsPopup(); - final VariableInplaceRenamer renamer = - new ParameterInplaceIntroducer(parameter, replaceChoice); - renamer.performInplaceRename(false, new LinkedHashSet(Arrays.asList(names))); + final LinkedHashSet nameSuggestions = new LinkedHashSet(); + nameSuggestions.add(parameter.getName()); + nameSuggestions.addAll(Arrays.asList(names)); + final VariableInplaceRenamer renamer = new ParameterInplaceIntroducer(parameter); + renamer.performInplaceRename(false, nameSuggestions); } } }, IntroduceParameterHandler.REFACTORING_NAME, null); @@ -340,9 +385,10 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { return ApplicationManager.getApplication().runWriteAction(new Computable() { @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(names[0], defaultType), - JavaIntroduceParameterMethodUsagesProcessor.getAnchorParameter(myMethod)); + .addAfter(elementFactory.createParameter(name, defaultType), anchor); PsiUtil.setModifierProperty(psiParameter, PsiModifier.FINAL, hasFinalModifier()); return psiParameter; } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterDialog.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterDialog.java index 8876e3826590..5d4186ae438c 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterDialog.java @@ -40,8 +40,6 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; import java.util.List; public class IntroduceParameterDialog extends RefactoringDialog { @@ -60,8 +58,7 @@ public class IntroduceParameterDialog extends RefactoringDialog { // private JComponent myParameterNameField = null; private NameSuggestionsField myParameterNameField; - private JCheckBox myCbReplaceAllOccurences = null; - private JCheckBox myCbGenerateDelegate = null; + private final NameSuggestionsGenerator myNameSuggestionsGenerator; private final TypeSelectorManager myTypeSelectorManager; @@ -106,13 +103,7 @@ public class IntroduceParameterDialog extends RefactoringDialog { return myCbDeclareFinal != null && myCbDeclareFinal.isSelected(); } - private boolean isReplaceAllOccurences() { - return myPanel.myIsInvokedOnDeclaration || myCbReplaceAllOccurences != null && myCbReplaceAllOccurences.isSelected(); - } - private boolean isGenerateDelegate() { - return myCbGenerateDelegate != null && myCbGenerateDelegate.isSelected(); - } private String getParameterName() { return myParameterNameField.getEnteredName().trim(); @@ -196,11 +187,7 @@ public class IntroduceParameterDialog extends RefactoringDialog { gbConstraints.gridwidth = 2; if (myOccurenceNumber > 1 && !myPanel.myIsInvokedOnDeclaration) { gbConstraints.gridy++; - myCbReplaceAllOccurences = new NonFocusableCheckBox(); - myCbReplaceAllOccurences.setText(RefactoringBundle.message("replace.all.occurences", myOccurenceNumber)); - - panel.add(myCbReplaceAllOccurences, gbConstraints); - myCbReplaceAllOccurences.setSelected(false); + myPanel.createOccurrencesCb(gbConstraints, panel, myOccurenceNumber); } JavaRefactoringSettings settings = JavaRefactoringSettings.getInstance(); @@ -218,31 +205,19 @@ public class IntroduceParameterDialog extends RefactoringDialog { myCbDeclareFinal.setEnabled(false); } - if(myCbReplaceAllOccurences != null) { + if(myPanel.myCbReplaceAllOccurences != null) { gbConstraints.insets = new Insets(0, 16, 4, 8); } myPanel.createLocalVariablePanel(gbConstraints, panel, settings); gbConstraints.insets = new Insets(4, 0, 4, 8); gbConstraints.gridy++; - myCbGenerateDelegate = new NonFocusableCheckBox(RefactoringBundle.message("delegation.panel.delegate.via.overloading.method")); - panel.add(myCbGenerateDelegate, gbConstraints); + myPanel.createDelegateCb(gbConstraints, panel); - final JCheckBox[] removeParamsCb = myPanel.createRemoveParamsPanel(gbConstraints, panel); - if (myCbReplaceAllOccurences != null) { - myCbReplaceAllOccurences.addItemListener( - new ItemListener() { - public void itemStateChanged(ItemEvent e) { - myPanel.updateControls(removeParamsCb); - } - } - ); - } return panel; } - protected JComponent createCenterPanel() { if(Util.anyFieldsWithGettersPresent(myClassMembersList)) { return myPanel.createReplaceFieldsWithGettersPanel(); @@ -276,8 +251,8 @@ public class IntroduceParameterDialog extends RefactoringDialog { myProject, myMethodToReplaceIn, myMethodToSearchFor, parameterInitializer, myExpression, myLocalVar, isDeleteLocalVariable, - getParameterName(), isReplaceAllOccurences(), - myPanel.getReplaceFieldsWithGetters(), isDeclareFinal(), isGenerateDelegate(), getSelectedType(), myPanel.getParametersToRemove()); + getParameterName(), myPanel.isReplaceAllOccurences(), + myPanel.getReplaceFieldsWithGetters(), isDeclareFinal(), myPanel.isGenerateDelegate(), getSelectedType(), myPanel.getParametersToRemove()); invokeRefactoring(processor); myParameterNameField.requestFocusInWindow(); } @@ -299,29 +274,10 @@ public class IntroduceParameterDialog extends RefactoringDialog { super(project, onLocalVariable, onExpression, methodToReplaceIn, parametersToRemove); } + @Override - protected void updateControls(JCheckBox[] removeParamsCb) { - if (myCbReplaceAllOccurences != null) { - for (JCheckBox box : removeParamsCb) { - if (box != null) { - box.setEnabled(myCbReplaceAllOccurences.isSelected()); - } - } - myTypeSelectorManager.setAllOccurences(myCbReplaceAllOccurences.isSelected()); - if (myCbReplaceAllOccurences.isSelected()) { - if (myCbDeleteLocalVariable != null) { - myCbDeleteLocalVariable.makeSelectable(); - } - } - else { - if (myCbDeleteLocalVariable != null) { - myCbDeleteLocalVariable.makeUnselectable(false); - } - } - } - else { - myTypeSelectorManager.setAllOccurences(myIsInvokedOnDeclaration); - } + protected TypeSelectorManager getTypeSelectionManager() { + return myTypeSelectorManager; } } } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java index 64e08642e02d..76cf915b1d26 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java @@ -196,15 +196,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R ? new TypeSelectorManagerImpl(project, initializerType, expr, occurences) : new TypeSelectorManagerImpl(project, initializerType, occurences); - NameSuggestionsGenerator nameSuggestionsGenerator = new NameSuggestionsGenerator() { - public SuggestedNameInfo getSuggestedNameInfo(PsiType type) { - final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(myProject); - final SuggestedNameInfo info = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, propName, expr, type); - final String[] strings = JavaCompletionUtil.completeVariableNameForRefactoring(codeStyleManager, type, VariableKind.LOCAL_VARIABLE, info); - return new SuggestedNameInfo.Delegate(strings, info); - } - - }; + NameSuggestionsGenerator nameSuggestionsGenerator = createNameSuggestionGenerator(expr, propName); boolean isInplaceAvailableOnDataContext = editor != null && editor.getSettings().isVariableInplaceRenameEnabled() && method == methodToSearchFor && method.hasModifierProperty(PsiModifier.PRIVATE); @@ -220,7 +212,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R } } else { new InplaceIntroduceParameterPopup(project, editor, classMemberRefs, - typeSelectorManager, nameSuggestionsGenerator, + typeSelectorManager, expr, localVar, method, methodToSearchFor, occurences, parametersToRemove, mustBeFinal).inplaceIntroduceParameter(); } @@ -228,6 +220,20 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R return true; } + protected static NameSuggestionsGenerator createNameSuggestionGenerator(final PsiExpression expr, + final String propName) { + return new NameSuggestionsGenerator() { + public SuggestedNameInfo getSuggestedNameInfo(PsiType type) { + final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(expr.getProject()); + final SuggestedNameInfo info = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, propName, expr, type); + final String[] strings = JavaCompletionUtil + .completeVariableNameForRefactoring(codeStyleManager, type, VariableKind.LOCAL_VARIABLE, info); + return new SuggestedNameInfo.Delegate(strings, info); + } + + }; + } + private static void showErrorMessage(Project project, String message, Editor editor) { CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.INTRODUCE_PARAMETER); } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterSettingsUI.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterSettingsUI.java index a82a481b7f12..21fee109fade 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterSettingsUI.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterSettingsUI.java @@ -24,6 +24,7 @@ import com.intellij.refactoring.IntroduceParameterRefactoring; import com.intellij.refactoring.JavaRefactoringSettings; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.ui.RefactoringDialog; +import com.intellij.refactoring.ui.TypeSelectorManager; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.NonFocusableCheckBox; import com.intellij.ui.StateRestoringCheckBox; @@ -34,6 +35,8 @@ import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; /** * User: anna @@ -53,6 +56,9 @@ public abstract class IntroduceParameterSettingsUI { protected final boolean[] myParametersToRemoveChecked; protected final boolean myIsLocalVariable; + protected JCheckBox myCbReplaceAllOccurences = null; + private JCheckBox myCbGenerateDelegate = null; + public IntroduceParameterSettingsUI(Project project, PsiLocalVariable onLocalVariable, PsiExpression onExpression, @@ -97,6 +103,14 @@ public abstract class IntroduceParameterSettingsUI { return IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE; } + public boolean isReplaceAllOccurences() { + return myIsInvokedOnDeclaration || myCbReplaceAllOccurences != null && myCbReplaceAllOccurences.isSelected(); + } + + public boolean isGenerateDelegate() { + return myCbGenerateDelegate != null && myCbGenerateDelegate.isSelected(); + } + protected JPanel createReplaceFieldsWithGettersPanel() { JPanel radioButtonPanel = new JPanel(new GridBagLayout()); @@ -169,9 +183,33 @@ public abstract class IntroduceParameterSettingsUI { return parameters; } - protected abstract void updateControls(JCheckBox[] removeParamsCb); + protected void updateControls(JCheckBox[] removeParamsCb) { + if (myCbReplaceAllOccurences != null) { + for (JCheckBox box : removeParamsCb) { + if (box != null) { + box.setEnabled(myCbReplaceAllOccurences.isSelected()); + } + } + getTypeSelectionManager().setAllOccurences(myCbReplaceAllOccurences.isSelected()); + if (myCbReplaceAllOccurences.isSelected()) { + if (myCbDeleteLocalVariable != null) { + myCbDeleteLocalVariable.makeSelectable(); + } + } + else { + if (myCbDeleteLocalVariable != null) { + myCbDeleteLocalVariable.makeUnselectable(false); + } + } + } + else { + getTypeSelectionManager().setAllOccurences(myIsInvokedOnDeclaration); + } + } - protected JCheckBox[] createRemoveParamsPanel(GridBagConstraints gbConstraints, JPanel panel) { + protected abstract TypeSelectorManager getTypeSelectionManager(); + + protected void createRemoveParamsPanel(GridBagConstraints gbConstraints, JPanel panel) { final JCheckBox[] removeParamsCb = new JCheckBox[myParametersToRemove.length]; for (int i = 0; i < myParametersToRemove.length; i++) { PsiParameter parameter = myParametersToRemove[i]; @@ -192,7 +230,15 @@ public abstract class IntroduceParameterSettingsUI { } updateControls(removeParamsCb); - return removeParamsCb; + if (myCbReplaceAllOccurences != null) { + myCbReplaceAllOccurences.addItemListener( + new ItemListener() { + public void itemStateChanged(ItemEvent e) { + updateControls(removeParamsCb); + } + } + ); + } } protected void createLocalVariablePanel(GridBagConstraints gbConstraints, JPanel panel, JavaRefactoringSettings settings) { @@ -216,4 +262,18 @@ public abstract class IntroduceParameterSettingsUI { } } } + + + protected void createDelegateCb(GridBagConstraints gbConstraints, JPanel panel) { + myCbGenerateDelegate = new NonFocusableCheckBox(RefactoringBundle.message("delegation.panel.delegate.via.overloading.method")); + panel.add(myCbGenerateDelegate, gbConstraints); + } + + protected void createOccurrencesCb(GridBagConstraints gbConstraints, JPanel panel, final int occurenceNumber) { + myCbReplaceAllOccurences = new NonFocusableCheckBox(); + myCbReplaceAllOccurences.setText(RefactoringBundle.message("replace.all.occurences", occurenceNumber)); + + panel.add(myCbReplaceAllOccurences, gbConstraints); + myCbReplaceAllOccurences.setSelected(false); + } } From 703612fcc7297f71002258e6bf776ffd1820c581 Mon Sep 17 00:00:00 2001 From: anna Date: Tue, 1 Mar 2011 20:21:08 +0100 Subject: [PATCH 2/4] inplace introduce parameter: choose methods to introduce parameters in popup --- .../BaseExpressionToFieldHandler.java | 10 +- .../IntroduceParameterDialog.java | 2 +- .../IntroduceParameterHandler.java | 303 +++++++++++++----- 3 files changed, 229 insertions(+), 86 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java index f203196b8d56..f99ae678c7c5 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java @@ -28,6 +28,7 @@ import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInsight.ChangeContextUtil; import com.intellij.codeInsight.TestUtil; import com.intellij.codeInsight.highlighting.HighlightManager; +import com.intellij.codeInsight.lookup.LookupManager; import com.intellij.ide.util.DirectoryChooserUtil; import com.intellij.ide.util.PackageUtil; import com.intellij.openapi.application.ApplicationManager; @@ -552,15 +553,18 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase public void pass(final ElementToWorkOn elementToWorkOn) { if (elementToWorkOn == null) return; + final boolean hasRunTemplate = LookupManager.getActiveLookup(editor) == null; if (elementToWorkOn.getExpression() == null) { final PsiLocalVariable localVariable = elementToWorkOn.getLocalVariable(); - final boolean result = invokeImpl(project, localVariable, editor); + final boolean result = invokeImpl(project, localVariable, editor) && hasRunTemplate; if (result) { editor.getSelectionModel().removeSelection(); } } - else if (invokeImpl(project, elementToWorkOn.getExpression(), editor)) { - editor.getSelectionModel().removeSelection(); + else { + if (invokeImpl(project, elementToWorkOn.getExpression(), editor) && hasRunTemplate) { + editor.getSelectionModel().removeSelection(); + } } } }; diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterDialog.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterDialog.java index 5d4186ae438c..828e93793032 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterDialog.java @@ -209,7 +209,7 @@ public class IntroduceParameterDialog extends RefactoringDialog { gbConstraints.insets = new Insets(0, 16, 4, 8); } myPanel.createLocalVariablePanel(gbConstraints, panel, settings); - + myPanel.createRemoveParamsPanel(gbConstraints, panel); gbConstraints.insets = new Insets(4, 0, 4, 8); gbConstraints.gridy++; myPanel.createDelegateCb(gbConstraints, panel); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java index 76cf915b1d26..1a8665a108d2 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java @@ -32,8 +32,16 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; 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.*; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.popup.*; +import com.intellij.openapi.ui.popup.util.BaseListPopupStep; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Pass; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.psi.*; import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.codeStyle.SuggestedNameInfo; @@ -41,17 +49,28 @@ import com.intellij.psi.codeStyle.VariableKind; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.*; import com.intellij.refactoring.introduceField.ElementToWorkOn; +import com.intellij.refactoring.ui.MethodCellRenderer; import com.intellij.refactoring.ui.NameSuggestionsGenerator; 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; import gnu.trove.TIntArrayList; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; import java.util.*; import java.util.List; @@ -60,6 +79,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.introduceParameter.IntroduceParameterHandler"); static final String REFACTORING_NAME = RefactoringBundle.message("introduce.parameter.title"); private Project myProject; + private JBPopup myEnclosingMethodsPopup; public void invoke(@NotNull final Project project, final Editor editor, PsiFile file, DataContext dataContext) { PsiDocumentManager.getInstance(project).commitAllDocuments(); @@ -86,7 +106,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R return invoke(editor, project, null, localVariable, true); } - private boolean invoke(Editor editor, Project project, final PsiExpression expr, + private boolean invoke(final Editor editor, final Project project, final PsiExpression expr, PsiLocalVariable localVar, boolean invokedOnDeclaration) { LOG.assertTrue(!PsiDocumentManager.getInstance(project).hasUncommitedDocuments()); PsiMethod method; @@ -131,95 +151,108 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R return false; } - method = chooseEnclosingMethod(method); - if (method == null) return false; - - final PsiMethod methodToSearchFor = SuperMethodWarningUtil.checkSuperMethod(method, RefactoringBundle.message("to.refactor")); - if (methodToSearchFor == null) return false; - if (!CommonRefactoringUtil.checkReadOnlyStatus(project, methodToSearchFor)) return false; - - PsiExpression[] occurences; - if (expr != null) { - occurences = new ExpressionOccurenceManager(expr, method, null).findExpressionOccurrences(); + final List validEnclosingMethods = getEnclosingMethods(method); + if (validEnclosingMethods.isEmpty()) { + return false; } - else { // local variable - occurences = CodeInsightUtil.findReferenceExpressions(method, localVar); - } - PsiExpression expressionToRemoveParamFrom = expr; - if (expr == null) { - expressionToRemoveParamFrom = localVar.getInitializer(); - } - TIntArrayList parametersToRemove = expressionToRemoveParamFrom == null ? new TIntArrayList() : Util.findParametersToRemove(method, expressionToRemoveParamFrom, occurences); - - boolean mustBeFinal = false; - if (localVar != null) { - for(PsiExpression occurrence: occurences) { - if (PsiTreeUtil.getParentOfType(occurrence, PsiClass.class, PsiMethod.class) != method) { - mustBeFinal = true; - break; - } + final Introducer introducer = new Introducer(project, expr, localVar, editor); + final boolean unitTestMode = ApplicationManager.getApplication().isUnitTestMode(); + if (validEnclosingMethods.size() == 1 || unitTestMode) { + if (validEnclosingMethods.get(0).findDeepestSuperMethod() == null || unitTestMode) { + introducer.introduceParameter(method, method); + return true; } } - List localVars = new ArrayList(); - List classMemberRefs = new ArrayList(); - List params = new ArrayList(); + chooseMethodToIntroduceParameter(editor, validEnclosingMethods, introducer); - - if (expr != null) { - Util.analyzeExpression(expr, localVars, classMemberRefs, params); - } - - if (expr instanceof PsiReferenceExpression) { - PsiElement resolved = ((PsiReferenceExpression) expr).resolve(); - if (resolved instanceof PsiLocalVariable) { - localVar = (PsiLocalVariable) resolved; - } - } - - - if (ApplicationManager.getApplication().isUnitTestMode()) { - @NonNls String parameterName = "anObject"; - boolean replaceAllOccurences = true; - boolean isDeleteLocalVariable = true; - PsiExpression initializer = localVar != null && expr == null ? localVar.getInitializer() : expr; - new IntroduceParameterProcessor(myProject, method, methodToSearchFor, initializer, expr, localVar, isDeleteLocalVariable, parameterName, - replaceAllOccurences, IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, mustBeFinal, - false, null, - parametersToRemove).run(); - } - else { - final String propName = localVar != null ? JavaCodeStyleManager.getInstance(myProject).variableNameToPropertyName(localVar.getName(), VariableKind.LOCAL_VARIABLE) : null; - final PsiType initializerType = IntroduceParameterProcessor.getInitializerType(null, expr, localVar); - - TypeSelectorManagerImpl typeSelectorManager = expr != null - ? new TypeSelectorManagerImpl(project, initializerType, expr, occurences) - : new TypeSelectorManagerImpl(project, initializerType, occurences); - - NameSuggestionsGenerator nameSuggestionsGenerator = createNameSuggestionGenerator(expr, propName); - boolean isInplaceAvailableOnDataContext = editor != null && editor.getSettings().isVariableInplaceRenameEnabled() - && method == methodToSearchFor - && method.hasModifierProperty(PsiModifier.PRIVATE); - - if (!isInplaceAvailableOnDataContext) { - if (editor != null) { - RefactoringUtil.highlightAllOccurences(myProject, occurences, editor); - } - new IntroduceParameterDialog(myProject, classMemberRefs, occurences.length, localVar, expr, nameSuggestionsGenerator, - typeSelectorManager, methodToSearchFor, method, parametersToRemove, mustBeFinal).show(); - if (editor != null) { - editor.getSelectionModel().removeSelection(); - } - } else { - new InplaceIntroduceParameterPopup(project, editor, classMemberRefs, - typeSelectorManager, - expr, localVar, method, methodToSearchFor, occurences, parametersToRemove, - mustBeFinal).inplaceIntroduceParameter(); - } - } return true; } + private void chooseMethodToIntroduceParameter(final Editor editor, + final List validEnclosingMethods, + final Introducer introducer) { + final JPanel panel = new JPanel(new BorderLayout()); + panel.setBorder(IdeBorderFactory.createRoundedBorder()); + final JCheckBox superMethod = new JCheckBox("Choose base method", true); + superMethod.setMnemonic('b'); + panel.add(superMethod, BorderLayout.SOUTH); + final JBList list = new JBList(validEnclosingMethods.toArray()); + list.setCellRenderer(new MethodCellRenderer()); + list.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + list.setSelectedIndex(0); + final List highlighters = new ArrayList(); + final TextAttributes attributes = + EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES); + list.addListSelectionListener(new ListSelectionListener() { + public void valueChanged(final ListSelectionEvent e) { + final PsiMethod selectedMethod = (PsiMethod)list.getSelectedValue(); + if (selectedMethod == null) return; + dropHighlighters(highlighters); + updateView(selectedMethod, editor, attributes, highlighters, superMethod); + } + }); + updateView(validEnclosingMethods.get(0), editor, attributes, highlighters, superMethod); + panel.add(ScrollPaneFactory.createScrollPane(list), BorderLayout.CENTER); + + final List> + keyboardActions = Collections.singletonList(Pair.create(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + final PsiMethod methodToSearchIn = (PsiMethod)list.getSelectedValue(); + if (myEnclosingMethodsPopup != null && myEnclosingMethodsPopup.isVisible()) { + myEnclosingMethodsPopup.cancel(); + } + + final PsiMethod methodToSearchFor = superMethod.isEnabled() && superMethod.isSelected() + ? methodToSearchIn.findDeepestSuperMethod() : methodToSearchIn; + Runnable runnable = new Runnable() { + public void run() { + introducer.introduceParameter(methodToSearchIn, methodToSearchFor); + } + }; + IdeFocusManager.findInstance().doWhenFocusSettlesDown(runnable); + } + }, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0))); + myEnclosingMethodsPopup = JBPopupFactory.getInstance().createComponentPopupBuilder(panel, list) + .setTitle("Introduce parameter to method") + .setMovable(false) + .setResizable(false) + .setRequestFocus(true) + .setKeyboardActions(keyboardActions).addListener(new JBPopupAdapter() { + @Override + public void onClosed(LightweightWindowEvent event) { + dropHighlighters(highlighters); + } + }).createPopup(); + myEnclosingMethodsPopup.showInBestPositionFor(editor); + } + + private static void updateView(PsiMethod selectedMethod, + Editor editor, + TextAttributes attributes, + List highlighters, + JCheckBox superMethod) { + final MarkupModel markupModel = editor.getMarkupModel(); + final PsiIdentifier nameIdentifier = selectedMethod.getNameIdentifier(); + if (nameIdentifier != null) { + final TextRange textRange = nameIdentifier.getTextRange(); + final RangeHighlighter rangeHighlighter = markupModel.addRangeHighlighter( + textRange.getStartOffset(), textRange.getEndOffset(), HighlighterLayer.SELECTION - 1, + attributes, + HighlighterTargetArea.EXACT_RANGE); + highlighters.add(rangeHighlighter); + } + superMethod.setEnabled(selectedMethod.findDeepestSuperMethod() != null); + } + + private static void dropHighlighters(List highlighters) { + for (RangeHighlighter highlighter : highlighters) { + highlighter.dispose(); + } + highlighters.clear(); + } + protected static NameSuggestionsGenerator createNameSuggestionGenerator(final PsiExpression expr, final String propName) { return new NameSuggestionsGenerator() { @@ -291,4 +324,110 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R private static boolean isLibraryInterfaceMethod(final PsiMethod method) { return method.hasModifierProperty(PsiModifier.ABSTRACT) && !method.getManager().isInProject(method); } + + private static class Introducer { + + private final Project myProject; + + private final PsiExpression myExpr; + private PsiLocalVariable myLocalVar; + private final Editor myEditor; + + public Introducer(Project project, + PsiExpression expr, + PsiLocalVariable localVar, + Editor editor) { + myProject = project; + myExpr = expr; + myLocalVar = localVar; + myEditor = editor; + } + + public void introduceParameter(PsiMethod method, PsiMethod methodToSearchFor) { + if (!CommonRefactoringUtil.checkReadOnlyStatus(myProject, methodToSearchFor)) return; + + PsiExpression[] occurences; + if (myExpr != null) { + occurences = new ExpressionOccurenceManager(myExpr, method, null).findExpressionOccurrences(); + } + else { // local variable + occurences = CodeInsightUtil.findReferenceExpressions(method, myLocalVar); + } + PsiExpression expressionToRemoveParamFrom = myExpr; + if (myExpr == null) { + expressionToRemoveParamFrom = myLocalVar.getInitializer(); + } + TIntArrayList parametersToRemove = expressionToRemoveParamFrom == null ? new TIntArrayList() : Util + .findParametersToRemove(method, expressionToRemoveParamFrom, occurences); + + boolean mustBeFinal = false; + if (myLocalVar != null) { + for(PsiExpression occurrence: occurences) { + if (PsiTreeUtil.getParentOfType(occurrence, PsiClass.class, PsiMethod.class) != method) { + mustBeFinal = true; + break; + } + } + } + + List localVars = new ArrayList(); + List classMemberRefs = new ArrayList(); + List params = new ArrayList(); + + + if (myExpr != null) { + Util.analyzeExpression(myExpr, localVars, classMemberRefs, params); + } + + if (myExpr instanceof PsiReferenceExpression) { + PsiElement resolved = ((PsiReferenceExpression)myExpr).resolve(); + if (resolved instanceof PsiLocalVariable) { + myLocalVar = (PsiLocalVariable) resolved; + } + } + + + if (ApplicationManager.getApplication().isUnitTestMode()) { + @NonNls String parameterName = "anObject"; + boolean replaceAllOccurences = true; + boolean isDeleteLocalVariable = true; + PsiExpression initializer = myLocalVar != null && myExpr == null ? myLocalVar.getInitializer() : myExpr; + new IntroduceParameterProcessor(myProject, method, methodToSearchFor, initializer, myExpr, myLocalVar, isDeleteLocalVariable, parameterName, + replaceAllOccurences, IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, mustBeFinal, + false, null, + parametersToRemove).run(); + } + else { + final String propName = myLocalVar != null ? JavaCodeStyleManager + .getInstance(myProject).variableNameToPropertyName(myLocalVar.getName(), VariableKind.LOCAL_VARIABLE) : null; + final PsiType initializerType = IntroduceParameterProcessor.getInitializerType(null, myExpr, myLocalVar); + + TypeSelectorManagerImpl typeSelectorManager = myExpr != null + ? new TypeSelectorManagerImpl(myProject, initializerType, myExpr, occurences) + : new TypeSelectorManagerImpl(myProject, initializerType, occurences); + + NameSuggestionsGenerator nameSuggestionsGenerator = createNameSuggestionGenerator(myExpr, propName); + boolean isInplaceAvailableOnDataContext = myEditor != null && myEditor.getSettings().isVariableInplaceRenameEnabled(); + + if (!isInplaceAvailableOnDataContext) { + if (myEditor != null) { + RefactoringUtil.highlightAllOccurences(myProject, occurences, myEditor); + } + new IntroduceParameterDialog(myProject, classMemberRefs, occurences.length, myLocalVar, myExpr, nameSuggestionsGenerator, + typeSelectorManager, methodToSearchFor, method, parametersToRemove, mustBeFinal).show(); + if (myEditor != null) { + myEditor.getSelectionModel().removeSelection(); + } + } + else { + new InplaceIntroduceParameterPopup(myProject, myEditor, classMemberRefs, + typeSelectorManager, + myExpr, myLocalVar, method, methodToSearchFor, occurences, parametersToRemove, + mustBeFinal).inplaceIntroduceParameter(); + } + } + } + } + + } From 92696623d4cd47f80d960db7d402eb4e2581027e Mon Sep 17 00:00:00 2001 From: anna Date: Tue, 1 Mar 2011 21:17:20 +0100 Subject: [PATCH 3/4] NPE --- .../InplaceIntroduceParameterPopup.java | 2 +- .../introduceParameter/IntroduceParameterHandler.java | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java index cce7d69e081a..468109d654fb 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java @@ -362,7 +362,7 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { 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) + final String[] names = IntroduceParameterHandler.createNameSuggestionGenerator(myExpr, propName, myProject) .getSuggestedNameInfo(defaultType).names; final PsiParameter parameter = createParameterToStartTemplateOn(names, defaultType); if (parameter != null) { diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java index 1a8665a108d2..463b38926bd7 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java @@ -26,7 +26,6 @@ package com.intellij.refactoring.introduceParameter; import com.intellij.codeInsight.CodeInsightUtil; import com.intellij.codeInsight.completion.JavaCompletionUtil; -import com.intellij.ide.util.SuperMethodWarningUtil; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; @@ -37,7 +36,6 @@ import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.markup.*; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.*; -import com.intellij.openapi.ui.popup.util.BaseListPopupStep; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Pass; import com.intellij.openapi.util.TextRange; @@ -254,10 +252,11 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R } protected static NameSuggestionsGenerator createNameSuggestionGenerator(final PsiExpression expr, - final String propName) { + final String propName, + final Project project) { return new NameSuggestionsGenerator() { public SuggestedNameInfo getSuggestedNameInfo(PsiType type) { - final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(expr.getProject()); + final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project); final SuggestedNameInfo info = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, propName, expr, type); final String[] strings = JavaCompletionUtil .completeVariableNameForRefactoring(codeStyleManager, type, VariableKind.LOCAL_VARIABLE, info); @@ -277,7 +276,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R /* do nothing */ } - private static List getEnclosingMethods(PsiMethod nearest) { + public static List getEnclosingMethods(PsiMethod nearest) { List enclosingMethods = new ArrayList(); enclosingMethods.add(nearest); PsiMethod method = nearest; @@ -406,7 +405,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R ? new TypeSelectorManagerImpl(myProject, initializerType, myExpr, occurences) : new TypeSelectorManagerImpl(myProject, initializerType, occurences); - NameSuggestionsGenerator nameSuggestionsGenerator = createNameSuggestionGenerator(myExpr, propName); + NameSuggestionsGenerator nameSuggestionsGenerator = createNameSuggestionGenerator(myExpr, propName, myProject); boolean isInplaceAvailableOnDataContext = myEditor != null && myEditor.getSettings().isVariableInplaceRenameEnabled(); if (!isInplaceAvailableOnDataContext) { From de8ae316f5e5cc79e48dd2a603e7871cbe414453 Mon Sep 17 00:00:00 2001 From: anna Date: Tue, 1 Mar 2011 21:36:05 +0100 Subject: [PATCH 4/4] inplace introduce parameter: cleanup --- .../InplaceIntroduceParameterPopup.java | 121 +++++++++--------- 1 file changed, 59 insertions(+), 62 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java index 468109d654fb..b94db818fdaf 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java @@ -41,7 +41,6 @@ import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.JavaRefactoringSettings; -import com.intellij.refactoring.introduceVariable.OccurrencesChooser; import com.intellij.refactoring.introduceVariable.VariableInplaceIntroducer; import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer; import com.intellij.refactoring.ui.TypeSelectorManager; @@ -129,7 +128,31 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { void inplaceIntroduceParameter() { - new IntroduceParameterPass().pass(OccurrencesChooser.ReplaceChoice.NO); + startIntroduceTemplate(false); + } + + private void startIntroduceTemplate(final boolean replaceAllOccurrences) { + 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); + if (parameter != null) { + myParameterIndex = myMethod.getParameterList().getParameterIndex(parameter); + myEditor.getCaretModel().moveToOffset(parameter.getTextOffset()); + showBalloon(); + final LinkedHashSet nameSuggestions = new LinkedHashSet(); + nameSuggestions.add(parameter.getName()); + nameSuggestions.addAll(Arrays.asList(names)); + final VariableInplaceRenamer renamer = new ParameterInplaceIntroducer(parameter); + renamer.performInplaceRename(false, nameSuggestions); + } + } + }, IntroduceParameterHandler.REFACTORING_NAME, null); } @Override @@ -191,7 +214,8 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { for (PsiExpression expression : myOccurrences) { stringUsages.add(Pair.create(expression, new TextRange(0, expression.getTextLength()))); } - } else if (myExpr != null){ + } + else if (myExpr != null) { stringUsages.add(Pair.create(myExpr, new TextRange(0, myExpr.getTextLength()))); } } @@ -215,7 +239,8 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { final int startOffset = marker.getStartOffset(); highlightManager.addOccurrenceHighlight(editor, startOffset, startOffset + variableNameLength, attributes, 0, highlighters, null); } - } else if (myExpr != null) { + } + else if (myExpr != null) { final int startOffset = myExprMarker.getStartOffset(); highlightManager.addOccurrenceHighlight(editor, startOffset, startOffset + variableNameLength, attributes, 0, highlighters, null); } @@ -276,7 +301,6 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { } - @Override public void finish() { super.finish(); @@ -348,67 +372,40 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI { final TemplateState templateState = TemplateManagerImpl.getTemplateState(myEditor); if (templateState != null) { templateState.gotoEnd(true); - new IntroduceParameterPass().pass(isReplaceAllOccurences() ? OccurrencesChooser.ReplaceChoice.ALL : OccurrencesChooser.ReplaceChoice.NO); + startIntroduceTemplate(isReplaceAllOccurences()); } } - private class IntroduceParameterPass extends Pass { - @Override - public void pass(final OccurrencesChooser.ReplaceChoice replaceChoice) { - CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { - public void run() { - myTypeSelectorManager.setAllOccurences(replaceChoice != OccurrencesChooser.ReplaceChoice.NO); - 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); - if (parameter != null) { - myParameterIndex = myMethod.getParameterList().getParameterIndex(parameter); - myEditor.getCaretModel().moveToOffset(parameter.getTextOffset()); - showSettingsPopup(); - final LinkedHashSet nameSuggestions = new LinkedHashSet(); - nameSuggestions.add(parameter.getName()); - nameSuggestions.addAll(Arrays.asList(names)); - final VariableInplaceRenamer renamer = new ParameterInplaceIntroducer(parameter); - renamer.performInplaceRename(false, nameSuggestions); - } - } - }, IntroduceParameterHandler.REFACTORING_NAME, null); - } + private PsiParameter createParameterToStartTemplateOn(final String[] names, + final PsiType defaultType) { + final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myMethod.getProject()); + return ApplicationManager.getApplication().runWriteAction(new Computable() { + @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; + } + }); + } - private PsiParameter createParameterToStartTemplateOn(final String[] names, - final PsiType defaultType) { - final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myMethod.getProject()); - return ApplicationManager.getApplication().runWriteAction(new Computable() { - @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; - } - }); - } - - private void showSettingsPopup() { - BalloonBuilder balloonBuilder = JBPopupFactory.getInstance().createBalloonBuilder(myWholePanel); - balloonBuilder.setFadeoutTime(0); - balloonBuilder.setFillColor(IdeTooltipManager.GRAPHITE_COLOR); - balloonBuilder.setAnimationCycle(0); - balloonBuilder.setHideOnClickOutside(false); - balloonBuilder.setHideOnKeyOutside(false); - balloonBuilder.setHideOnAction(false); - balloonBuilder.setCloseButtonEnabled(true); - final RelativePoint target = JBPopupFactory.getInstance().guessBestPopupLocation(myEditor); - final Point screenPoint = target.getScreenPoint(); - myBalloon = balloonBuilder.createBalloon(); - myBalloon - .show(new RelativePoint(new Point(screenPoint.x, screenPoint.y - myEditor.getLineHeight())), Balloon.Position.above); - } + private void showBalloon() { + final BalloonBuilder balloonBuilder = JBPopupFactory.getInstance().createBalloonBuilder(myWholePanel); + balloonBuilder.setFadeoutTime(0); + balloonBuilder.setFillColor(IdeTooltipManager.GRAPHITE_COLOR); + balloonBuilder.setAnimationCycle(0); + balloonBuilder.setHideOnClickOutside(false); + balloonBuilder.setHideOnKeyOutside(false); + balloonBuilder.setHideOnAction(false); + balloonBuilder.setCloseButtonEnabled(true); + final RelativePoint target = JBPopupFactory.getInstance().guessBestPopupLocation(myEditor); + final Point screenPoint = target.getScreenPoint(); + myBalloon = balloonBuilder.createBalloon(); + myBalloon + .show(new RelativePoint(new Point(screenPoint.x, screenPoint.y - myEditor.getLineHeight())), Balloon.Position.above); } }