net.sourceforge.pmd.lang.apex.ApexViolationSuppressors Maven / Gradle / Ivy
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.apex;
import static net.sourceforge.pmd.util.CollectionUtil.listOf;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import org.checkerframework.checker.nullness.qual.NonNull;
import net.sourceforge.pmd.lang.apex.ast.ASTAnnotation;
import net.sourceforge.pmd.lang.apex.ast.ASTAnnotationParameter;
import net.sourceforge.pmd.lang.apex.ast.ASTField;
import net.sourceforge.pmd.lang.apex.ast.ASTFieldDeclarationStatements;
import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
import net.sourceforge.pmd.lang.apex.ast.ASTModifierNode;
import net.sourceforge.pmd.lang.apex.ast.ASTParameter;
import net.sourceforge.pmd.lang.apex.ast.ASTUserClassOrInterface;
import net.sourceforge.pmd.lang.apex.ast.ASTUserEnum;
import net.sourceforge.pmd.lang.apex.ast.ASTVariableDeclarationStatements;
import net.sourceforge.pmd.lang.apex.ast.ApexNode;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.rule.Rule;
import net.sourceforge.pmd.reporting.Report;
import net.sourceforge.pmd.reporting.Report.SuppressedViolation;
import net.sourceforge.pmd.reporting.RuleViolation;
import net.sourceforge.pmd.reporting.ViolationSuppressor;
final class ApexViolationSuppressors {
private static final ViolationSuppressor APEX_ANNOT_SUPPRESSOR = new ViolationSuppressor() {
@Override
public String getId() {
return "@SuppressWarnings";
}
@Override
public Report.SuppressedViolation suppressOrNull(RuleViolation rv, @NonNull Node node) {
if (node instanceof ApexNode && isSuppressed((ApexNode>) node, rv.getRule())) {
return new SuppressedViolation(rv, this, null);
}
return null;
}
};
static final List ALL_APEX_SUPPRESSORS = listOf(APEX_ANNOT_SUPPRESSOR);
private ApexViolationSuppressors() {
}
/**
* Check for suppression on this node, on parents, and on contained types
* for ASTCompilationUnit
*/
private static boolean isSuppressed(ApexNode> node, Rule rule) {
boolean result = suppresses(node, rule);
if (!result) {
ApexNode> parent = node.getParent();
while (!result && parent != null) {
result = suppresses(parent, rule);
parent = parent.getParent();
}
}
return result;
}
private static boolean canSuppressWarnings(ApexNode> node) {
return node instanceof ASTFieldDeclarationStatements
|| node instanceof ASTVariableDeclarationStatements
|| node instanceof ASTField
|| node instanceof ASTMethod
|| node instanceof ASTUserClassOrInterface
|| node instanceof ASTUserEnum
|| node instanceof ASTParameter;
}
private static boolean suppresses(final ApexNode> node, Rule rule) {
return canSuppressWarnings(node) && hasSuppressWarningsAnnotationFor(node, rule);
}
private static boolean hasSuppressWarningsAnnotationFor(ApexNode> node, Rule rule) {
return node.children(ASTModifierNode.class)
.children(ASTAnnotation.class)
.any(a -> suppresses(a, rule));
}
private static boolean suppresses(ASTAnnotation annot, Rule rule) {
final String ruleAnno = "PMD." + rule.getName();
if ("SuppressWarnings".equalsIgnoreCase(annot.getName())) {
for (ASTAnnotationParameter param : annot.children(ASTAnnotationParameter.class)) {
String image = param.getValue();
if (image != null) {
Set paramValues = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
paramValues.addAll(Arrays.asList(image.replaceAll("\\s+", "").split(",")));
if (paramValues.contains("PMD") || paramValues.contains(ruleAnno) || paramValues.contains("all")) {
return true;
}
}
}
}
return false;
}
}