2 * Copyright 2000-2013 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.
17 package com.intellij.codeInsight.daemon.impl.actions;
19 import com.intellij.codeInsight.FileModificationService;
20 import com.intellij.codeInspection.InjectionAwareSuppressQuickFix;
21 import com.intellij.codeInspection.InspectionsBundle;
22 import com.intellij.codeInspection.ProblemDescriptor;
23 import com.intellij.codeInspection.SuppressionUtil;
24 import com.intellij.icons.AllIcons;
25 import com.intellij.lang.Language;
26 import com.intellij.openapi.command.undo.UndoUtil;
27 import com.intellij.openapi.project.Project;
28 import com.intellij.openapi.util.Iconable;
29 import com.intellij.psi.PsiComment;
30 import com.intellij.psi.PsiElement;
31 import com.intellij.psi.PsiManager;
32 import com.intellij.psi.PsiWhiteSpace;
33 import com.intellij.psi.util.PsiTreeUtil;
34 import com.intellij.util.IncorrectOperationException;
35 import com.intellij.util.ThreeState;
36 import org.jetbrains.annotations.NotNull;
37 import org.jetbrains.annotations.Nullable;
40 import java.util.Collections;
41 import java.util.List;
44 * @author Roman.Chernyatchik
47 public abstract class AbstractBatchSuppressByNoInspectionCommentFix implements InjectionAwareSuppressQuickFix, Iconable {
48 @NotNull protected final String myID;
49 private final boolean myReplaceOtherSuppressionIds;
50 private ThreeState myShouldBeAppliedToInjectionHost = ThreeState.UNSURE;
53 public abstract PsiElement getContainer(final PsiElement context);
56 * @param ID Inspection ID
57 * @param replaceOtherSuppressionIds Merge suppression policy. If false new tool id will be append to the end
58 * otherwise replace other ids
60 public AbstractBatchSuppressByNoInspectionCommentFix(@NotNull String ID, final boolean replaceOtherSuppressionIds) {
62 myReplaceOtherSuppressionIds = replaceOtherSuppressionIds;
65 public void setShouldBeAppliedToInjectionHost(ThreeState shouldBeAppliedToInjectionHost) {
66 myShouldBeAppliedToInjectionHost = shouldBeAppliedToInjectionHost;
70 public ThreeState isShouldBeAppliedToInjectionHost() {
71 return myShouldBeAppliedToInjectionHost;
76 public String getName() {
81 public Icon getIcon(int flags) {
82 return AllIcons.General.InspectionsOff;
85 private String myText = "";
87 public String getText() {
91 protected void setText(@NotNull String text) {
95 public boolean startInWriteAction() {
100 public String toString() {
105 public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
106 PsiElement element = descriptor.getStartElement();
107 if (element == null) return;
108 invoke(project, element);
111 protected final void replaceSuppressionComment(@NotNull final PsiElement comment) {
112 SuppressionUtil.replaceSuppressionComment(comment, myID, myReplaceOtherSuppressionIds, getCommentLanguage(comment));
115 protected void createSuppression(@NotNull Project project,
116 @NotNull PsiElement element,
117 @NotNull PsiElement container) throws IncorrectOperationException {
118 SuppressionUtil.createSuppression(project, container, myID, getCommentLanguage(element));
122 * @param element quickfix target or existing comment element
123 * @return language that will be used for comment creating.
124 * In common case language will be the same as language of quickfix target
127 protected Language getCommentLanguage(@NotNull PsiElement element) {
128 return element.getLanguage();
132 public boolean isAvailable(@NotNull final Project project, @NotNull final PsiElement context) {
133 return context.isValid() && PsiManager.getInstance(project).isInProject(context) && getContainer(context) != null;
136 public void invoke(@NotNull final Project project, @NotNull final PsiElement element) throws IncorrectOperationException {
137 if (!isAvailable(project, element)) return;
138 PsiElement container = getContainer(element);
139 if (container == null) return;
141 if (!FileModificationService.getInstance().preparePsiElementForWrite(container)) return;
143 if (replaceSuppressionComments(container)) return;
145 createSuppression(project, element, container);
146 UndoUtil.markPsiFileForUndo(element.getContainingFile());
149 protected boolean replaceSuppressionComments(PsiElement container) {
150 final List<? extends PsiElement> comments = getCommentsFor(container);
151 if (comments != null) {
152 for (PsiElement comment : comments) {
153 if (comment instanceof PsiComment && SuppressionUtil.isSuppressionComment(comment)) {
154 replaceSuppressionComment(comment);
163 protected List<? extends PsiElement> getCommentsFor(@NotNull final PsiElement container) {
164 final PsiElement prev = PsiTreeUtil.skipSiblingsBackward(container, PsiWhiteSpace.class);
168 return Collections.singletonList(prev);
174 public String getFamilyName() {
175 return InspectionsBundle.message("suppress.inspection.family");