rename all super methods in case of multiple inheritance (IDEA-167599)

This commit is contained in:
Anna Kozlova
2017-06-20 11:32:03 +03:00
parent 39815e1c7a
commit 18f18cb834
2 changed files with 55 additions and 27 deletions
@@ -23,6 +23,7 @@ import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
@@ -43,6 +44,7 @@ import java.util.HashSet;
import java.util.Set;
public class SuperMethodWarningUtil {
public static Key<PsiMethod[]> SIBLINGS = Key.create("MULTIPLE_INHERITANCE");
private SuperMethodWarningUtil() {}
@NotNull
@@ -138,37 +140,52 @@ public class SuperMethodWarningUtil {
return;
}
PsiMethod superMethod = method.findDeepestSuperMethod();
if (superMethod == null) {
PsiMethod[] superMethods = method.findDeepestSuperMethods();
if (superMethods.length == 0) {
processor.execute(method);
return;
}
final PsiClass containingClass = superMethod.getContainingClass();
final PsiClass containingClass = superMethods[0].getContainingClass();
if (containingClass == null) {
processor.execute(method);
return;
}
if (ApplicationManager.getApplication().isUnitTestMode()) {
processor.execute(superMethod);
processor.execute(superMethods[0]);
return;
}
final PsiMethod[] methods = {superMethod, method};
final String renameBase = actionString + " base method";
final PsiMethod[] methods = {superMethods[0], method};
final String renameBase = actionString + " base method" + (superMethods.length > 1 ? "s" : "");
final String renameCurrent = actionString + " only current method";
final JBList list = new JBList(renameBase, renameCurrent);
final JBList<String> list = new JBList<>(renameBase, renameCurrent);
String title = method.getName() +
(superMethods.length > 1 ? " has super methods"
: (containingClass.isInterface() && !aClass.isInterface() ? " implements"
: " overrides") +
" method of " + SymbolPresentationUtil.getSymbolPresentableText(containingClass));
JBPopupFactory.getInstance().createListPopupBuilder(list)
.setTitle(method.getName() + (containingClass.isInterface() && !aClass.isInterface() ? " implements" : " overrides") + " method of " +
SymbolPresentationUtil.getSymbolPresentableText(containingClass))
.setTitle(title)
.setMovable(false)
.setResizable(false)
.setRequestFocus(true)
.setItemChoosenCallback(() -> {
final Object value = list.getSelectedValue();
if (value instanceof String) {
processor.execute(methods[value.equals(renameBase) ? 0 : 1]);
if (value != null) {
if (value.equals(renameBase)) {
try {
methods[0].putUserData(SIBLINGS, superMethods);
processor.execute(methods[0]);
}
finally {
methods[0].putUserData(SIBLINGS, null);
}
}
else {
processor.execute(methods[1]);
}
}
}).createPopup().showInBestPositionFor(editor);
}
@@ -274,25 +274,36 @@ public class RenameJavaMethodProcessor extends RenameJavaMemberProcessor {
@Override
public void prepareRenaming(PsiElement element, final String newName, final Map<PsiElement, String> allRenames, SearchScope scope) {
final PsiMethod method = (PsiMethod) element;
OverridingMethodsSearch.search(method, scope, true).forEach(overrider -> {
if (overrider instanceof PsiMirrorElement) {
final PsiElement prototype = ((PsiMirrorElement)overrider).getPrototype();
if (prototype instanceof PsiMethod) {
overrider = (PsiMethod)prototype;
PsiMethod[] siblings = method.getUserData(SuperMethodWarningUtil.SIBLINGS);
if (siblings == null) {
siblings = new PsiMethod[] {method};
}
for (PsiMethod sibling : siblings) {
//append all super methods
if (sibling != method) {
allRenames.put(sibling, newName);
}
OverridingMethodsSearch.search(sibling, scope, true).forEach(overrider -> {
if (overrider instanceof PsiMirrorElement) {
final PsiElement prototype = ((PsiMirrorElement)overrider).getPrototype();
if (prototype instanceof PsiMethod) {
overrider = (PsiMethod)prototype;
}
}
}
if (overrider instanceof SyntheticElement) return true;
if (overrider instanceof SyntheticElement) return true;
final String overriderName = overrider.getName();
final String baseName = method.getName();
final String newOverriderName = RefactoringUtil.suggestNewOverriderName(overriderName, baseName, newName);
if (newOverriderName != null) {
RenameProcessor.assertNonCompileElement(overrider);
allRenames.put(overrider, newOverriderName);
}
return true;
});
final String overriderName = overrider.getName();
final String baseName = sibling.getName();
final String newOverriderName = RefactoringUtil.suggestNewOverriderName(overriderName, baseName, newName);
if (newOverriderName != null) {
RenameProcessor.assertNonCompileElement(overrider);
allRenames.put(overrider, newOverriderName);
}
return true;
});
}
}
@NonNls