push up/down working over multiple carets

This commit is contained in:
Anna.Kozlova
2016-04-29 19:22:54 +02:00
parent cb93a73770
commit ee28567312
2 changed files with 69 additions and 88 deletions
@@ -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<PsiElement> 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<PsiMember>() {
@Override
public boolean includeMember(PsiMember element) {
return true;
}
});
MemberInfoStorage memberInfoStorage = new MemberInfoStorage(mySubclass, element -> true);
List<MemberInfo> members = memberInfoStorage.getClassMemberInfos(mySubclass);
PsiManager manager = mySubclass.getManager();
for (MemberInfoBase<PsiMember> 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;
}
}
}
@@ -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<PsiElement> 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<PsiElement> 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<PsiMember>() {
public boolean includeMember(PsiMember element) {
return !(element instanceof PsiEnumConstant);
}
});
MemberInfoStorage memberInfoStorage = new MemberInfoStorage(aClass, element -> !(element instanceof PsiEnumConstant));
List<MemberInfo> members = memberInfoStorage.getClassMemberInfos(aClass);
PsiManager manager = aClass.getManager();
for (MemberInfoBase<PsiMember> 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();
}