change signature dialog

This commit is contained in:
Maxim Medvedev
2010-03-15 19:20:33 +03:00
parent cb337058b8
commit f304012e1a
5 changed files with 239 additions and 31 deletions
@@ -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;
@@ -132,7 +132,7 @@
<text value="Protected"/>
</properties>
</component>
<component id="8f6d2" class="javax.swing.JRadioButton" binding="myPrivateRadioButton1" default-binding="true">
<component id="8f6d2" class="javax.swing.JRadioButton" binding="myPrivateRadioButton" default-binding="true">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
@@ -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<GrParameterInfo> 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<GrParameterInfo> 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;
}
}
@@ -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<PsiElement, String> findConflicts(Ref<UsageInfo[]> refUsages) {
return new MultiMap<PsiElement, String>();//todo
}
@Override
protected boolean preprocessUsages(Ref<UsageInfo[]> 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<GrParameterInfo> myParameters;
private boolean myChangeParameters = false;
public GrChangeInfoImpl(GrMethod method,
String visibilityModifier,
CanonicalTypes.Type returnType,
String newName,
List<GrParameterInfo> 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;
}
}
}
@@ -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();
}
}