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
;
54 import javax
.swing
.event
.TableModelEvent
;
55 import javax
.swing
.event
.TableModelListener
;
56 import javax
.swing
.table
.TableColumn
;
58 import java
.awt
.event
.ActionEvent
;
59 import java
.awt
.event
.ActionListener
;
60 import java
.awt
.event
.InputEvent
;
61 import java
.awt
.event
.KeyEvent
;
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
) {
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
);
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());
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
= "";
126 private String
getMethodName() {
127 if (myNameField
!= null) {
128 return myNameField
.getText().trim();
131 return myMethod
.getName();
135 private CanonicalTypes
.Type
getReturnType() {
136 if (myReturnTypeField
!= null) {
138 final PsiType type
= myReturnTypeCodeFragment
.getType();
139 return CanonicalTypes
.createTypeWrapper(type
);
141 catch (PsiTypeCodeFragment
.TypeSyntaxException e
) {
144 catch (PsiTypeCodeFragment
.NoTypeException e
) {
152 private String
getVisibility() {
153 if (myVisibilityPanel
!= null) {
154 return myVisibilityPanel
.getVisibility();
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();
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();
213 propagatePanel
.add(myPropagateExnChangesButton
);
214 top
.add(propagatePanel
, BorderLayout
.EAST
);
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
) {
242 myNameField
.addDocumentListener(documentListener
);
243 myReturnTypeField
.addDocumentListener(documentListener
);
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() {
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
);
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
) {
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());
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) {
364 final PsiType type
= ((PsiTypeCodeFragment
)valueAt
).getType();
365 ((PsiExpressionCodeFragment
)myCodeFragment
).setExpectedType(type
);
367 catch (PsiTypeCodeFragment
.TypeSyntaxException e
) {}
368 catch (PsiTypeCodeFragment
.NoTypeException e
) {}
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
);
415 private void updateSignature() {
416 if (mySignatureArea
== null) return;
418 myUpdateSignatureAlarm
.cancelAllRequests();
419 myUpdateSignatureAlarm
.addRequest(new Runnable() {
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;
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;
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
);
469 StringBuilder buf
= new StringBuilder(modifiers
);
471 index
+ oldModifier
.length() + ("".equals(newModifierStr
) ?
1 : 0),
473 modifiers
= buf
.toString();
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
, ' ')) {
486 if (!myMethod
.isConstructor()) {
487 final CanonicalTypes
.Type returnType
= getReturnType();
488 if (returnType
!= null) {
489 buffer
.append(returnType
.getTypeText());
493 buffer
.append(getMethodName());
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
];
507 buffer
.append(indent
);
508 buffer
.append(codeFraments
.get(i
).getText());
510 buffer
.append(info
.getName());
512 if (parameterInfos
.length
> 0) {
516 PsiTypeCodeFragment
[] thrownExceptionsFragments
= myExceptionsTableModel
.getTypeCodeFragments();
517 if (thrownExceptionsFragments
.length
> 0) {
519 buffer
.append("throws\n");
520 for (PsiTypeCodeFragment thrownExceptionsFragment
: thrownExceptionsFragments
) {
521 String text
= thrownExceptionsFragment
.getText();
522 buffer
.append(indent
);
527 return buffer
.toString();
530 protected void doAction() {
532 String message
= validateAndCommitData();
533 if (message
!= null) {
534 CommonRefactoringUtil
.showErrorMessage(RefactoringBundle
.message("error.incorrect.data"), message
, HelpID
.CHANGE_SIGNATURE
, myProject
);
537 if (!checkMethodConflicts()) {
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()) {
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());
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());
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
;
616 if (!(type
instanceof PsiEllipsisType
)) {
617 if (def
.length() == 0) {
618 return RefactoringBundle
.message("changeSignature.no.default.value", info
.getName());
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
];
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");
660 private boolean checkMethodConflicts() {
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
) {}
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
) {
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());
713 int row
= myParametersTable
.getEditingRow();
714 PsiType type
= myParametersTableModel
.getTypeByRow(row
);
716 completeVariable(textField
, type
);
720 }, KeyStroke
.getKeyStroke(KeyEvent
.VK_SPACE
, InputEvent
.CTRL_MASK
), JComponent
.WHEN_IN_FOCUSED_WINDOW
);