update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / refactoring / changeSignature / ChangeSignatureDialog.java
blob0c69f4a5ac5b8fe68bfd3c0abb90f48443349abc
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.refactoring.changeSignature;
18 import com.intellij.codeInsight.completion.JavaCompletionUtil;
19 import com.intellij.codeInsight.lookup.LookupElement;
20 import com.intellij.codeInsight.lookup.LookupManager;
21 import com.intellij.openapi.Disposable;
22 import com.intellij.openapi.application.ModalityState;
23 import com.intellij.openapi.diagnostic.Logger;
24 import com.intellij.openapi.editor.Document;
25 import com.intellij.openapi.editor.Editor;
26 import com.intellij.openapi.editor.event.DocumentEvent;
27 import com.intellij.openapi.editor.event.DocumentListener;
28 import com.intellij.openapi.fileTypes.StdFileTypes;
29 import com.intellij.openapi.help.HelpManager;
30 import com.intellij.openapi.project.Project;
31 import com.intellij.openapi.ui.Messages;
32 import com.intellij.openapi.ui.VerticalFlowLayout;
33 import com.intellij.openapi.util.Disposer;
34 import com.intellij.openapi.util.text.StringUtil;
35 import com.intellij.psi.*;
36 import com.intellij.psi.codeStyle.VariableKind;
37 import com.intellij.refactoring.HelpID;
38 import com.intellij.refactoring.RefactoringBundle;
39 import com.intellij.refactoring.changeSignature.inCallers.CallerChooser;
40 import com.intellij.refactoring.ui.*;
41 import com.intellij.refactoring.util.CanonicalTypes;
42 import com.intellij.refactoring.util.CommonRefactoringUtil;
43 import com.intellij.refactoring.util.RefactoringMessageUtil;
44 import com.intellij.refactoring.util.RefactoringUtil;
45 import com.intellij.ui.*;
46 import com.intellij.ui.treeStructure.Tree;
47 import com.intellij.util.Alarm;
48 import com.intellij.util.IncorrectOperationException;
49 import com.intellij.util.VisibilityUtil;
50 import com.intellij.util.ui.Table;
51 import org.jetbrains.annotations.NonNls;
53 import javax.swing.*;
54 import javax.swing.event.TableModelEvent;
55 import javax.swing.event.TableModelListener;
56 import javax.swing.table.TableColumn;
57 import java.awt.*;
58 import java.awt.event.ActionEvent;
59 import java.awt.event.ActionListener;
60 import java.awt.event.InputEvent;
61 import java.awt.event.KeyEvent;
62 import java.util.*;
63 import java.util.List;
65 public class ChangeSignatureDialog extends RefactoringDialog {
66 private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.changeSignature.ChangeSignatureDialog");
67 private final PsiMethod myMethod;
68 private final boolean myAllowDelegation;
69 private EditorTextField myNameField;
70 private EditorTextField myReturnTypeField;
71 private JTable myParametersTable;
72 private final ParameterTableModel myParametersTableModel;
73 private JTextArea mySignatureArea;
74 private final Alarm myUpdateSignatureAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
76 private VisibilityPanel myVisibilityPanel;
77 private PsiTypeCodeFragment myReturnTypeCodeFragment;
78 private DelegationPanel myDelegationPanel;
79 private JTable myExceptionsTable;
80 private final ExceptionsTableModel myExceptionsTableModel;
81 private JButton myPropagateParamChangesButton;
82 private JButton myPropagateExnChangesButton;
83 private Set<PsiMethod> myMethodsToPropagateParameters = null;
84 private Set<PsiMethod> myMethodsToPropagateExceptions = null;
86 private Tree myExceptionPropagationTree;
87 private Tree myParameterPropagationTree;
89 public ChangeSignatureDialog(Project project, final PsiMethod method, boolean allowDelegation, final PsiReferenceExpression ref) {
90 super(project, true);
91 myMethod = method;
92 myParametersTableModel = new ParameterTableModel(myMethod.getParameterList(), ref, this);
93 myExceptionsTableModel = new ExceptionsTableModel(myMethod.getThrowsList());
94 myAllowDelegation = allowDelegation;
96 setParameterInfos(getParameterInfos(method));
97 myExceptionsTableModel.setTypeInfos(method);
99 setTitle(ChangeSignatureHandler.REFACTORING_NAME);
100 init();
101 doUpdateSignature();
102 Disposer.register(myDisposable, new Disposable() {
103 public void dispose() {
104 myUpdateSignatureAlarm.cancelAllRequests();
109 public void setParameterInfos(List<ParameterInfoImpl> parameterInfos) {
110 myParametersTableModel.setParameterInfos(parameterInfos, myMethod.getParameterList());
111 updateSignature();
114 private static List<ParameterInfoImpl> getParameterInfos(PsiMethod method) {
115 final ArrayList<ParameterInfoImpl> result = new ArrayList<ParameterInfoImpl>();
116 final PsiParameter[] parameters = method.getParameterList().getParameters();
117 for (int i = 0; i < parameters.length; i++) {
118 PsiParameter parameter = parameters[i];
119 ParameterInfoImpl info = new ParameterInfoImpl(i, parameter.getName(), parameter.getType());
120 info.defaultValue = "";
121 result.add(info);
123 return result;
126 private String getMethodName() {
127 if (myNameField != null) {
128 return myNameField.getText().trim();
130 else {
131 return myMethod.getName();
135 private CanonicalTypes.Type getReturnType() {
136 if (myReturnTypeField != null) {
137 try {
138 final PsiType type = myReturnTypeCodeFragment.getType();
139 return CanonicalTypes.createTypeWrapper(type);
141 catch (PsiTypeCodeFragment.TypeSyntaxException e) {
142 return null;
144 catch (PsiTypeCodeFragment.NoTypeException e) {
145 return null;
149 return null;
152 private String getVisibility() {
153 if (myVisibilityPanel != null) {
154 return myVisibilityPanel.getVisibility();
156 else {
157 return VisibilityUtil.getVisibilityModifier(myMethod.getModifierList());
161 public ParameterInfoImpl[] getParameters() {
162 return myParametersTableModel.getParameters();
165 private ThrownExceptionInfo[] getExceptions() {
166 return myExceptionsTableModel.getThrownExceptions();
169 public boolean isGenerateDelegate() {
170 return myAllowDelegation && myDelegationPanel.isGenerateDelegate();
173 public JComponent getPreferredFocusedComponent() {
174 return myParametersTableModel.getRowCount() > 0 ? myParametersTable : myNameField;
178 protected JComponent createNorthPanel() {
179 JPanel panel = new JPanel(new VerticalFlowLayout(VerticalFlowLayout.TOP));
181 JPanel top = new JPanel(new BorderLayout());
182 if (myAllowDelegation)
184 myDelegationPanel = createDelegationPanel();
185 top.add(myDelegationPanel, BorderLayout.WEST);
188 JPanel propagatePanel = new JPanel();
189 myPropagateParamChangesButton = new JButton(RefactoringBundle.message("changeSignature.propagate.parameters.title"));
190 myPropagateParamChangesButton.addActionListener(new ActionListener() {
191 public void actionPerformed(ActionEvent e) {
192 new CallerChooser(myMethod, RefactoringBundle.message("changeSignature.parameter.caller.chooser"), myParameterPropagationTree) {
193 protected void callersChosen(Set<PsiMethod> callers) {
194 myMethodsToPropagateParameters = callers;
195 myParameterPropagationTree = getTree();
197 }.show();
200 propagatePanel.add(myPropagateParamChangesButton);
202 myPropagateExnChangesButton = new JButton(RefactoringBundle.message("changeSignature.propagate.exceptions.title"));
203 myPropagateExnChangesButton.addActionListener(new ActionListener() {
204 public void actionPerformed(ActionEvent e) {
205 new CallerChooser(myMethod, RefactoringBundle.message("changeSignature.exception.caller.chooser"), myExceptionPropagationTree) {
206 protected void callersChosen(Set<PsiMethod> callers) {
207 myMethodsToPropagateExceptions = callers;
208 myExceptionPropagationTree = getTree();
210 }.show();
213 propagatePanel.add(myPropagateExnChangesButton);
214 top.add(propagatePanel, BorderLayout.EAST);
216 panel.add(top);
217 if (!myMethod.isConstructor()) {
218 JLabel namePrompt = new JLabel();
219 myNameField = new EditorTextField(myMethod.getName());
220 namePrompt.setText(RefactoringBundle.message("name.prompt"));
221 panel.add(namePrompt);
222 panel.add(myNameField);
224 JLabel typePrompt = new JLabel();
225 panel.add(typePrompt);
226 final PsiElementFactory factory = JavaPsiFacade.getInstance(myMethod.getProject()).getElementFactory();
227 myReturnTypeCodeFragment = factory.createTypeCodeFragment(myMethod.getReturnTypeElement().getText(), myMethod.getParameterList(), true, true);
228 final Document document = PsiDocumentManager.getInstance(myProject).getDocument(myReturnTypeCodeFragment);
229 myReturnTypeField = new EditorTextField(document, myProject, StdFileTypes.JAVA);
230 typePrompt.setText(RefactoringBundle.message("changeSignature.return.type.prompt"));
231 panel.add(myReturnTypeField);
233 final DocumentListener documentListener = new DocumentListener() {
234 public void beforeDocumentChange(DocumentEvent event) {
237 public void documentChanged(DocumentEvent event) {
238 updateSignature();
242 myNameField.addDocumentListener(documentListener);
243 myReturnTypeField.addDocumentListener(documentListener);
246 return panel;
249 private DelegationPanel createDelegationPanel() {
250 return new DelegationPanel() {
251 protected void stateModified() {
252 myParametersTableModel.fireTableDataChanged();
253 configureParameterTableEditors();
258 protected JComponent createCenterPanel() {
259 JPanel panel = new JPanel(new BorderLayout());
260 JPanel subPanel = new JPanel(new BorderLayout());
261 subPanel.add(createParametersPanel(), BorderLayout.CENTER);
263 if (myMethod.getContainingClass() != null
264 && !myMethod.getContainingClass().isInterface()) {
265 myVisibilityPanel = new VisibilityPanel(false, false);
266 myVisibilityPanel.setVisibility(VisibilityUtil.getVisibilityModifier(myMethod.getModifierList()));
267 myVisibilityPanel.addStateChangedListener(new VisibilityPanel.StateChanged() {
268 public void visibilityChanged() {
269 updateSignature();
272 subPanel.add(myVisibilityPanel, BorderLayout.EAST);
275 panel.add(subPanel, BorderLayout.CENTER);
277 JPanel subPanel1 = new JPanel(new GridBagLayout());
278 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));
279 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));
280 panel.add(subPanel1, BorderLayout.SOUTH);
282 return panel;
285 protected String getDimensionServiceKey() {
286 return "refactoring.ChangeSignatureDialog";
289 private JPanel createParametersPanel() {
290 myParametersTable = new Table(myParametersTableModel);
291 myParametersTable.setFocusCycleRoot(true);
292 final int minWidth = new JCheckBox().getPreferredSize().width;
293 final TableColumn anyVarColumn = myParametersTable.getColumnModel().getColumn(3);
294 final int headerWidth = myParametersTable.getFontMetrics(myParametersTable.getFont()).stringWidth(ParameterTableModel.ANY_VAR_COLUMN_NAME) + 8;
295 anyVarColumn.setMaxWidth(Math.max(minWidth, headerWidth));
296 configureParameterTableEditors();
297 return createTablePanelImpl(myParametersTable, myParametersTableModel, RefactoringBundle.message("parameters.border.title"), true);
300 private JPanel createExceptionsPanel() {
301 myExceptionsTable = new Table(myExceptionsTableModel);
302 configureExceptionTableEditors();
303 return createTablePanelImpl(myExceptionsTable, myExceptionsTableModel, RefactoringBundle.message("changeSignature.exceptions.panel.border.title"), false);
306 private JPanel createTablePanelImpl (JTable table, RowEditableTableModel tableModel, String borderTitle, boolean addMnemonics) {
307 JPanel panel = new JPanel(new BorderLayout());
308 panel.setBorder(IdeBorderFactory.createTitledBorder(borderTitle));
310 JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(table);
312 JPanel tablePanel = new JPanel(new BorderLayout());
313 tablePanel.add(scrollPane, BorderLayout.CENTER);
315 tablePanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
316 panel.add(tablePanel, BorderLayout.CENTER);
318 table.setPreferredScrollableViewportSize(new Dimension(450, table.getRowHeight() * 8));
319 table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
320 table.getSelectionModel().setSelectionInterval(0, 0);
321 table.setSurrendersFocusOnKeystroke(true);
323 JPanel buttonsPanel = EditableRowTable.createButtonsTable(table, tableModel, addMnemonics);
325 panel.add(buttonsPanel, BorderLayout.EAST);
327 tableModel.addTableModelListener(
328 new TableModelListener() {
329 public void tableChanged(TableModelEvent e) {
330 updateSignature();
335 return panel;
338 private void configureParameterTableEditors() {
339 myParametersTable.getColumnModel().getColumn(0).setCellRenderer(new CodeFragmentTableCellRenderer(myProject));
340 myParametersTable.getColumnModel().getColumn(1).setCellRenderer(new MyCellRenderer());
341 myParametersTable.getColumnModel().getColumn(2).setCellRenderer(new CodeFragmentTableCellRenderer(myProject));
342 if (myParametersTable.getColumnCount() == 4) {
343 myParametersTable.getColumnModel().getColumn(3).setCellRenderer(new BooleanTableCellRenderer() {
344 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
345 super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
346 if (!myParametersTableModel.isCellEditable(row, myParametersTable.convertColumnIndexToModel(column))) {
347 setBackground(getBackground().darker());
349 return this;
353 myParametersTable.getColumnModel().getColumn(0).setCellEditor(new CodeFragmentTableCellEditor(myProject));
354 myParametersTable.getColumnModel().getColumn(1).setCellEditor(new MyNameTableCellEditor(myProject));
356 myParametersTable.getColumnModel().getColumn(2).setCellEditor(new CodeFragmentTableCellEditor(myProject) {
357 public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
358 final Component editor = super.getTableCellEditorComponent(table, value, isSelected, row, column);
360 if (myCodeFragment instanceof PsiExpressionCodeFragment) {
361 final Object valueAt = table.getValueAt(row, 0);
362 if (valueAt != null) {
363 try {
364 final PsiType type = ((PsiTypeCodeFragment)valueAt).getType();
365 ((PsiExpressionCodeFragment)myCodeFragment).setExpectedType(type);
367 catch (PsiTypeCodeFragment.TypeSyntaxException e) {}
368 catch (PsiTypeCodeFragment.NoTypeException e) {}
372 return editor;
377 private void configureExceptionTableEditors () {
378 myExceptionsTable.getColumnModel().getColumn(0).setCellRenderer(new CodeFragmentTableCellRenderer(myProject));
379 myExceptionsTable.getColumnModel().getColumn(0).setCellEditor(new CodeFragmentTableCellEditor(myProject));
382 private void completeVariable(EditorTextField editorTextField, PsiType type) {
383 Editor editor = editorTextField.getEditor();
384 String prefix = editorTextField.getText();
385 if (prefix == null) prefix = "";
386 Set<LookupElement> set = new LinkedHashSet<LookupElement>();
387 JavaCompletionUtil.completeVariableNameForRefactoring(myProject, set, prefix, type, VariableKind.PARAMETER);
389 LookupElement[] lookupItems = set.toArray(new LookupElement[set.size()]);
390 editor.getCaretModel().moveToOffset(prefix.length());
391 editor.getSelectionModel().removeSelection();
392 LookupManager.getInstance(myProject).showLookup(editor, lookupItems, prefix);
395 private JComponent createSignaturePanel() {
396 JPanel panel = new JPanel(new BorderLayout());
397 panel.setBorder(BorderFactory.createCompoundBorder(IdeBorderFactory.createTitledBorder(RefactoringBundle.message("signature.preview.border.title")), IdeBorderFactory.createEmptyBorder(new Insets(4, 4, 4, 4))));
399 String s = calculateSignature();
400 s = StringUtil.convertLineSeparators(s);
401 int height = new StringTokenizer(s, "\n\r").countTokens() + 2;
402 if (height > 10) height = 10;
403 mySignatureArea = new JTextArea(height, 50);
404 mySignatureArea.setEditable(false);
405 mySignatureArea.setBackground(getContentPane().getBackground());
406 //mySignatureArea.setFont(myTableFont);
407 JScrollPane scrollPane = new JScrollPane(mySignatureArea);
408 scrollPane.setBorder(IdeBorderFactory.createEmptyBorder(new Insets(0,0,0,0)));
409 panel.add(scrollPane, BorderLayout.CENTER);
411 updateSignature();
412 return panel;
415 private void updateSignature() {
416 if (mySignatureArea == null) return;
418 myUpdateSignatureAlarm.cancelAllRequests();
419 myUpdateSignatureAlarm.addRequest(new Runnable() {
420 public void run() {
421 doUpdateSignature();
422 updatePropagateButtons();
424 }, 100, ModalityState.stateForComponent(mySignatureArea));
427 private void doUpdateSignature() {
428 PsiDocumentManager.getInstance(myProject).commitAllDocuments();
429 String signature = calculateSignature();
430 mySignatureArea.setText(signature);
433 private void updatePropagateButtons () {
434 myPropagateParamChangesButton.setEnabled(!isGenerateDelegate() && mayPropagateParameters());
435 myPropagateExnChangesButton.setEnabled(!isGenerateDelegate() && mayPropagateExceptions());
438 private boolean mayPropagateExceptions() {
439 final ThrownExceptionInfo[] thrownExceptions = myExceptionsTableModel.getThrownExceptions();
440 final PsiClassType[] types = myMethod.getThrowsList().getReferencedTypes();
441 if (thrownExceptions.length < types.length) return false;
442 for (int i = 0; i < types.length; i++) {
443 if (thrownExceptions[i].oldIndex != i) return false;
445 return true;
448 private boolean mayPropagateParameters() {
449 final ParameterInfoImpl[] infos = myParametersTableModel.getParameters();
450 final PsiParameter[] parameters = myMethod.getParameterList().getParameters();
451 if (infos.length < parameters.length) return false;
452 for (int i = 0; i < parameters.length; i++) {
453 if (infos[i].oldParameterIndex != i) return false;
455 return true;
458 private String calculateSignature() {
459 @NonNls StringBuilder buffer = new StringBuilder();
461 PsiModifierList modifierList = myMethod.getModifierList();
462 String modifiers = modifierList.getText();
463 String oldModifier = VisibilityUtil.getVisibilityModifier(modifierList);
464 String newModifier = getVisibility();
465 String newModifierStr = VisibilityUtil.getVisibilityString(newModifier);
466 if (!newModifier.equals(oldModifier)) {
467 int index = modifiers.indexOf(oldModifier);
468 if (index >= 0) {
469 StringBuilder buf = new StringBuilder(modifiers);
470 buf.replace(index,
471 index + oldModifier.length() + ("".equals(newModifierStr) ? 1 : 0),
472 newModifierStr);
473 modifiers = buf.toString();
475 else {
476 if (!"".equals(newModifierStr)) newModifierStr += " ";
477 modifiers = newModifierStr + modifiers;
481 buffer.append(modifiers);
482 if (modifiers.length() > 0 &&
483 !StringUtil.endsWithChar(modifiers, '\n') && !StringUtil.endsWithChar(modifiers, '\r') && !StringUtil.endsWithChar(modifiers, ' ')) {
484 buffer.append(" ");
486 if (!myMethod.isConstructor()) {
487 final CanonicalTypes.Type returnType = getReturnType();
488 if (returnType != null) {
489 buffer.append(returnType.getTypeText());
491 buffer.append(" ");
493 buffer.append(getMethodName());
494 buffer.append("(");
496 final List<PsiTypeCodeFragment> codeFraments = myParametersTableModel.getCodeFraments();
498 final ParameterInfoImpl[] parameterInfos = myParametersTableModel.getParameters();
499 LOG.assertTrue(codeFraments.size() == parameterInfos.length);
500 final String indent = " ";
501 for (int i = 0; i < parameterInfos.length; i++) {
502 ParameterInfoImpl info = parameterInfos[i];
503 if (i > 0) {
504 buffer.append(",");
506 buffer.append("\n");
507 buffer.append(indent);
508 buffer.append(codeFraments.get(i).getText());
509 buffer.append(" ");
510 buffer.append(info.getName());
512 if (parameterInfos.length > 0) {
513 buffer.append("\n");
515 buffer.append(")");
516 PsiTypeCodeFragment[] thrownExceptionsFragments = myExceptionsTableModel.getTypeCodeFragments();
517 if (thrownExceptionsFragments.length > 0) {
518 buffer.append("\n");
519 buffer.append("throws\n");
520 for (PsiTypeCodeFragment thrownExceptionsFragment : thrownExceptionsFragments) {
521 String text = thrownExceptionsFragment.getText();
522 buffer.append(indent);
523 buffer.append(text);
524 buffer.append("\n");
527 return buffer.toString();
530 protected void doAction() {
531 stopEditing();
532 String message = validateAndCommitData();
533 if (message != null) {
534 CommonRefactoringUtil.showErrorMessage(RefactoringBundle.message("error.incorrect.data"), message, HelpID.CHANGE_SIGNATURE, myProject);
535 return;
537 if (!checkMethodConflicts()) {
538 return;
541 if (myMethodsToPropagateParameters != null && !mayPropagateParameters()) {
542 Messages.showWarningDialog(myProject, RefactoringBundle.message("changeSignature.parameters.wont.propagate"), ChangeSignatureHandler.REFACTORING_NAME);
543 myMethodsToPropagateParameters = null;
545 if (myMethodsToPropagateExceptions != null && !mayPropagateExceptions()) {
546 Messages.showWarningDialog(myProject, RefactoringBundle.message("changeSignature.exceptions.wont.propagate"), ChangeSignatureHandler.REFACTORING_NAME);
547 myMethodsToPropagateExceptions = null;
550 invokeRefactoring(new ChangeSignatureProcessor(getProject(), myMethod, isGenerateDelegate(),
551 getVisibility(), getMethodName(), getReturnType(),
552 getParameters(), getExceptions(),
553 myMethodsToPropagateParameters,
554 myMethodsToPropagateExceptions));
557 private String validateAndCommitData() {
558 PsiManager manager = PsiManager.getInstance(myProject);
559 PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
561 String name = getMethodName();
562 if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isIdentifier(name)) {
563 return RefactoringMessageUtil.getIncorrectIdentifierMessage(name);
566 if (!myMethod.isConstructor()) {
567 try {
568 myReturnTypeCodeFragment.getType();
570 catch (PsiTypeCodeFragment.TypeSyntaxException e) {
571 myReturnTypeField.requestFocus();
572 return RefactoringBundle.message("changeSignature.wrong.return.type", myReturnTypeCodeFragment.getText());
574 catch (PsiTypeCodeFragment.NoTypeException e) {
575 myReturnTypeField.requestFocus();
576 return RefactoringBundle.message("changeSignature.no.return.type");
580 final List<PsiTypeCodeFragment> codeFraments = myParametersTableModel.getCodeFraments();
581 final List<JavaCodeFragment> defaultValueFraments = myParametersTableModel.getDefaultValueFraments();
582 ParameterInfoImpl[] parameterInfos = myParametersTableModel.getParameters();
583 final int newParametersNumber = parameterInfos.length;
584 LOG.assertTrue(codeFraments.size() == newParametersNumber);
586 for (int i = 0; i < newParametersNumber; i++) {
587 ParameterInfoImpl info = parameterInfos[i];
588 PsiTypeCodeFragment psiCodeFragment = codeFraments.get(i);
589 PsiCodeFragment defaultValueFragment = defaultValueFraments.get(i);
591 if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isIdentifier(info.getName())) {
592 return RefactoringMessageUtil.getIncorrectIdentifierMessage(info.getName());
595 final PsiType type;
596 try {
597 type = psiCodeFragment.getType();
599 catch (PsiTypeCodeFragment.TypeSyntaxException e) {
600 return RefactoringBundle.message("changeSignature.wrong.type.for.parameter", psiCodeFragment.getText(), info.getName());
602 catch (PsiTypeCodeFragment.NoTypeException e) {
603 return RefactoringBundle.message("changeSignature.no.type.for.parameter", info.getName());
606 info.setType(type);
608 if (type instanceof PsiEllipsisType && i != newParametersNumber - 1) {
609 return RefactoringBundle.message("changeSignature.vararg.not.last");
612 if (info.oldParameterIndex < 0) {
613 info.defaultValue = defaultValueFragment.getText();
614 String def = info.defaultValue;
615 def = def.trim();
616 if (!(type instanceof PsiEllipsisType)) {
617 if (def.length() == 0) {
618 return RefactoringBundle.message("changeSignature.no.default.value", info.getName());
621 try {
622 factory.createExpressionFromText(info.defaultValue, null);
624 catch (IncorrectOperationException e) {
625 return e.getMessage();
631 ThrownExceptionInfo[] exceptionInfos = myExceptionsTableModel.getThrownExceptions();
632 PsiTypeCodeFragment[] typeCodeFragments = myExceptionsTableModel.getTypeCodeFragments();
633 for (int i = 0; i < exceptionInfos.length; i++) {
634 ThrownExceptionInfo exceptionInfo = exceptionInfos[i];
635 PsiTypeCodeFragment typeCodeFragment = typeCodeFragments[i];
636 try {
637 PsiType type = typeCodeFragment.getType();
638 if (!(type instanceof PsiClassType)) {
639 return RefactoringBundle.message("changeSignature.wrong.type.for.exception", typeCodeFragment.getText());
642 PsiClassType throwable = JavaPsiFacade.getInstance(myMethod.getProject()).getElementFactory()
643 .createTypeByFQClassName("java.lang.Throwable", type.getResolveScope());
644 if (!throwable.isAssignableFrom(type)) {
645 return RefactoringBundle.message("changeSignature.not.throwable.type", typeCodeFragment.getText());
647 exceptionInfo.setType((PsiClassType)type);
649 catch (PsiTypeCodeFragment.TypeSyntaxException e) {
650 return RefactoringBundle.message("changeSignature.wrong.type.for.exception", typeCodeFragment.getText());
652 catch (PsiTypeCodeFragment.NoTypeException e) {
653 return RefactoringBundle.message("changeSignature.no.type.for.exception");
657 return null;
660 private boolean checkMethodConflicts() {
661 try {
662 PsiManager manager = PsiManager.getInstance(myProject);
663 ParameterInfoImpl[] parameters = getParameters();
665 for (ParameterInfoImpl info : parameters) {
666 final PsiType parameterType = info.createType(myMethod, manager);
668 if (!RefactoringUtil.isResolvableType(parameterType)) {
669 final int ret = Messages.showOkCancelDialog(myProject,
670 RefactoringBundle.message("changeSignature.cannot.resolve.type", info.getTypeText()),
671 ChangeSignatureHandler.REFACTORING_NAME, Messages.getErrorIcon()
673 if (ret != 0) return false;
678 catch (IncorrectOperationException e) {}
679 return true;
682 private void stopEditing() {
683 TableUtil.stopEditing(myParametersTable);
686 protected void doHelpAction() {
687 HelpManager.getInstance().invokeHelp(HelpID.CHANGE_SIGNATURE);
690 private class MyCellRenderer extends ColoredTableCellRenderer {
692 public void customizeCellRenderer(JTable table, Object value,
693 boolean isSelected, boolean hasFocus, int row, int column) {
694 if (value == null) return;
695 if (!myParametersTableModel.isCellEditable(row, myParametersTable.convertColumnIndexToModel(column))) {
696 setBackground(getBackground().darker());
698 append((String)value, new SimpleTextAttributes(Font.PLAIN, null));
702 private class MyNameTableCellEditor extends StringTableCellEditor {
703 public MyNameTableCellEditor(Project project) {
704 super(project);
707 public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
708 final EditorTextField textField = (EditorTextField)super.getTableCellEditorComponent(table, value, isSelected, row, column);
709 textField.registerKeyboardAction(new ActionListener() {
710 public void actionPerformed(ActionEvent e) {
711 int column = myParametersTable.convertColumnIndexToModel(myParametersTable.getEditingColumn());
712 if (column == 1) {
713 int row = myParametersTable.getEditingRow();
714 PsiType type = myParametersTableModel.getTypeByRow(row);
715 if (type != null) {
716 completeVariable(textField, type);
720 }, KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, InputEvent.CTRL_MASK), JComponent.WHEN_IN_FOCUSED_WINDOW);
721 return textField;