IDEADEV-33516: suppress for tag in html
[fedora-idea.git] / xml / openapi / src / com / intellij / codeInspection / DefaultXmlSuppressionProvider.java
blob641d80eccb18e4e432989e4aa1fc137a2e9f3697
1 /*
2 * Copyright 2000-2008 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.codeInspection;
19 import com.intellij.openapi.command.undo.UndoUtil;
20 import com.intellij.openapi.editor.Document;
21 import com.intellij.openapi.project.Project;
22 import com.intellij.openapi.util.TextRange;
23 import com.intellij.psi.PsiComment;
24 import com.intellij.psi.PsiDocumentManager;
25 import com.intellij.psi.PsiElement;
26 import com.intellij.psi.PsiFile;
27 import com.intellij.psi.codeStyle.CodeStyleManager;
28 import com.intellij.psi.util.PsiTreeUtil;
29 import com.intellij.psi.xml.*;
30 import com.intellij.refactoring.util.CommonRefactoringUtil;
31 import com.intellij.util.ArrayUtil;
32 import org.jetbrains.annotations.NonNls;
33 import org.jetbrains.annotations.Nullable;
35 /**
36 * @author Dmitry Avdeev
38 public class DefaultXmlSuppressionProvider extends XmlSuppressionProvider {
40 @Override
41 public boolean isProviderAvailable(PsiFile file) {
42 return true;
45 public boolean isSuppressedFor(PsiElement element, String inspectionId) {
46 final XmlTag tag = PsiTreeUtil.getContextOfType(element, XmlTag.class, false);
47 return tag != null && findSuppression(tag, inspectionId, element) != null;
50 public void suppressForFile(PsiElement element, String inspectionId) {
51 final PsiFile file = element.getContainingFile();
52 final XmlDocument document = ((XmlFile)file).getDocument();
53 final PsiElement anchor = document != null ? document.getRootTag() : file.findElementAt(0);
54 assert anchor != null;
55 suppress(file, findFileSuppression(anchor, null, element), inspectionId, anchor.getTextRange().getStartOffset());
58 public void suppressForTag(PsiElement element, String inspectionId) {
59 final XmlTag tag = PsiTreeUtil.getParentOfType(element, XmlTag.class);
60 assert tag != null;
61 suppress(element.getContainingFile(), findSuppressionLeaf(tag, null, 0), inspectionId, tag.getTextRange().getStartOffset());
64 @Nullable
65 protected PsiElement findSuppression(final PsiElement anchor, final String id, PsiElement originalElement) {
66 final PsiElement element = findSuppressionLeaf(anchor, id, 0);
67 if (element != null) return element;
69 return findFileSuppression(anchor, id, originalElement);
72 @Nullable
73 protected PsiElement findFileSuppression(PsiElement anchor, String id, PsiElement originalElement) {
74 final PsiFile file = anchor.getContainingFile();
75 if (file instanceof XmlFile) {
76 final XmlDocument document = ((XmlFile)file).getDocument();
77 final XmlTag rootTag = document != null ? document.getRootTag() : null;
78 PsiElement leaf = rootTag != null ? rootTag.getPrevSibling() : file.findElementAt(0);
79 return findSuppressionLeaf(leaf, id, 0);
81 return null;
84 @Nullable
85 protected PsiElement findSuppressionLeaf(PsiElement leaf, @Nullable final String id, int offset) {
86 while (leaf != null && leaf.getTextOffset() >= offset) {
87 if (leaf instanceof PsiComment || leaf instanceof XmlProlog || leaf instanceof XmlText) {
88 @NonNls String text = leaf.getText();
89 if (isSuppressedFor(text, id)) return leaf;
91 leaf = leaf.getPrevSibling();
92 if (leaf instanceof XmlTag) {
93 return null;
96 return null;
99 private boolean isSuppressedFor(@NonNls final String text, @Nullable final String id) {
100 if (!text.contains(getPrefix())) {
101 return false;
103 if (id == null) {
104 return true;
106 @NonNls final String[] parts = text.split("[ ,]");
107 return ArrayUtil.find(parts, id) != -1 || ArrayUtil.find(parts, XmlSuppressableInspectionTool.ALL) != -1;
110 protected void suppress(PsiFile file, final PsiElement suppressionElement, String inspectionId, final int offset) {
111 final Project project = file.getProject();
112 if (!CommonRefactoringUtil.checkReadOnlyStatus(file)) {
113 return;
115 final Document doc = PsiDocumentManager.getInstance(project).getDocument(file);
116 assert doc != null;
118 if (suppressionElement != null) {
119 final TextRange textRange = suppressionElement.getTextRange();
120 String text = suppressionElement.getText();
121 final String suppressionText = getSuppressionText(inspectionId, text);
122 doc.replaceString(textRange.getStartOffset(), textRange.getEndOffset(), suppressionText);
123 } else {
124 final String suppressionText = getSuppressionText(inspectionId, null);
125 doc.insertString(offset, suppressionText);
126 CodeStyleManager.getInstance(project).adjustLineIndent(doc, offset + suppressionText.length());
127 UndoUtil.markPsiFileForUndo(file);
131 protected String getSuppressionText(String inspectionId, @Nullable String originalText) {
132 if (originalText == null) {
133 return getPrefix() + inspectionId + getSuffix();
134 } else if (inspectionId.equals(XmlSuppressableInspectionTool.ALL)) {
135 final int pos = originalText.indexOf(getPrefix());
136 return originalText.substring(0, pos) + getPrefix() + inspectionId + getSuffix();
138 return originalText.replace(getSuffix(), ", " + inspectionId + getSuffix());
141 @NonNls
142 protected String getPrefix() {
143 return "<!--suppress ";
146 @NonNls
147 protected String getSuffix() {
148 return " -->\n";