diff --git a/java/java-impl/src/com/intellij/lang/java/JavaRefactoringSupportProvider.java b/java/java-impl/src/com/intellij/lang/java/JavaRefactoringSupportProvider.java index 64747b2d233d..264d26b3a72d 100644 --- a/java/java-impl/src/com/intellij/lang/java/JavaRefactoringSupportProvider.java +++ b/java/java-impl/src/com/intellij/lang/java/JavaRefactoringSupportProvider.java @@ -21,9 +21,11 @@ import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.search.SearchScope; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.RefactoringActionHandler; -import com.intellij.refactoring.extractSuperclass.ExtractSuperclassHandler; +import com.intellij.refactoring.changeSignature.ChangeSignatureHandler; +import com.intellij.refactoring.changeSignature.JavaChangeSignatureHandler; import com.intellij.refactoring.extractInterface.ExtractInterfaceHandler; import com.intellij.refactoring.extractMethod.ExtractMethodHandler; +import com.intellij.refactoring.extractSuperclass.ExtractSuperclassHandler; import com.intellij.refactoring.introduceField.IntroduceConstantHandler; import com.intellij.refactoring.introduceField.IntroduceFieldHandler; import com.intellij.refactoring.introduceParameter.IntroduceParameterHandler; @@ -84,6 +86,11 @@ public class JavaRefactoringSupportProvider extends DefaultRefactoringSupportPro return new ExtractSuperclassHandler(); } + @Override + public ChangeSignatureHandler getChangeSignatureHandler() { + return new JavaChangeSignatureHandler(); + } + public static boolean mayRenameInplace(PsiElement elementToRename, final PsiElement nameSuggestionContext) { if (!(elementToRename instanceof PsiVariable)) return false; if (nameSuggestionContext != null && nameSuggestionContext.getContainingFile() != elementToRename.getContainingFile()) return false; diff --git a/java/java-impl/src/com/intellij/refactoring/actions/ChangeSignatureAction.java b/java/java-impl/src/com/intellij/refactoring/actions/ChangeSignatureAction.java index 1da3be897e59..382cc4adb1ed 100644 --- a/java/java-impl/src/com/intellij/refactoring/actions/ChangeSignatureAction.java +++ b/java/java-impl/src/com/intellij/refactoring/actions/ChangeSignatureAction.java @@ -15,13 +15,16 @@ */ package com.intellij.refactoring.actions; +import com.intellij.lang.Language; +import com.intellij.lang.LanguageRefactoringSupport; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.psi.*; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.changeSignature.ChangeSignatureHandler; -import com.intellij.refactoring.changeSignature.ChangeSignatureTargetUtil; +import org.jetbrains.annotations.Nullable; public class ChangeSignatureAction extends BaseRefactoringAction { public boolean isAvailableInEditorOnly() { @@ -35,13 +38,29 @@ public class ChangeSignatureAction extends BaseRefactoringAction { protected boolean isAvailableOnElementInEditor(final PsiElement element, final Editor editor) { final Document document = editor.getDocument(); final PsiFile file = PsiDocumentManager.getInstance(element.getProject()).getPsiFile(document); - if (file != null && ChangeSignatureTargetUtil.findTargetMember(file, editor) != null) { + final ChangeSignatureHandler handler = getChangeSignatureHandler(element.getLanguage()); + if (handler == null) return false; + if (file != null && handler.findTargetMember(file, editor) != null) { return true; } return element instanceof PsiMethod || element instanceof PsiClass; } public RefactoringActionHandler getHandler(DataContext dataContext) { - return new ChangeSignatureHandler(); + final Language language = LangDataKeys.LANGUAGE.getData(dataContext); + if (language != null) { + return getChangeSignatureHandler(language); + } + return null; + } + + @Override + protected boolean isAvailableForLanguage(Language language) { + return getChangeSignatureHandler(language) != null; + } + + @Nullable + private static ChangeSignatureHandler getChangeSignatureHandler(Language language) { + return LanguageRefactoringSupport.INSTANCE.forLanguage(language).getChangeSignatureHandler(); } } diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureDialog.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureDialog.java index 510c5e1892c4..7ccd058327b1 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureDialog.java @@ -282,8 +282,12 @@ public class ChangeSignatureDialog extends RefactoringDialog { panel.add(subPanel, BorderLayout.CENTER); JPanel subPanel1 = new JPanel(new GridBagLayout()); - 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)); - 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)); + 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)); + 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)); panel.add(subPanel1, BorderLayout.SOUTH); return panel; diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessor.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessor.java index 909b200d8e67..2c7a3c5f9e79 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessor.java @@ -58,6 +58,7 @@ import com.intellij.util.VisibilityUtil; import com.intellij.util.containers.HashSet; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -479,7 +480,7 @@ public class ChangeSignatureProcessor extends BaseRefactoringProcessor { protected boolean isProcessCovariantOverriders() { return Messages.showYesNoDialog(myProject, RefactoringBundle.message("do.you.want.to.process.overriding.methods.with.covariant.return.type"), - ChangeSignatureHandler.REFACTORING_NAME, Messages.getQuestionIcon()) + JavaChangeSignatureHandler.REFACTORING_NAME, Messages.getQuestionIcon()) == DialogWrapper.OK_EXIT_CODE; } @@ -941,17 +942,13 @@ public class ChangeSignatureProcessor extends BaseRefactoringProcessor { newArgs [newNonVarargCount] = createActualArgument(list, changeInfo.newParms [newNonVarargCount], toInsertDefaultValue, args); } else { - for (int i = 0; i < newVarargInitializers.length; i++) { - newArgs [i + newNonVarargCount] = newVarargInitializers [i]; - } + System.arraycopy(newVarargInitializers, 0, newArgs, newNonVarargCount, newVarargInitializers.length); } } else { final int newVarargCount = newArgsLength - newNonVarargCount; LOG.assertTrue(newVarargCount == 0 || newVarargCount == varargCount); - for (int i = 0; i < newVarargCount; i++) { - newArgs[newNonVarargCount + i] = args[nonVarargCount + i]; - } + System.arraycopy(args, nonVarargCount, newArgs, newNonVarargCount, newVarargCount); } ChangeSignatureUtil.synchronizeList(list, Arrays.asList(newArgs), ExpressionList.INSTANCE, changeInfo.toRemoveParm); } @@ -973,6 +970,7 @@ public class ChangeSignatureProcessor extends BaseRefactoringProcessor { } } + @Nullable private PsiExpression createDefaultValue(final PsiElementFactory factory, final ParameterInfoImpl info, final PsiExpressionList list) throws IncorrectOperationException { if (info.useAnySingleVariable) { diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureTargetUtil.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureTargetUtil.java deleted file mode 100644 index 5c947f4c48bb..000000000000 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureTargetUtil.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * User: anna - * Date: 24-Nov-2009 - */ -package com.intellij.refactoring.changeSignature; - -import com.intellij.openapi.editor.Editor; -import com.intellij.psi.*; -import com.intellij.psi.util.PsiTreeUtil; -import org.jetbrains.annotations.Nullable; - -public class ChangeSignatureTargetUtil { - private ChangeSignatureTargetUtil() {} - - @Nullable - public static PsiMember findTargetMember(PsiFile file, Editor editor) { - PsiElement element = file.findElementAt(editor.getCaretModel().getOffset()); - if (PsiTreeUtil.getParentOfType(element, PsiParameterList.class) != null) { - return PsiTreeUtil.getParentOfType(element, PsiMethod.class); - } - - final PsiMethodCallExpression expression = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class); - if (expression != null) { - assert element != null; - final PsiExpression qualifierExpression = expression.getMethodExpression().getQualifierExpression(); - if (PsiTreeUtil.isAncestor(qualifierExpression, element, false)) { - final PsiExpressionList expressionList = PsiTreeUtil.getParentOfType(qualifierExpression, PsiExpressionList.class); - if (expressionList != null) { - final PsiElement parent = expressionList.getParent(); - if (parent instanceof PsiMethodCallExpression) { - return ((PsiMethodCallExpression)parent).resolveMethod(); - } - } - } else { - return expression.resolveMethod(); - } - } - - final PsiTypeParameterList typeParameterList = PsiTreeUtil.getParentOfType(element, PsiTypeParameterList.class); - if (typeParameterList != null) { - return PsiTreeUtil.getParentOfType(typeParameterList, PsiMember.class); - } - - final PsiReferenceParameterList referenceParameterList = PsiTreeUtil.getParentOfType(element, PsiReferenceParameterList.class); - if (referenceParameterList != null) { - final PsiJavaCodeReferenceElement referenceElement = - PsiTreeUtil.getParentOfType(referenceParameterList, PsiJavaCodeReferenceElement.class); - if (referenceElement != null) { - final PsiElement resolved = referenceElement.resolve(); - if (resolved instanceof PsiClass) { - return (PsiMember)resolved; - } - else if (resolved instanceof PsiMethod) { - return (PsiMember)resolved; - } - } - } - return null; - } - -} diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureUtil.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureUtil.java index 708bb92ebf5e..96275d137b80 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureUtil.java @@ -26,10 +26,13 @@ import java.util.List; * @author dsl */ public class ChangeSignatureUtil { - private ChangeSignatureUtil() {} + private ChangeSignatureUtil() { + } - public static - void synchronizeList(Parent list, final List newElements, ChildrenGenerator generator, final boolean[] shouldRemoveChild) + public static void synchronizeList(Parent list, + final List newElements, + ChildrenGenerator generator, + final boolean[] shouldRemoveChild) throws IncorrectOperationException { ArrayList elementsToRemove = null; @@ -72,7 +75,7 @@ public class ChangeSignatureUtil { } } - public static interface ChildrenGenerator { + public interface ChildrenGenerator { List getChildren(Parent parent); } } diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureHandler.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureHandler.java similarity index 65% rename from java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureHandler.java rename to java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureHandler.java index 5c099c16bb49..d8d683553901 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureHandler.java @@ -24,20 +24,19 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.ScrollType; import com.intellij.openapi.project.Project; import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.HelpID; -import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.changeClassSignature.ChangeClassSignatureDialog; import com.intellij.refactoring.util.CommonRefactoringUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class ChangeSignatureHandler implements RefactoringActionHandler { - public static final String REFACTORING_NAME = RefactoringBundle.message("changeSignature.refactoring.name"); +public class JavaChangeSignatureHandler implements ChangeSignatureHandler { public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) { editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); - PsiElement element = ChangeSignatureTargetUtil.findTargetMember(file, editor); + PsiElement element = findTargetMember(file, editor); if (element == null) { element = LangDataKeys.PSI_ELEMENT.getData(dataContext); } @@ -96,4 +95,51 @@ public class ChangeSignatureHandler implements RefactoringActionHandler { ChangeClassSignatureDialog dialog = new ChangeClassSignatureDialog(aClass); dialog.show(); } + + @Nullable + public PsiMember findTargetMember(PsiFile file, Editor editor) { + PsiElement element = file.findElementAt(editor.getCaretModel().getOffset()); + if (PsiTreeUtil.getParentOfType(element, PsiParameterList.class) != null) { + return PsiTreeUtil.getParentOfType(element, PsiMethod.class); + } + + final PsiMethodCallExpression expression = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class); + if (expression != null) { + assert element != null; + final PsiExpression qualifierExpression = expression.getMethodExpression().getQualifierExpression(); + if (PsiTreeUtil.isAncestor(qualifierExpression, element, false)) { + final PsiExpressionList expressionList = PsiTreeUtil.getParentOfType(qualifierExpression, PsiExpressionList.class); + if (expressionList != null) { + final PsiElement parent = expressionList.getParent(); + if (parent instanceof PsiMethodCallExpression) { + return ((PsiMethodCallExpression)parent).resolveMethod(); + } + } + } + else { + return expression.resolveMethod(); + } + } + + final PsiTypeParameterList typeParameterList = PsiTreeUtil.getParentOfType(element, PsiTypeParameterList.class); + if (typeParameterList != null) { + return PsiTreeUtil.getParentOfType(typeParameterList, PsiMember.class); + } + + final PsiReferenceParameterList referenceParameterList = PsiTreeUtil.getParentOfType(element, PsiReferenceParameterList.class); + if (referenceParameterList != null) { + final PsiJavaCodeReferenceElement referenceElement = + PsiTreeUtil.getParentOfType(referenceParameterList, PsiJavaCodeReferenceElement.class); + if (referenceElement != null) { + final PsiElement resolved = referenceElement.resolve(); + if (resolved instanceof PsiClass) { + return (PsiMember)resolved; + } + else if (resolved instanceof PsiMethod) { + return (PsiMember)resolved; + } + } + } + return null; + } } diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModel.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModel.java index bd09d2a2e501..ed0baa199151 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModel.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModel.java @@ -116,8 +116,7 @@ class ParameterTableModel extends AbstractTableModel implements RowEditableTable public void setValueAt(Object aValue, int rowIndex, int columnIndex) { if (rowIndex < 0 || rowIndex >= myParameterInfos.size()) return; - String s = aValue instanceof String ? (String)aValue : null; - if (s == null) s = ""; + String s = aValue instanceof String ? (String)aValue : ""; s = s.trim(); ParameterInfoImpl info = myParameterInfos.get(rowIndex); switch (columnIndex) { @@ -186,8 +185,8 @@ class ParameterTableModel extends AbstractTableModel implements RowEditableTable } private JavaCodeFragment createDefaultValueCodeFragment(final String expressionText, final PsiType expectedType) { - PsiExpressionCodeFragment codeFragment = JavaPsiFacade.getInstance(myParameterList.getProject()).getElementFactory().createExpressionCodeFragment(expressionText, - myReferenceExpression, expectedType, true); + PsiExpressionCodeFragment codeFragment = JavaPsiFacade.getInstance(myParameterList.getProject()).getElementFactory() + .createExpressionCodeFragment(expressionText, myReferenceExpression, expectedType, true); codeFragment.setVisibilityChecker(JavaCodeFragment.VisibilityChecker.EVERYTHING_VISIBLE); return codeFragment; } diff --git a/java/java-impl/src/com/intellij/refactoring/openapi/impl/JavaRefactoringActionHandlerFactoryImpl.java b/java/java-impl/src/com/intellij/refactoring/openapi/impl/JavaRefactoringActionHandlerFactoryImpl.java index d2f23b4831a6..23d965134c31 100644 --- a/java/java-impl/src/com/intellij/refactoring/openapi/impl/JavaRefactoringActionHandlerFactoryImpl.java +++ b/java/java-impl/src/com/intellij/refactoring/openapi/impl/JavaRefactoringActionHandlerFactoryImpl.java @@ -18,7 +18,7 @@ package com.intellij.refactoring.openapi.impl; import com.intellij.refactoring.JavaRefactoringActionHandlerFactory; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.anonymousToInner.AnonymousToInnerHandler; -import com.intellij.refactoring.changeSignature.ChangeSignatureHandler; +import com.intellij.refactoring.changeSignature.JavaChangeSignatureHandler; import com.intellij.refactoring.convertToInstanceMethod.ConvertToInstanceMethodHandler; import com.intellij.refactoring.encapsulateFields.EncapsulateFieldsHandler; import com.intellij.refactoring.extractInterface.ExtractInterfaceHandler; @@ -86,7 +86,7 @@ public class JavaRefactoringActionHandlerFactoryImpl extends JavaRefactoringActi } public RefactoringActionHandler createChangeSignatureHandler() { - return new ChangeSignatureHandler(); + return new JavaChangeSignatureHandler(); } public RefactoringActionHandler createExtractSuperclassHandler() { diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTargetTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTargetTest.java index 6ac077915e71..c2161d9179ce 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTargetTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTargetTest.java @@ -8,7 +8,7 @@ import com.intellij.JavaTestUtil; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; import com.intellij.psi.PsiMember; -import com.intellij.refactoring.changeSignature.ChangeSignatureTargetUtil; +import com.intellij.refactoring.changeSignature.JavaChangeSignatureHandler; import com.intellij.testFramework.LightCodeInsightTestCase; import org.jetbrains.annotations.NonNls; @@ -43,7 +43,7 @@ public class ChangeSignatureTargetTest extends LightCodeInsightTestCase { String basePath = "/refactoring/changeSignatureTarget/" + getTestName(true); @NonNls final String filePath = basePath + ".java"; configureByFile(filePath); - final PsiMember member = ChangeSignatureTargetUtil.findTargetMember(getFile(), getEditor()); + final PsiMember member = new JavaChangeSignatureHandler().findTargetMember(getFile(), getEditor()); assertNotNull(member); assertEquals(expectedMemberName, member.getName()); } diff --git a/platform/lang-api/src/com/intellij/lang/refactoring/DefaultRefactoringSupportProvider.java b/platform/lang-api/src/com/intellij/lang/refactoring/DefaultRefactoringSupportProvider.java index e1d5f95e8bb2..3db3337d1493 100644 --- a/platform/lang-api/src/com/intellij/lang/refactoring/DefaultRefactoringSupportProvider.java +++ b/platform/lang-api/src/com/intellij/lang/refactoring/DefaultRefactoringSupportProvider.java @@ -18,6 +18,7 @@ package com.intellij.lang.refactoring; import com.intellij.psi.PsiElement; import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.changeSignature.ChangeSignatureHandler; import org.jetbrains.annotations.Nullable; /** @@ -69,4 +70,8 @@ public class DefaultRefactoringSupportProvider implements RefactoringSupportProv public boolean doInplaceRenameFor(final PsiElement element, final PsiElement context) { return false; } + + public ChangeSignatureHandler getChangeSignatureHandler() { + return null; + } } diff --git a/platform/lang-api/src/com/intellij/lang/refactoring/RefactoringSupportProvider.java b/platform/lang-api/src/com/intellij/lang/refactoring/RefactoringSupportProvider.java index 46b8ed98a5db..7aa9480d5e7b 100644 --- a/platform/lang-api/src/com/intellij/lang/refactoring/RefactoringSupportProvider.java +++ b/platform/lang-api/src/com/intellij/lang/refactoring/RefactoringSupportProvider.java @@ -17,6 +17,7 @@ package com.intellij.lang.refactoring; import com.intellij.psi.PsiElement; import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.changeSignature.ChangeSignatureHandler; import org.jetbrains.annotations.Nullable; /** @@ -91,5 +92,11 @@ public interface RefactoringSupportProvider { */ @Nullable RefactoringActionHandler getExtractSuperClassHandler(); + /** + * @return handler for changing signature in this language + * @see com.intellij.refactoring.RefactoringActionHandler + */ + @Nullable ChangeSignatureHandler getChangeSignatureHandler(); + boolean doInplaceRenameFor(PsiElement element, PsiElement context); } diff --git a/platform/lang-api/src/com/intellij/refactoring/changeSignature/ChangeSignatureHandler.java b/platform/lang-api/src/com/intellij/refactoring/changeSignature/ChangeSignatureHandler.java new file mode 100644 index 000000000000..00a88165b802 --- /dev/null +++ b/platform/lang-api/src/com/intellij/refactoring/changeSignature/ChangeSignatureHandler.java @@ -0,0 +1,33 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.refactoring.changeSignature; + +import com.intellij.openapi.editor.Editor; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.RefactoringBundle; +import org.jetbrains.annotations.Nullable; + +/** + * @author Maxim.Medvedev + */ +public interface ChangeSignatureHandler extends RefactoringActionHandler{ + String REFACTORING_NAME = RefactoringBundle.message("changeSignature.refactoring.name"); + + @Nullable + PsiElement findTargetMember(PsiFile file, Editor editor); +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringBundle.properties index 10fd18f55e55..eb617f3e9cb6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringBundle.properties +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringBundle.properties @@ -99,3 +99,9 @@ variable.conflicts.with.field.0=Chosen name will conflict with field {0} introduce.parameter.title=Introduce Parameter groovy.does.not.support.inner.classes.but.it.is.used.in.parameter.initializer=Groovy does not support inner classes but it is used in parameter initializer. groovy.does.not.support.anonymous.classes.but.it.is.used.in.parameter.initializer=Groovy does not support anonymous classes but it is used in parameter initializer. +error.wrong.caret.position.method.name=The caret should be positioned at the name of the method to be refactored. +changeSignature.refactoring.name=Change Signature +column.name.type=Type +column.name.name=Name +column.name.default.initializer=Default initializer +column.name.default.value=Default value\ diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringSupportProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringSupportProvider.java index 1aa3631adcf4..61e08638e865 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringSupportProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringSupportProvider.java @@ -19,8 +19,10 @@ package org.jetbrains.plugins.groovy.refactoring; import com.intellij.lang.refactoring.DefaultRefactoringSupportProvider; import com.intellij.psi.PsiElement; import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.changeSignature.ChangeSignatureHandler; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; +import org.jetbrains.plugins.groovy.refactoring.changeSignature.GrChangeSignatureHandler; import org.jetbrains.plugins.groovy.refactoring.extractMethod.GroovyExtractMethodHandler; import org.jetbrains.plugins.groovy.refactoring.introduceVariable.GroovyIntroduceVariableHandler; @@ -47,4 +49,9 @@ public class GroovyRefactoringSupportProvider extends DefaultRefactoringSupportP public RefactoringActionHandler getExtractMethodHandler() { return new GroovyExtractMethodHandler(); } + + @Override + public ChangeSignatureHandler getChangeSignatureHandler() { + return new GrChangeSignatureHandler(); + } } 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 new file mode 100644 index 000000000000..8afbd5ea2cca --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureDialog.form @@ -0,0 +1,181 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 new file mode 100644 index 000000000000..ae0a8c0726df --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureDialog.java @@ -0,0 +1,67 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.refactoring.changeSignature; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; + +import javax.swing.*; + +/** + * @author Maxim.Medvedev + */ +public class GrChangeSignatureDialog extends DialogWrapper { + private JTextField myNameField; + private JTextField myReturnTypeField; + private JRadioButton myPublicRadioButton; + + private JRadioButton myProtectedRadioButton; + private JRadioButton myPrivateRadioButton1; + private JPanel myParametersPanel; + private JTable myParameterTable; + private JButton myAddButton; + private JButton myRemoveButton; + private JButton myMoveUpButton; + private JButton myMoveDownButton; + private JPanel contentPane; + private GrParameterTableModel myParameterModel; + private GrMethod myMethod; + + public GrChangeSignatureDialog(@NotNull Project project, GrMethod method) { + super(project, true); + myMethod = method; + myParameterModel = new GrParameterTableModel(myMethod, this); + myParameterTable.setModel(myParameterModel); + myParameterTable.setCellSelectionEnabled(true); + init(); + } + + public GrChangeSignatureDialog() { + super(true); + } + + @Override + protected void doOKAction() { + super.doOKAction(); + } + + @Override + protected JComponent createCenterPanel() { + return contentPane; + } +} \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureHandler.java new file mode 100644 index 000000000000..7383624792f6 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureHandler.java @@ -0,0 +1,103 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.refactoring.changeSignature; + +import com.intellij.codeInsight.TargetElementUtil; +import com.intellij.ide.util.SuperMethodWarningUtil; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.changeSignature.ChangeSignatureHandler; +import com.intellij.refactoring.util.CommonRefactoringUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; +import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle; + +/** + * @author Maxim.Medvedev + */ +public class GrChangeSignatureHandler implements ChangeSignatureHandler { + public static final String REFACTORING_NAME = GroovyRefactoringBundle.message("changeSignature.refactoring.name"); + + public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) { + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + PsiElement element = findTargetMember(file, editor); + if (element == null) { + element = LangDataKeys.PSI_ELEMENT.getData(dataContext); + } + invokeOnElement(project, editor, element); + } + + private static void invokeOnElement(Project project, Editor editor, PsiElement element) { + if (element instanceof PsiMethod) { + invoke((PsiMethod)element, project, editor); + } + else { + String message = + RefactoringBundle.getCannotRefactorMessage(GroovyRefactoringBundle.message("error.wrong.caret.position.method.name")); + CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.CHANGE_SIGNATURE); + } + } + + public void invoke(@NotNull final Project project, @NotNull final PsiElement[] elements, final DataContext dataContext) { + if (elements.length != 1) return; + Editor editor = PlatformDataKeys.EDITOR.getData(dataContext); + invokeOnElement(project, editor, elements[0]); + } + + private static void invoke(final PsiMethod method, final Project project, @Nullable final Editor editor) { + if (!CommonRefactoringUtil.checkReadOnlyStatus(project, method)) return; + + PsiMethod newMethod = SuperMethodWarningUtil.checkSuperMethod(method, RefactoringBundle.message("to.refactor")); + if (newMethod == null) return; + + if (!newMethod.equals(method)) { + invoke(newMethod, project, editor); + return; + } + + if (!CommonRefactoringUtil.checkReadOnlyStatus(project, method)) return; + + final PsiClass containingClass = method.getContainingClass(); + final PsiReference refExpr = editor != null ? TargetElementUtil.findReference(editor) : null; + if (!(method instanceof GrMethod)) return; //todo + final GrChangeSignatureDialog dialog = new GrChangeSignatureDialog(project, (GrMethod)method); + dialog.show(); + } + + @Nullable + public PsiMethod findTargetMember(PsiFile file, Editor editor) { + final PsiElement element = file.findElementAt(editor.getCaretModel().getOffset()); + final GrParameterList parameterList = PsiTreeUtil.getParentOfType(element, GrParameterList.class); + if (parameterList != null) { + final PsiElement parent = parameterList.getParent(); + if (parent instanceof PsiMethod) return (PsiMethod)parent; + } + final GrMethodCallExpression expression = PsiTreeUtil.getParentOfType(element, GrMethodCallExpression.class); + if (expression == null) return null; + return expression.resolveMethod(); + } +} 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 new file mode 100644 index 000000000000..8df0e66339c7 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrParameterInfo.java @@ -0,0 +1,85 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.refactoring.changeSignature; + +import com.intellij.psi.PsiType; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; + +/** + * @author Maxim.Medvedev + */ +public class GrParameterInfo { + private String myName = ""; + private String myDefaultValue = ""; + private String myType = ""; + private String myDefaultInitializer = ""; + private final int myPosition; + + public GrParameterInfo(GrParameter parameter, int position) { + myPosition = position; + myName = parameter.getName(); + final PsiType type = parameter.getDeclaredType(); + if (type != null) { + myType = type.getCanonicalText(); + } + final GrExpression defaultInitializer = parameter.getDefaultInitializer(); + if (defaultInitializer != null) { + myDefaultInitializer = defaultInitializer.getText(); + } + } + + + public GrParameterInfo() { + this.myPosition = -1; + } + + public String getName() { + return myName; + } + + public String getDefaultValue() { + return myDefaultValue; + } + + public String getType() { + return myType; + } + + public String getDefaultInitializer() { + return myDefaultInitializer; + } + + public void setName(String name) { + myName = name; + } + + public void setDefaultValue(String defaultValue) { + myDefaultValue = defaultValue; + } + + public void setType(String type) { + myType = type; + } + + public void setDefaultInitializer(String defaultInitializer) { + myDefaultInitializer = defaultInitializer; + } + + public int getPosition() { + return myPosition; + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrParameterTableModel.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrParameterTableModel.java new file mode 100644 index 000000000000..5dfd38f676cb --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrParameterTableModel.java @@ -0,0 +1,138 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.refactoring.changeSignature; + +import com.intellij.ui.RowEditableTableModel; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; +import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle; + +import javax.swing.table.AbstractTableModel; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Maxim.Medvedev + */ +public class GrParameterTableModel extends AbstractTableModel implements RowEditableTableModel { + private final List infos; + private final GrMethod myMethod; + private final GrChangeSignatureDialog myDialog; + + + public GrParameterTableModel(GrMethod method, GrChangeSignatureDialog dialog) { + myMethod = method; + myDialog = dialog; + final GrParameter[] parameters = myMethod.getParameters(); + infos = new ArrayList(parameters.length); + for (int i = 0; i < parameters.length; i++) { + GrParameter parameter = parameters[i]; + infos.add(new GrParameterInfo(parameter, i)); + } + } + + public void addRow() { + final int row = infos.size(); + infos.add(new GrParameterInfo()); + fireTableRowsInserted(row, row); + } + + public void removeRow(int index) { + infos.remove(index); + fireTableRowsDeleted(index, index); + } + + public void exchangeRows(int index1, int index2) { + final GrParameterInfo info = infos.get(index1); + infos.set(index1, infos.get(index2)); + infos.set(index2, info); + fireTableRowsUpdated(Math.min(index1, index2), Math.max(index1, index2)); + } + + + public int getRowCount() { + return infos.size(); + } + + public int getColumnCount() { + return 4; + } + + @Nullable + public Object getValueAt(int rowIndex, int columnIndex) { + if (rowIndex < 0 || rowIndex >= infos.size()) return null; + final GrParameterInfo info = infos.get(rowIndex); + switch (columnIndex) { + case 0: + return info.getType(); + case 1: + return info.getName(); + case 2: + return info.getDefaultInitializer(); + case 3: + return info.getDefaultValue(); + default: + throw new IllegalArgumentException(); + } + } + + @Override + public void setValueAt(Object value, int rowIndex, int columnIndex) { + if (rowIndex < 0 || rowIndex >= infos.size()) return; + if (columnIndex < 0 || columnIndex > 3) return; + + String s = value instanceof String ? (String)value : ""; + s = s.trim(); + final GrParameterInfo info = infos.get(rowIndex); + switch (columnIndex) { + case 0: + info.setType(s); + case 1: + info.setName(s); + case 2: + info.setDefaultInitializer(s); + case 3: + info.setDefaultValue(s); + } + fireTableCellUpdated(rowIndex, columnIndex); + } + + + @Override + public String getColumnName(int column) { + switch (column) { + case 0: + return GroovyRefactoringBundle.message("column.name.type"); + case 1: + return GroovyRefactoringBundle.message("column.name.name"); + case 2: + return GroovyRefactoringBundle.message("column.name.default.initializer"); + case 3: + return GroovyRefactoringBundle.message("column.name.default.value"); + default: + throw new IllegalArgumentException(); + } + } + + @Override + public Class getColumnClass(int columnIndex) { + if (columnIndex < 0 || columnIndex > 3) throw new IllegalArgumentException(); + return String.class; + } + + +} \ No newline at end of file