use of com.intellij.codeInsight.daemon.impl.RemoveSuppressWarningAction in project intellij-community by JetBrains.
the class RedundantSuppressInspectionBase method checkElement.
@NotNull
public ProblemDescriptor[] checkElement(@NotNull final PsiElement psiElement, @NotNull final InspectionManager manager) {
final Map<PsiElement, Collection<String>> suppressedScopes = new THashMap<>();
psiElement.accept(new JavaRecursiveElementWalkingVisitor() {
@Override
public void visitModifierList(PsiModifierList list) {
super.visitModifierList(list);
final PsiElement parent = list.getParent();
if (parent instanceof PsiModifierListOwner && !(parent instanceof PsiClass)) {
checkElement(parent);
}
}
@Override
public void visitComment(PsiComment comment) {
checkElement(comment);
}
@Override
public void visitClass(PsiClass aClass) {
if (aClass == psiElement) {
super.visitClass(aClass);
checkElement(aClass);
}
}
private void checkElement(final PsiElement owner) {
String idsString = JavaSuppressionUtil.getSuppressedInspectionIdsIn(owner);
if (idsString != null && !idsString.isEmpty()) {
List<String> ids = StringUtil.split(idsString, ",");
if (IGNORE_ALL && (ids.contains(SuppressionUtil.ALL) || ids.contains(SuppressionUtil.ALL.toLowerCase())))
return;
Collection<String> suppressed = suppressedScopes.get(owner);
if (suppressed == null) {
suppressed = ids;
} else {
for (String id : ids) {
if (!suppressed.contains(id)) {
suppressed.add(id);
}
}
}
suppressedScopes.put(owner, suppressed);
}
}
});
if (suppressedScopes.values().isEmpty())
return ProblemDescriptor.EMPTY_ARRAY;
// have to visit all file from scratch since inspections can be written in any pervasive way including checkFile() overriding
Map<InspectionToolWrapper, String> suppressedTools = new THashMap<>();
InspectionToolWrapper[] toolWrappers = getInspectionTools(psiElement, manager);
for (Collection<String> ids : suppressedScopes.values()) {
for (Iterator<String> iterator = ids.iterator(); iterator.hasNext(); ) {
final String shortName = iterator.next().trim();
for (InspectionToolWrapper toolWrapper : toolWrappers) {
if (toolWrapper instanceof LocalInspectionToolWrapper && (((LocalInspectionToolWrapper) toolWrapper).getTool().getID().equals(shortName) || shortName.equals(((LocalInspectionToolWrapper) toolWrapper).getTool().getAlternativeID()))) {
if (((LocalInspectionToolWrapper) toolWrapper).isUnfair()) {
iterator.remove();
break;
} else {
suppressedTools.put(toolWrapper, shortName);
}
} else if (toolWrapper.getShortName().equals(shortName)) {
//ignore global unused as it won't be checked anyway
if (toolWrapper instanceof LocalInspectionToolWrapper || toolWrapper instanceof GlobalInspectionToolWrapper && !((GlobalInspectionToolWrapper) toolWrapper).getTool().isGraphNeeded()) {
suppressedTools.put(toolWrapper, shortName);
} else {
iterator.remove();
break;
}
}
}
}
}
PsiFile file = psiElement.getContainingFile();
final AnalysisScope scope = new AnalysisScope(file);
final GlobalInspectionContextBase globalContext = createContext(file);
globalContext.setCurrentScope(scope);
final RefManagerImpl refManager = (RefManagerImpl) globalContext.getRefManager();
refManager.inspectionReadActionStarted();
final List<ProblemDescriptor> result;
try {
result = new ArrayList<>();
for (InspectionToolWrapper toolWrapper : suppressedTools.keySet()) {
String toolId = suppressedTools.get(toolWrapper);
toolWrapper.initialize(globalContext);
final Collection<CommonProblemDescriptor> descriptors;
if (toolWrapper instanceof LocalInspectionToolWrapper) {
LocalInspectionToolWrapper local = (LocalInspectionToolWrapper) toolWrapper;
//cant't work with passes other than LocalInspectionPass
if (local.isUnfair())
continue;
List<ProblemDescriptor> results = local.getTool().processFile(file, manager);
descriptors = new ArrayList<>(results);
} else if (toolWrapper instanceof GlobalInspectionToolWrapper) {
final GlobalInspectionToolWrapper global = (GlobalInspectionToolWrapper) toolWrapper;
GlobalInspectionTool globalTool = global.getTool();
//when graph is needed, results probably depend on outer files so absence of results on one file (in current context) doesn't guarantee anything
if (globalTool.isGraphNeeded())
continue;
descriptors = new ArrayList<>();
globalContext.getRefManager().iterate(new RefVisitor() {
@Override
public void visitElement(@NotNull RefEntity refEntity) {
CommonProblemDescriptor[] descriptors1 = global.getTool().checkElement(refEntity, scope, manager, globalContext, new ProblemDescriptionsProcessor() {
});
if (descriptors1 != null) {
ContainerUtil.addAll(descriptors, descriptors1);
}
}
});
} else {
continue;
}
for (PsiElement suppressedScope : suppressedScopes.keySet()) {
Collection<String> suppressedIds = suppressedScopes.get(suppressedScope);
if (!suppressedIds.contains(toolId))
continue;
for (CommonProblemDescriptor descriptor : descriptors) {
if (!(descriptor instanceof ProblemDescriptor))
continue;
PsiElement element = ((ProblemDescriptor) descriptor).getPsiElement();
if (element == null)
continue;
PsiElement annotation = JavaSuppressionUtil.getElementToolSuppressedIn(element, toolId);
if (annotation != null && PsiTreeUtil.isAncestor(suppressedScope, annotation, false) || annotation == null && !PsiTreeUtil.isAncestor(suppressedScope, element, false)) {
suppressedIds.remove(toolId);
break;
}
}
}
}
for (PsiElement suppressedScope : suppressedScopes.keySet()) {
Collection<String> suppressedIds = suppressedScopes.get(suppressedScope);
for (String toolId : suppressedIds) {
PsiJavaDocumentedElement psiMember;
String problemLine = null;
if (suppressedScope instanceof PsiJavaDocumentedElement) {
psiMember = (PsiJavaDocumentedElement) suppressedScope;
} else {
psiMember = PsiTreeUtil.getParentOfType(suppressedScope, PsiJavaDocumentedElement.class);
final PsiStatement statement = PsiTreeUtil.getNextSiblingOfType(suppressedScope, PsiStatement.class);
problemLine = statement != null ? statement.getText() : null;
}
if (psiMember != null && psiMember.isValid()) {
String description = InspectionsBundle.message("inspection.redundant.suppression.description");
if (myQuickFixes == null)
myQuickFixes = new BidirectionalMap<>();
final String key = toolId + (problemLine != null ? ";" + problemLine : "");
QuickFix fix = myQuickFixes.get(key);
if (fix == null) {
fix = new RemoveSuppressWarningAction(toolId, problemLine);
myQuickFixes.put(key, fix);
}
PsiElement identifier;
if (!(suppressedScope instanceof PsiJavaDocumentedElement)) {
identifier = suppressedScope;
} else {
identifier = psiMember.getNameIdentifier();
}
if (identifier == null) {
identifier = psiMember;
}
result.add(manager.createProblemDescriptor(identifier, description, (LocalQuickFix) fix, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, false));
}
}
}
} finally {
refManager.inspectionReadActionFinished();
globalContext.close(true);
}
return result.toArray(new ProblemDescriptor[result.size()]);
}
Aggregations