update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / codeInsight / daemon / impl / quickfix / ModifierFix.java
bloba5d1ea164e74f6e135ddb5f4a3f0e2a1954a60ea
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.codeInsight.daemon.impl.quickfix;
18 import com.intellij.codeInsight.CodeInsightUtilBase;
19 import com.intellij.codeInsight.daemon.QuickFixBundle;
20 import com.intellij.codeInspection.IntentionAndQuickFixAction;
21 import com.intellij.openapi.application.ApplicationManager;
22 import com.intellij.openapi.command.undo.UndoUtil;
23 import com.intellij.openapi.diagnostic.Logger;
24 import com.intellij.openapi.editor.Editor;
25 import com.intellij.openapi.project.Project;
26 import com.intellij.openapi.ui.DialogWrapper;
27 import com.intellij.openapi.ui.Messages;
28 import com.intellij.psi.*;
29 import com.intellij.psi.search.PsiElementProcessor;
30 import com.intellij.psi.search.PsiElementProcessorAdapter;
31 import com.intellij.psi.search.searches.OverridingMethodsSearch;
32 import com.intellij.psi.util.PsiFormatUtil;
33 import com.intellij.psi.util.PsiUtil;
34 import com.intellij.util.VisibilityUtil;
35 import com.intellij.util.IncorrectOperationException;
36 import org.jetbrains.annotations.NotNull;
37 import org.jetbrains.annotations.Nullable;
39 import java.util.ArrayList;
40 import java.util.List;
42 public class ModifierFix extends IntentionAndQuickFixAction {
43 private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.ModifierFix");
45 private final PsiModifierList myModifierList;
46 @Modifier private final String myModifier;
47 private final boolean myShouldHave;
48 private final boolean myShowContainingClass;
49 private PsiVariable myVariable;
51 public ModifierFix(PsiModifierList modifierList, @Modifier @NotNull String modifier, boolean shouldHave, boolean showContainingClass) {
52 myModifierList = modifierList;
53 myModifier = modifier;
54 myShouldHave = shouldHave;
55 myShowContainingClass = showContainingClass;
57 public ModifierFix(@NotNull PsiModifierListOwner owner, @Modifier @NotNull String modifier, boolean shouldHave, boolean showContainingClass) {
58 this(owner.getModifierList(), modifier, shouldHave, showContainingClass);
59 if (owner instanceof PsiVariable) {
60 myVariable = (PsiVariable)owner;
64 @NotNull
65 public String getName() {
66 String name = null;
67 PsiElement parent = myVariable == null ? myModifierList.getParent() : myVariable;
68 if (parent instanceof PsiClass) {
69 name = ((PsiClass)parent).getName();
71 else {
72 int options = PsiFormatUtil.SHOW_NAME | (myShowContainingClass ? PsiFormatUtil.SHOW_CONTAINING_CLASS : 0);
73 if (parent instanceof PsiMethod) {
74 name = PsiFormatUtil.formatMethod((PsiMethod)parent, PsiSubstitutor.EMPTY, options, 0);
76 else if (parent instanceof PsiVariable) {
77 name = PsiFormatUtil.formatVariable((PsiVariable)parent, options, PsiSubstitutor.EMPTY);
79 else if (parent instanceof PsiClassInitializer) {
80 PsiClass containingClass = ((PsiClassInitializer)parent).getContainingClass();
81 String className = containingClass instanceof PsiAnonymousClass
82 ? QuickFixBundle.message("anonymous.class.presentation", ((PsiAnonymousClass)containingClass).getBaseClassType().getPresentableText())
83 : containingClass.getName();
84 name = QuickFixBundle.message("class.initializer.presentation", className);
88 String modifierText = VisibilityUtil.toPresentableText(myModifier);
90 return QuickFixBundle.message(myShouldHave ? "add.modifier.fix" : "remove.modifier.fix", name, modifierText);
93 @NotNull
94 public String getFamilyName() {
95 return QuickFixBundle.message("fix.modifiers.family");
98 public boolean isAvailable(@NotNull final Project project, final Editor editor, final PsiFile file) {
99 return myModifierList != null &&
100 myModifierList.isValid() &&
101 myModifierList.getManager().isInProject(myModifierList) &&
102 (myVariable == null || myVariable.isValid());
105 private void changeModifierList (PsiModifierList modifierList) {
106 try {
107 modifierList.setModifierProperty(myModifier, myShouldHave);
109 catch (IncorrectOperationException e) {
110 LOG.error(e);
114 public void applyFix(final Project project, final PsiFile file, @Nullable final Editor editor) {
115 if (!CodeInsightUtilBase.preparePsiElementForWrite(myModifierList)) return;
116 final List<PsiModifierList> modifierLists = new ArrayList<PsiModifierList>();
117 final PsiFile containingFile = myModifierList.getContainingFile();
118 final PsiModifierList modifierList;
119 if (myVariable != null && myVariable.isValid()) {
120 ApplicationManager.getApplication().runWriteAction(new Runnable() {
121 public void run() {
122 try {
123 myVariable.normalizeDeclaration();
125 catch (IncorrectOperationException e) {
126 LOG.error(e);
130 modifierList = myVariable.getModifierList();
131 assert modifierList != null;
133 else {
134 modifierList = myModifierList;
136 PsiElement owner = modifierList.getParent();
137 if (owner instanceof PsiMethod) {
138 PsiModifierList copy = (PsiModifierList)myModifierList.copy();
139 changeModifierList(copy);
140 final int accessLevel = PsiUtil.getAccessLevel(copy);
142 OverridingMethodsSearch.search((PsiMethod)owner, owner.getResolveScope(), true).forEach(new PsiElementProcessorAdapter<PsiMethod>(new PsiElementProcessor<PsiMethod>() {
143 public boolean execute(PsiMethod inheritor) {
144 PsiModifierList list = inheritor.getModifierList();
145 if (inheritor.getManager().isInProject(inheritor) && PsiUtil.getAccessLevel(list) < accessLevel) {
146 modifierLists.add(list);
148 return true;
150 }));
153 if (!CodeInsightUtilBase.prepareFileForWrite(containingFile)) return;
155 if (!modifierLists.isEmpty()) {
156 if (Messages.showYesNoDialog(project,
157 QuickFixBundle.message("change.inheritors.visibility.warning.text"),
158 QuickFixBundle.message("change.inheritors.visibility.warning.title"),
159 Messages.getQuestionIcon()) == DialogWrapper.OK_EXIT_CODE) {
160 ApplicationManager.getApplication().runWriteAction(new Runnable() {
161 public void run() {
162 if (!CodeInsightUtilBase.preparePsiElementsForWrite(modifierLists)) {
163 return;
166 for (final PsiModifierList modifierList : modifierLists) {
167 changeModifierList(modifierList);
174 ApplicationManager.getApplication().runWriteAction(new Runnable() {
175 public void run() {
176 changeModifierList(modifierList);
177 UndoUtil.markPsiFileForUndo(containingFile);
182 public boolean startInWriteAction() {
183 return false;