diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java index c0814e770a24..48887b6057a8 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java @@ -1,514 +1,516 @@ -/* - * Copyright 2000-2012 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.extractMethod; - -import com.intellij.ide.highlighter.JavaFileType; -import com.intellij.openapi.editor.event.DocumentAdapter; -import com.intellij.openapi.editor.event.DocumentEvent; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.Splitter; -import com.intellij.openapi.ui.VerticalFlowLayout; -import com.intellij.psi.*; -import com.intellij.psi.util.PsiFormatUtil; -import com.intellij.psi.util.PsiUtil; -import com.intellij.refactoring.RefactoringBundle; -import com.intellij.refactoring.ui.ComboBoxVisibilityPanel; -import com.intellij.refactoring.ui.ConflictsDialog; -import com.intellij.refactoring.ui.JavaComboBoxVisibilityPanel; -import com.intellij.refactoring.ui.MethodSignatureComponent; -import com.intellij.refactoring.util.ConflictsUtil; -import com.intellij.refactoring.util.ParameterTablePanel; -import com.intellij.ui.EditorTextField; -import com.intellij.ui.IdeBorderFactory; -import com.intellij.ui.NonFocusableCheckBox; -import com.intellij.ui.SeparatorFactory; -import com.intellij.util.IncorrectOperationException; -import com.intellij.util.VisibilityUtil; -import com.intellij.util.containers.MultiMap; -import com.intellij.util.ui.UIUtil; -import org.jetbrains.annotations.NonNls; - -import javax.swing.*; -import javax.swing.border.Border; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import java.awt.*; -import java.awt.event.*; -import java.util.Arrays; - - -/** - * @author Konstantin Bulenkov - */ -@SuppressWarnings("MethodMayBeStatic") -public class ExtractMethodDialog extends AbstractExtractDialog { - private final Project myProject; - private final PsiType myReturnType; - private final PsiTypeParameterList myTypeParameterList; - private final PsiType[] myExceptions; - private final boolean myStaticFlag; - private boolean myCanBeStatic; - private final PsiElement[] myElementsToExtract; - private final String myHelpId; - - private final EditorTextField myNameField; - private final MethodSignatureComponent mySignature; - private final JCheckBox myMakeStatic; - protected JCheckBox myMakeVarargs; - private JCheckBox myCbChainedConstructor; - - private final InputVariables myVariableData; - private final PsiClass myTargetClass; - private ComboBoxVisibilityPanel myVisibilityPanel; - - private boolean myDefaultVisibility = true; - private boolean myChangingVisibility; - - private final JCheckBox myFoldParameters = new NonFocusableCheckBox(RefactoringBundle.message("declare.folded.parameters")); - public JPanel myCenterPanel; - public JPanel myParamTable; - private ParameterTablePanel.VariableData[] myInputVariables; - - public ExtractMethodDialog(Project project, - PsiClass targetClass, final InputVariables inputVariables, PsiType returnType, - PsiTypeParameterList typeParameterList, PsiType[] exceptions, boolean isStatic, boolean canBeStatic, - final boolean canBeChainedConstructor, - String initialMethodName, - String title, - String helpId, - final PsiElement[] elementsToExtract) { - super(project); - myProject = project; - myTargetClass = targetClass; - myReturnType = returnType; - myTypeParameterList = typeParameterList; - myExceptions = exceptions; - myStaticFlag = isStatic; - myCanBeStatic = canBeStatic; - myElementsToExtract = elementsToExtract; - myVariableData = inputVariables; - myHelpId = helpId; - mySignature = new MethodSignatureComponent("", project, JavaFileType.INSTANCE); - mySignature.setPreferredSize(new Dimension(500, 100)); - mySignature.setMinimumSize(new Dimension(500, 100)); - setTitle(title); - - // Create UI components - - myNameField = createNameField(initialMethodName); - - int height = myVariableData.getInputVariables().size() + 2; - if (myExceptions.length > 0) { - height += myExceptions.length + 1; - } - myMakeStatic = new NonFocusableCheckBox(); - myMakeStatic.setText(RefactoringBundle.message("declare.static.checkbox")); - if (canBeChainedConstructor) { - myCbChainedConstructor = new NonFocusableCheckBox(RefactoringBundle.message("extract.chained.constructor.checkbox")); - } - - init(); - } - - protected EditorTextField createNameField(String initialMethodName) { - return new EditorTextField(initialMethodName); - } - - protected boolean areTypesDirected() { - return true; - } - - public boolean isMakeStatic() { - if (myStaticFlag) return true; - return myCanBeStatic && myMakeStatic.isSelected(); - } - - public boolean isChainedConstructor() { - return myCbChainedConstructor != null && myCbChainedConstructor.isSelected(); - } - - protected Action[] createActions() { - if (myHelpId != null) { - return new Action[]{getOKAction(), getCancelAction(), getHelpAction()}; - } else { - return new Action[]{getOKAction(), getCancelAction()}; - } - } - - public String getChosenMethodName() { - return myNameField.getText(); - } - - public ParameterTablePanel.VariableData[] getChosenParameters() { - return myInputVariables; - } - - public JComponent getPreferredFocusedComponent() { - return myNameField; - } - - @Override - protected String getHelpId() { - return myHelpId; - } - - protected void doOKAction() { - MultiMap conflicts = new MultiMap(); - checkMethodConflicts(conflicts); - if (!conflicts.isEmpty()) { - final ConflictsDialog conflictsDialog = new ConflictsDialog(myProject, conflicts); - conflictsDialog.show(); - if (!conflictsDialog.isOK()){ - if (conflictsDialog.isShowConflicts()) close(CANCEL_EXIT_CODE); - return; - } - } - - if (myMakeVarargs != null && myMakeVarargs.isSelected()) { - final ParameterTablePanel.VariableData data = myInputVariables[myInputVariables.length - 1]; - if (data.type instanceof PsiArrayType) { - data.type = new PsiEllipsisType(((PsiArrayType)data.type).getComponentType()); - } - } - super.doOKAction(); - } - - protected JComponent createNorthPanel() { - final JPanel main = new JPanel(new BorderLayout()); - final JPanel namePanel = new JPanel(new VerticalFlowLayout(VerticalFlowLayout.TOP, 0, 2, true, false)); - final JLabel nameLabel = new JLabel(); - nameLabel.setText(RefactoringBundle.message("changeSignature.name.prompt")); - namePanel.add(nameLabel); - namePanel.add(myNameField); - nameLabel.setLabelFor(myNameField); - - myNameField.getDocument().addDocumentListener(new DocumentAdapter() { - public void documentChanged(DocumentEvent e) { - update(); - } - }); - - myVisibilityPanel = createVisibilityPanel(); - final JPanel visibilityAndName = new JPanel(new BorderLayout(2, 0)); - visibilityAndName.add(myVisibilityPanel, BorderLayout.WEST); - visibilityAndName.add(namePanel, BorderLayout.CENTER); - main.add(visibilityAndName, BorderLayout.CENTER); - setOKActionEnabled(false); - - setOKActionEnabled(JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(myNameField.getText())); - final JPanel options = new JPanel(new BorderLayout()); - options.add(createOptionsPanel(), BorderLayout.WEST); - main.add(options, BorderLayout.SOUTH); - return main; - } - - protected JPanel createOptionsPanel() { - final JPanel optionsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 5)); - - //optionsPanel.add(new JLabel("Options: ")); - - if (myStaticFlag || myCanBeStatic) { - myMakeStatic.setEnabled(!myStaticFlag); - myMakeStatic.setSelected(myStaticFlag); - myMakeStatic.addItemListener(new ItemListener() { - public void itemStateChanged(ItemEvent e) { - updateSignature(); - } - }); - optionsPanel.add(myMakeStatic); - } else { - myMakeStatic.setSelected(false); - myMakeStatic.setEnabled(false); - } - final Border emptyBorder = IdeBorderFactory.createEmptyBorder(5, 0, 5, 4); - myMakeStatic.setBorder(emptyBorder); - - myFoldParameters.setSelected(myVariableData.isFoldingSelectedByDefault()); - myFoldParameters.setVisible(myVariableData.isFoldable()); - myVariableData.setFoldingAvailable(myFoldParameters.isSelected()); - myInputVariables = myVariableData.getInputVariables().toArray(new ParameterTablePanel.VariableData[myVariableData.getInputVariables().size()]); - myFoldParameters.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - myVariableData.setFoldingAvailable(myFoldParameters.isSelected()); - myInputVariables = - myVariableData.getInputVariables().toArray(new ParameterTablePanel.VariableData[myVariableData.getInputVariables().size()]); - updateVarargsEnabled(); - createParametersPanel(); - updateSignature(); - } - }); - optionsPanel.add(myFoldParameters); - myFoldParameters.setBorder(emptyBorder); - - boolean canBeVarargs = false; - for (ParameterTablePanel.VariableData data : myInputVariables) { - canBeVarargs |= data.type instanceof PsiArrayType; - } - if (myVariableData.isFoldable()) { - canBeVarargs |= myVariableData.isFoldingSelectedByDefault(); - } - - if (canBeVarargs) { - myMakeVarargs = new NonFocusableCheckBox(RefactoringBundle.message("declare.varargs.checkbox")); - myMakeVarargs.setBorder(emptyBorder); - updateVarargsEnabled(); - myMakeVarargs.addItemListener(new ItemListener() { - public void itemStateChanged(ItemEvent e) { - updateSignature(); - } - }); - myMakeVarargs.setSelected(false); - optionsPanel.add(myMakeVarargs); - } - - if (myCbChainedConstructor != null) { - optionsPanel.add(myCbChainedConstructor); - myCbChainedConstructor.setBorder(emptyBorder); - myCbChainedConstructor.addItemListener(new ItemListener() { - public void itemStateChanged(final ItemEvent e) { - if (myDefaultVisibility) { - myChangingVisibility = true; - try { - if (isChainedConstructor()) { - myVisibilityPanel.setVisibility(VisibilityUtil.getVisibilityModifier(myTargetClass.getModifierList())); - } - else { - myVisibilityPanel.setVisibility(PsiModifier.PRIVATE); - } - } - finally { - myChangingVisibility = false; - } - } - update(); - } - }); - } - return optionsPanel; - } - - private ComboBoxVisibilityPanel createVisibilityPanel() { - final JavaComboBoxVisibilityPanel panel = new JavaComboBoxVisibilityPanel(); - panel.setVisibility(PsiModifier.PRIVATE); - panel.addListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - updateSignature(); - if (!myChangingVisibility) { - myDefaultVisibility = false; - } - } - }); - return panel; - } - - private void updateVarargsEnabled() { - if (myMakeVarargs != null) { - myMakeVarargs.setEnabled(myInputVariables[myInputVariables.length - 1].type instanceof PsiArrayType); - } - } - - private void update() { - myNameField.setEnabled(!isChainedConstructor()); - if (myMakeStatic != null) { - myMakeStatic.setEnabled(!myStaticFlag && myCanBeStatic && !isChainedConstructor()); - } - updateSignature(); - setOKActionEnabled(JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(myNameField.getText()) || - isChainedConstructor()); - } - - public String getVisibility() { - return myVisibilityPanel.getVisibility(); - } - - - protected JComponent createCenterPanel() { - myCenterPanel = new JPanel(new BorderLayout()); - createParametersPanel(); - - final Splitter splitter = new Splitter(true); - splitter.setShowDividerIcon(false); - splitter.setFirstComponent(myCenterPanel); - splitter.setSecondComponent(createSignaturePanel()); - return splitter; - } - - protected boolean isOutputVariable(PsiVariable var) { - return false; - } - - protected void createParametersPanel() { - if (myParamTable != null) { - myCenterPanel.remove(myParamTable); - } - - myParamTable = createParameterTableComponent(); - myParamTable.setMinimumSize(new Dimension(500, 100)); - myCenterPanel.add(myParamTable, BorderLayout.CENTER); - final JTable table = UIUtil.findComponentOfType(myParamTable, JTable.class); - myCenterPanel.add(SeparatorFactory.createSeparator("&Parameters", table), BorderLayout.NORTH); - if (table != null) { - table.addFocusListener(new FocusAdapter() { - @Override - public void focusGained(FocusEvent e) { - if (table.getRowCount() > 0) { - final int col = table.getSelectedColumn(); - final int row = table.getSelectedRow(); - if (col == -1 || row == -1) { - table.getSelectionModel().setSelectionInterval(0, 0); - table.getColumnModel().getSelectionModel().setSelectionInterval(0, 0); - } - } - } - }); - } - } - - protected ParameterTablePanel createParameterTableComponent() { - return new ParameterTablePanel(myProject, myInputVariables, myElementsToExtract) { - protected void updateSignature() { - updateVarargsEnabled(); - ExtractMethodDialog.this.updateSignature(); - } - - protected void doEnterAction() { - clickDefaultButton(); - } - - protected void doCancelAction() { - ExtractMethodDialog.this.doCancelAction(); - } - - protected boolean areTypesDirected() { - return ExtractMethodDialog.this.areTypesDirected(); - } - - @Override - protected boolean isUsedAfter(PsiVariable variable) { - return isOutputVariable(variable); - } - }; - } - - protected JComponent createSignaturePanel() { - final JPanel panel = new JPanel(new BorderLayout()); - panel.add(SeparatorFactory.createSeparator(RefactoringBundle.message("signature.preview.border.title"), null), BorderLayout.NORTH); - panel.add(mySignature, BorderLayout.CENTER); - - updateSignature(); - return panel; - } - - protected void updateSignature() { - if (mySignature != null) { - mySignature.setSignature(getSignature()); - } - } - - protected String getSignature() { - final @NonNls StringBuilder buffer = new StringBuilder(); - final String visibilityString = VisibilityUtil.getVisibilityString(myVisibilityPanel.getVisibility()); - buffer.append(visibilityString); - if (buffer.length() > 0) { - buffer.append(" "); - } - if (isMakeStatic() && !isChainedConstructor()) { - buffer.append("static "); - } - if (myTypeParameterList != null) { - final String typeParamsText = myTypeParameterList.getText(); - if (!typeParamsText.isEmpty()) { - buffer.append(typeParamsText); - buffer.append(" "); - } - } - - if (isChainedConstructor()) { - buffer.append(myTargetClass.getName()); - } - else { - buffer.append(PsiFormatUtil.formatType(myReturnType, 0, PsiSubstitutor.EMPTY)); - buffer.append(" "); - buffer.append(myNameField.getText()); - } - buffer.append("("); - int count = 0; - char[] chars = new char[buffer.toString().length()]; - Arrays.fill(chars, ' '); - - final String INDENT = new String(chars); - - final ParameterTablePanel.VariableData[] datas = myInputVariables; - for (int i = 0; i < datas.length;i++) { - ParameterTablePanel.VariableData data = datas[i]; - if (data.passAsParameter) { - //String typeAndModifiers = PsiFormatUtil.formatVariable(data.variable, - // PsiFormatUtil.SHOW_MODIFIERS | PsiFormatUtil.SHOW_TYPE); - PsiType type = data.type; - if (i == datas.length - 1 && type instanceof PsiArrayType && myMakeVarargs != null && myMakeVarargs.isSelected()) { - type = new PsiEllipsisType(((PsiArrayType)type).getComponentType()); - } - - String typeText = type.getPresentableText(); - if (count > 0) { - buffer.append(",\n"); - buffer.append(INDENT); - } - buffer.append(typeText); - buffer.append(" "); - buffer.append(data.name); - count++; - } - } - buffer.append(")"); - if (myExceptions.length > 0) { - buffer.append("\n"); - buffer.append("throws\n"); - for (PsiType exception : myExceptions) { - buffer.append(INDENT); - buffer.append(PsiFormatUtil.formatType(exception, 0, PsiSubstitutor.EMPTY)); - buffer.append("\n"); - } - } - return buffer.toString(); - } - - @Override - protected String getDimensionServiceKey() { - return "extract.method.dialog"; - } - - protected void checkMethodConflicts(MultiMap conflicts) { - PsiMethod prototype; - try { - PsiElementFactory factory = JavaPsiFacade.getInstance(myProject).getElementFactory(); - prototype = factory.createMethod(myNameField.getText().trim(), myReturnType); - if (myTypeParameterList != null) prototype.getTypeParameterList().replace(myTypeParameterList); - for (ParameterTablePanel.VariableData data : myInputVariables) { - if (data.passAsParameter) { - prototype.getParameterList().add(factory.createParameter(data.name, data.type)); - } - } - // set the modifiers with which the method is supposed to be created - PsiUtil.setModifierProperty(prototype, PsiModifier.PRIVATE, true); - } catch (IncorrectOperationException e) { - return; - } - - ConflictsUtil.checkMethodConflicts(myTargetClass, null, prototype, conflicts); - } -} +/* + * Copyright 2000-2012 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.extractMethod; + +import com.intellij.ide.highlighter.JavaFileType; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Splitter; +import com.intellij.openapi.ui.VerticalFlowLayout; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiFormatUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.ui.ComboBoxVisibilityPanel; +import com.intellij.refactoring.ui.ConflictsDialog; +import com.intellij.refactoring.ui.JavaComboBoxVisibilityPanel; +import com.intellij.refactoring.ui.MethodSignatureComponent; +import com.intellij.refactoring.util.ConflictsUtil; +import com.intellij.refactoring.util.ParameterTablePanel; +import com.intellij.ui.EditorTextField; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.NonFocusableCheckBox; +import com.intellij.ui.SeparatorFactory; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.VisibilityUtil; +import com.intellij.util.containers.MultiMap; +import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NonNls; + +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; +import java.awt.event.*; +import java.util.Arrays; + + +/** + * @author Konstantin Bulenkov + */ +@SuppressWarnings("MethodMayBeStatic") +public class ExtractMethodDialog extends AbstractExtractDialog { + private final Project myProject; + private final PsiType myReturnType; + private final PsiTypeParameterList myTypeParameterList; + private final PsiType[] myExceptions; + private final boolean myStaticFlag; + private boolean myCanBeStatic; + private final PsiElement[] myElementsToExtract; + private final String myHelpId; + + private final EditorTextField myNameField; + private final MethodSignatureComponent mySignature; + private final JCheckBox myMakeStatic; + protected JCheckBox myMakeVarargs; + private JCheckBox myCbChainedConstructor; + + private final InputVariables myVariableData; + private final PsiClass myTargetClass; + private ComboBoxVisibilityPanel myVisibilityPanel; + + private boolean myDefaultVisibility = true; + private boolean myChangingVisibility; + + private final JCheckBox myFoldParameters = new NonFocusableCheckBox(RefactoringBundle.message("declare.folded.parameters")); + public JPanel myCenterPanel; + public JPanel myParamTable; + private ParameterTablePanel.VariableData[] myInputVariables; + + public ExtractMethodDialog(Project project, + PsiClass targetClass, final InputVariables inputVariables, PsiType returnType, + PsiTypeParameterList typeParameterList, PsiType[] exceptions, boolean isStatic, boolean canBeStatic, + final boolean canBeChainedConstructor, + String initialMethodName, + String title, + String helpId, + final PsiElement[] elementsToExtract) { + super(project); + myProject = project; + myTargetClass = targetClass; + myReturnType = returnType; + myTypeParameterList = typeParameterList; + myExceptions = exceptions; + myStaticFlag = isStatic; + myCanBeStatic = canBeStatic; + myElementsToExtract = elementsToExtract; + myVariableData = inputVariables; + myHelpId = helpId; + mySignature = new MethodSignatureComponent("", project, JavaFileType.INSTANCE); + mySignature.setPreferredSize(new Dimension(500, 100)); + mySignature.setMinimumSize(new Dimension(500, 100)); + setTitle(title); + + // Create UI components + + myNameField = createNameField(initialMethodName); + + int height = myVariableData.getInputVariables().size() + 2; + if (myExceptions.length > 0) { + height += myExceptions.length + 1; + } + myMakeStatic = new NonFocusableCheckBox(); + myMakeStatic.setText(RefactoringBundle.message("declare.static.checkbox")); + if (canBeChainedConstructor) { + myCbChainedConstructor = new NonFocusableCheckBox(RefactoringBundle.message("extract.chained.constructor.checkbox")); + } + + init(); + } + + protected EditorTextField createNameField(String initialMethodName) { + EditorTextField field = new EditorTextField(initialMethodName); + field.selectAll(); + return field; + } + + protected boolean areTypesDirected() { + return true; + } + + public boolean isMakeStatic() { + if (myStaticFlag) return true; + return myCanBeStatic && myMakeStatic.isSelected(); + } + + public boolean isChainedConstructor() { + return myCbChainedConstructor != null && myCbChainedConstructor.isSelected(); + } + + protected Action[] createActions() { + if (myHelpId != null) { + return new Action[]{getOKAction(), getCancelAction(), getHelpAction()}; + } else { + return new Action[]{getOKAction(), getCancelAction()}; + } + } + + public String getChosenMethodName() { + return myNameField.getText(); + } + + public ParameterTablePanel.VariableData[] getChosenParameters() { + return myInputVariables; + } + + public JComponent getPreferredFocusedComponent() { + return myNameField; + } + + @Override + protected String getHelpId() { + return myHelpId; + } + + protected void doOKAction() { + MultiMap conflicts = new MultiMap(); + checkMethodConflicts(conflicts); + if (!conflicts.isEmpty()) { + final ConflictsDialog conflictsDialog = new ConflictsDialog(myProject, conflicts); + conflictsDialog.show(); + if (!conflictsDialog.isOK()){ + if (conflictsDialog.isShowConflicts()) close(CANCEL_EXIT_CODE); + return; + } + } + + if (myMakeVarargs != null && myMakeVarargs.isSelected()) { + final ParameterTablePanel.VariableData data = myInputVariables[myInputVariables.length - 1]; + if (data.type instanceof PsiArrayType) { + data.type = new PsiEllipsisType(((PsiArrayType)data.type).getComponentType()); + } + } + super.doOKAction(); + } + + protected JComponent createNorthPanel() { + final JPanel main = new JPanel(new BorderLayout()); + final JPanel namePanel = new JPanel(new VerticalFlowLayout(VerticalFlowLayout.TOP, 0, 2, true, false)); + final JLabel nameLabel = new JLabel(); + nameLabel.setText(RefactoringBundle.message("changeSignature.name.prompt")); + namePanel.add(nameLabel); + namePanel.add(myNameField); + nameLabel.setLabelFor(myNameField); + + myNameField.getDocument().addDocumentListener(new DocumentAdapter() { + public void documentChanged(DocumentEvent e) { + update(); + } + }); + + myVisibilityPanel = createVisibilityPanel(); + final JPanel visibilityAndName = new JPanel(new BorderLayout(2, 0)); + visibilityAndName.add(myVisibilityPanel, BorderLayout.WEST); + visibilityAndName.add(namePanel, BorderLayout.CENTER); + main.add(visibilityAndName, BorderLayout.CENTER); + setOKActionEnabled(false); + + setOKActionEnabled(JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(myNameField.getText())); + final JPanel options = new JPanel(new BorderLayout()); + options.add(createOptionsPanel(), BorderLayout.WEST); + main.add(options, BorderLayout.SOUTH); + return main; + } + + protected JPanel createOptionsPanel() { + final JPanel optionsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 5)); + + //optionsPanel.add(new JLabel("Options: ")); + + if (myStaticFlag || myCanBeStatic) { + myMakeStatic.setEnabled(!myStaticFlag); + myMakeStatic.setSelected(myStaticFlag); + myMakeStatic.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + updateSignature(); + } + }); + optionsPanel.add(myMakeStatic); + } else { + myMakeStatic.setSelected(false); + myMakeStatic.setEnabled(false); + } + final Border emptyBorder = IdeBorderFactory.createEmptyBorder(5, 0, 5, 4); + myMakeStatic.setBorder(emptyBorder); + + myFoldParameters.setSelected(myVariableData.isFoldingSelectedByDefault()); + myFoldParameters.setVisible(myVariableData.isFoldable()); + myVariableData.setFoldingAvailable(myFoldParameters.isSelected()); + myInputVariables = myVariableData.getInputVariables().toArray(new ParameterTablePanel.VariableData[myVariableData.getInputVariables().size()]); + myFoldParameters.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + myVariableData.setFoldingAvailable(myFoldParameters.isSelected()); + myInputVariables = + myVariableData.getInputVariables().toArray(new ParameterTablePanel.VariableData[myVariableData.getInputVariables().size()]); + updateVarargsEnabled(); + createParametersPanel(); + updateSignature(); + } + }); + optionsPanel.add(myFoldParameters); + myFoldParameters.setBorder(emptyBorder); + + boolean canBeVarargs = false; + for (ParameterTablePanel.VariableData data : myInputVariables) { + canBeVarargs |= data.type instanceof PsiArrayType; + } + if (myVariableData.isFoldable()) { + canBeVarargs |= myVariableData.isFoldingSelectedByDefault(); + } + + if (canBeVarargs) { + myMakeVarargs = new NonFocusableCheckBox(RefactoringBundle.message("declare.varargs.checkbox")); + myMakeVarargs.setBorder(emptyBorder); + updateVarargsEnabled(); + myMakeVarargs.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + updateSignature(); + } + }); + myMakeVarargs.setSelected(false); + optionsPanel.add(myMakeVarargs); + } + + if (myCbChainedConstructor != null) { + optionsPanel.add(myCbChainedConstructor); + myCbChainedConstructor.setBorder(emptyBorder); + myCbChainedConstructor.addItemListener(new ItemListener() { + public void itemStateChanged(final ItemEvent e) { + if (myDefaultVisibility) { + myChangingVisibility = true; + try { + if (isChainedConstructor()) { + myVisibilityPanel.setVisibility(VisibilityUtil.getVisibilityModifier(myTargetClass.getModifierList())); + } + else { + myVisibilityPanel.setVisibility(PsiModifier.PRIVATE); + } + } + finally { + myChangingVisibility = false; + } + } + update(); + } + }); + } + return optionsPanel; + } + + private ComboBoxVisibilityPanel createVisibilityPanel() { + final JavaComboBoxVisibilityPanel panel = new JavaComboBoxVisibilityPanel(); + panel.setVisibility(PsiModifier.PRIVATE); + panel.addListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + updateSignature(); + if (!myChangingVisibility) { + myDefaultVisibility = false; + } + } + }); + return panel; + } + + private void updateVarargsEnabled() { + if (myMakeVarargs != null) { + myMakeVarargs.setEnabled(myInputVariables[myInputVariables.length - 1].type instanceof PsiArrayType); + } + } + + private void update() { + myNameField.setEnabled(!isChainedConstructor()); + if (myMakeStatic != null) { + myMakeStatic.setEnabled(!myStaticFlag && myCanBeStatic && !isChainedConstructor()); + } + updateSignature(); + setOKActionEnabled(JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(myNameField.getText()) || + isChainedConstructor()); + } + + public String getVisibility() { + return myVisibilityPanel.getVisibility(); + } + + + protected JComponent createCenterPanel() { + myCenterPanel = new JPanel(new BorderLayout()); + createParametersPanel(); + + final Splitter splitter = new Splitter(true); + splitter.setShowDividerIcon(false); + splitter.setFirstComponent(myCenterPanel); + splitter.setSecondComponent(createSignaturePanel()); + return splitter; + } + + protected boolean isOutputVariable(PsiVariable var) { + return false; + } + + protected void createParametersPanel() { + if (myParamTable != null) { + myCenterPanel.remove(myParamTable); + } + + myParamTable = createParameterTableComponent(); + myParamTable.setMinimumSize(new Dimension(500, 100)); + myCenterPanel.add(myParamTable, BorderLayout.CENTER); + final JTable table = UIUtil.findComponentOfType(myParamTable, JTable.class); + myCenterPanel.add(SeparatorFactory.createSeparator("&Parameters", table), BorderLayout.NORTH); + if (table != null) { + table.addFocusListener(new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + if (table.getRowCount() > 0) { + final int col = table.getSelectedColumn(); + final int row = table.getSelectedRow(); + if (col == -1 || row == -1) { + table.getSelectionModel().setSelectionInterval(0, 0); + table.getColumnModel().getSelectionModel().setSelectionInterval(0, 0); + } + } + } + }); + } + } + + protected ParameterTablePanel createParameterTableComponent() { + return new ParameterTablePanel(myProject, myInputVariables, myElementsToExtract) { + protected void updateSignature() { + updateVarargsEnabled(); + ExtractMethodDialog.this.updateSignature(); + } + + protected void doEnterAction() { + clickDefaultButton(); + } + + protected void doCancelAction() { + ExtractMethodDialog.this.doCancelAction(); + } + + protected boolean areTypesDirected() { + return ExtractMethodDialog.this.areTypesDirected(); + } + + @Override + protected boolean isUsedAfter(PsiVariable variable) { + return isOutputVariable(variable); + } + }; + } + + protected JComponent createSignaturePanel() { + final JPanel panel = new JPanel(new BorderLayout()); + panel.add(SeparatorFactory.createSeparator(RefactoringBundle.message("signature.preview.border.title"), null), BorderLayout.NORTH); + panel.add(mySignature, BorderLayout.CENTER); + + updateSignature(); + return panel; + } + + protected void updateSignature() { + if (mySignature != null) { + mySignature.setSignature(getSignature()); + } + } + + protected String getSignature() { + final @NonNls StringBuilder buffer = new StringBuilder(); + final String visibilityString = VisibilityUtil.getVisibilityString(myVisibilityPanel.getVisibility()); + buffer.append(visibilityString); + if (buffer.length() > 0) { + buffer.append(" "); + } + if (isMakeStatic() && !isChainedConstructor()) { + buffer.append("static "); + } + if (myTypeParameterList != null) { + final String typeParamsText = myTypeParameterList.getText(); + if (!typeParamsText.isEmpty()) { + buffer.append(typeParamsText); + buffer.append(" "); + } + } + + if (isChainedConstructor()) { + buffer.append(myTargetClass.getName()); + } + else { + buffer.append(PsiFormatUtil.formatType(myReturnType, 0, PsiSubstitutor.EMPTY)); + buffer.append(" "); + buffer.append(myNameField.getText()); + } + buffer.append("("); + int count = 0; + char[] chars = new char[buffer.toString().length()]; + Arrays.fill(chars, ' '); + + final String INDENT = new String(chars); + + final ParameterTablePanel.VariableData[] datas = myInputVariables; + for (int i = 0; i < datas.length;i++) { + ParameterTablePanel.VariableData data = datas[i]; + if (data.passAsParameter) { + //String typeAndModifiers = PsiFormatUtil.formatVariable(data.variable, + // PsiFormatUtil.SHOW_MODIFIERS | PsiFormatUtil.SHOW_TYPE); + PsiType type = data.type; + if (i == datas.length - 1 && type instanceof PsiArrayType && myMakeVarargs != null && myMakeVarargs.isSelected()) { + type = new PsiEllipsisType(((PsiArrayType)type).getComponentType()); + } + + String typeText = type.getPresentableText(); + if (count > 0) { + buffer.append(",\n"); + buffer.append(INDENT); + } + buffer.append(typeText); + buffer.append(" "); + buffer.append(data.name); + count++; + } + } + buffer.append(")"); + if (myExceptions.length > 0) { + buffer.append("\n"); + buffer.append("throws\n"); + for (PsiType exception : myExceptions) { + buffer.append(INDENT); + buffer.append(PsiFormatUtil.formatType(exception, 0, PsiSubstitutor.EMPTY)); + buffer.append("\n"); + } + } + return buffer.toString(); + } + + @Override + protected String getDimensionServiceKey() { + return "extract.method.dialog"; + } + + protected void checkMethodConflicts(MultiMap conflicts) { + PsiMethod prototype; + try { + PsiElementFactory factory = JavaPsiFacade.getInstance(myProject).getElementFactory(); + prototype = factory.createMethod(myNameField.getText().trim(), myReturnType); + if (myTypeParameterList != null) prototype.getTypeParameterList().replace(myTypeParameterList); + for (ParameterTablePanel.VariableData data : myInputVariables) { + if (data.passAsParameter) { + prototype.getParameterList().add(factory.createParameter(data.name, data.type)); + } + } + // set the modifiers with which the method is supposed to be created + PsiUtil.setModifierProperty(prototype, PsiModifier.PRIVATE, true); + } catch (IncorrectOperationException e) { + return; + } + + ConflictsUtil.checkMethodConflicts(myTargetClass, null, prototype, conflicts); + } +} diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java index 4524b8b0e36f..c1fe88b3b7e2 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java @@ -42,13 +42,16 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Pass; import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.WindowManager; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.codeStyle.JavaCodeStyleManager; +import com.intellij.psi.codeStyle.VariableKind; import com.intellij.psi.controlFlow.ControlFlowUtil; +import com.intellij.psi.impl.source.codeStyle.JavaCodeStyleManagerImpl; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.search.PsiElementProcessor; @@ -472,7 +475,8 @@ public class ExtractMethodProcessor implements MatchProvider { protected AbstractExtractDialog createExtractMethodDialog(final boolean direct) { return new ExtractMethodDialog(myProject, myTargetClass, myInputVariables, myReturnType, myTypeParameterList, - myThrownExceptions, myStatic, myCanBeStatic, myCanBeChainedConstructor, myInitialMethodName, + myThrownExceptions, myStatic, myCanBeStatic, myCanBeChainedConstructor, + suggestInitialMethodName(), myRefactoringName, myHelpId, myElements) { protected boolean areTypesDirected() { return direct; @@ -485,6 +489,41 @@ public class ExtractMethodProcessor implements MatchProvider { }; } + protected String suggestInitialMethodName() { + if (StringUtil.isEmpty(myInitialMethodName)) { + final String initialMethodName; + final JavaCodeStyleManagerImpl codeStyleManager = (JavaCodeStyleManagerImpl)JavaCodeStyleManager.getInstance(myProject); + final String[] names = codeStyleManager.suggestVariableName(VariableKind.FIELD, null, myExpression, myReturnType).names; + if (names.length > 0) { + initialMethodName = codeStyleManager.variableNameToPropertyName(names[0], VariableKind.FIELD); + } else { + return myInitialMethodName; + } + + if (myReturnType != null && !(myReturnType instanceof PsiPrimitiveType)) { + return PropertyUtil.suggestGetterName(initialMethodName, myReturnType); + } else if (myExpression != null) { + if (myExpression instanceof PsiMethodCallExpression) { + PsiExpression qualifierExpression = ((PsiMethodCallExpression)myExpression).getMethodExpression().getQualifierExpression(); + if (qualifierExpression != null && PsiUtil.resolveGenericsClassInType(qualifierExpression.getType()) != myTargetClass) { + return initialMethodName; + } + } else { + return initialMethodName; + } + } + + PsiElement prevSibling = PsiTreeUtil.skipSiblingsBackward(myElements[0], PsiWhiteSpace.class); + if (prevSibling instanceof PsiComment && ((PsiComment)prevSibling).getTokenType() == JavaTokenType.END_OF_LINE_COMMENT) { + final String text = prevSibling.getText().trim().replaceAll(" ", "").substring(2); + if (JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(text) && text.length() < 20) { + return text; + } + } + } + return myInitialMethodName; + } + public boolean isOutputVariable(PsiVariable var) { return ArrayUtil.find(myOutputVariables, var) != -1; }