diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHandler.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHandler.java index 5a21d945fd79..d24ffeeaf2ac 100644 --- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/JavaPullUpHandler.java @@ -28,12 +28,14 @@ import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Caret; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.ScrollType; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; 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; @@ -58,56 +60,41 @@ public class JavaPullUpHandler implements RefactoringActionHandler, PullUpDialog @Override public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) { - int offset = editor.getCaretModel().getOffset(); editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); - PsiElement element = file.findElementAt(offset); + List elements = new ArrayList<>(); + for (Caret caret : editor.getCaretModel().getAllCarets()) { + int offset = caret.getOffset(); + PsiElement element = file.findElementAt(offset); - while (true) { - if (element == null || element instanceof PsiFile) { - String message = RefactoringBundle - .getCannotRefactorMessage(RefactoringBundle.message("the.caret.should.be.positioned.inside.a.class.to.pull.members.from")); - CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.MEMBERS_PULL_UP); - return; + while (element != null && !(element instanceof PsiFile)) { + if (element instanceof PsiClass || element instanceof PsiField || element instanceof PsiMethod) { + elements.add(element); + break; + } + element = element.getParent(); } - - if (!CommonRefactoringUtil.checkReadOnlyStatus(project, element)) return; - - if (element instanceof PsiClass || element instanceof PsiField || element instanceof PsiMethod) { - invoke(project, new PsiElement[]{element}, dataContext); - return; - } - element = element.getParent(); + } + if (elements.isEmpty()) { + String message = RefactoringBundle + .getCannotRefactorMessage(RefactoringBundle.message("the.caret.should.be.positioned.inside.a.class.to.pull.members.from")); + CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.MEMBERS_PULL_UP); + } + else { + invoke(project, elements.toArray(PsiElement.EMPTY_ARRAY),dataContext); } } @Override public void invoke(@NotNull final Project project, @NotNull PsiElement[] elements, DataContext dataContext) { - if (elements.length != 1) return; + myProject = project; - PsiElement element = elements[0]; - PsiClass aClass; - PsiElement aMember = null; + PsiClass aClass = PsiTreeUtil.getParentOfType(PsiTreeUtil.findCommonParent(elements), PsiClass.class, false); - if (element instanceof PsiClass) { - aClass = (PsiClass)element; - } - else if (element instanceof PsiMethod) { - aClass = ((PsiMethod)element).getContainingClass(); - aMember = element; - } - else if (element instanceof PsiField) { - aClass = ((PsiField)element).getContainingClass(); - aMember = element; - } - else { - return; - } - - invoke(project, dataContext, aClass, aMember); + invoke(project, dataContext, aClass, elements); } - private void invoke(Project project, DataContext dataContext, PsiClass aClass, PsiElement aMember) { + private void invoke(Project project, DataContext dataContext, PsiClass aClass, PsiElement... selectedMembers) { final Editor editor = dataContext != null ? CommonDataKeys.EDITOR.getData(dataContext) : null; if (aClass == null) { String message = @@ -130,21 +117,17 @@ public class JavaPullUpHandler implements RefactoringActionHandler, PullUpDialog return; } - + if (!CommonRefactoringUtil.checkReadOnlyStatus(project, aClass)) return; mySubclass = aClass; - MemberInfoStorage memberInfoStorage = new MemberInfoStorage(mySubclass, new MemberInfo.Filter() { - @Override - public boolean includeMember(PsiMember element) { - return true; - } - }); + MemberInfoStorage memberInfoStorage = new MemberInfoStorage(mySubclass, element -> true); List members = memberInfoStorage.getClassMemberInfos(mySubclass); - PsiManager manager = mySubclass.getManager(); for (MemberInfoBase member : members) { - if (manager.areElementsEquivalent(member.getMember(), aMember)) { - member.setChecked(true); - break; + for (PsiElement aMember : selectedMembers) { + if (PsiTreeUtil.isAncestor(member.getMember(), aMember, false)) { + member.setChecked(true); + break; + } } } diff --git a/java/java-impl/src/com/intellij/refactoring/memberPushDown/JavaPushDownHandler.java b/java/java-impl/src/com/intellij/refactoring/memberPushDown/JavaPushDownHandler.java index 1997191a9fee..3e12e982a481 100644 --- a/java/java-impl/src/com/intellij/refactoring/memberPushDown/JavaPushDownHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/memberPushDown/JavaPushDownHandler.java @@ -16,22 +16,24 @@ package com.intellij.refactoring.memberPushDown; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Caret; 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.impl.source.jsp.jspJava.JspClass; +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.classMembers.MemberInfoBase; import com.intellij.refactoring.lang.ElementsHandler; import com.intellij.refactoring.util.CommonRefactoringUtil; -import com.intellij.refactoring.util.RefactoringMessageUtil; import com.intellij.refactoring.util.classMembers.MemberInfo; import com.intellij.refactoring.util.classMembers.MemberInfoStorage; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; import java.util.List; /** @@ -41,67 +43,63 @@ public class JavaPushDownHandler implements RefactoringActionHandler, ElementsHa public static final String REFACTORING_NAME = RefactoringBundle.message("push.members.down.title"); public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) { - int offset = editor.getCaretModel().getOffset(); editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); - PsiElement element = file.findElementAt(offset); + ArrayList elements = new ArrayList<>(); + String errorMessage = null; + for (Caret caret : editor.getCaretModel().getAllCarets()) { + int offset = caret.getOffset(); + PsiElement element = file.findElementAt(offset); + String errorFromElement = collectElementsUnderCaret(element, elements); + if (errorFromElement != null) { + errorMessage = errorFromElement; + } + } + if (elements.isEmpty()) { + String message = errorMessage != null ? errorMessage + : RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("the.caret.should.be.positioned.inside.a.class.to.push.members.from")); + CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.MEMBERS_PUSH_DOWN); + return; + } + + invoke(project, elements.toArray(new PsiElement[0]), dataContext); + } + + private static String collectElementsUnderCaret(PsiElement element, List elements) { while (true) { if (element == null || element instanceof PsiFile) { - String message = RefactoringBundle.getCannotRefactorMessage( - RefactoringBundle.message("the.caret.should.be.positioned.inside.a.class.to.push.members.from")); - CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.MEMBERS_PUSH_DOWN); - return; + return RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("the.caret.should.be.positioned.inside.a.class.to.push.members.from")); } if (element instanceof PsiClass || element instanceof PsiField || element instanceof PsiMethod) { if (element instanceof JspClass) { - RefactoringMessageUtil.showNotSupportedForJspClassesError(project, editor, REFACTORING_NAME, HelpID.MEMBERS_PUSH_DOWN); - return; + return RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("refactoring.is.not.supported.for.jsp.classes")); } - invoke(project, new PsiElement[]{element}, dataContext); - return; + elements.add(element); + return null; } element = element.getParent(); } } public void invoke(@NotNull final Project project, @NotNull PsiElement[] elements, DataContext dataContext) { - if (elements.length != 1) return; - - PsiElement element = elements[0]; - PsiClass aClass; - PsiElement aMember = null; - - if (element instanceof PsiClass) { - aClass = (PsiClass) element; - } else if (element instanceof PsiMethod) { - aClass = ((PsiMethod) element).getContainingClass(); - aMember = element; - } else if (element instanceof PsiField) { - aClass = ((PsiField) element).getContainingClass(); - aMember = element; - } else - return; + PsiClass aClass = PsiTreeUtil.getParentOfType(PsiTreeUtil.findCommonParent(elements), PsiClass.class, false); + if (aClass == null) return; if (!CommonRefactoringUtil.checkReadOnlyStatus(project, aClass)) return; - MemberInfoStorage memberInfoStorage = new MemberInfoStorage(aClass, new MemberInfo.Filter() { - public boolean includeMember(PsiMember element) { - return !(element instanceof PsiEnumConstant); - } - }); + MemberInfoStorage memberInfoStorage = new MemberInfoStorage(aClass, element -> !(element instanceof PsiEnumConstant)); + List members = memberInfoStorage.getClassMemberInfos(aClass); - PsiManager manager = aClass.getManager(); for (MemberInfoBase member : members) { - if (manager.areElementsEquivalent(member.getMember(), aMember)) { - member.setChecked(true); - break; + for (PsiElement element : elements) { + if (PsiTreeUtil.isAncestor(member.getMember(), element, false)) { + member.setChecked(true); + break; + } } } - PushDownDialog dialog = new PushDownDialog( - project, - members.toArray(new MemberInfo[members.size()]), - aClass); + PushDownDialog dialog = new PushDownDialog(project, members.toArray(new MemberInfo[members.size()]), aClass); dialog.show(); }