mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
inplace rename: ask about super method non-modal
This commit is contained in:
@@ -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) {
|
||||
}
|
||||
|
||||
+16
-2
@@ -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;
|
||||
}
|
||||
|
||||
+2
-3
@@ -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");
|
||||
|
||||
+16
-13
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user