Search in sources :

Example 1 with RemoveSuppressWarningAction

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()]);
}
Also used : NotNull(org.jetbrains.annotations.NotNull) AnalysisScope(com.intellij.analysis.AnalysisScope) RemoveSuppressWarningAction(com.intellij.codeInsight.daemon.impl.RemoveSuppressWarningAction) THashMap(gnu.trove.THashMap) BidirectionalMap(com.intellij.util.containers.BidirectionalMap) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

AnalysisScope (com.intellij.analysis.AnalysisScope)1 RemoveSuppressWarningAction (com.intellij.codeInsight.daemon.impl.RemoveSuppressWarningAction)1 BidirectionalMap (com.intellij.util.containers.BidirectionalMap)1 THashMap (gnu.trove.THashMap)1 NotNull (org.jetbrains.annotations.NotNull)1