More cleanups

This commit is contained in:
Clément Fournier committed 2022-04-15 20:55:01 +02:00
1 parent d7d3bb8ef2
commit 6084611032
9 files changed
+118 -50

No files matched your search

@@ -163,11 +163,6 @@ public final class PMD {
return runPmd(parseResult.toConfiguration());
}
static void printErrorDetected(int errors) {
String msg = CliMessages.errorDetectedMessage(errors, "PMD");
log.error(msg);
}
/**
* Execute PMD from a configuration. Returns the status code without
* exiting the VM. This is the main entry point to run a full PMD run
@@ -226,7 +221,7 @@ public final class PMD {
} catch (Exception e) {
pmdReporter.errorEx("Exception while running PMD.", e);
printErrorDetected(1);
PmdAnalysis.printErrorDetected(pmdReporter, 1);
return StatusCode.ERROR;
} finally {
finishBenchmarker(configuration);
@@ -23,6 +23,7 @@ import net.sourceforge.pmd.benchmark.TimeTracker;
import net.sourceforge.pmd.benchmark.TimedOperation;
import net.sourceforge.pmd.benchmark.TimedOperationCategory;
import net.sourceforge.pmd.cache.AnalysisCacheListener;
import net.sourceforge.pmd.cli.internal.CliMessages;
import net.sourceforge.pmd.internal.util.AssertionUtil;
import net.sourceforge.pmd.internal.util.FileCollectionUtil;
import net.sourceforge.pmd.lang.Language;
@@ -417,15 +418,24 @@ public final class PmdAnalysis implements AutoCloseable {
} catch (Exception e) {
getReporter().errorEx("Exception during processing", e);
ReportStats stats = listener.getResult();
PMD.printErrorDetected(1 + stats.getNumErrors());
printErrorDetected(1 + stats.getNumErrors());
return stats; // should have been closed
}
ReportStats stats = listener.getResult();
if (stats.getNumErrors() > 0) {
PMD.printErrorDetected(stats.getNumErrors());
printErrorDetected(stats.getNumErrors());
}
return stats;
}
static void printErrorDetected(MessageReporter reporter, int errors) {
String msg = CliMessages.errorDetectedMessage(errors, "PMD");
reporter.error(msg);
}
void printErrorDetected(int errors) {
printErrorDetected(getReporter(), errors);
}
}
@@ -109,4 +109,19 @@ public enum RulePriority {
return null;
}
}
/**
* Returns the priority which corresponds to the given number as returned by
* {@link RulePriority#getPriority()}. If the number is an invalid value,
* then null will be returned.
*
* @param priority The numeric priority value.
*/
public static RulePriority valueOfNullable(String priority) {
try {
int integer = Integer.parseInt(priority);
return RulePriority.values()[integer - 1];
} catch (ArrayIndexOutOfBoundsException | NumberFormatException e) {
return null;
}
}
}
@@ -4,6 +4,7 @@
package net.sourceforge.pmd;
import static net.sourceforge.pmd.util.CollectionUtil.setOf;
import static net.sourceforge.pmd.util.internal.xml.SchemaConstants.DESCRIPTION;
import static net.sourceforge.pmd.util.internal.xml.SchemaConstants.EXCLUDE;
import static net.sourceforge.pmd.util.internal.xml.SchemaConstants.EXCLUDE_PATTERN;
@@ -38,7 +39,6 @@ import org.slf4j.LoggerFactory;
import org.slf4j.event.Level;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
@@ -47,6 +47,7 @@ import net.sourceforge.pmd.lang.rule.RuleReference;
import net.sourceforge.pmd.rules.RuleFactory;
import net.sourceforge.pmd.util.ResourceLoader;
import net.sourceforge.pmd.util.internal.xml.PmdXmlReporter;
import net.sourceforge.pmd.util.internal.xml.SchemaConstants;
import net.sourceforge.pmd.util.internal.xml.XmlUtil;
import net.sourceforge.pmd.util.log.MessageReporter;
@@ -358,20 +359,25 @@ final class RuleSetFactory {
String ref,
Set<String> rulesetReferences,
PmdXmlReporter err) {
String priority = null;
NodeList childNodes = ruleElement.getChildNodes();
RulePriority priority = null;
Map<String, Element> excludedRulesCheck = new HashMap<>();
for (int i = 0; i < childNodes.getLength(); i++) {
Node child = childNodes.item(i);
for (Element child : XmlUtil.getElementChildrenList(ruleElement)) {
if (EXCLUDE.isElementWithName(child)) {
Element excludeElement = (Element) child;
String excludedRuleName = excludeElement.getAttribute("name");
String excludedRuleName;
try {
excludedRuleName = SchemaConstants.NAME.getAttributeOrThrow(child, err);
} catch (XmlException ignored) {
// has been reported
continue;
}
excludedRuleName = compatibilityFilter.applyExclude(ref, excludedRuleName, this.warnDeprecated);
if (excludedRuleName != null) {
excludedRulesCheck.put(excludedRuleName, excludeElement);
excludedRulesCheck.put(excludedRuleName, child);
}
} else if (PRIORITY.isElementWithName(child)) {
priority = XmlUtil.parseTextNode(child).trim();
priority = RuleFactory.parsePriority(err, child);
} else {
XmlUtil.reportIgnoredUnexpectedElt(ruleElement, child, setOf(EXCLUDE, PRIORITY), err);
}
}
final RuleSetReference ruleSetReference = new RuleSetReference(ref, true, excludedRulesCheck.keySet());
@@ -388,7 +394,7 @@ final class RuleSetFactory {
RuleReference ruleReference = new RuleReference(rule, ruleSetReference);
// override the priority
if (priority != null) {
ruleReference.setPriority(RulePriority.valueOf(Integer.parseInt(priority)));
ruleReference.setPriority(priority);
}
if (rule.isDeprecated()) {
@@ -19,7 +19,7 @@ import org.slf4j.LoggerFactory;
*
* @see <a href="https://sourceforge.net/p/pmd/bugs/1360/">issue 1360</a>
*/
public final class RuleSetFactoryCompatibility {
final class RuleSetFactoryCompatibility {
static final RuleSetFactoryCompatibility EMPTY = new RuleSetFactoryCompatibility();
/** The instance with the built-in filters for the modified PMD rules. */
@@ -184,7 +184,10 @@ public class RuleFactory {
rule.addExample(XmlUtil.parseTextNode(node));
break;
case PRIORITY:
RulePriority rp = parsePriority(err, node, XmlUtil.parseTextNode(node));
RulePriority rp = parsePriority(err, node);
if (rp == null) {
rp = RulePriority.MEDIUM;
}
rule.setPriority(rp);
break;
case PROPERTIES:
@@ -214,20 +217,17 @@ public class RuleFactory {
}
private @NonNull RulePriority parsePriority(PmdXmlReporter err, Element node, String trim) {
try {
int i = Integer.parseInt(trim.trim());
RulePriority rp = RulePriority.valueOfNullable(i);
if (rp == null) {
err.at(node).warn(XmlErrorMessages.WARN__INVALID_PRIORITY_VALUE, i);
return RulePriority.MEDIUM;
} else {
return rp;
}
} catch (NumberFormatException e) {
err.at(node).warn(XmlErrorMessages.WARN__INVALID_PRIORITY_VALUE, trim);
return RulePriority.MEDIUM;
/**
* Parse a priority. If invalid, report it and return null.
*/
public static @Nullable RulePriority parsePriority(PmdXmlReporter err, Element node) {
String text = XmlUtil.parseTextNode(node);
RulePriority rp = RulePriority.valueOfNullable(text);
if (rp == null) {
err.at(node).error(XmlErrorMessages.ERR__INVALID_PRIORITY_VALUE, text);
return null;
}
return rp;
}
private LanguageVersion getLanguageVersion(Element ruleElement, PmdXmlReporter err, Language language, String attrName) {
@@ -7,6 +7,7 @@ package net.sourceforge.pmd.util.internal.xml;
import static net.sourceforge.pmd.util.CollectionUtil.setOf;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
@@ -18,7 +19,8 @@ import org.w3c.dom.Node;
/**
* Constants of the ruleset schema.
* Wraps the name of eg an attribute or element, and provides convenience
* methods to query the DOM.
*/
public class SchemaConstant {
@@ -73,16 +75,16 @@ public class SchemaConstant {
}
public List<Element> getElementChildrenNamedReportOthers(Element elt, PmdXmlReporter err) {
return XmlUtil.getElementChildrenNamedReportOthers(elt, setOf(name), err)
return XmlUtil.getElementChildrenNamedReportOthers(elt, setOf(this), err)
.collect(Collectors.toList());
}
public Element getSingleChildIn(Element elt, PmdXmlReporter err) {
return XmlUtil.getSingleChildIn(elt, true, err, setOf(name));
return XmlUtil.getSingleChildIn(elt, true, err, setOf(this));
}
public Element getOptChildIn(Element elt, PmdXmlReporter err) {
return XmlUtil.getSingleChildIn(elt, false, err, setOf(name));
return XmlUtil.getSingleChildIn(elt, false, err, setOf(this));
}
public void setOn(Element element, String value) {
@@ -108,4 +110,21 @@ public class SchemaConstant {
public boolean isElementWithName(Node node) {
return node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals(name);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
SchemaConstant that = (SchemaConstant) o;
return Objects.equals(name, that.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}
@@ -9,8 +9,8 @@ public final class XmlErrorMessages {
private static final String THIS_WILL_BE_IGNORED = ", this will be ignored";
/** {0}: unexpected element name; {1}: list of allowed elements in this context */
public static final String ERR__UNEXPECTED_ELEMENT = "Unexpected element ''{0}'', expecting {1}";
/** {0}: unexpected element name; {1}: parent node name; {2}: list of allowed elements in this context */
public static final String ERR__UNEXPECTED_ELEMENT = "Unexpected element ''{0}'' in {1}, expecting {2}";
/** {0}: unexpected element name; {1}: parent node name */
public static final String ERR__UNEXPECTED_ELEMENT_IN = "Unexpected element ''{0}'' in {1}";
/** {0}: unexpected attr name; {1}: parent node name */
@@ -19,7 +19,7 @@ public final class XmlErrorMessages {
public static final String ERR__BLANK_REQUIRED_ATTRIBUTE = "Required attribute ''{0}'' is blank";
public static final String ERR__MISSING_REQUIRED_ELEMENT = "Required child element named {0} is missing";
/** {0}: unexpected element name; {1}: allowed elements in this context */
/** {0}: unexpected element name; {1}: parent node name; {2}: allowed elements in this context */
public static final String IGNORED__UNEXPECTED_ELEMENT = ERR__UNEXPECTED_ELEMENT + THIS_WILL_BE_IGNORED;
/** {0}: unexpected element name; {1}: parent node name */
public static final String IGNORED__UNEXPECTED_ELEMENT_IN = ERR__UNEXPECTED_ELEMENT_IN + THIS_WILL_BE_IGNORED;
@@ -36,7 +36,7 @@ public final class XmlErrorMessages {
public static final String ERR__INVALID_LANG_VERSION = "Invalid language version ''{0}'' for language ''{1}'', supported versions are {2}";
public static final String WARN__DEPRECATED_USE_OF_ATTRIBUTE = "The use of the ''{0}'' attribute is deprecated. Use a nested element, e.g. {1}";
public static final String WARN__INVALID_PRIORITY_VALUE = "Not a valid priority ''{}'', expected a number in [1,5]";
public static final String ERR__INVALID_PRIORITY_VALUE = "Not a valid priority ''{0}'', expected a number in [1,5]";
public static final String ERR__UNSUPPORTED_PROPERTY_TYPE = "Unsupported property type ''{0}''";
private XmlErrorMessages() {
@@ -6,6 +6,7 @@ package net.sourceforge.pmd.util.internal.xml;
import static net.sourceforge.pmd.util.internal.xml.XmlErrorMessages.ERR__MISSING_REQUIRED_ELEMENT;
import static net.sourceforge.pmd.util.internal.xml.XmlErrorMessages.IGNORED__DUPLICATE_CHILD_ELEMENT;
import static net.sourceforge.pmd.util.internal.xml.XmlErrorMessages.IGNORED__UNEXPECTED_ELEMENT;
import static net.sourceforge.pmd.util.internal.xml.XmlErrorMessages.IGNORED__UNEXPECTED_ELEMENT_IN;
import java.util.List;
@@ -18,6 +19,8 @@ import org.checkerframework.checker.nullness.qual.Nullable;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import net.sourceforge.pmd.util.StringUtil;
import com.github.oowekyala.ooxml.DomUtils;
public final class XmlUtil {
@@ -32,14 +35,18 @@ public final class XmlUtil {
.map(Element.class::cast);
}
public static Stream<Element> getElementChildrenNamed(Element parent, Set<String> names) {
return getElementChildren(parent).filter(e -> names.contains(e.getTagName()));
public static List<Element> getElementChildrenList(Element parent) {
return getElementChildren(parent).collect(Collectors.toList());
}
public static Stream<Element> getElementChildrenNamedReportOthers(Element parent, Set<String> names, PmdXmlReporter err) {
public static Stream<Element> getElementChildrenNamed(Element parent, Set<SchemaConstant> names) {
return getElementChildren(parent).filter(e -> matchesName(e, names));
}
public static Stream<Element> getElementChildrenNamedReportOthers(Element parent, Set<SchemaConstant> names, PmdXmlReporter err) {
return getElementChildren(parent)
.map(it -> {
if (names.contains(it.getTagName())) {
if (matchesName(it, names)) {
return it;
} else {
err.at(it).warn(IGNORED__UNEXPECTED_ELEMENT_IN, it.getTagName(), formatPossibleNames(names));
@@ -48,6 +55,20 @@ public final class XmlUtil {
}).filter(Objects::nonNull);
}
public static boolean matchesName(Element elt, Set<SchemaConstant> names) {
return names.stream().anyMatch(it -> it.xmlName().equals(elt.getTagName()));
}
public static void reportIgnoredUnexpectedElt(Element parent,
Element unexpectedChild,
Set<SchemaConstant> names,
PmdXmlReporter err) {
err.at(unexpectedChild).warn(IGNORED__UNEXPECTED_ELEMENT,
unexpectedChild.getTagName(),
parent.getTagName(),
formatPossibleNames(names));
}
public static Stream<Element> getElementChildrenNamed(Element parent, String name) {
return getElementChildren(parent).filter(e -> name.equals(e.getTagName()));
}
@@ -61,7 +82,7 @@ public final class XmlUtil {
}).collect(Collectors.toList());
}
public static Element getSingleChildIn(Element elt, boolean throwOnMissing, PmdXmlReporter err, Set<String> names) {
public static Element getSingleChildIn(Element elt, boolean throwOnMissing, PmdXmlReporter err, Set<SchemaConstant> names) {
List<Element> children = getElementChildrenNamed(elt, names).collect(Collectors.toList());
if (children.size() == 1) {
return children.get(0);
@@ -80,14 +101,16 @@ public final class XmlUtil {
}
}
@Nullable
public static String formatPossibleNames(Set<String> names) {
public static @Nullable String formatPossibleNames(Set<SchemaConstant> names) {
if (names.isEmpty()) {
return null;
} else if (names.size() == 1) {
return "'" + names.iterator().next() + "'";
return StringUtil.inSingleQuotes(names.iterator().next().xmlName());
} else {
return "one of " + names.stream().map(it -> "'" + it + "'").collect(Collectors.joining(", "));
return "one of " + names.stream()
.map(SchemaConstant::xmlName)
.map(StringUtil::inSingleQuotes)
.collect(Collectors.joining(", "));
}
}