inplace rename: ask about super method non-modal

This commit is contained in:
anna
2011-11-23 09:42:27 +01:00
parent 1bb7a9c409
commit c29b5854fa
7 changed files with 120 additions and 21 deletions
@@ -16,12 +16,17 @@
package com.intellij.ide.util;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.presentation.java.SymbolPresentationUtil;
import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.search.searches.DeepestSuperMethodsSearch;
import com.intellij.ui.components.JBList;
import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
@@ -102,4 +107,51 @@ public class SuperMethodWarningUtil {
return null;
}
public static void checkSuperMethod(final PsiMethod method,
final String actionString,
final PsiElementProcessor<PsiMethod> processor,
final Editor editor) {
PsiClass aClass = method.getContainingClass();
if (aClass == null) {
processor.execute(method);
return;
}
PsiMethod superMethod = method.findDeepestSuperMethod();
if (superMethod == null) {
processor.execute(method);
return;
}
final PsiClass containingClass = superMethod.getContainingClass();
if (containingClass == null) {
processor.execute(method);
return;
}
if (ApplicationManager.getApplication().isUnitTestMode()) {
processor.execute(superMethod);
return;
}
final PsiMethod[] methods = new PsiMethod[]{superMethod, method};
final String renameBase = actionString + " base method";
final String renameCurrent = actionString + " only current method";
final JBList list = new JBList(renameBase, renameCurrent);
JBPopupFactory.getInstance().createListPopupBuilder(list)
.setTitle(method.getName() + (containingClass.isInterface() && !aClass.isInterface() ? " implements" : " overrides") + " method of " +
SymbolPresentationUtil.getSymbolPresentableText(containingClass))
.setMovable(false)
.setResizable(false)
.setRequestFocus(true)
.setItemChoosenCallback(new Runnable() {
public void run() {
final Object value = list.getSelectedValue();
if (value instanceof String) {
processor.execute(methods[value.equals(renameBase) ? 0 : 1]);
}
}
}).createPopup().showInBestPositionFor(editor);
}
}
@@ -65,9 +65,6 @@ public class JavaRefactoringSupportProvider extends RefactoringSupportProvider {
@Override
public boolean isMemberInplaceRenameAvailable(PsiElement elementToRename, PsiElement context) {
if (elementToRename instanceof PsiMethod && ((PsiMethod)elementToRename).findDeepestSuperMethods().length > 0) {
return false;
}
return elementToRename instanceof PsiMember;
}
@@ -18,8 +18,10 @@ package com.intellij.refactoring.rename;
import com.intellij.ide.util.SuperMethodWarningUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.Pass;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.search.searches.MethodReferencesSearch;
@@ -237,6 +239,25 @@ public class RenameJavaMethodProcessor extends RenameJavaMemberProcessor {
return SuperMethodWarningUtil.checkSuperMethod(psiMethod, RefactoringBundle.message("to.rename"));
}
@Override
public void substituteElementToRename(@NotNull PsiElement element,
@NotNull Editor editor,
@NotNull final Pass<PsiElement> renameCallback) {
PsiMethod psiMethod = (PsiMethod)element;
if (psiMethod.isConstructor()) {
super.substituteElementToRename(element, editor, renameCallback);
}
else {
SuperMethodWarningUtil.checkSuperMethod(psiMethod, "Rename", new PsiElementProcessor<PsiMethod>() {
@Override
public boolean execute(@NotNull PsiMethod method) {
renameCallback.pass(method);
return false;
}
}, editor);
}
}
private static void findSubmemberHidesMemberCollisions(final PsiMethod method, final String newName, final List<UsageInfo> result) {
final PsiClass containingClass = method.getContainingClass();
if (containingClass == null) return;
@@ -21,6 +21,7 @@ import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Pass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileSystemItem;
@@ -161,6 +162,18 @@ public abstract class RenamePsiElementProcessor {
return element;
}
/**
* Substitutes element to be renamed and initiate rename procedure. Should be used in order to prevent modal dialogs to appear during inplace rename
* @param element the element on which refactoring was invoked
* @param editor the editor in which inplace refactoring was invoked
* @param renameCallback rename procedure which should be called on the chosen substitution
*/
public void substituteElementToRename(@NotNull final PsiElement element, @NotNull Editor editor, @NotNull Pass<PsiElement> renameCallback) {
final PsiElement psiElement = substituteElementToRename(element, editor);
if (psiElement == null) return;
renameCallback.pass(psiElement);
}
public void findCollisions(final PsiElement element, final String newName, final Map<? extends PsiElement, String> allRenames,
final List<UsageInfo> result) {
}
@@ -18,12 +18,15 @@ package com.intellij.refactoring.rename.inplace;
import com.intellij.codeInsight.lookup.LookupManager;
import com.intellij.lang.LanguageRefactoringSupport;
import com.intellij.lang.refactoring.RefactoringSupportProvider;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.Pass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiNameIdentifierOwner;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.rename.RenamePsiElementProcessor;
import org.jetbrains.annotations.NotNull;
/**
@@ -45,9 +48,20 @@ public class MemberInplaceRenameHandler extends VariableInplaceRenameHandler {
}
@Override
protected VariableInplaceRenamer createRenamer(@NotNull PsiElement elementToRename, Editor editor) {
public VariableInplaceRenamer doRename(@NotNull final PsiElement elementToRename, final Editor editor, final DataContext dataContext) {
if (elementToRename instanceof PsiNameIdentifierOwner) {
return new MemberInplaceRenamer((PsiNameIdentifierOwner)elementToRename, editor);
RenamePsiElementProcessor.forElement(elementToRename).substituteElementToRename(elementToRename, editor, new Pass<PsiElement>() {
@Override
public void pass(PsiElement element) {
final MemberInplaceRenamer renamer = new MemberInplaceRenamer((PsiNameIdentifierOwner)elementToRename, element, editor);
boolean startedRename = renamer.performInplaceRename();
if (!startedRename) {
performDialogRename(elementToRename, editor, dataContext);
}
}
});
} else {
performDialogRename(elementToRename, editor, dataContext);
}
return null;
}
@@ -58,11 +58,10 @@ public class MemberInplaceRenamer extends VariableInplaceRenamer {
private final PsiElement mySubstituted;
private RangeMarker mySubstitutedRange;
public MemberInplaceRenamer(@NotNull PsiNameIdentifierOwner elementToRename, Editor editor) {
public MemberInplaceRenamer(@NotNull PsiNameIdentifierOwner elementToRename, PsiElement substituted, Editor editor) {
super(elementToRename, editor);
myOldName = elementToRename.getName();
final RenamePsiElementProcessor processor = RenamePsiElementProcessor.forElement(elementToRename);
mySubstituted = processor.substituteElementToRename(elementToRename, myEditor);
mySubstituted = substituted;
mySubstitutedRange = mySubstituted != null && mySubstituted != myElementToRename && mySubstituted.getTextRange() != null ? myEditor.getDocument().createRangeMarker(mySubstituted.getTextRange()) : null;
showDialogAdvertisement("RenameElement");
@@ -112,23 +112,26 @@ public class VariableInplaceRenameHandler implements RenameHandler {
boolean startedRename = renamer == null ? false : renamer.performInplaceRename();
if (!startedRename) {
try {
ourPreventInlineRenameFlag.set(Boolean.TRUE);
RenameHandler handler = RenameHandlerRegistry.getInstance().getRenameHandler(dataContext);
assert handler != null;
handler.invoke(
elementToRename.getProject(),
editor,
elementToRename.getContainingFile(), dataContext
);
} finally {
ourPreventInlineRenameFlag.set(null);
}
performDialogRename(elementToRename, editor, dataContext);
}
return renamer;
}
protected static void performDialogRename(PsiElement elementToRename, Editor editor, DataContext dataContext) {
try {
ourPreventInlineRenameFlag.set(Boolean.TRUE);
RenameHandler handler = RenameHandlerRegistry.getInstance().getRenameHandler(dataContext);
assert handler != null;
handler.invoke(
elementToRename.getProject(),
editor,
elementToRename.getContainingFile(), dataContext
);
} finally {
ourPreventInlineRenameFlag.set(null);
}
}
@Nullable
protected VariableInplaceRenamer createRenamer(@NotNull PsiElement elementToRename, Editor editor) {
return new VariableInplaceRenamer((PsiNameIdentifierOwner)elementToRename, editor);