diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureViewDescriptor.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureViewDescriptor.java index 86ce5b030019..cd453595851e 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureViewDescriptor.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureViewDescriptor.java @@ -20,16 +20,16 @@ */ package com.intellij.refactoring.changeSignature; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; import com.intellij.refactoring.RefactoringBundle; import com.intellij.usageView.UsageViewBundle; import com.intellij.usageView.UsageViewDescriptor; import com.intellij.usageView.UsageViewUtil; -import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; -class ChangeSignatureViewDescriptor implements UsageViewDescriptor { +public class ChangeSignatureViewDescriptor implements UsageViewDescriptor { private final PsiMethod myMethod; private final String myProcessedElementsHeader; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureDialog.form b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureDialog.form index 6baa6a42b2b4..9036d53d1a4a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureDialog.form +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureDialog.form @@ -132,7 +132,7 @@ - + diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureDialog.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureDialog.java index 6b812eb426e7..22cf9c2333eb 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureDialog.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureDialog.java @@ -17,17 +17,23 @@ package org.jetbrains.plugins.groovy.refactoring.changeSignature; import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiType; import com.intellij.psi.PsiTypeCodeFragment; +import com.intellij.refactoring.HelpID; import com.intellij.refactoring.ui.CodeFragmentTableCellEditor; import com.intellij.refactoring.ui.CodeFragmentTableCellRenderer; +import com.intellij.refactoring.ui.RefactoringDialog; +import com.intellij.refactoring.util.CanonicalTypes; +import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.ui.EditorTextField; +import com.intellij.ui.TableUtil; import com.intellij.util.ui.Table; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.GroovyFileType; import org.jetbrains.plugins.groovy.debugger.fragments.GroovyCodeFragment; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; @@ -44,13 +50,12 @@ import java.util.List; /** * @author Maxim.Medvedev */ -public class GrChangeSignatureDialog extends DialogWrapper { +public class GrChangeSignatureDialog extends RefactoringDialog { private EditorTextField myNameField; private EditorTextField myReturnTypeField; private JRadioButton myPublicRadioButton; - private JRadioButton myProtectedRadioButton; - private JRadioButton myPrivateRadioButton1; + private JRadioButton myPrivateRadioButton; private JPanel myParametersPanel; private Table myParameterTable; private JButton myAddButton; @@ -61,12 +66,12 @@ public class GrChangeSignatureDialog extends DialogWrapper { private JLabel mySignatureLabel; private GrParameterTableModel myParameterModel; private GrMethod myMethod; - private Project myProject; +// private Project myProject; private PsiTypeCodeFragment myReturnTypeCodeFragment; + private GroovyCodeFragment myNameCodeFragment; public GrChangeSignatureDialog(@NotNull Project project, GrMethod method) { super(project, true); - myProject = project; myMethod = method; init(); configureParameterButtons(); @@ -121,10 +126,8 @@ public class GrChangeSignatureDialog extends DialogWrapper { super.init(); } - @Override - protected void doOKAction() { - super.doOKAction(); - + private void stopEditing() { + TableUtil.stopEditing(myParameterTable); } @Override @@ -139,7 +142,10 @@ public class GrChangeSignatureDialog extends DialogWrapper { } private void createNameAndReturnTypeEditors() { - myNameField = new EditorTextField("", myProject, GroovyFileType.GROOVY_FILE_TYPE); + myNameCodeFragment = new GroovyCodeFragment(myProject, ""); + myNameField = new EditorTextField(PsiDocumentManager.getInstance(myProject).getDocument(myNameCodeFragment), myProject, + myNameCodeFragment.getFileType()); + myReturnTypeCodeFragment = JavaPsiFacade.getInstance(myProject).getElementFactory().createTypeCodeFragment("", myMethod, true, true); final Document document = PsiDocumentManager.getInstance(myProject).getDocument(myReturnTypeCodeFragment); myReturnTypeField = new EditorTextField(document, myProject, myReturnTypeCodeFragment.getFileType()); @@ -166,8 +172,10 @@ public class GrChangeSignatureDialog extends DialogWrapper { myParameterTable.getColumnModel().getColumn(2).setCellEditor(new GrCodeFragmentTableCellEditor(myProject)); myParameterTable.getColumnModel().getColumn(3).setCellEditor(new GrCodeFragmentTableCellEditor(myProject)); - myParameterTable.setRowSelectionInterval(0, 0); - myParameterTable.setColumnSelectionInterval(0, 0); + if (myParameterTable.getRowCount() > 0) { + myParameterTable.setRowSelectionInterval(0, 0); + myParameterTable.setColumnSelectionInterval(0, 0); + } myParameterModel.addTableModelListener(new TableModelListener() { public void tableChanged(TableModelEvent e) { @@ -188,13 +196,19 @@ public class GrChangeSignatureDialog extends DialogWrapper { } private String generateSignatureText() { - String name = myNameField.getText().trim(); + String name = getNewName(); String type = myReturnTypeField.getText().trim(); - if (type.length() == 0) { - type = GrModifier.DEF; - } StringBuilder builder = new StringBuilder(); + if (myPublicRadioButton.isSelected() && type.length() == 0) { + builder.append(GrModifier.DEF); + } + if (myPrivateRadioButton.isSelected()) { + builder.append(GrModifier.PRIVATE).append(' '); + } + else if (myProtectedRadioButton.isSelected()) { + builder.append(GrModifier.PROTECTED).append(' '); + } builder.append(type).append(' '); builder.append(name).append('('); final List infos = myParameterModel.getParameterInfos(); @@ -214,7 +228,7 @@ public class GrChangeSignatureDialog extends DialogWrapper { private static void generateParameterText(GrParameterInfo info, StringBuilder builder) { final PsiTypeCodeFragment typeFragment = info.getType(); builder.append(typeFragment != null ? typeFragment.getText().trim() : GrModifier.DEF).append(' '); - final GroovyCodeFragment nameFragment = info.getName(); + final GroovyCodeFragment nameFragment = info.getNameFragment(); builder.append(nameFragment != null ? nameFragment.getText().trim() : ""); final GroovyCodeFragment defaultInitializer = info.getDefaultInitializer(); @@ -223,4 +237,91 @@ public class GrChangeSignatureDialog extends DialogWrapper { builder.append(" = ").append(defaultInitializerText); } } + + @Override + protected void doAction() { + if (!validateInputData()) { + return; + } + + stopEditing(); + String modifier = ""; + if (myPublicRadioButton.isSelected()) { + modifier = GrModifier.PUBLIC; + } + else if (myPrivateRadioButton.isSelected()) { + modifier = GrModifier.PRIVATE; + } + else if (myProtectedRadioButton.isSelected()) { + modifier = GrModifier.PROTECTED; + } + + PsiType returnType = null; + try { + returnType = myReturnTypeCodeFragment.getType(); + } + catch (PsiTypeCodeFragment.TypeSyntaxException e) { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + catch (PsiTypeCodeFragment.NoTypeException e) { + returnType = PsiType.NULL; + } + + String newName = getNewName(); + final List parameterInfos = myParameterModel.getParameterInfos(); + invokeRefactoring(new GrChangeSignatureProcessor(myProject, new GrChangeSignatureProcessor.GrChangeInfoImpl(myMethod, modifier, + CanonicalTypes.createTypeWrapper( + returnType), newName, + parameterInfos))); + + } + + private String getNewName() { + return myNameField.getText().trim(); + } + + private boolean validateInputData() { + if (!checkName()) { + CommonRefactoringUtil.showErrorHint(myProject, null, "Name is wrong", "Incorrect data", HelpID.CHANGE_SIGNATURE); + return false; + } + + if (!checkType(myReturnTypeCodeFragment)) { + CommonRefactoringUtil.showErrorHint(myProject, null, "Return type is wrong", "Incorrect data", HelpID.CHANGE_SIGNATURE); + } + + for (GrParameterInfo info : myParameterModel.getParameterInfos()) { + if (!checkType(info.getType())) { + CommonRefactoringUtil + .showErrorHint(myProject, null, "Type for parameter " + info.getName() + " is wrong", "Incorrect data", HelpID.CHANGE_SIGNATURE); + return false; + } + } + return true; + } + + private boolean checkType(PsiTypeCodeFragment typeCodeFragment) { + try { + typeCodeFragment.getType(); + } + catch (PsiTypeCodeFragment.TypeSyntaxException e) { + return false; + } + catch (PsiTypeCodeFragment.NoTypeException e) { + return true; + } + return true; + } + + private boolean checkName() { + final String newName = getNewName(); + if (StringUtil.isJavaIdentifier(newName)) return true; + try { + GroovyPsiElementFactory.getInstance(myProject).createMethodFromText("def " + newName + "(){}"); + } + catch (Throwable e) { + return false; + } + return true; + } } \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureProcessor.java index 76d650d3d2f3..0826dcf688e4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureProcessor.java @@ -16,23 +16,38 @@ package org.jetbrains.plugins.groovy.refactoring.changeSignature; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Ref; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.changeSignature.ChangeInfo; +import com.intellij.refactoring.changeSignature.ChangeSignatureViewDescriptor; +import com.intellij.refactoring.changeSignature.ParameterInfo; +import com.intellij.refactoring.util.CanonicalTypes; import com.intellij.usageView.UsageInfo; import com.intellij.usageView.UsageViewDescriptor; +import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; + +import java.util.List; /** * @author Maxim.Medvedev */ -public class GrChangeSignatureProcessor extends BaseRefactoringProcessor{ - public GrChangeSignatureProcessor(Project project) { +public class GrChangeSignatureProcessor extends BaseRefactoringProcessor { + private final GrChangeInfoImpl myInfo; + + //private + + public GrChangeSignatureProcessor(Project project, GrChangeInfoImpl changeInfo) { super(project); + myInfo = changeInfo; } @Override protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) { - return null; //To change body of implemented methods use File | Settings | File Templates. + return new ChangeSignatureViewDescriptor(myInfo.getMethod()); } @NotNull @@ -48,12 +63,95 @@ public class GrChangeSignatureProcessor extends BaseRefactoringProcessor{ @Override protected void performRefactoring(UsageInfo[] usages) { - //To change body of implemented methods use File | Settings | File Templates. + changeMethod(); + } + + private void changeMethod() { + final PsiMethod method = myInfo.getMethod(); + if (myInfo.isChangeName()) { + method.setName(myInfo.getNewName()); + } + + if (myInfo.isChangeVisibility()) { + method.getModifierList().setModifierProperty(myInfo.getVisibilityModifier(), true); + } } @Override protected String getCommandName() { return ""; - //return RefactoringBundle.message("changing.signature.of.0", UsageViewUtil.getDescriptiveName(myChangeInfo.getMethod())); + //return RefactoringBundle.message("changing.signature.of.0", UsageViewUtil.getDescriptiveName(myInfo.getMethod())); + } + + + private MultiMap findConflicts(Ref refUsages) { + return new MultiMap();//todo + } + + @Override + protected boolean preprocessUsages(Ref refUsages) { + return showConflicts(findConflicts(refUsages)); + } + + static class GrChangeInfoImpl implements ChangeInfo { + private GrMethod myMethod; + private String myNewName; + private CanonicalTypes.Type myReturnType; + private String myVisibilityModifier; + private List myParameters; + private boolean myChangeParameters = false; + + public GrChangeInfoImpl(GrMethod method, + String visibilityModifier, + CanonicalTypes.Type returnType, + String newName, + List parameters) { + myMethod = method; + myVisibilityModifier = visibilityModifier; + myReturnType = returnType; + myParameters = parameters; + myNewName = newName; + + final int oldParameterCount = myMethod.getParameters().length; + if (oldParameterCount != myParameters.size()) { + myChangeParameters = true; + } + + for (int i = 0, parametersSize = parameters.size(); i < parametersSize; i++) { + GrParameterInfo parameter = parameters.get(i); + if (parameter.getOldIndex() != i) { + myChangeParameters = true; + } + } + } + + @NotNull + public ParameterInfo[] getNewParameters() { + return myParameters.toArray(new GrParameterInfo[myParameters.size()]); + } + + public boolean isParameterSetOrOrderChanged() { + return myChangeParameters; + } + + public PsiMethod getMethod() { + return myMethod; + } + + public boolean isChangeVisibility() { + return !myMethod.getModifierList().hasModifierProperty(myVisibilityModifier); + } + + public boolean isChangeName() { + return !myMethod.getName().equals(myNewName); + } + + public String getNewName() { + return myNewName; + } + + public String getVisibilityModifier() { + return myVisibilityModifier; + } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrParameterInfo.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrParameterInfo.java index bdf0ff357c4f..127fea01d7ee 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrParameterInfo.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrParameterInfo.java @@ -20,6 +20,7 @@ import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiType; import com.intellij.psi.PsiTypeCodeFragment; +import com.intellij.refactoring.changeSignature.ParameterInfo; import org.jetbrains.plugins.groovy.debugger.fragments.GroovyCodeFragment; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; @@ -27,7 +28,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; /** * @author Maxim.Medvedev */ -public class GrParameterInfo { +public class GrParameterInfo implements ParameterInfo{ private GroovyCodeFragment myName; private GroovyCodeFragment myDefaultValue; private PsiTypeCodeFragment myType; @@ -56,11 +57,11 @@ public class GrParameterInfo { myDefaultInitializer = new GroovyCodeFragment(project, ""); } - public GroovyCodeFragment getName() { + public GroovyCodeFragment getNameFragment() { return myName; } - public GroovyCodeFragment getDefaultValue() { + public GroovyCodeFragment getDefaultValueFragment() { return myDefaultValue; } @@ -72,7 +73,15 @@ public class GrParameterInfo { return myDefaultInitializer; } - public int getPosition() { + public String getName() { + return myName.getText().trim(); + } + + public int getOldIndex() { return myPosition; } + + public String getDefaultValue() { + return myDefaultValue.getText().trim(); + } }