More cleanups
This commit is contained in:
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(", "));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user