mock filetype manager if no application allows running lexer suites.
[fedora-idea.git] / refactoring / impl / com / intellij / refactoring / memberPullUp / PullUpHandler.java
blob8d52149aefadd0f7d3ba1ccd50416b017730899b
1 /*
2 * Created by IntelliJ IDEA.
3 * User: dsl
4 * Date: 18.06.2002
5 * Time: 12:45:30
6 * To change template for new class use
7 * Code Style | Class Templates options (Tools | IDE Options).
8 */
9 package com.intellij.refactoring.memberPullUp;
11 import com.intellij.history.LocalHistoryAction;
12 import com.intellij.history.LocalHistory;
13 import com.intellij.openapi.actionSystem.DataContext;
14 import com.intellij.openapi.actionSystem.PlatformDataKeys;
15 import com.intellij.openapi.application.ApplicationManager;
16 import com.intellij.openapi.command.CommandProcessor;
17 import com.intellij.openapi.diagnostic.Logger;
18 import com.intellij.openapi.editor.Editor;
19 import com.intellij.openapi.editor.ScrollType;
20 import com.intellij.openapi.project.Project;
21 import com.intellij.psi.*;
22 import com.intellij.refactoring.HelpID;
23 import com.intellij.refactoring.RefactoringActionHandler;
24 import com.intellij.refactoring.RefactoringBundle;
25 import com.intellij.refactoring.ui.ConflictsDialog;
26 import com.intellij.refactoring.util.CommonRefactoringUtil;
27 import com.intellij.refactoring.util.JavaDocPolicy;
28 import com.intellij.refactoring.util.RefactoringHierarchyUtil;
29 import com.intellij.refactoring.util.classMembers.MemberInfo;
30 import com.intellij.refactoring.util.classMembers.MemberInfoStorage;
31 import com.intellij.usageView.UsageViewUtil;
32 import com.intellij.util.IncorrectOperationException;
33 import org.jetbrains.annotations.NotNull;
35 import java.util.ArrayList;
36 import java.util.List;
38 public class PullUpHandler implements RefactoringActionHandler, PullUpDialog.Callback {
39 private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.memberPullUp.PullUpHandler");
40 public static final String REFACTORING_NAME = RefactoringBundle.message("pull.members.up.title");
41 private PsiClass mySubclass;
42 private Project myProject;
44 public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) {
45 int offset = editor.getCaretModel().getOffset();
46 editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
47 PsiElement element = file.findElementAt(offset);
49 while (true) {
50 if (element == null || element instanceof PsiFile) {
51 String message = RefactoringBundle
52 .getCannotRefactorMessage(RefactoringBundle.message("the.caret.should.be.positioned.inside.a.class.to.pull.members.from"));
53 CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.MEMBERS_PULL_UP);
54 return;
57 if (!CommonRefactoringUtil.checkReadOnlyStatus(project, element)) return;
59 if (element instanceof PsiClass || element instanceof PsiField || element instanceof PsiMethod) {
60 invoke(project, new PsiElement[]{element}, dataContext);
61 return;
63 element = element.getParent();
67 public void invoke(@NotNull final Project project, @NotNull PsiElement[] elements, DataContext dataContext) {
68 if (elements.length != 1) return;
69 myProject = project;
71 PsiElement element = elements[0];
72 PsiClass aClass;
73 PsiElement aMember = null;
75 if (element instanceof PsiClass) {
76 aClass = (PsiClass)element;
78 else if (element instanceof PsiMethod) {
79 aClass = ((PsiMethod)element).getContainingClass();
80 aMember = element;
82 else if (element instanceof PsiField) {
83 aClass = ((PsiField)element).getContainingClass();
84 aMember = element;
86 else {
87 return;
90 Editor editor = PlatformDataKeys.EDITOR.getData(dataContext);
91 if (aClass == null) {
92 String message =
93 RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("is.not.supported.in.the.current.context", REFACTORING_NAME));
94 CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.MEMBERS_PULL_UP);
95 return;
98 ArrayList<PsiClass> bases = RefactoringHierarchyUtil.createBasesList(aClass, false, true);
100 if (bases.isEmpty()) {
101 String message = RefactoringBundle.getCannotRefactorMessage(
102 RefactoringBundle.message("class.does.not.have.base.classes.interfaces.in.current.project", aClass.getQualifiedName()));
103 CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.MEMBERS_PULL_UP);
104 return;
108 mySubclass = aClass;
109 MemberInfoStorage memberInfoStorage = new MemberInfoStorage(mySubclass, new MemberInfo.Filter() {
110 public boolean includeMember(PsiMember element) {
111 return true;
114 List<MemberInfo> members = memberInfoStorage.getClassMemberInfos(mySubclass);
115 PsiManager manager = mySubclass.getManager();
117 for (MemberInfo member : members) {
118 if (manager.areElementsEquivalent(member.getMember(), aMember)) {
119 member.setChecked(true);
120 break;
124 final PullUpDialog dialog = new PullUpDialog(project, aClass, bases, memberInfoStorage, this);
127 dialog.show();
129 if (!dialog.isOK()) return;
131 CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
132 public void run() {
133 final Runnable action = new Runnable() {
134 public void run() {
135 doRefactoring(dialog);
138 ApplicationManager.getApplication().runWriteAction(action);
140 }, REFACTORING_NAME, null);
145 private void doRefactoring(PullUpDialog dialog) {
146 LocalHistoryAction a = LocalHistory.startAction(myProject, getCommandName());
147 try {
148 try {
149 PullUpHelper helper = new PullUpHelper(mySubclass, dialog.getSuperClass(), dialog.getSelectedMemberInfos(),
150 new JavaDocPolicy(dialog.getJavaDocPolicy()));
151 helper.moveMembersToBase();
152 helper.moveFieldInitializations();
154 finally {
155 a.finish();
158 catch (IncorrectOperationException e) {
159 LOG.error(e);
163 private String getCommandName() {
164 return RefactoringBundle.message("pullUp.command", UsageViewUtil.getDescriptiveName(mySubclass));
167 public boolean checkConflicts(PullUpDialog dialog) {
168 final MemberInfo[] infos = dialog.getSelectedMemberInfos();
169 PsiClass superClass = dialog.getSuperClass();
170 if (!checkWritable(superClass, infos)) return false;
171 String[] conflicts = PullUpConflictsUtil.checkConflicts(infos, mySubclass, superClass, null, null, dialog.getContainmentVerifier());
172 if (conflicts.length > 0) {
173 ConflictsDialog conflictsDialog = new ConflictsDialog(myProject, conflicts);
174 conflictsDialog.show();
175 return conflictsDialog.isOK();
177 return true;
180 private boolean checkWritable(PsiClass superClass, MemberInfo[] infos) {
181 if (!CommonRefactoringUtil.checkReadOnlyStatus(myProject, superClass)) return false;
182 for (MemberInfo info : infos) {
183 if (info.getMember() instanceof PsiClass && info.getOverrides() != null) continue;
184 if (!CommonRefactoringUtil.checkReadOnlyStatus(myProject, info.getMember())) return false;
186 return true;