Merge branch '7.0.x' into java-grammar

This commit is contained in:
Clément Fournier
2020-01-05 21:11:37 +01:00
83 changed files with 1030 additions and 261 deletions

View File

@ -41,16 +41,29 @@ the implementation based on your feedback.
at runtime. So, if you try to do this, you'll get an error at runtime, hence this is error prone. See also
the discussion on [#2064](https://github.com/pmd/pmd/issues/2064).
* The Java rule {% rule "java/documentation/CommentRequired" %} (`java-documentation`) has a new property
`classCommentRequirement`. This replaces the now deprecated property `headerCommentRequirement`, since
the name was misleading. (File) header comments are not checked, but class comments are.
### Fixed Issues
* core
* [#2006](https://github.com/pmd/pmd/issues/2006): \[core] PMD should warn about multiple instances of the same rule in a ruleset
* [#2161](https://github.com/pmd/pmd/issues/2161): \[core] ResourceLoader is deprecated and marked as internal but is exposed
* [#2170](https://github.com/pmd/pmd/issues/2170): \[core] DocumentFile doesn't preserve newlines
* java-bestpractices
* [#2149](https://github.com/pmd/pmd/issues/2149): \[java] JUnitAssertionsShouldIncludeMessage - False positive with assertEquals and JUnit5
* java-codestyle
* [#2167](https://github.com/pmd/pmd/issues/2167): \[java] UnnecessaryLocalBeforeReturn false positive with variable captured by method reference
* java-documentation
* [#1683](https://github.com/pmd/pmd/issues/1683): \[java] CommentRequired property names are inconsistent
* java-errorprone
* [#2140](https://github.com/pmd/pmd/issues/2140): \[java] AvoidLiteralsInIfCondition: false negative for expressions
* java-performance
* [#2141](https://github.com/pmd/pmd/issues/2141): \[java] StringInstatiation: False negative with String-array access
* plsql
* [#2008](https://github.com/pmd/pmd/issues/2008): \[plsql] In StringLiteral using alternative quoting mechanism single quotes cause parsing errors
* [#2009](https://github.com/pmd/pmd/issues/2009): \[plsql] Multiple DDL commands are skipped during parsing
### API Changes
@ -72,6 +85,11 @@ You can identify them with the `@InternalApi` annotation. You'll also get a depr
eg {% jdoc java::lang.java.rule.JavaRuleViolation %}. See javadoc of
{% jdoc core::RuleViolation %}.
* {% jdoc core::rules.RuleFactory %}
* {% jdoc core::rules.RuleBuilder %}
* Constructors of {% jdoc core::RuleSetFactory %}, use factory methods from {% jdoc core::RulesetsFactoryUtils %} instead
* {% jdoc core::RulesetsFactoryUtils#getRulesetFactory(core::PMDConfiguration, core::util.ResourceLoader) %}
##### For removal
* {% jdoc java::lang.java.AbstractJavaParser %}
@ -93,13 +111,21 @@ You can identify them with the `@InternalApi` annotation. You'll also get a depr
instead. This affects {% jdoc !!java::lang.java.ast.ASTAnnotationTypeDeclaration#getImage() %},
{% jdoc !!java::lang.java.ast.ASTClassOrInterfaceDeclaration#getImage() %}, and
{% jdoc !!java::lang.java.ast.ASTEnumDeclaration#getImage() %}.
* Several methods of {% jdoc java::lang.java.ast.ASTTryStatement %}, replacements with other names
have been added. This includes the XPath attribute `@Finally`, replace it with a test for `child::FinallyStatement`.
* Several methods named `getGuardExpressionNode` are replaced with `getCondition`. This affects the
following nodes: WhileStatement, DoStatement, ForStatement, IfStatement, AssertStatement, ConditionalExpression.
* {% jdoc java::lang.java.ast.ASTYieldStatement %} will not implement {% jdoc java::lang.java.ast.TypeNode %}
anymore come 7.0.0. Test the type of the expression nested within it.
### External Contributions
* [#2041](https://github.com/pmd/pmd/pull/2041): \[modelica] Initial implementation for PMD - [Anatoly Trosinenko](https://github.com/atrosinenko)
* [#2051](https://github.com/pmd/pmd/pull/2051): \[doc] Update the docs on adding a new language - [Anatoly Trosinenko](https://github.com/atrosinenko)
* [#2069](https://github.com/pmd/pmd/pull/2069): \[java] CommentRequired: make property names consistent - [snuyanzin](https://github.com/snuyanzin)
* [#2169](https://github.com/pmd/pmd/pull/2169): \[modelica] Follow-up fixes for Modelica language module - [Anatoly Trosinenko](https://github.com/atrosinenko)
* [#2193](https://github.com/pmd/pmd/pull/2193): \[core] Fix odd logic in test runner - [Egor Bredikhin](https://github.com/Egor18)
* [#2194](https://github.com/pmd/pmd/pull/2194): \[java] Fix odd logic in AvoidUsingHardCodedIPRule - [Egor Bredikhin](https://github.com/Egor18)
{% endtocmaker %}

View File

@ -24,7 +24,7 @@
<target>
<ant antfile="src/main/ant/alljavacc.xml">
<property name="target" value="${project.build.directory}/generated-sources/javacc" />
<property name="javacc.jar" value="${settings.localRepository}/net/java/dev/javacc/javacc/${javacc.version}/javacc-${javacc.version}.jar" />
<property name="javacc.jar" value="${javacc.jar}" />
</ant>
</target>
</configuration>

View File

@ -152,6 +152,32 @@ public class RuleSet implements ChecksumAware {
return this;
}
/**
* Finds an already added rule by same name and language, if it already exists.
* @param rule the rule to search
* @return the already added rule or <code>null</code> if no rule was added yet to the builder.
*/
Rule getExistingRule(final Rule rule) {
for (Rule r : rules) {
if (r.getName().equals(rule.getName()) && r.getLanguage() == rule.getLanguage()) {
return r;
}
}
return null;
}
/**
* Checks, whether a rule with the same name and language already exists in the
* ruleset.
* @param rule to rule to check
* @return <code>true</code> if the rule already exists, <code>false</code> if the given
* rule is the first configuration of this rule.
*/
boolean hasRule(final Rule rule) {
return getExistingRule(rule) != null;
}
/**
* Adds a rule. If a rule with the same name and language already
* existed before in the ruleset, then the new rule will replace it.
@ -197,13 +223,7 @@ public class RuleSet implements ChecksumAware {
rule = ((RuleReference) rule).getRule();
}
boolean exists = false;
for (final Rule r : rules) {
if (r.getName().equals(rule.getName()) && r.getLanguage() == rule.getLanguage()) {
exists = true;
break;
}
}
boolean exists = hasRule(rule);
if (!exists) {
addRule(ruleOrRef);
}

View File

@ -60,22 +60,31 @@ public class RuleSetFactory {
private final boolean warnDeprecated;
private final RuleSetFactoryCompatibility compatibilityFilter;
/**
* @deprecated Use {@link RulesetsFactoryUtils#defaultFactory()}
*/
@Deprecated // to be removed with PMD 7.0.0.
public RuleSetFactory() {
this(new ResourceLoader(), RulePriority.LOW, false, true);
}
/**
* @deprecated Use {@link #RuleSetFactory(ResourceLoader, RulePriority, boolean, boolean)} with
* {@link ResourceLoader} instead of a {@link ClassLoader}.
* @deprecated Use {@link RulesetsFactoryUtils#createFactory(ClassLoader, RulePriority, boolean, boolean)}
* or {@link RulesetsFactoryUtils#createFactory(RulePriority, boolean, boolean)}
*/
@Deprecated // to be removed with PMD 7.0.0.
public RuleSetFactory(final ClassLoader classLoader, final RulePriority minimumPriority,
final boolean warnDeprecated, final boolean enableCompatibility) {
final boolean warnDeprecated, final boolean enableCompatibility) {
this(new ResourceLoader(classLoader), minimumPriority, warnDeprecated, enableCompatibility);
}
/**
* @deprecated Use {@link RulesetsFactoryUtils#createFactory(ClassLoader, RulePriority, boolean, boolean)}
* or {@link RulesetsFactoryUtils#createFactory(RulePriority, boolean, boolean)}
*/
@Deprecated // to be hidden with PMD 7.0.0.
public RuleSetFactory(final ResourceLoader resourceLoader, final RulePriority minimumPriority,
final boolean warnDeprecated, final boolean enableCompatibility) {
final boolean warnDeprecated, final boolean enableCompatibility) {
this.resourceLoader = resourceLoader;
this.minimumPriority = minimumPriority;
this.warnDeprecated = warnDeprecated;
@ -374,6 +383,8 @@ public class RuleSetFactory {
ruleSetBuilder.withName("Missing RuleSet Name");
}
Set<String> rulesetReferences = new HashSet<>();
NodeList nodeList = ruleSetElement.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
@ -395,7 +406,7 @@ public class RuleSetFactory {
}
ruleSetBuilder.withFileExclusions(pattern);
} else if ("rule".equals(nodeName)) {
parseRuleNode(ruleSetReferenceId, ruleSetBuilder, node, withDeprecatedRuleReferences);
parseRuleNode(ruleSetReferenceId, ruleSetBuilder, node, withDeprecatedRuleReferences, rulesetReferences);
} else {
throw new IllegalArgumentException(UNEXPECTED_ELEMENT + node.getNodeName()
+ "> encountered as child of <ruleset> element.");
@ -481,14 +492,15 @@ public class RuleSetFactory {
* @param withDeprecatedRuleReferences
* whether rule references that are deprecated should be ignored
* or not
* @param rulesetReferences keeps track of already processed complete ruleset references in order to log a warning
*/
private void parseRuleNode(RuleSetReferenceId ruleSetReferenceId, RuleSetBuilder ruleSetBuilder, Node ruleNode,
boolean withDeprecatedRuleReferences)
boolean withDeprecatedRuleReferences, Set<String> rulesetReferences)
throws ClassNotFoundException, InstantiationException, IllegalAccessException, RuleSetNotFoundException {
Element ruleElement = (Element) ruleNode;
String ref = ruleElement.getAttribute("ref");
if (ref.endsWith("xml")) {
parseRuleSetReferenceNode(ruleSetBuilder, ruleElement, ref);
parseRuleSetReferenceNode(ruleSetBuilder, ruleElement, ref, rulesetReferences);
} else if (StringUtils.isBlank(ref)) {
parseSingleRuleNode(ruleSetReferenceId, ruleSetBuilder, ruleNode);
} else {
@ -508,8 +520,9 @@ public class RuleSetFactory {
* Must be a rule element node.
* @param ref
* The RuleSet reference.
* @param rulesetReferences keeps track of already processed complete ruleset references in order to log a warning
*/
private void parseRuleSetReferenceNode(RuleSetBuilder ruleSetBuilder, Element ruleElement, String ref)
private void parseRuleSetReferenceNode(RuleSetBuilder ruleSetBuilder, Element ruleElement, String ref, Set<String> rulesetReferences)
throws RuleSetNotFoundException {
String priority = null;
NodeList childNodes = ruleElement.getChildNodes();
@ -571,6 +584,12 @@ public class RuleSetFactory {
+ "; perhaps the rule name is mispelled or the rule doesn't exist anymore?");
}
}
if (rulesetReferences.contains(ref)) {
LOG.warning("The ruleset " + ref + " is referenced multiple times in \""
+ ruleSetBuilder.getName() + "\".");
}
rulesetReferences.add(ref);
}
/**
@ -694,6 +713,19 @@ public class RuleSetFactory {
}
if (withDeprecatedRuleReferences || !isSameRuleSet || !ruleReference.isDeprecated()) {
Rule existingRule = ruleSetBuilder.getExistingRule(ruleReference);
if (existingRule instanceof RuleReference) {
RuleReference existingRuleReference = (RuleReference) existingRule;
// the only valid use case is: the existing rule does not override anything yet
// which means, it is a plain reference. And the new reference overrides.
// for all other cases, we should log a warning
if (existingRuleReference.hasOverriddenAttributes() || !ruleReference.hasOverriddenAttributes()) {
LOG.warning("The rule " + ruleReference.getName() + " is referenced multiple times in \""
+ ruleSetBuilder.getName() + "\". "
+ "Only the last rule configuration is used.");
}
}
ruleSetBuilder.addRuleReplaceIfExists(ruleReference);
}
}

View File

@ -7,6 +7,7 @@ package net.sourceforge.pmd;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.benchmark.TimeTracker;
import net.sourceforge.pmd.benchmark.TimedOperation;
import net.sourceforge.pmd.benchmark.TimedOperationCategory;
@ -61,24 +62,119 @@ public final class RulesetsFactoryUtils {
* @throws IllegalArgumentException
* if rulesets is empty (means, no rules have been found) or if
* a ruleset couldn't be found.
* @deprecated Is internal API
*/
@InternalApi
@Deprecated
public static RuleSets getRuleSetsWithBenchmark(String rulesets, RuleSetFactory factory) {
try (TimedOperation to = TimeTracker.startOperation(TimedOperationCategory.LOAD_RULES)) {
return getRuleSets(rulesets, factory);
}
}
/**
* @deprecated Use {@link #createFactory(PMDConfiguration)} or {@link #createFactory(PMDConfiguration, ClassLoader)}
*/
@InternalApi
@Deprecated
public static RuleSetFactory getRulesetFactory(final PMDConfiguration configuration,
final ResourceLoader resourceLoader) {
final ResourceLoader resourceLoader) {
return new RuleSetFactory(resourceLoader, configuration.getMinimumPriority(), true,
configuration.isRuleSetFactoryCompatibilityEnabled());
configuration.isRuleSetFactoryCompatibilityEnabled());
}
/**
* Returns a ruleset factory which uses the classloader for PMD
* classes to resolve resource references.
*
* @param configuration PMD configuration, contains info about the
* factory parameters
*
* @return A ruleset factory
*
* @see #createFactory(PMDConfiguration, ClassLoader)
*/
public static RuleSetFactory createFactory(final PMDConfiguration configuration) {
return createFactory(configuration, RulesetsFactoryUtils.class.getClassLoader());
}
/**
* Returns a ruleset factory with default parameters. It doesn't prune
* rules based on priority, and doesn't warn for deprecations.
*
* @return A ruleset factory
*
* @see #createFactory(PMDConfiguration, ClassLoader)
*/
public static RuleSetFactory defaultFactory() {
return new RuleSetFactory();
}
/**
* Returns a ruleset factory which uses the provided {@link ClassLoader}
* to resolve resource references. It warns for deprecated rule usages.
*
* @param configuration PMD configuration, contains info about the
* factory parameters
* @param classLoader Class loader to load resources
*
* @return A ruleset factory
*
* @see #createFactory(PMDConfiguration)
*/
public static RuleSetFactory createFactory(final PMDConfiguration configuration, ClassLoader classLoader) {
return createFactory(classLoader,
configuration.getMinimumPriority(),
true,
configuration.isRuleSetFactoryCompatibilityEnabled());
}
/**
* Returns a ruleset factory which uses the provided {@link ClassLoader}
* to resolve resource references.
*
* @param minimumPriority Minimum priority for rules to be included
* @param warnDeprecated If true, print warnings when deprecated rules are included
* @param enableCompatibility If true, rule references to moved rules are mapped to their
* new location if they are known
* @param classLoader Class loader to load resources
*
* @return A ruleset factory
*
* @see #createFactory(PMDConfiguration)
*/
public static RuleSetFactory createFactory(ClassLoader classLoader,
RulePriority minimumPriority,
boolean warnDeprecated,
boolean enableCompatibility) {
return new RuleSetFactory(new ResourceLoader(classLoader), minimumPriority, warnDeprecated, enableCompatibility);
}
/**
* Returns a ruleset factory which uses the classloader for PMD
* classes to resolve resource references.
*
* @param minimumPriority Minimum priority for rules to be included
* @param warnDeprecated If true, print warnings when deprecated rules are included
* @param enableCompatibility If true, rule references to moved rules are mapped to their
* new location if they are known
*
* @return A ruleset factory
*
* @see #createFactory(PMDConfiguration)
*/
public static RuleSetFactory createFactory(RulePriority minimumPriority,
boolean warnDeprecated,
boolean enableCompatibility) {
return new RuleSetFactory(new ResourceLoader(), minimumPriority, warnDeprecated, enableCompatibility);
}
/**
* If in debug modus, print the names of the rules.
*
* @param rulesets
* the RuleSets to print
* @param rulesets the RuleSets to print
*/
private static void printRuleNamesInDebug(RuleSets rulesets) {
if (LOG.isLoggable(Level.FINER)) {

View File

@ -27,6 +27,7 @@ import net.sourceforge.pmd.RuleSet;
import net.sourceforge.pmd.RuleSetFactory;
import net.sourceforge.pmd.RuleSetNotFoundException;
import net.sourceforge.pmd.RuleSets;
import net.sourceforge.pmd.RulesetsFactoryUtils;
import net.sourceforge.pmd.SourceCodeProcessor;
import net.sourceforge.pmd.lang.Language;
import net.sourceforge.pmd.lang.LanguageFilenameFilter;
@ -116,7 +117,7 @@ public final class Benchmarker {
System.out.println("Checking directory " + srcDir);
}
Set<RuleDuration> results = new TreeSet<>();
RuleSetFactory factory = new RuleSetFactory();
RuleSetFactory factory = RulesetsFactoryUtils.defaultFactory();
if (StringUtils.isNotBlank(ruleset)) {
stress(languageVersion, factory.createRuleSet(ruleset), dataSources, results, debug);
} else {
@ -174,7 +175,7 @@ public final class Benchmarker {
private static void stress(LanguageVersion languageVersion, RuleSet ruleSet, List<DataSource> dataSources,
Set<RuleDuration> results, boolean debug) throws PMDException, IOException {
final RuleSetFactory factory = new RuleSetFactory();
final RuleSetFactory factory = RulesetsFactoryUtils.defaultFactory();
for (Rule rule: ruleSet.getRules()) {
if (debug) {
System.out.println("Starting " + rule.getName());

View File

@ -21,6 +21,8 @@ import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.io.IOUtils;
/**
* Implementation that handles a Document as a file in the filesystem and receives operations in a sorted manner
* (i.e. the regions are sorted). This improves the efficiency of reading the file by only scanning it once while
@ -157,11 +159,7 @@ public class DocumentFile implements Document, Closeable {
}
private void writeUntilEOF() throws IOException {
String line;
while ((line = reader.readLine()) != null) {
writer.write(line);
}
IOUtils.copy(reader, writer);
}
/* package-private */ List<Integer> getLineToOffset() {

View File

@ -5,16 +5,38 @@
package net.sourceforge.pmd.internal.util;
import org.checkerframework.checker.nullness.qual.NonNull;
public final class AssertionUtil {
private AssertionUtil() {
// utility class
}
public static void assertArgNonNegative(int n) {
if (n < 0) {
throw new IllegalArgumentException("Argument should be positive or null, got " + n);
public static int requireOver1(String name, final int value) {
if (value < 1) {
throw mustBe(name, value, ">= 1");
}
return value;
}
public static int requireNonNegative(String name, int value) {
if (value < 0) {
throw mustBe(name, value, "non-negative");
}
return value;
}
public static RuntimeException mustBe(String name, Object value, String condition) {
return new IllegalArgumentException(String.format("%s must be %s, got %s", name, condition, value));
}
@NonNull
public static <T> T requireParamNotNull(String paramName, T obj) {
if (obj == null) {
throw new NullPointerException("Parameter " + paramName + " is null");
}
return obj;
}
}

View File

@ -201,7 +201,7 @@ public final class IteratorUtil {
/** Advance {@code n} times. */
public static void advance(Iterator<?> iterator, int n) {
AssertionUtil.assertArgNonNegative(n);
AssertionUtil.requireNonNegative("n", n);
while (n > 0 && iterator.hasNext()) {
iterator.next();
@ -211,7 +211,7 @@ public final class IteratorUtil {
/** Limit the number of elements yielded by this iterator to the given number. */
public static <T> Iterator<T> take(Iterator<T> iterator, final int n) {
AssertionUtil.assertArgNonNegative(n);
AssertionUtil.requireNonNegative("n", n);
if (n == 0) {
return Collections.emptyIterator();
}
@ -233,7 +233,7 @@ public final class IteratorUtil {
/** Produce an iterator whose first element is the nth element of the given source. */
public static <T> Iterator<T> drop(Iterator<T> source, final int n) {
AssertionUtil.assertArgNonNegative(n);
AssertionUtil.requireNonNegative("n", n);
if (n == 0) {
return source;
}

View File

@ -86,7 +86,7 @@ abstract class AxisStream<T extends Node> extends IteratorBasedNStream<T> {
@Override
public NodeStream<T> drop(int n) {
AssertionUtil.assertArgNonNegative(n);
AssertionUtil.requireNonNegative("n", n);
switch (n) {
case 0:
return this;
@ -306,13 +306,13 @@ abstract class AxisStream<T extends Node> extends IteratorBasedNStream<T> {
@Override
public NodeStream<T> take(int maxSize) {
AssertionUtil.assertArgNonNegative(maxSize);
AssertionUtil.requireNonNegative("maxSize", maxSize);
return StreamImpl.sliceChildren(node, filter, low, min(maxSize, len));
}
@Override
public NodeStream<T> drop(int n) {
AssertionUtil.assertArgNonNegative(n);
AssertionUtil.requireNonNegative("n", n);
int newLow = min(low + n, node.jjtGetNumChildren());
int newLen = max(len - n, 0);

View File

@ -78,13 +78,13 @@ abstract class IteratorBasedNStream<T extends Node> implements NodeStream<T> {
@Override
public NodeStream<T> drop(int n) {
AssertionUtil.assertArgNonNegative(n);
AssertionUtil.requireNonNegative("n", n);
return n == 0 ? this : mapIter(iter -> IteratorUtil.drop(iter, n));
}
@Override
public NodeStream<T> take(int maxSize) {
AssertionUtil.assertArgNonNegative(maxSize);
AssertionUtil.requireNonNegative("maxSize", maxSize);
return maxSize == 0 ? NodeStream.empty() : mapIter(iter -> IteratorUtil.take(iter, maxSize));
}

View File

@ -92,13 +92,13 @@ final class SingletonNodeStream<T extends Node> extends IteratorBasedNStream<T>
@Override
public NodeStream<T> drop(int n) {
AssertionUtil.assertArgNonNegative(n);
AssertionUtil.requireNonNegative("n", n);
return n == 0 ? this : NodeStream.empty();
}
@Override
public NodeStream<T> take(int maxSize) {
AssertionUtil.assertArgNonNegative(maxSize);
AssertionUtil.requireNonNegative("maxSize", maxSize);
return maxSize >= 1 ? this : NodeStream.empty();
}

View File

@ -28,6 +28,7 @@ import net.sourceforge.pmd.lang.ast.internal.AxisStream.FilteredDescendantStream
public final class StreamImpl {
@SuppressWarnings("rawtypes")
private static final NodeStream EMPTY = new IteratorBasedNStream() {
@Override
public Iterator iterator() {

View File

@ -389,4 +389,17 @@ public class RuleReference extends AbstractDelegateRule {
public Rule deepCopy() {
return new RuleReference(this);
}
/**
* Checks whether this rule reference explicitly overrides any of the possible
* attributes of the referenced rule.
* @return <code>true</code> if there is at least one attribute overridden. <code>false</code> if
* the referenced rule is referenced without any change.
*/
public boolean hasOverriddenAttributes() {
return deprecated != null || description != null || examples != null || externalInfoUrl != null
|| maximumLanguageVersion != null || minimumLanguageVersion != null
|| message != null || name != null || priority != null
|| propertyDescriptors != null || propertyValues != null;
}
}

View File

@ -14,6 +14,7 @@ import org.w3c.dom.Element;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.RulePriority;
import net.sourceforge.pmd.RuleSetReference;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.Language;
import net.sourceforge.pmd.lang.LanguageRegistry;
import net.sourceforge.pmd.lang.LanguageVersion;
@ -28,6 +29,8 @@ import net.sourceforge.pmd.util.ResourceLoader;
* @author Clément Fournier
* @since 6.0.0
*/
@InternalApi
@Deprecated
public class RuleBuilder {
private List<PropertyDescriptor<?>> definedProperties = new ArrayList<>();

View File

@ -26,6 +26,7 @@ import org.w3c.dom.NodeList;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.RulePriority;
import net.sourceforge.pmd.RuleSetReference;
import net.sourceforge.pmd.annotation.InternalApi;
import net.sourceforge.pmd.lang.rule.RuleReference;
import net.sourceforge.pmd.properties.PropertyDescriptor;
import net.sourceforge.pmd.properties.PropertyDescriptorField;
@ -40,6 +41,8 @@ import net.sourceforge.pmd.util.ResourceLoader;
* @author Clément Fournier
* @since 6.0.0
*/
@InternalApi
@Deprecated
public class RuleFactory {
private static final Logger LOG = Logger.getLogger(RuleFactory.class.getName());
@ -57,7 +60,7 @@ public class RuleFactory {
private static final String DESCRIPTION = "description";
private static final String PROPERTY = "property";
private static final String CLASS = "class";
private static final List<String> REQUIRED_ATTRIBUTES = Collections.unmodifiableList(Arrays.asList(NAME, CLASS));
private final ResourceLoader resourceLoader;
@ -337,7 +340,7 @@ public class RuleFactory {
Attr a = (Attr) atts.item(i);
values.put(PropertyDescriptorField.getConstant(a.getName()), a.getValue());
}
if (StringUtils.isBlank(values.get(DEFAULT_VALUE))) {
NodeList children = propertyElement.getElementsByTagName(DEFAULT_VALUE.attributeName());
if (children.getLength() == 1) {

View File

@ -53,10 +53,8 @@ public final class StringUtil {
* Return whether the non-null text arg starts with any of the prefix
* values.
*
* @param text
* @param prefixes
*
* @return boolean
*
* @deprecated {@link StringUtils#startsWithAny(CharSequence, CharSequence...)}
*/
@Deprecated
@ -75,9 +73,6 @@ public final class StringUtil {
/**
* Returns whether the non-null text arg matches any of the test values.
*
* @param text
* @param tests
*
* @return boolean
*/
public static boolean isAnyOf(String text, String... tests) {
@ -96,9 +91,6 @@ public final class StringUtil {
* Checks for the existence of any of the listed prefixes on the non-null
* text and removes them.
*
* @param text
* @param prefixes
*
* @return String
*/
public static String withoutPrefixes(String text, String... prefixes) {
@ -117,6 +109,7 @@ public final class StringUtil {
* @param value String
*
* @return boolean
*
* @deprecated {@link StringUtils#isNotBlank(CharSequence)}
*/
@Deprecated
@ -133,6 +126,7 @@ public final class StringUtil {
* @param value String to test
*
* @return <code>true</code> if the value is empty, <code>false</code> otherwise.
*
* @deprecated {@link StringUtils#isBlank(CharSequence)}
*/
@Deprecated
@ -147,6 +141,7 @@ public final class StringUtil {
* @param value String to test
*
* @return True if the argument is null or the empty string
*
* @deprecated {@link StringUtils#isEmpty(CharSequence)}
*/
@Deprecated
@ -159,9 +154,6 @@ public final class StringUtil {
* Returns true if both strings are effectively null or whitespace, returns
* false otherwise if they have actual text that differs.
*
* @param a
* @param b
*
* @return boolean
*/
@Deprecated
@ -184,6 +176,7 @@ public final class StringUtil {
* @param newString String
*
* @return String
*
* @deprecated {@link StringUtils#replace(String, String, String)}
*/
@Deprecated
@ -207,11 +200,8 @@ public final class StringUtil {
}
/**
* @param buf
* @param src
* @param supportUTF8 override the default setting, whether special characters should be replaced with entities (
* <code>false</code>) or should be included as is ( <code>true</code>).
*
*/
public static void appendXmlEscaped(StringBuilder buf, String src, boolean supportUTF8) {
char c;
@ -249,8 +239,6 @@ public final class StringUtil {
/**
* Replace some whitespace characters so they are visually apparent.
*
* @param o
*
* @return String
*/
public static String escapeWhitespace(Object o) {
@ -271,6 +259,7 @@ public final class StringUtil {
* @param newString String
*
* @return String
*
* @deprecated {@link StringUtils#replace(String, String, String)} or {@link StringUtils#replaceChars(String, char, char)}
*/
@Deprecated
@ -304,6 +293,7 @@ public final class StringUtil {
* @param delimiter char
*
* @return String[]
*
* @deprecated {@link StringUtils#split(String, char)}
*/
@Deprecated
@ -352,6 +342,7 @@ public final class StringUtil {
* @param separator char
*
* @return String[]
*
* @deprecated {@link StringUtils#split(String, String)}
*/
@Deprecated
@ -386,6 +377,7 @@ public final class StringUtil {
* @param sb StringBuffer
* @param iter Iterator
* @param separator String
*
* @deprecated {@link StringUtils#join(Iterator, String)}
*/
@Deprecated
@ -411,6 +403,7 @@ public final class StringUtil {
* @param sb StringBuilder
* @param items Object[]
* @param separator String
*
* @deprecated {@link StringUtils#join(Iterable, String)}
*/
@Deprecated
@ -497,9 +490,6 @@ public final class StringUtil {
* Trims off the leading characters off the strings up to the trimDepth
* specified. Returns the same strings if trimDepth = 0
*
* @param strings
* @param trimDepth
*
* @return String[]
*/
public static String[] trimStartOn(String[] strings, int trimDepth) {
@ -523,6 +513,7 @@ public final class StringUtil {
* @param length The desired minimum length of the resulting padded String
*
* @return The resulting left padded String
*
* @deprecated {@link StringUtils#leftPad(String, int)}
*/
@Deprecated

View File

@ -28,7 +28,7 @@ public class RuleSetFactoryCompatibilityTest {
+ " <description>Test</description>\n" + "\n"
+ " <rule ref=\"rulesets/dummy/notexisting.xml/DummyBasicMockRule\" />\n" + "</ruleset>\n";
RuleSetFactory factory = new RuleSetFactory();
RuleSetFactory factory = RulesetsFactoryUtils.defaultFactory();
factory.getCompatibilityFilter().addFilterRuleMoved("dummy", "notexisting", "basic", "DummyBasicMockRule");
RuleSet createdRuleSet = createRulesetFromString(ruleset, factory);
@ -66,7 +66,7 @@ public class RuleSetFactoryCompatibilityTest {
+ " <description>Test</description>\n" + "\n" + " <rule ref=\"rulesets/dummy/basic.xml\">\n"
+ " <exclude name=\"OldNameOfSampleXPathRule\"/>\n" + " </rule>\n" + "</ruleset>\n";
RuleSetFactory factory = new RuleSetFactory();
RuleSetFactory factory = RulesetsFactoryUtils.defaultFactory();
factory.getCompatibilityFilter().addFilterRuleRenamed("dummy", "basic", "OldNameOfSampleXPathRule",
"SampleXPathRule");

View File

@ -0,0 +1,81 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import net.sourceforge.pmd.junit.JavaUtilLoggingRule;
import net.sourceforge.pmd.junit.LocaleRule;
public class RuleSetFactoryDuplicatedRuleLoggingTest {
@org.junit.Rule
public ExpectedException ex = ExpectedException.none();
@org.junit.Rule
public LocaleRule localeRule = LocaleRule.en();
@org.junit.Rule
public JavaUtilLoggingRule logging = new JavaUtilLoggingRule(RuleSetFactory.class.getName());
@Test
public void duplicatedRuleReferenceShouldWarn() throws RuleSetNotFoundException {
RuleSet ruleset = loadRuleSet("duplicatedRuleReference.xml");
assertEquals(1, ruleset.getRules().size());
Rule mockRule = ruleset.getRuleByName("DummyBasicMockRule");
assertNotNull(mockRule);
assertEquals(RulePriority.MEDIUM, mockRule.getPriority());
assertTrue(logging.getLog().contains("The rule DummyBasicMockRule is referenced multiple times in \"Custom Rules\". "
+ "Only the last rule configuration is used."));
}
@Test
public void duplicatedRuleReferenceWithOverrideShouldNotWarn() throws RuleSetNotFoundException {
RuleSet ruleset = loadRuleSet("duplicatedRuleReferenceWithOverride.xml");
assertEquals(2, ruleset.getRules().size());
Rule mockRule = ruleset.getRuleByName("DummyBasicMockRule");
assertNotNull(mockRule);
assertEquals(RulePriority.HIGH, mockRule.getPriority());
assertNotNull(ruleset.getRuleByName("SampleXPathRule"));
assertTrue(logging.getLog().isEmpty());
}
@Test
public void duplicatedRuleReferenceWithOverrideBeforeShouldNotWarn() throws RuleSetNotFoundException {
RuleSet ruleset = loadRuleSet("duplicatedRuleReferenceWithOverrideBefore.xml");
assertEquals(2, ruleset.getRules().size());
Rule mockRule = ruleset.getRuleByName("DummyBasicMockRule");
assertNotNull(mockRule);
assertEquals(RulePriority.HIGH, mockRule.getPriority());
assertNotNull(ruleset.getRuleByName("SampleXPathRule"));
assertTrue(logging.getLog().isEmpty());
}
@Test
public void multipleDuplicates() throws RuleSetNotFoundException {
RuleSet ruleset = loadRuleSet("multipleDuplicates.xml");
assertEquals(2, ruleset.getRules().size());
Rule mockRule = ruleset.getRuleByName("DummyBasicMockRule");
assertNotNull(mockRule);
assertEquals(RulePriority.MEDIUM_HIGH, mockRule.getPriority());
assertNotNull(ruleset.getRuleByName("SampleXPathRule"));
assertTrue(logging.getLog().contains("The rule DummyBasicMockRule is referenced multiple times in \"Custom Rules\". "
+ "Only the last rule configuration is used."));
assertTrue(logging.getLog().contains("The ruleset rulesets/dummy/basic.xml is referenced multiple times in \"Custom Rules\"."));
}
private RuleSet loadRuleSet(String ruleSetFilename) throws RuleSetNotFoundException {
RuleSetFactory rsf = RulesetsFactoryUtils.defaultFactory();
return rsf.createRuleSet("net/sourceforge/pmd/rulesets/duplicatedRuleLoggingTest/" + ruleSetFilename);
}
}

View File

@ -46,7 +46,7 @@ public class RuleSetFactoryTest {
RuleSet rs = loadRuleSet(EMPTY_RULESET);
assertNull("RuleSet file name not expected", rs.getFileName());
RuleSetFactory rsf = new RuleSetFactory();
RuleSetFactory rsf = RulesetsFactoryUtils.defaultFactory();
rs = rsf.createRuleSet("net/sourceforge/pmd/TestRuleset1.xml");
assertEquals("wrong RuleSet file name", rs.getFileName(), "net/sourceforge/pmd/TestRuleset1.xml");
}
@ -59,7 +59,7 @@ public class RuleSetFactoryTest {
@Test
public void testRefs() throws Exception {
RuleSetFactory rsf = new RuleSetFactory();
RuleSetFactory rsf = RulesetsFactoryUtils.defaultFactory();
RuleSet rs = rsf.createRuleSet("net/sourceforge/pmd/TestRuleset1.xml");
assertNotNull(rs.getRuleByName("TestRuleRef"));
}
@ -70,7 +70,7 @@ public class RuleSetFactoryTest {
assertNotNull("Test ruleset not found - can't continue with test!", in);
in.close();
RuleSetFactory rsf = new RuleSetFactory();
RuleSetFactory rsf = RulesetsFactoryUtils.defaultFactory();
RuleSets rs = rsf.createRuleSets("net/sourceforge/pmd/rulesets/reference-ruleset.xml");
// added by referencing a complete ruleset (TestRuleset1.xml)
assertNotNull(rs.getRuleByName("MockRule1"));
@ -128,7 +128,7 @@ public class RuleSetFactoryTest {
@Test(expected = RuleSetNotFoundException.class)
public void testRuleSetNotFound() throws RuleSetNotFoundException {
RuleSetFactory rsf = new RuleSetFactory();
RuleSetFactory rsf = RulesetsFactoryUtils.defaultFactory();
rsf.createRuleSet("fooooo");
}
@ -535,7 +535,7 @@ public class RuleSetFactoryTest {
assertNotNull(ruleset.getRuleByName("SampleXPathRule"));
// now, load with default minimum priority
rsf = new RuleSetFactory();
rsf = RulesetsFactoryUtils.defaultFactory();
ruleset = rsf.createRuleSet("net/sourceforge/pmd/rulesets/ruleset-minimum-priority.xml");
assertEquals("Number of Rules", 2, ruleset.getRules().size());
Rule dummyBasicMockRule = ruleset.getRuleByName("DummyBasicMockRule");
@ -544,13 +544,13 @@ public class RuleSetFactoryTest {
@Test
public void testExcludeWithMinimumPriority() throws RuleSetNotFoundException {
RuleSetFactory rsf = new RuleSetFactory(new ResourceLoader(), RulePriority.HIGH, true, true);
RuleSetFactory rsf = RulesetsFactoryUtils.createFactory(RulePriority.HIGH, true, true);
RuleSet ruleset = rsf.createRuleSet("net/sourceforge/pmd/rulesets/ruleset-minimum-priority-exclusion.xml");
// no rules should be loaded
assertEquals("Number of Rules", 0, ruleset.getRules().size());
// now, load with default minimum priority
rsf = new RuleSetFactory();
rsf = RulesetsFactoryUtils.defaultFactory();
ruleset = rsf.createRuleSet("net/sourceforge/pmd/rulesets/ruleset-minimum-priority-exclusion.xml");
// only one rule, we have excluded one...
assertEquals("Number of Rules", 1, ruleset.getRules().size());
@ -663,7 +663,7 @@ public class RuleSetFactoryTest {
@Test
public void testDeprecatedRuleSetReference() throws RuleSetNotFoundException {
RuleSetFactory ruleSetFactory = new RuleSetFactory();
RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.defaultFactory();
RuleSet ruleSet = ruleSetFactory.createRuleSet("net/sourceforge/pmd/rulesets/ruleset-deprecated.xml");
assertEquals(2, ruleSet.getRules().size());
}
@ -705,7 +705,7 @@ public class RuleSetFactoryTest {
+ " <properties>\n" + " <property name=\"xpath\" value=\"//TypeDeclaration\" />\n"
+ " <property name=\"message\" value=\"Foo\" />\n" + " </properties>\n" + " </rule>\n"
+ "</ruleset>\n");
RuleSetFactory ruleSetFactory = new RuleSetFactory();
RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.defaultFactory();
ruleSetFactory.createRuleSet(ref);
}
@ -723,7 +723,7 @@ public class RuleSetFactoryTest {
+ " xsi:schemaLocation=\"http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd\">\n"
+ " <description>PMD Ruleset.</description>\n" + "\n"
+ " <exclude-pattern>.*Test.*</exclude-pattern>\n" + "\n" + "</ruleset>\n");
RuleSetFactory ruleSetFactory = new RuleSetFactory();
RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.defaultFactory();
RuleSet ruleset = ruleSetFactory.createRuleSet(ref);
assertEquals(0, ruleset.getRules().size());
}
@ -766,7 +766,7 @@ public class RuleSetFactoryTest {
+ " xsi:schemaLocation=\"http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd\">\n"
+ " <description>Custom ruleset for tests</description>\n"
+ " <rule ref=\"net/sourceforge/pmd/TestRuleset1.xml/ThisRuleDoesNotExist\"/>\n" + "</ruleset>\n");
RuleSetFactory ruleSetFactory = new RuleSetFactory();
RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.defaultFactory();
ruleSetFactory.createRuleSet(ref);
}
@ -786,7 +786,7 @@ public class RuleSetFactoryTest {
+ " <description>PMD Plugin preferences rule set</description>\n" + "\n"
+ "<rule name=\"OverriddenDummyBasicMockRule\"\n"
+ " ref=\"rulesets/dummy/basic.xml/DummyBasicMockRule\">\n" + "</rule>\n" + "\n" + "</ruleset>");
RuleSetFactory ruleSetFactory = new RuleSetFactory();
RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.defaultFactory();
RuleSet rs = ruleSetFactory.createRuleSet(ref);
Rule r = rs.getRules().toArray(new Rule[1])[0];
@ -813,7 +813,7 @@ public class RuleSetFactoryTest {
+ " <description>Custom ruleset for tests</description>\n"
+ " <rule ref=\"net/sourceforge/pmd/TestRuleset1.xml\">\n"
+ " <exclude name=\"ThisRuleDoesNotExist\"/>\n" + " </rule>\n" + "</ruleset>\n");
RuleSetFactory ruleSetFactory = new RuleSetFactory();
RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.defaultFactory();
RuleSet ruleset = ruleSetFactory.createRuleSet(ref);
assertEquals(4, ruleset.getRules().size());
}
@ -843,7 +843,7 @@ public class RuleSetFactoryTest {
+ " <description>Custom ruleset for tests</description>\n"
+ " <rule ref=\"rulesets/dummy/basic.xml\">\n" + " <exclude name=\"DummyBasicMockRule\"/>\n"
+ " </rule>\n" + "</ruleset>\n");
RuleSetFactory ruleSetFactory = new RuleSetFactory();
RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.defaultFactory();
RuleSet ruleset = ruleSetFactory.createRuleSet(ref1);
assertNull(ruleset.getRuleByName("DummyBasicMockRule"));
@ -855,7 +855,7 @@ public class RuleSetFactoryTest {
+ " <description>Custom ruleset for tests</description>\n"
+ " <rule ref=\"rulesets/dummy/basic.xml\">\n" + " <exclude name=\"DummyBasicMockRule\"/>\n"
+ " </rule>\n" + " <rule ref=\"rulesets/dummy/basic.xml\"/>\n" + "</ruleset>\n");
RuleSetFactory ruleSetFactory2 = new RuleSetFactory();
RuleSetFactory ruleSetFactory2 = RulesetsFactoryUtils.defaultFactory();
RuleSet ruleset2 = ruleSetFactory2.createRuleSet(ref2);
assertNotNull(ruleset2.getRuleByName("DummyBasicMockRule"));
@ -867,7 +867,7 @@ public class RuleSetFactoryTest {
+ " <description>Custom ruleset for tests</description>\n"
+ " <rule ref=\"rulesets/dummy/basic.xml\"/>\n" + " <rule ref=\"rulesets/dummy/basic.xml\">\n"
+ " <exclude name=\"DummyBasicMockRule\"/>\n" + " </rule>\n" + "</ruleset>\n");
RuleSetFactory ruleSetFactory3 = new RuleSetFactory();
RuleSetFactory ruleSetFactory3 = RulesetsFactoryUtils.defaultFactory();
RuleSet ruleset3 = ruleSetFactory3.createRuleSet(ref3);
assertNotNull(ruleset3.getRuleByName("DummyBasicMockRule"));
}
@ -885,7 +885,7 @@ public class RuleSetFactoryTest {
+ " <description>Custom ruleset for tests</description>\n"
+ " <rule ref=\"rulesets/dummy/basic.xml\"/>\n"
+ " </ruleset>\n");
RuleSetFactory ruleSetFactory = new RuleSetFactory();
RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.defaultFactory();
ruleSetFactory.createRuleSet(ref);
assertTrue(logging.getLog().contains("RuleSet name is missing."));
@ -900,7 +900,7 @@ public class RuleSetFactoryTest {
+ " xsi:schemaLocation=\"http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd\">\n"
+ " <rule ref=\"rulesets/dummy/basic.xml\"/>\n"
+ " </ruleset>\n");
RuleSetFactory ruleSetFactory = new RuleSetFactory();
RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.defaultFactory();
ruleSetFactory.createRuleSet(ref);
assertTrue(logging.getLog().contains("RuleSet description is missing."));
}
@ -1100,12 +1100,12 @@ public class RuleSetFactoryTest {
}
private RuleSet loadRuleSet(String ruleSetXml) throws RuleSetNotFoundException {
RuleSetFactory rsf = new RuleSetFactory();
RuleSetFactory rsf = RulesetsFactoryUtils.defaultFactory();
return rsf.createRuleSet(createRuleSetReferenceId(ruleSetXml));
}
private RuleSet loadRuleSetWithDeprecationWarnings(String ruleSetXml) throws RuleSetNotFoundException {
RuleSetFactory rsf = new RuleSetFactory(new ResourceLoader(), RulePriority.LOW, true, false);
RuleSetFactory rsf = RulesetsFactoryUtils.createFactory(RulePriority.LOW, true, false);
return rsf.createRuleSet(createRuleSetReferenceId(ruleSetXml));
}

View File

@ -60,7 +60,7 @@ public class RuleSetTest {
public void testNoDFA() {
MockRule mock = new MockRule("name", "desc", "msg", "rulesetname");
mock.setLanguage(LanguageRegistry.getLanguage(DummyLanguageModule.NAME));
RuleSet rs = new RuleSetFactory().createSingleRuleRuleSet(mock);
RuleSet rs = RulesetsFactoryUtils.defaultFactory().createSingleRuleRuleSet(mock);
assertFalse(rs.usesDFA(LanguageRegistry.getLanguage(DummyLanguageModule.NAME)));
}
@ -69,7 +69,7 @@ public class RuleSetTest {
MockRule mock = new MockRule("name", "desc", "msg", "rulesetname");
mock.setLanguage(LanguageRegistry.getLanguage(DummyLanguageModule.NAME));
mock.setDfa(true);
RuleSet rs = new RuleSetFactory().createSingleRuleRuleSet(mock);
RuleSet rs = RulesetsFactoryUtils.defaultFactory().createSingleRuleRuleSet(mock);
assertTrue(rs.usesDFA(LanguageRegistry.getLanguage(DummyLanguageModule.NAME)));
}
@ -88,21 +88,21 @@ public class RuleSetTest {
@Test
public void testGetRuleByName() {
MockRule mock = new MockRule("name", "desc", "msg", "rulesetname");
RuleSet rs = new RuleSetFactory().createSingleRuleRuleSet(mock);
RuleSet rs = RulesetsFactoryUtils.defaultFactory().createSingleRuleRuleSet(mock);
assertEquals("unable to fetch rule by name", mock, rs.getRuleByName("name"));
}
@Test
public void testGetRuleByName2() {
MockRule mock = new MockRule("name", "desc", "msg", "rulesetname");
RuleSet rs = new RuleSetFactory().createSingleRuleRuleSet(mock);
RuleSet rs = RulesetsFactoryUtils.defaultFactory().createSingleRuleRuleSet(mock);
assertNull("the rule FooRule must not be found!", rs.getRuleByName("FooRule"));
}
@Test
public void testRuleList() {
MockRule rule = new MockRule("name", "desc", "msg", "rulesetname");
RuleSet ruleset = new RuleSetFactory().createSingleRuleRuleSet(rule);
RuleSet ruleset = RulesetsFactoryUtils.defaultFactory().createSingleRuleRuleSet(rule);
assertEquals("Size of RuleSet isn't one.", 1, ruleset.size());

View File

@ -51,7 +51,7 @@ public class RuleSetWriterTest {
*/
@Test
public void testWrite() throws Exception {
RuleSet braces = new RuleSetFactory().createRuleSet("net/sourceforge/pmd/TestRuleset1.xml");
RuleSet braces = RulesetsFactoryUtils.defaultFactory().createRuleSet("net/sourceforge/pmd/TestRuleset1.xml");
RuleSet ruleSet = new RuleSetBuilder(new Random().nextLong())
.withName("ruleset")
.withDescription("ruleset description")
@ -72,7 +72,7 @@ public class RuleSetWriterTest {
*/
@Test
public void testRuleReferenceOverriddenName() throws Exception {
RuleSetFactory ruleSetFactory = new RuleSetFactory();
RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.defaultFactory();
RuleSet rs = ruleSetFactory.createRuleSet("dummy-basic");
RuleSetReference ruleSetReference = new RuleSetReference("rulesets/dummy/basic.xml");

View File

@ -16,6 +16,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.io.IOUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@ -48,6 +49,22 @@ public class DocumentFileTest {
}
}
@Test
public void shouldPreserveNewlines() throws IOException {
final String testFileContent = IOUtils.toString(
DocumentFileTest.class.getResource("ShouldPreserveNewlines.java"), StandardCharsets.UTF_8);
writeContentToTemporaryFile(testFileContent);
try (DocumentFile documentFile = new DocumentFile(temporaryFile, StandardCharsets.UTF_8)) {
documentFile.insert(0, 0, "public ");
}
try (FileInputStream stream = new FileInputStream(temporaryFile)) {
final String actualContent = new String(readAllBytes(stream));
assertEquals("public " + testFileContent, actualContent);
}
}
private byte[] readAllBytes(final FileInputStream stream) throws IOException {
final int defaultBufferSize = 8192;
final int maxBufferSize = Integer.MAX_VALUE - 8;

View File

@ -17,6 +17,7 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@ -206,9 +207,7 @@ public class NodeStreamBlanketTest<T extends Node> {
@SafeVarargs
private static <T> void assertImplication(T input, Prop<? super T> precond, Prop<? super T>... properties) {
if (!precond.test(input)) {
return;
}
Assume.assumeTrue(precond.test(input));
for (Prop<? super T> prop2 : properties) {
Assert.assertTrue(

View File

@ -22,6 +22,7 @@ import net.sourceforge.pmd.Report.ConfigurationError;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.RuleSetFactory;
import net.sourceforge.pmd.RuleViolation;
import net.sourceforge.pmd.RulesetsFactoryUtils;
import net.sourceforge.pmd.ThreadSafeReportListener;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.rule.AbstractRule;
@ -51,9 +52,9 @@ public class MultiThreadProcessorTest {
ctx.getReport().addListener(reportListener);
processor = new MultiThreadProcessor(configuration);
ruleSetFactory = new RuleSetFactory();
ruleSetFactory = RulesetsFactoryUtils.defaultFactory();
}
@Test
public void testRulesDysnfunctionalLog() throws IOException {
setUpForTest("rulesets/MultiThreadProcessorTest/dysfunctional.xml");

View File

@ -30,7 +30,7 @@ import org.junit.rules.ExpectedException;
import net.sourceforge.pmd.FooRule;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.RuleSet;
import net.sourceforge.pmd.RuleSetFactory;
import net.sourceforge.pmd.RulesetsFactoryUtils;
import net.sourceforge.pmd.properties.constraints.PropertyConstraint;
@ -57,7 +57,7 @@ public class PropertyDescriptorTest {
FooRule rule = new FooRule();
rule.definePropertyDescriptor(intProperty);
rule.setProperty(intProperty, 1000);
RuleSet ruleSet = new RuleSetFactory().createSingleRuleRuleSet(rule);
RuleSet ruleSet = RulesetsFactoryUtils.defaultFactory().createSingleRuleRuleSet(rule);
List<Rule> dysfunctional = new ArrayList<>();
ruleSet.removeDysfunctionalRules(dysfunctional);
@ -78,7 +78,7 @@ public class PropertyDescriptorTest {
FooRule rule = new FooRule();
rule.definePropertyDescriptor(descriptor);
rule.setProperty(descriptor, Collections.singletonList(1000d)); // not in range
RuleSet ruleSet = new RuleSetFactory().createSingleRuleRuleSet(rule);
RuleSet ruleSet = RulesetsFactoryUtils.defaultFactory().createSingleRuleRuleSet(rule);
List<Rule> dysfunctional = new ArrayList<>();
ruleSet.removeDysfunctionalRules(dysfunctional);

View File

@ -0,0 +1,8 @@
class ShouldPreserveNewlines {
public static void main(String[] args) {
System.out.println("Test");
}
}
// note: multiple empty lines at the end

View File

@ -0,0 +1,12 @@
<?xml version="1.0"?>
<ruleset name="Custom Rules"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
<description>My custom rules</description>
<rule ref="rulesets/dummy/basic.xml/DummyBasicMockRule" />
<rule ref="rulesets/dummy/basic.xml/DummyBasicMockRule" />
</ruleset>

View File

@ -0,0 +1,14 @@
<?xml version="1.0"?>
<ruleset name="Custom Rules"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
<description>My custom rules</description>
<rule ref="rulesets/dummy/basic.xml" />
<rule ref="rulesets/dummy/basic.xml/DummyBasicMockRule">
<priority>1</priority>
</rule>
</ruleset>

View File

@ -0,0 +1,14 @@
<?xml version="1.0"?>
<ruleset name="Custom Rules"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
<description>My custom rules</description>
<rule ref="rulesets/dummy/basic.xml/DummyBasicMockRule">
<priority>1</priority>
</rule>
<rule ref="rulesets/dummy/basic.xml" />
</ruleset>

Some files were not shown because too many files have changed in this diff Show More