introduce LookupArranger to support different sorting strategies in lookups
[fedora-idea.git] / java / java-impl / src / com / intellij / refactoring / changeSignature / ChangeSignatureDialog.java
blobe168c558a3224b3cb54c70162945ad550dfa3ff9
1 package com.intellij.refactoring.changeSignature;
3 import com.intellij.codeInsight.completion.JavaCompletionUtil;
4 import com.intellij.codeInsight.lookup.LookupElement;
5 import com.intellij.codeInsight.lookup.LookupManager;
6 import com.intellij.openapi.Disposable;
7 import com.intellij.openapi.application.ModalityState;
8 import com.intellij.openapi.diagnostic.Logger;
9 import com.intellij.openapi.editor.Document;
10 import com.intellij.openapi.editor.Editor;
11 import com.intellij.openapi.editor.event.DocumentEvent;
12 import com.intellij.openapi.editor.event.DocumentListener;
13 import com.intellij.openapi.fileTypes.StdFileTypes;
14 import com.intellij.openapi.help.HelpManager;
15 import com.intellij.openapi.project.Project;
16 import com.intellij.openapi.ui.Messages;
17 import com.intellij.openapi.ui.VerticalFlowLayout;
18 import com.intellij.openapi.util.Disposer;
19 import com.intellij.openapi.util.text.StringUtil;
20 import com.intellij.psi.*;
21 import com.intellij.psi.codeStyle.VariableKind;
22 import com.intellij.refactoring.HelpID;
23 import com.intellij.refactoring.RefactoringBundle;
24 import com.intellij.refactoring.changeSignature.inCallers.CallerChooser;
25 import com.intellij.refactoring.ui.*;
26 import com.intellij.refactoring.util.CanonicalTypes;
27 import com.intellij.refactoring.util.CommonRefactoringUtil;
28 import com.intellij.refactoring.util.RefactoringMessageUtil;
29 import com.intellij.refactoring.util.RefactoringUtil;
30 import com.intellij.ui.*;
31 import com.intellij.ui.treeStructure.Tree;
32 import com.intellij.util.Alarm;
33 import com.intellij.util.IncorrectOperationException;
34 import com.intellij.util.VisibilityUtil;
35 import com.intellij.util.ui.Table;
36 import org.jetbrains.annotations.NonNls;
38 import javax.swing.*;
39 import javax.swing.event.TableModelEvent;
40 import javax.swing.event.TableModelListener;
41 import javax.swing.table.TableColumn;
42 import java.awt.*;
43 import java.awt.event.ActionEvent;
44 import java.awt.event.ActionListener;
45 import java.awt.event.InputEvent;
46 import java.awt.event.KeyEvent;
47 import java.util.*;
48 import java.util.List;
50 public class ChangeSignatureDialog extends RefactoringDialog {
51 private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.changeSignature.ChangeSignatureDialog");
52 private final PsiMethod myMethod;
53 private final boolean myAllowDelegation;
54 private EditorTextField myNameField;
55 private EditorTextField myReturnTypeField;
56 private JTable myParametersTable;
57 private final ParameterTableModel myParametersTableModel;
58 private JTextArea mySignatureArea;
59 private final Alarm myUpdateSignatureAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
61 private VisibilityPanel myVisibilityPanel;
62 private PsiTypeCodeFragment myReturnTypeCodeFragment;
63 private DelegationPanel myDelegationPanel;
64 private JTable myExceptionsTable;
65 private final ExceptionsTableModel myExceptionsTableModel;
66 private JButton myPropagateParamChangesButton;
67 private JButton myPropagateExnChangesButton;
68 private Set<PsiMethod> myMethodsToPropagateParameters = null;
69 private Set<PsiMethod> myMethodsToPropagateExceptions = null;
71 private Tree myExceptionPropagationTree;
72 private Tree myParameterPropagationTree;
74 public ChangeSignatureDialog(Project project, final PsiMethod method, boolean allowDelegation, final PsiReferenceExpression ref) {
75 super(project, true);
76 myMethod = method;
77 myParametersTableModel = new ParameterTableModel(myMethod.getParameterList(), ref, this);
78 myExceptionsTableModel = new ExceptionsTableModel(myMethod.getThrowsList());
79 myAllowDelegation = allowDelegation;
81 setParameterInfos(getParameterInfos(method));
82 myExceptionsTableModel.setTypeInfos(method);
84 setTitle(ChangeSignatureHandler.REFACTORING_NAME);
85 init();
86 doUpdateSignature();
87 Disposer.register(myDisposable, new Disposable() {
88 public void dispose() {
89 myUpdateSignatureAlarm.cancelAllRequests();
91 });
94 public void setParameterInfos(List<ParameterInfoImpl> parameterInfos) {
95 myParametersTableModel.setParameterInfos(parameterInfos, myMethod.getParameterList());
96 updateSignature();
99 private static List<ParameterInfoImpl> getParameterInfos(PsiMethod method) {
100 final ArrayList<ParameterInfoImpl> result = new ArrayList<ParameterInfoImpl>();
101 final PsiParameter[] parameters = method.getParameterList().getParameters();
102 for (int i = 0; i < parameters.length; i++) {
103 PsiParameter parameter = parameters[i];
104 ParameterInfoImpl info = new ParameterInfoImpl(i, parameter.getName(), parameter.getType());
105 info.defaultValue = "";
106 result.add(info);
108 return result;
111 private String getMethodName() {
112 if (myNameField != null) {
113 return myNameField.getText().trim();
115 else {
116 return myMethod.getName();
120 private CanonicalTypes.Type getReturnType() {
121 if (myReturnTypeField != null) {
122 try {
123 final PsiType type = myReturnTypeCodeFragment.getType();
124 return CanonicalTypes.createTypeWrapper(type);
126 catch (PsiTypeCodeFragment.TypeSyntaxException e) {
127 return null;
129 catch (PsiTypeCodeFragment.NoTypeException e) {
130 return null;
134 return null;
137 private String getVisibility() {
138 if (myVisibilityPanel != null) {
139 return myVisibilityPanel.getVisibility();
141 else {
142 return VisibilityUtil.getVisibilityModifier(myMethod.getModifierList());
146 public ParameterInfoImpl[] getParameters() {
147 return myParametersTableModel.getParameters();
150 private ThrownExceptionInfo[] getExceptions() {
151 return myExceptionsTableModel.getThrownExceptions();
154 public boolean isGenerateDelegate() {
155 return myAllowDelegation && myDelegationPanel.isGenerateDelegate();
158 public JComponent getPreferredFocusedComponent() {
159 return myParametersTableModel.getRowCount() > 0 ? myParametersTable : myNameField;
163 protected JComponent createNorthPanel() {
164 JPanel panel = new JPanel(new VerticalFlowLayout(VerticalFlowLayout.TOP));
166 JPanel top = new JPanel(new BorderLayout());
167 if (myAllowDelegation)
169 myDelegationPanel = createDelegationPanel();
170 top.add(myDelegationPanel, BorderLayout.WEST);
173 JPanel propagatePanel = new JPanel();
174 myPropagateParamChangesButton = new JButton(RefactoringBundle.message("changeSignature.propagate.parameters.title"));
175 myPropagateParamChangesButton.addActionListener(new ActionListener() {
176 public void actionPerformed(ActionEvent e) {
177 new CallerChooser(myMethod, RefactoringBundle.message("changeSignature.parameter.caller.chooser"), myParameterPropagationTree) {
178 protected void callersChosen(Set<PsiMethod> callers) {
179 myMethodsToPropagateParameters = callers;
180 myParameterPropagationTree = getTree();
182 }.show();
185 propagatePanel.add(myPropagateParamChangesButton);
187 myPropagateExnChangesButton = new JButton(RefactoringBundle.message("changeSignature.propagate.exceptions.title"));
188 myPropagateExnChangesButton.addActionListener(new ActionListener() {
189 public void actionPerformed(ActionEvent e) {
190 new CallerChooser(myMethod, RefactoringBundle.message("changeSignature.exception.caller.chooser"), myExceptionPropagationTree) {
191 protected void callersChosen(Set<PsiMethod> callers) {
192 myMethodsToPropagateExceptions = callers;
193 myExceptionPropagationTree = getTree();
195 }.show();
198 propagatePanel.add(myPropagateExnChangesButton);
199 top.add(propagatePanel, BorderLayout.EAST);
201 panel.add(top);
202 if (!myMethod.isConstructor()) {
203 JLabel namePrompt = new JLabel();
204 myNameField = new EditorTextField(myMethod.getName());
205 namePrompt.setText(RefactoringBundle.message("name.prompt"));
206 panel.add(namePrompt);
207 panel.add(myNameField);
209 JLabel typePrompt = new JLabel();
210 panel.add(typePrompt);
211 final PsiElementFactory factory = JavaPsiFacade.getInstance(myMethod.getProject()).getElementFactory();
212 myReturnTypeCodeFragment = factory.createTypeCodeFragment(myMethod.getReturnTypeElement().getText(), myMethod.getParameterList(), true, true);
213 final Document document = PsiDocumentManager.getInstance(myProject).getDocument(myReturnTypeCodeFragment);
214 myReturnTypeField = new EditorTextField(document, myProject, StdFileTypes.JAVA);
215 typePrompt.setText(RefactoringBundle.message("changeSignature.return.type.prompt"));
216 panel.add(myReturnTypeField);
218 final DocumentListener documentListener = new DocumentListener() {
219 public void beforeDocumentChange(DocumentEvent event) {
222 public void documentChanged(DocumentEvent event) {
223 updateSignature();
227 myNameField.addDocumentListener(documentListener);
228 myReturnTypeField.addDocumentListener(documentListener);
231 return panel;
234 private DelegationPanel createDelegationPanel() {
235 return new DelegationPanel() {
236 protected void stateModified() {
237 myParametersTableModel.fireTableDataChanged();
238 configureParameterTableEditors();
243 protected JComponent createCenterPanel() {
244 JPanel panel = new JPanel(new BorderLayout());
245 JPanel subPanel = new JPanel(new BorderLayout());
246 subPanel.add(createParametersPanel(), BorderLayout.CENTER);
248 if (myMethod.getContainingClass() != null
249 && !myMethod.getContainingClass().isInterface()) {
250 myVisibilityPanel = new VisibilityPanel(false, false);
251 myVisibilityPanel.setVisibility(VisibilityUtil.getVisibilityModifier(myMethod.getModifierList()));
252 myVisibilityPanel.addStateChangedListener(new VisibilityPanel.StateChanged() {
253 public void visibilityChanged() {
254 updateSignature();
257 subPanel.add(myVisibilityPanel, BorderLayout.EAST);
260 panel.add(subPanel, BorderLayout.CENTER);
262 JPanel subPanel1 = new JPanel(new GridBagLayout());
263 subPanel1.add(createExceptionsPanel(), new GridBagConstraints(0, 0, 1, 1, 0.5, 0.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(4,4,4,0), 0, 0));
264 subPanel1.add(createSignaturePanel(), new GridBagConstraints(1, 0, 1, 1, 0.5, 0.0, GridBagConstraints.EAST, GridBagConstraints.BOTH, new Insets(4,0,4,4), 0, 0));
265 panel.add(subPanel1, BorderLayout.SOUTH);
267 return panel;
270 protected String getDimensionServiceKey() {
271 return "refactoring.ChangeSignatureDialog";
274 private JPanel createParametersPanel() {
275 myParametersTable = new Table(myParametersTableModel);
276 myParametersTable.setFocusCycleRoot(true);
277 final int minWidth = new JCheckBox().getPreferredSize().width;
278 final TableColumn anyVarColumn = myParametersTable.getColumnModel().getColumn(3);
279 final int headerWidth = myParametersTable.getFontMetrics(myParametersTable.getFont()).stringWidth(ParameterTableModel.ANY_VAR_COLUMN_NAME) + 8;
280 anyVarColumn.setMaxWidth(Math.max(minWidth, headerWidth));
281 configureParameterTableEditors();
282 return createTablePanelImpl(myParametersTable, myParametersTableModel, RefactoringBundle.message("parameters.border.title"), true);
285 private JPanel createExceptionsPanel() {
286 myExceptionsTable = new Table(myExceptionsTableModel);
287 configureExceptionTableEditors();
288 return createTablePanelImpl(myExceptionsTable, myExceptionsTableModel, RefactoringBundle.message("changeSignature.exceptions.panel.border.title"), false);
291 private JPanel createTablePanelImpl (JTable table, RowEditableTableModel tableModel, String borderTitle, boolean addMnemonics) {
292 JPanel panel = new JPanel(new BorderLayout());
293 panel.setBorder(IdeBorderFactory.createTitledBorder(borderTitle));
295 JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(table);
297 JPanel tablePanel = new JPanel(new BorderLayout());
298 tablePanel.add(scrollPane, BorderLayout.CENTER);
300 tablePanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
301 panel.add(tablePanel, BorderLayout.CENTER);
303 table.setPreferredScrollableViewportSize(new Dimension(450, table.getRowHeight() * 8));
304 table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
305 table.getSelectionModel().setSelectionInterval(0, 0);
306 table.setSurrendersFocusOnKeystroke(true);
308 JPanel buttonsPanel = EditableRowTable.createButtonsTable(table, tableModel, addMnemonics);
310 panel.add(buttonsPanel, BorderLayout.EAST);
312 tableModel.addTableModelListener(
313 new TableModelListener() {
314 public void tableChanged(TableModelEvent e) {
315 updateSignature();
320 return panel;
323 private void configureParameterTableEditors() {
324 myParametersTable.getColumnModel().getColumn(0).setCellRenderer(new CodeFragmentTableCellRenderer(myProject));
325 myParametersTable.getColumnModel().getColumn(1).setCellRenderer(new MyCellRenderer());
326 myParametersTable.getColumnModel().getColumn(2).setCellRenderer(new CodeFragmentTableCellRenderer(myProject));
327 if (myParametersTable.getColumnCount() == 4) {
328 myParametersTable.getColumnModel().getColumn(3).setCellRenderer(new BooleanTableCellRenderer() {
329 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
330 super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
331 if (!myParametersTableModel.isCellEditable(row, myParametersTable.convertColumnIndexToModel(column))) {
332 setBackground(getBackground().darker());
334 return this;
338 myParametersTable.getColumnModel().getColumn(0).setCellEditor(new CodeFragmentTableCellEditor(myProject));
339 myParametersTable.getColumnModel().getColumn(1).setCellEditor(new MyNameTableCellEditor(myProject));
341 myParametersTable.getColumnModel().getColumn(2).setCellEditor(new CodeFragmentTableCellEditor(myProject) {
342 public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
343 final Component editor = super.getTableCellEditorComponent(table, value, isSelected, row, column);
345 if (myCodeFragment instanceof PsiExpressionCodeFragment) {
346 final Object valueAt = table.getValueAt(row, 0);
347 if (valueAt != null) {
348 try {
349 final PsiType type = ((PsiTypeCodeFragment)valueAt).getType();
350 ((PsiExpressionCodeFragment)myCodeFragment).setExpectedType(type);
352 catch (PsiTypeCodeFragment.TypeSyntaxException e) {}
353 catch (PsiTypeCodeFragment.NoTypeException e) {}
357 return editor;
362 private void configureExceptionTableEditors () {
363 myExceptionsTable.getColumnModel().getColumn(0).setCellRenderer(new CodeFragmentTableCellRenderer(myProject));
364 myExceptionsTable.getColumnModel().getColumn(0).setCellEditor(new CodeFragmentTableCellEditor(myProject));
367 private void completeVariable(EditorTextField editorTextField, PsiType type) {
368 Editor editor = editorTextField.getEditor();
369 String prefix = editorTextField.getText();
370 if (prefix == null) prefix = "";
371 Set<LookupElement> set = new LinkedHashSet<LookupElement>();
372 JavaCompletionUtil.completeVariableNameForRefactoring(myProject, set, prefix, type, VariableKind.PARAMETER);
374 LookupElement[] lookupItems = set.toArray(new LookupElement[set.size()]);
375 editor.getCaretModel().moveToOffset(prefix.length());
376 editor.getSelectionModel().removeSelection();
377 LookupManager.getInstance(myProject).showLookup(editor, lookupItems, prefix);
380 private JComponent createSignaturePanel() {
381 JPanel panel = new JPanel(new BorderLayout());
382 panel.setBorder(BorderFactory.createCompoundBorder(IdeBorderFactory.createTitledBorder(RefactoringBundle.message("signature.preview.border.title")), IdeBorderFactory.createEmptyBorder(new Insets(4, 4, 4, 4))));
384 String s = calculateSignature();
385 s = StringUtil.convertLineSeparators(s);
386 int height = new StringTokenizer(s, "\n\r").countTokens() + 2;
387 if (height > 10) height = 10;
388 mySignatureArea = new JTextArea(height, 50);
389 mySignatureArea.setEditable(false);
390 mySignatureArea.setBackground(getContentPane().getBackground());
391 //mySignatureArea.setFont(myTableFont);
392 JScrollPane scrollPane = new JScrollPane(mySignatureArea);
393 scrollPane.setBorder(IdeBorderFactory.createEmptyBorder(new Insets(0,0,0,0)));
394 panel.add(scrollPane, BorderLayout.CENTER);
396 updateSignature();
397 return panel;
400 private void updateSignature() {
401 if (mySignatureArea == null) return;
403 myUpdateSignatureAlarm.cancelAllRequests();
404 myUpdateSignatureAlarm.addRequest(new Runnable() {
405 public void run() {
406 doUpdateSignature();
407 updatePropagateButtons();
409 }, 100, ModalityState.stateForComponent(mySignatureArea));
412 private void doUpdateSignature() {
413 PsiDocumentManager.getInstance(myProject).commitAllDocuments();
414 String signature = calculateSignature();
415 mySignatureArea.setText(signature);
418 private void updatePropagateButtons () {
419 myPropagateParamChangesButton.setEnabled(!isGenerateDelegate() && mayPropagateParameters());
420 myPropagateExnChangesButton.setEnabled(!isGenerateDelegate() && mayPropagateExceptions());
423 private boolean mayPropagateExceptions() {
424 final ThrownExceptionInfo[] thrownExceptions = myExceptionsTableModel.getThrownExceptions();
425 final PsiClassType[] types = myMethod.getThrowsList().getReferencedTypes();
426 if (thrownExceptions.length < types.length) return false;
427 for (int i = 0; i < types.length; i++) {
428 if (thrownExceptions[i].oldIndex != i) return false;
430 return true;
433 private boolean mayPropagateParameters() {
434 final ParameterInfoImpl[] infos = myParametersTableModel.getParameters();
435 final PsiParameter[] parameters = myMethod.getParameterList().getParameters();
436 if (infos.length < parameters.length) return false;
437 for (int i = 0; i < parameters.length; i++) {
438 if (infos[i].oldParameterIndex != i) return false;
440 return true;
443 private String calculateSignature() {
444 @NonNls StringBuilder buffer = new StringBuilder();
446 PsiModifierList modifierList = myMethod.getModifierList();
447 String modifiers = modifierList.getText();
448 String oldModifier = VisibilityUtil.getVisibilityModifier(modifierList);
449 String newModifier = getVisibility();
450 String newModifierStr = VisibilityUtil.getVisibilityString(newModifier);
451 if (!newModifier.equals(oldModifier)) {
452 int index = modifiers.indexOf(oldModifier);
453 if (index >= 0) {
454 StringBuilder buf = new StringBuilder(modifiers);
455 buf.replace(index,
456 index + oldModifier.length() + ("".equals(newModifierStr) ? 1 : 0),
457 newModifierStr);
458 modifiers = buf.toString();
460 else {
461 if (!"".equals(newModifierStr)) newModifierStr += " ";
462 modifiers = newModifierStr + modifiers;
466 buffer.append(modifiers);
467 if (modifiers.length() > 0 &&
468 !StringUtil.endsWithChar(modifiers, '\n') && !StringUtil.endsWithChar(modifiers, '\r') && !StringUtil.endsWithChar(modifiers, ' ')) {
469 buffer.append(" ");
471 if (!myMethod.isConstructor()) {
472 final CanonicalTypes.Type returnType = getReturnType();
473 if (returnType != null) {
474 buffer.append(returnType.getTypeText());
476 buffer.append(" ");
478 buffer.append(getMethodName());
479 buffer.append("(");
481 final List<PsiTypeCodeFragment> codeFraments = myParametersTableModel.getCodeFraments();
483 final ParameterInfoImpl[] parameterInfos = myParametersTableModel.getParameters();
484 LOG.assertTrue(codeFraments.size() == parameterInfos.length);
485 final String indent = " ";
486 for (int i = 0; i < parameterInfos.length; i++) {
487 ParameterInfoImpl info = parameterInfos[i];
488 if (i > 0) {
489 buffer.append(",");
491 buffer.append("\n");
492 buffer.append(indent);
493 buffer.append(codeFraments.get(i).getText());
494 buffer.append(" ");
495 buffer.append(info.getName());
497 if (parameterInfos.length > 0) {
498 buffer.append("\n");
500 buffer.append(")");
501 PsiTypeCodeFragment[] thrownExceptionsFragments = myExceptionsTableModel.getTypeCodeFragments();
502 if (thrownExceptionsFragments.length > 0) {
503 buffer.append("\n");
504 buffer.append("throws\n");
505 for (PsiTypeCodeFragment thrownExceptionsFragment : thrownExceptionsFragments) {
506 String text = thrownExceptionsFragment.getText();
507 buffer.append(indent);
508 buffer.append(text);
509 buffer.append("\n");
512 return buffer.toString();
515 protected void doAction() {
516 stopEditing();
517 String message = validateAndCommitData();
518 if (message != null) {
519 CommonRefactoringUtil.showErrorMessage(RefactoringBundle.message("error.incorrect.data"), message, HelpID.CHANGE_SIGNATURE, myProject);
520 return;
522 if (!checkMethodConflicts()) {
523 return;
526 if (myMethodsToPropagateParameters != null && !mayPropagateParameters()) {
527 Messages.showWarningDialog(myProject, RefactoringBundle.message("changeSignature.parameters.wont.propagate"), ChangeSignatureHandler.REFACTORING_NAME);
528 myMethodsToPropagateParameters = null;
530 if (myMethodsToPropagateExceptions != null && !mayPropagateExceptions()) {
531 Messages.showWarningDialog(myProject, RefactoringBundle.message("changeSignature.exceptions.wont.propagate"), ChangeSignatureHandler.REFACTORING_NAME);
532 myMethodsToPropagateExceptions = null;
535 invokeRefactoring(new ChangeSignatureProcessor(getProject(), myMethod, isGenerateDelegate(),
536 getVisibility(), getMethodName(), getReturnType(),
537 getParameters(), getExceptions(),
538 myMethodsToPropagateParameters,
539 myMethodsToPropagateExceptions));
542 private String validateAndCommitData() {
543 PsiManager manager = PsiManager.getInstance(myProject);
544 PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
546 String name = getMethodName();
547 if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isIdentifier(name)) {
548 return RefactoringMessageUtil.getIncorrectIdentifierMessage(name);
551 if (!myMethod.isConstructor()) {
552 try {
553 myReturnTypeCodeFragment.getType();
555 catch (PsiTypeCodeFragment.TypeSyntaxException e) {
556 myReturnTypeField.requestFocus();
557 return RefactoringBundle.message("changeSignature.wrong.return.type", myReturnTypeCodeFragment.getText());
559 catch (PsiTypeCodeFragment.NoTypeException e) {
560 myReturnTypeField.requestFocus();
561 return RefactoringBundle.message("changeSignature.no.return.type");
565 final List<PsiTypeCodeFragment> codeFraments = myParametersTableModel.getCodeFraments();
566 final List<JavaCodeFragment> defaultValueFraments = myParametersTableModel.getDefaultValueFraments();
567 ParameterInfoImpl[] parameterInfos = myParametersTableModel.getParameters();
568 final int newParametersNumber = parameterInfos.length;
569 LOG.assertTrue(codeFraments.size() == newParametersNumber);
571 for (int i = 0; i < newParametersNumber; i++) {
572 ParameterInfoImpl info = parameterInfos[i];
573 PsiTypeCodeFragment psiCodeFragment = codeFraments.get(i);
574 PsiCodeFragment defaultValueFragment = defaultValueFraments.get(i);
576 if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isIdentifier(info.getName())) {
577 return RefactoringMessageUtil.getIncorrectIdentifierMessage(info.getName());
580 final PsiType type;
581 try {
582 type = psiCodeFragment.getType();
584 catch (PsiTypeCodeFragment.TypeSyntaxException e) {
585 return RefactoringBundle.message("changeSignature.wrong.type.for.parameter", psiCodeFragment.getText(), info.getName());
587 catch (PsiTypeCodeFragment.NoTypeException e) {
588 return RefactoringBundle.message("changeSignature.no.type.for.parameter", info.getName());
591 info.setType(type);
593 if (type instanceof PsiEllipsisType && i != newParametersNumber - 1) {
594 return RefactoringBundle.message("changeSignature.vararg.not.last");
597 if (info.oldParameterIndex < 0) {
598 info.defaultValue = defaultValueFragment.getText();
599 String def = info.defaultValue;
600 def = def.trim();
601 if (!(type instanceof PsiEllipsisType)) {
602 if (def.length() == 0) {
603 return RefactoringBundle.message("changeSignature.no.default.value", info.getName());
606 try {
607 factory.createExpressionFromText(info.defaultValue, null);
609 catch (IncorrectOperationException e) {
610 return e.getMessage();
616 ThrownExceptionInfo[] exceptionInfos = myExceptionsTableModel.getThrownExceptions();
617 PsiTypeCodeFragment[] typeCodeFragments = myExceptionsTableModel.getTypeCodeFragments();
618 for (int i = 0; i < exceptionInfos.length; i++) {
619 ThrownExceptionInfo exceptionInfo = exceptionInfos[i];
620 PsiTypeCodeFragment typeCodeFragment = typeCodeFragments[i];
621 try {
622 PsiType type = typeCodeFragment.getType();
623 if (!(type instanceof PsiClassType)) {
624 return RefactoringBundle.message("changeSignature.wrong.type.for.exception", typeCodeFragment.getText());
627 PsiClassType throwable = JavaPsiFacade.getInstance(myMethod.getProject()).getElementFactory()
628 .createTypeByFQClassName("java.lang.Throwable", type.getResolveScope());
629 if (!throwable.isAssignableFrom(type)) {
630 return RefactoringBundle.message("changeSignature.not.throwable.type", typeCodeFragment.getText());
632 exceptionInfo.setType((PsiClassType)type);
634 catch (PsiTypeCodeFragment.TypeSyntaxException e) {
635 return RefactoringBundle.message("changeSignature.wrong.type.for.exception", typeCodeFragment.getText());
637 catch (PsiTypeCodeFragment.NoTypeException e) {
638 return RefactoringBundle.message("changeSignature.no.type.for.exception");
642 return null;
645 private boolean checkMethodConflicts() {
646 try {
647 PsiManager manager = PsiManager.getInstance(myProject);
648 ParameterInfoImpl[] parameters = getParameters();
650 for (ParameterInfoImpl info : parameters) {
651 final PsiType parameterType = info.createType(myMethod, manager);
653 if (!RefactoringUtil.isResolvableType(parameterType)) {
654 final int ret = Messages.showOkCancelDialog(myProject,
655 RefactoringBundle.message("changeSignature.cannot.resolve.type", info.getTypeText()),
656 ChangeSignatureHandler.REFACTORING_NAME, Messages.getErrorIcon()
658 if (ret != 0) return false;
663 catch (IncorrectOperationException e) {}
664 return true;
667 private void stopEditing() {
668 TableUtil.stopEditing(myParametersTable);
671 protected void doHelpAction() {
672 HelpManager.getInstance().invokeHelp(HelpID.CHANGE_SIGNATURE);
675 private class MyCellRenderer extends ColoredTableCellRenderer {
677 public void customizeCellRenderer(JTable table, Object value,
678 boolean isSelected, boolean hasFocus, int row, int column) {
679 if (value == null) return;
680 if (!myParametersTableModel.isCellEditable(row, myParametersTable.convertColumnIndexToModel(column))) {
681 setBackground(getBackground().darker());
683 append((String)value, new SimpleTextAttributes(Font.PLAIN, null));
687 private class MyNameTableCellEditor extends StringTableCellEditor {
688 public MyNameTableCellEditor(Project project) {
689 super(project);
692 public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
693 final EditorTextField textField = (EditorTextField)super.getTableCellEditorComponent(table, value, isSelected, row, column);
694 textField.registerKeyboardAction(new ActionListener() {
695 public void actionPerformed(ActionEvent e) {
696 int column = myParametersTable.convertColumnIndexToModel(myParametersTable.getEditingColumn());
697 if (column == 1) {
698 int row = myParametersTable.getEditingRow();
699 PsiType type = myParametersTableModel.getTypeByRow(row);
700 if (type != null) {
701 completeVariable(textField, type);
705 }, KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, InputEvent.CTRL_MASK), JComponent.WHEN_IN_FOCUSED_WINDOW);
706 return textField;