Merge branch 'master' into pmd/7.0.x
This commit is contained in:
22 files changed
+2055
-54
No files matched your search
@@ -21,7 +21,25 @@ This is a {{ site.pmd.release_type }} release.
|
||||
|
||||
#### New rules
|
||||
|
||||
This release ships with 1 new Java rule.
|
||||
This release ships with 3 new Java rules.
|
||||
|
||||
* {% rule java/bestpractices/PrimitiveWrapperInstantiation %} reports usages of primitive wrapper
|
||||
constructors. They are deprecated since Java 9 and should not be used.
|
||||
|
||||
```xml
|
||||
<rule ref="category/java/bestpractices.xml/PrimitiveWrapperInstantiation" />
|
||||
```
|
||||
|
||||
The rule is part of the quickstart.xml ruleset.
|
||||
|
||||
* {% rule java/bestpractices/SimplifiableTestAssertion %} suggests rewriting
|
||||
some test assertions to be more readable.
|
||||
|
||||
```xml
|
||||
<rule ref="category/java/bestpractices.xml/SimplifiableTestAssertion" />
|
||||
```
|
||||
|
||||
The rule is part of the quickstart.xml ruleset.
|
||||
|
||||
* {% rule java/errorprone/ReturnEmptyCollectionRatherThanNull %} suggests returning empty collections / arrays
|
||||
instead of null.
|
||||
@@ -43,9 +61,33 @@ This release ships with 1 new Java rule.
|
||||
|
||||
#### Deprecated rules
|
||||
|
||||
The rule {% rule java/errorprone/ReturnEmptyArrayRatherThanNull %} is deprecated and removed from
|
||||
the quickstart ruleset, as the new rule {% rule java/errorprone/ReturnEmptyCollectionRatherThanNull %}
|
||||
supersedes it.
|
||||
* The following Java rules are deprecated and removed from the quickstart ruleset,
|
||||
as the new rule {% rule java/bestpractices/SimplifiableTestAssertion %} merges
|
||||
their functionality:
|
||||
* {% rule java/bestpractices/UseAssertEqualsInsteadOfAssertTrue %}
|
||||
* {% rule java/bestpractices/UseAssertNullInsteadOfAssertTrue %}
|
||||
* {% rule java/bestpractices/UseAssertSameInsteadOfAssertTrue %}
|
||||
* {% rule java/bestpractices/UseAssertTrueInsteadOfAssertEquals %}
|
||||
* {% rule java/design/SimplifyBooleanAssertion %}
|
||||
|
||||
* The Java rule {% rule java/errorprone/ReturnEmptyArrayRatherThanNull %} is deprecated and removed from
|
||||
the quickstart ruleset, as the new rule {% rule java/errorprone/ReturnEmptyCollectionRatherThanNull %}
|
||||
supersedes it.
|
||||
|
||||
* The following Java rules are deprecated and removed from the quickstart ruleset,
|
||||
as the new rule {% rule java/bestpractices/PrimitiveWrapperInstantiation %} merges
|
||||
their functionality:
|
||||
* {% rule java/performance/BooleanInstantiation %}
|
||||
* {% rule java/performance/ByteInstantiation %}
|
||||
* {% rule java/performance/IntegerInstantiation %}
|
||||
* {% rule java/performance/LongInstantiation %}
|
||||
* {% rule java/performance/ShortInstantiation %}
|
||||
|
||||
* The Java rule {% rule java/performance/UnnecessaryWrapperObjectCreation %} is deprecated
|
||||
with no planned replacement before PMD 7. In it's current state, the rule is not useful
|
||||
as it finds only contrived cases of creating a primitive wrapper and unboxing it explicitly
|
||||
in the same expression. In PMD 7 this and more cases will be covered by a
|
||||
new rule `UnnecessaryBoxing`.
|
||||
|
||||
### Fixed Issues
|
||||
|
||||
@@ -53,14 +95,26 @@ supersedes it.
|
||||
* [#3201](https://github.com/pmd/pmd/issues/3201): \[apex] ApexCRUDViolation doesn't report Database class DMLs, inline no-arg object instantiations and inline list initialization
|
||||
* [#3329](https://github.com/pmd/pmd/issues/3329): \[apex] ApexCRUDViolation doesn't report SOQL for loops
|
||||
* core
|
||||
* [#1603](https://github.com/pmd/pmd/issues/1603): \[core] Language version comparison
|
||||
* [#3377](https://github.com/pmd/pmd/issues/3377): \[core] NPE when specifying report file in current directory in PMD CLI
|
||||
* [#3387](https://github.com/pmd/pmd/issues/3387): \[core] CPD should avoid unnecessary copies when running with --skip-lexical-errors
|
||||
* java-bestpractices
|
||||
* [#2908](https://github.com/pmd/pmd/issues/2908): \[java] Merge Junit assertion simplification rules
|
||||
* [#3235](https://github.com/pmd/pmd/issues/3235): \[java] UseTryWithResources false positive when closeable is provided as a method argument or class field
|
||||
* java-errorprone
|
||||
* [#3361](https://github.com/pmd/pmd/issues/3361): \[java] Rename rule MissingBreakInSwitch to ImplicitSwitchFallThrough
|
||||
* [#3382](https://github.com/pmd/pmd/pull/3382): \[java] New rule ReturnEmptyCollectionRatherThanNull
|
||||
|
||||
### API Changes
|
||||
|
||||
#### Internal API
|
||||
|
||||
Those APIs are not intended to be used by clients, and will be hidden or removed with PMD 7.0.0.
|
||||
You can identify them with the `@InternalApi` annotation. You'll also get a deprecation warning.
|
||||
|
||||
* The inner class {% jdoc !!core::cpd.TokenEntry.State %} is considered to be internal API.
|
||||
It will probably be moved away with PMD 7.
|
||||
|
||||
### External Contributions
|
||||
|
||||
* [#3367](https://github.com/pmd/pmd/pull/3367): \[apex] Check SOQL CRUD on for loops - [Jonathan Wiesel](https://github.com/jonathanwiesel)
|
||||
|
||||
@@ -147,12 +147,12 @@ public class CPD {
|
||||
}
|
||||
|
||||
private void addAndSkipLexicalErrors(SourceCode sourceCode) throws IOException {
|
||||
final TokenEntry.State savedState = tokens.snapshot();
|
||||
final TokenEntry.State savedState = new TokenEntry.State();
|
||||
try {
|
||||
addAndThrowLexicalError(sourceCode);
|
||||
} catch (TokenMgrError e) {
|
||||
System.err.println("Skipping " + sourceCode.getFileName() + ". Reason: " + e.getMessage());
|
||||
tokens.restore(savedState);
|
||||
savedState.restore(tokens);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import net.sourceforge.pmd.annotation.InternalApi;
|
||||
|
||||
public class TokenEntry implements Comparable<TokenEntry> {
|
||||
|
||||
public static final TokenEntry EOF = new TokenEntry();
|
||||
@@ -92,7 +94,11 @@ public class TokenEntry implements Comparable<TokenEntry> {
|
||||
/**
|
||||
* Helper class to preserve and restore the current state of the token
|
||||
* entries.
|
||||
*
|
||||
* @deprecated This is internal API.
|
||||
*/
|
||||
@InternalApi
|
||||
@Deprecated
|
||||
public static class State {
|
||||
private final int tokenCount;
|
||||
private final int tokensMapSize;
|
||||
@@ -102,7 +108,8 @@ public class TokenEntry implements Comparable<TokenEntry> {
|
||||
this.tokensMapSize = TokenEntry.TOKENS.get().size();
|
||||
}
|
||||
|
||||
public void restore(final List<TokenEntry> entries) {
|
||||
public void restore(Tokens tokens) {
|
||||
final List<TokenEntry> entries = tokens.getTokens();
|
||||
TokenEntry.TOKEN_COUNT.get().set(tokenCount);
|
||||
final Iterator<Map.Entry<String, Integer>> it = TOKENS.get().entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
|
||||
@@ -8,8 +8,6 @@ import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.pmd.cpd.TokenEntry.State;
|
||||
|
||||
public class Tokens {
|
||||
|
||||
private List<TokenEntry> tokens = new ArrayList<>();
|
||||
@@ -45,13 +43,4 @@ public class Tokens {
|
||||
public List<TokenEntry> getTokens() {
|
||||
return tokens;
|
||||
}
|
||||
|
||||
public State snapshot() {
|
||||
return new State();
|
||||
}
|
||||
|
||||
public void restore(final State savedState) {
|
||||
savedState.restore(tokens);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
package net.sourceforge.pmd.lang;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.sourceforge.pmd.Rule;
|
||||
import net.sourceforge.pmd.annotation.InternalApi;
|
||||
|
||||
@@ -120,27 +122,28 @@ public class LanguageVersion implements Comparable<LanguageVersion> {
|
||||
|
||||
@Override
|
||||
public int compareTo(LanguageVersion o) {
|
||||
if (o == null) {
|
||||
return 1;
|
||||
}
|
||||
List<LanguageVersion> versions = language.getVersions();
|
||||
int thisPosition = versions.indexOf(this);
|
||||
int otherPosition = versions.indexOf(o);
|
||||
return Integer.compare(thisPosition, otherPosition);
|
||||
}
|
||||
|
||||
int comp = getName().compareTo(o.getName());
|
||||
if (comp != 0) {
|
||||
return comp;
|
||||
}
|
||||
|
||||
String[] vals1 = getName().split("\\.");
|
||||
String[] vals2 = o.getName().split("\\.");
|
||||
int i = 0;
|
||||
while (i < vals1.length && i < vals2.length && vals1[i].equals(vals2[i])) {
|
||||
i++;
|
||||
}
|
||||
if (i < vals1.length && i < vals2.length) {
|
||||
int diff = Integer.valueOf(vals1[i]).compareTo(Integer.valueOf(vals2[i]));
|
||||
return Integer.signum(diff);
|
||||
} else {
|
||||
return Integer.signum(vals1.length - vals2.length);
|
||||
/**
|
||||
* Compare this version to another version of the same language identified
|
||||
* by the given version string.
|
||||
*
|
||||
* @param versionString The version with which to compare
|
||||
*
|
||||
* @throws IllegalArgumentException If the argument is not a valid version
|
||||
* string for the parent language
|
||||
*/
|
||||
public int compareToVersion(String versionString) {
|
||||
LanguageVersion otherVersion = language.getVersion(versionString);
|
||||
if (otherVersion == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"No such version '" + versionString + "' for language " + language.getName());
|
||||
}
|
||||
return this.compareTo(otherVersion);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<ruleset name="6370"
|
||||
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>
|
||||
This ruleset contains links to rules that are new in PMD v6.37.0
|
||||
</description>
|
||||
|
||||
<rule ref="category/java/bestpractices.xml/PrimitiveWrapperInstantiation" />
|
||||
<rule ref="category/java/bestpractices.xml/SimplifiableTestAssertion" />
|
||||
<rule ref="category/java/errorprone.xml/ReturnEmptyCollectionRatherThanNull" />
|
||||
|
||||
</ruleset>
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.java.rule.bestpractices;
|
||||
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTAllocationExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTArguments;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTArrayDimsAndInits;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTBooleanLiteral;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTName;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTPrimarySuffix;
|
||||
import net.sourceforge.pmd.lang.java.ast.JavaNode;
|
||||
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
|
||||
import net.sourceforge.pmd.lang.java.types.TypeTestUtil;
|
||||
|
||||
public class PrimitiveWrapperInstantiationRule extends AbstractJavaRule {
|
||||
|
||||
public PrimitiveWrapperInstantiationRule() {
|
||||
addRuleChainVisit(ASTAllocationExpression.class);
|
||||
addRuleChainVisit(ASTPrimaryExpression.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTAllocationExpression node, Object data) {
|
||||
if (node.getFirstChildOfType(ASTArrayDimsAndInits.class) != null) {
|
||||
return data;
|
||||
}
|
||||
ASTClassOrInterfaceType type = node.getFirstChildOfType(ASTClassOrInterfaceType.class);
|
||||
if (type == null) {
|
||||
return data;
|
||||
}
|
||||
|
||||
if (TypeTestUtil.isA(Double.class, type)
|
||||
|| TypeTestUtil.isA(Float.class, type)
|
||||
|| TypeTestUtil.isA(Long.class, type)
|
||||
|| TypeTestUtil.isA(Integer.class, type)
|
||||
|| TypeTestUtil.isA(Short.class, type)
|
||||
|| TypeTestUtil.isA(Byte.class, type)
|
||||
|| TypeTestUtil.isA(Character.class, type)) {
|
||||
addViolation(data, node, type.getImage());
|
||||
} else if (TypeTestUtil.isA(Boolean.class, type)) {
|
||||
checkArguments(node.getFirstChildOfType(ASTArguments.class), node, data);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds calls of "Boolean.valueOf".
|
||||
*/
|
||||
@Override
|
||||
public Object visit(ASTPrimaryExpression node, Object data) {
|
||||
if (!TypeTestUtil.isA(Boolean.class, node)) {
|
||||
return data;
|
||||
}
|
||||
|
||||
if (node.getNumChildren() >= 2 && node.getChild(0).getNumChildren() > 0
|
||||
&& node.getChild(0).getChild(0) instanceof ASTName
|
||||
&& node.getChild(0).getChild(0).hasImageEqualTo("Boolean.valueOf")) {
|
||||
ASTPrimarySuffix suffix = (ASTPrimarySuffix) node.getChild(1);
|
||||
checkArguments(suffix.getFirstChildOfType(ASTArguments.class), node, data);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private void checkArguments(ASTArguments arguments, JavaNode node, Object data) {
|
||||
if (arguments == null || arguments.size() != 1) {
|
||||
return;
|
||||
}
|
||||
String messagePart = node instanceof ASTAllocationExpression
|
||||
? "Do not use `new Boolean"
|
||||
: "Do not use `Boolean.valueOf";
|
||||
ASTLiteral stringLiteral = getFirstArgStringLiteralOrNull(arguments);
|
||||
ASTBooleanLiteral boolLiteral = getFirstArgBooleanLiteralOrNull(arguments);
|
||||
if (stringLiteral != null) {
|
||||
if (stringLiteral.hasImageEqualTo("\"true\"")) {
|
||||
addViolationWithMessage(data, node, messagePart + "(\"true\")`, prefer `Boolean.TRUE`");
|
||||
} else if (stringLiteral.hasImageEqualTo("\"false\"")) {
|
||||
addViolationWithMessage(data, node, messagePart + "(\"false\")`, prefer `Boolean.FALSE`");
|
||||
}
|
||||
} else if (boolLiteral != null) {
|
||||
if (boolLiteral.isTrue()) {
|
||||
addViolationWithMessage(data, node, messagePart + "(true)`, prefer `Boolean.TRUE`");
|
||||
} else {
|
||||
addViolationWithMessage(data, node, messagePart + "(false)`, prefer `Boolean.FALSE`");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* └─ Arguments
|
||||
* └─ ArgumentList
|
||||
* └─ Expression
|
||||
* └─ PrimaryExpression
|
||||
* └─ PrimaryPrefix
|
||||
* └─ Literal
|
||||
* </pre>
|
||||
*/
|
||||
private static ASTLiteral getFirstArgStringLiteralOrNull(ASTArguments arguments) {
|
||||
if (arguments.size() == 1) {
|
||||
ASTExpression expr = arguments.getFirstDescendantOfType(ASTExpression.class);
|
||||
ASTPrimaryExpression primaryExpr = getSingleChildOf(expr, ASTPrimaryExpression.class);
|
||||
ASTPrimaryPrefix prefix = getSingleChildOf(primaryExpr, ASTPrimaryPrefix.class);
|
||||
ASTLiteral literal = getSingleChildOf(prefix, ASTLiteral.class);
|
||||
if (literal != null && literal.isStringLiteral()) {
|
||||
return literal;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* └─ Arguments
|
||||
* └─ ArgumentList
|
||||
* └─ Expression
|
||||
* └─ PrimaryExpression
|
||||
* └─ PrimaryPrefix
|
||||
* └─ Literal
|
||||
* └─ BooleanLiteral
|
||||
* </pre>
|
||||
*/
|
||||
private static ASTBooleanLiteral getFirstArgBooleanLiteralOrNull(ASTArguments arguments) {
|
||||
if (arguments.size() == 1) {
|
||||
ASTExpression expr = arguments.getFirstDescendantOfType(ASTExpression.class);
|
||||
ASTPrimaryExpression primaryExpr = getSingleChildOf(expr, ASTPrimaryExpression.class);
|
||||
ASTPrimaryPrefix prefix = getSingleChildOf(primaryExpr, ASTPrimaryPrefix.class);
|
||||
ASTLiteral literal = getSingleChildOf(prefix, ASTLiteral.class);
|
||||
return getSingleChildOf(literal, ASTBooleanLiteral.class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static <N extends JavaNode> N getSingleChildOf(JavaNode node, Class<N> type) {
|
||||
if (node == null || node.getNumChildren() != 1
|
||||
|| type != node.getChild(0).getClass()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
N result = (N) node.getChild(0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+327
File diff suppressed because it is too large.
Load diff
+121
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.java.rule.bestpractices;
|
||||
|
||||
import static net.sourceforge.pmd.properties.PropertyFactory.stringListProperty;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sourceforge.pmd.RuleContext;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTArguments;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTFinallyStatement;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTName;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTPrimarySuffix;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTTryStatement;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
|
||||
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
|
||||
import net.sourceforge.pmd.lang.java.symboltable.MethodScope;
|
||||
import net.sourceforge.pmd.lang.java.symboltable.VariableNameDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.types.TypeTestUtil;
|
||||
import net.sourceforge.pmd.lang.symboltable.NameDeclaration;
|
||||
import net.sourceforge.pmd.lang.symboltable.NameOccurrence;
|
||||
import net.sourceforge.pmd.properties.PropertyDescriptor;
|
||||
|
||||
public final class UseTryWithResourcesRule extends AbstractJavaRule {
|
||||
|
||||
private static final PropertyDescriptor<List<String>> CLOSE_METHODS =
|
||||
stringListProperty("closeMethods")
|
||||
.desc("Method names in finally block, which trigger this rule")
|
||||
.defaultValues("close", "closeQuietly")
|
||||
.delim(',')
|
||||
.build();
|
||||
|
||||
public UseTryWithResourcesRule() {
|
||||
addRuleChainVisit(ASTTryStatement.class);
|
||||
definePropertyDescriptor(CLOSE_METHODS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTTryStatement node, Object data) {
|
||||
boolean isJava9OrLater = isJava9OrLater((RuleContext) data);
|
||||
|
||||
ASTFinallyStatement finallyClause = node.getFinallyClause();
|
||||
if (finallyClause != null) {
|
||||
List<ASTName> methods = findCloseMethods(finallyClause.findDescendantsOfType(ASTName.class));
|
||||
for (ASTName method : methods) {
|
||||
ASTName closeTarget = getCloseTarget(method);
|
||||
if (TypeTestUtil.isA(AutoCloseable.class, closeTarget)
|
||||
&& (isJava9OrLater || isLocalVar(closeTarget))) {
|
||||
addViolation(data, node);
|
||||
break; // only report the first closeable
|
||||
}
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private boolean isJava9OrLater(RuleContext ruleContext) {
|
||||
String currentVersion = ruleContext.getLanguageVersion().getVersion();
|
||||
currentVersion = currentVersion.replace("-preview", "");
|
||||
return Double.parseDouble(currentVersion) >= 9;
|
||||
}
|
||||
|
||||
private boolean isLocalVar(ASTName closeTarget) {
|
||||
NameDeclaration nameDeclaration = closeTarget.getNameDeclaration();
|
||||
if (nameDeclaration instanceof VariableNameDeclaration) {
|
||||
ASTVariableDeclaratorId id = ((VariableNameDeclaration) nameDeclaration).getDeclaratorId();
|
||||
return id.isLocalVariable();
|
||||
} else if (closeTarget.getImage().contains(".")) {
|
||||
// this is a workaround for a bug in the symbol table:
|
||||
// the name might be resolved to a wrong method
|
||||
int lastDot = closeTarget.getImage().lastIndexOf('.');
|
||||
String varName = closeTarget.getImage().substring(0, lastDot);
|
||||
Map<VariableNameDeclaration, List<NameOccurrence>> vars = closeTarget.getScope()
|
||||
.getEnclosingScope(MethodScope.class)
|
||||
.getDeclarations(VariableNameDeclaration.class);
|
||||
for (VariableNameDeclaration varDecl : vars.keySet()) {
|
||||
if (varDecl.getName().equals(varName)) {
|
||||
return varDecl.getDeclaratorId().isLocalVariable();
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private ASTName getCloseTarget(ASTName method) {
|
||||
ASTArguments arguments = method.getNthParent(2).getFirstDescendantOfType(ASTArguments.class);
|
||||
if (arguments.size() > 0) {
|
||||
ASTName firstArgument = arguments.getChild(0).getChild(0).getFirstDescendantOfType(ASTName.class);
|
||||
if (firstArgument != null) {
|
||||
return firstArgument;
|
||||
}
|
||||
}
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
private List<ASTName> findCloseMethods(List<ASTName> names) {
|
||||
List<ASTName> potentialCloses = new ArrayList<>();
|
||||
for (ASTName name : names) {
|
||||
String image = name.getImage();
|
||||
int lastDot = image.lastIndexOf('.');
|
||||
if (lastDot > -1) {
|
||||
image = image.substring(lastDot + 1);
|
||||
}
|
||||
if (getProperty(CLOSE_METHODS).contains(image) && isMethodCall(name)) {
|
||||
potentialCloses.add(name);
|
||||
}
|
||||
}
|
||||
return potentialCloses;
|
||||
}
|
||||
|
||||
private boolean isMethodCall(ASTName potentialMethodCall) {
|
||||
return potentialMethodCall.getNthParent(2) instanceof ASTPrimaryExpression
|
||||
&& !potentialMethodCall.getNthParent(2).findChildrenOfType(ASTPrimarySuffix.class).isEmpty();
|
||||
}
|
||||
}
|
||||
-1
@@ -31,7 +31,6 @@ public class BigIntegerInstantiationRule extends AbstractJavaRulechainRule {
|
||||
super(ASTConstructorCall.class);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object visit(ASTConstructorCall node, Object data) {
|
||||
LanguageVersion languageVersion = node.getAstInfo().getLanguageVersion();
|
||||
|
||||
+1
-3
@@ -10,7 +10,6 @@ import java.util.Set;
|
||||
|
||||
import net.sourceforge.pmd.lang.LanguageRegistry;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.java.JavaLanguageModule;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTName;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix;
|
||||
@@ -36,8 +35,7 @@ public class UnnecessaryWrapperObjectCreationRule extends AbstractJavaRule {
|
||||
image = image.substring(10);
|
||||
}
|
||||
|
||||
boolean checkBoolean = node.getAstInfo().getLanguageVersion()
|
||||
.compareTo(LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("1.5")) >= 0;
|
||||
boolean checkBoolean = node.getAstInfo().getLanguageVersion().compareToVersion("1.5") >= 0;
|
||||
|
||||
if (PREFIX_SET.contains(image) || checkBoolean && "Boolean.valueOf".equals(image)) {
|
||||
ASTPrimaryExpression parent = (ASTPrimaryExpression) node.getParent();
|
||||
|
||||
@@ -802,7 +802,6 @@ public class MyTest {
|
||||
since="6.35.0"
|
||||
message="JUnit 5 tests should be package-private."
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule"
|
||||
typeResolution="true"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junit5testshouldbepackageprivate">
|
||||
<description><![CDATA[
|
||||
Reports JUnit 5 test classes and methods that are not package-private.
|
||||
@@ -1197,6 +1196,36 @@ public class Foo {
|
||||
</example>
|
||||
</rule>
|
||||
|
||||
<rule name="PrimitiveWrapperInstantiation"
|
||||
language="java"
|
||||
since="6.37.0"
|
||||
message="Do not use `new {0}(...)`, prefer `{0}.valueOf(...)`"
|
||||
class="net.sourceforge.pmd.lang.java.rule.bestpractices.PrimitiveWrapperInstantiationRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#primitivewrapperinstantiation">
|
||||
<description>
|
||||
Reports usages of primitive wrapper constructors. They are deprecated
|
||||
since Java 9 and should not be used. Even before Java 9, they can
|
||||
be replaced with usage of the corresponding static `valueOf` factory method
|
||||
(which may be automatically inserted by the compiler since Java 1.5).
|
||||
This has the advantage that it may reuse common instances instead of creating
|
||||
a new instance each time.
|
||||
|
||||
Note that for `Boolean`, the named constants `Boolean.TRUE` and `Boolean.FALSE`
|
||||
are preferred instead of `Boolean.valueOf`.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<example>
|
||||
<![CDATA[
|
||||
public class Foo {
|
||||
private Integer ZERO = new Integer(0); // violation
|
||||
private Integer ZERO1 = Integer.valueOf(0); // better
|
||||
private Integer ZERO1 = 0; // even better
|
||||
}
|
||||
]]>
|
||||
</example>
|
||||
</rule>
|
||||
|
||||
|
||||
<rule name="ReplaceEnumerationWithIterator"
|
||||
language="java"
|
||||
since="3.4"
|
||||
@@ -1287,6 +1316,49 @@ public class Foo {
|
||||
</example>
|
||||
</rule>
|
||||
|
||||
<rule name="SimplifiableTestAssertion"
|
||||
language="java"
|
||||
since="6.37.0"
|
||||
message="Assertion may be simplified using {0}"
|
||||
class="net.sourceforge.pmd.lang.java.rule.bestpractices.SimplifiableTestAssertionRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#simplifiabletestassertion">
|
||||
<description>
|
||||
Reports test assertions that may be simplified using a more specific
|
||||
assertion method. This enables better error messages, and makes the
|
||||
assertions more readable.
|
||||
|
||||
The rule only applies within test classes for the moment. It replaces
|
||||
the deprecated rules {% rule UseAssertEqualsInsteadOfAssertTrue %},
|
||||
{% rule UseAssertNullInsteadOfAssertTrue %}, {% rule UseAssertSameInsteadOfAssertTrue %},
|
||||
{% rule UseAssertTrueInsteadOfAssertEquals %}, and {% rule java/design/SimplifyBooleanAssertion %}.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<example>
|
||||
<![CDATA[
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
class SomeTestClass {
|
||||
Object a,b;
|
||||
@Test
|
||||
void testMethod() {
|
||||
assertTrue(a.equals(b)); // could be assertEquals(a, b);
|
||||
assertTrue(!a.equals(b)); // could be assertNotEquals(a, b);
|
||||
|
||||
assertTrue(!something); // could be assertFalse(something);
|
||||
assertFalse(!something); // could be assertTrue(something);
|
||||
|
||||
assertTrue(a == b); // could be assertSame(a, b);
|
||||
assertTrue(a != b); // could be assertNotSame(a, b);
|
||||
|
||||
assertTrue(a == null); // could be assertNull(a);
|
||||
assertTrue(a != null); // could be assertNotNull(a);
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</example>
|
||||
</rule>
|
||||
|
||||
<rule name="SwitchStmtsShouldHaveDefault"
|
||||
language="java"
|
||||
since="1.0"
|
||||
@@ -1580,9 +1652,12 @@ public class Something {
|
||||
since="3.1"
|
||||
message="Use assertEquals(x, y) instead of assertTrue(x.equals(y))"
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule"
|
||||
deprecated="true"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#useassertequalsinsteadofasserttrue">
|
||||
<description>
|
||||
This rule detects JUnit assertions in object equality. These assertions should be made by more specific methods, like assertEquals.
|
||||
|
||||
Deprecated since PMD 6.37.0, use {% rule SimplifiableTestAssertion %} instead.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
@@ -1615,10 +1690,13 @@ public class FooTest extends TestCase {
|
||||
since="3.5"
|
||||
message="Use assertNull(x) instead of assertTrue(x==null), or assertNotNull(x) vs assertFalse(x==null)"
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule"
|
||||
deprecated="true"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#useassertnullinsteadofasserttrue">
|
||||
<description>
|
||||
This rule detects JUnit assertions in object references equality. These assertions should be made by
|
||||
more specific methods, like assertNull, assertNotNull.
|
||||
|
||||
Deprecated since PMD 6.37.0, use {% rule SimplifiableTestAssertion %} instead.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
@@ -1655,10 +1733,13 @@ public class FooTest extends TestCase {
|
||||
since="3.1"
|
||||
message="Use assertSame(x, y) instead of assertTrue(x==y), or assertNotSame(x,y) vs assertFalse(x==y)"
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule"
|
||||
deprecated="true"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#useassertsameinsteadofasserttrue">
|
||||
<description>
|
||||
This rule detects JUnit assertions in object references equality. These assertions should be made
|
||||
by more specific methods, like assertSame, assertNotSame.
|
||||
|
||||
Deprecated since PMD 6.37.0, use {% rule SimplifiableTestAssertion %} instead.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
@@ -1693,9 +1774,12 @@ public class FooTest extends TestCase {
|
||||
since="5.0"
|
||||
message="Use assertTrue(x)/assertFalse(x) instead of assertEquals(true, x)/assertEquals(false, x) or assertEquals(Boolean.TRUE, x)/assertEquals(Boolean.FALSE, x)."
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule"
|
||||
deprecated="true"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#useasserttrueinsteadofassertequals">
|
||||
<description>
|
||||
When asserting a value is the same as a literal or Boxed boolean, use assertTrue/assertFalse, instead of assertEquals.
|
||||
|
||||
Deprecated since PMD 6.37.0, use {% rule SimplifiableTestAssertion %} instead.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
@@ -1816,7 +1900,7 @@ public class UseStandardCharsets {
|
||||
minimumLanguageVersion="1.7"
|
||||
since="6.12.0"
|
||||
message="Consider using a try-with-resources statement instead of explicitly closing the resource"
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule"
|
||||
class="net.sourceforge.pmd.lang.java.rule.bestpractices.UseTryWithResourcesRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#usetrywithresources">
|
||||
<description>
|
||||
Java 7 introduced the try-with-resources statement. This statement ensures that each resource is closed at the end
|
||||
|
||||
@@ -1169,6 +1169,7 @@ public class Foo {
|
||||
since="3.6"
|
||||
message="assertTrue(!expr) can be replaced by assertFalse(expr)"
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule"
|
||||
deprecated="true"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#simplifybooleanassertion">
|
||||
<description>
|
||||
Avoid negation in an assertTrue or assertFalse test.
|
||||
@@ -1181,6 +1182,7 @@ as:
|
||||
|
||||
assertFalse(expr);
|
||||
|
||||
Deprecated since PMD 6.37.0, use {% rule java/bestpractices/SimplifiableTestAssertion %} instead.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
|
||||
@@ -341,10 +341,13 @@ BigDecimal bd3 = new BigDecimal(10); // reference BigDecimal.TEN instead
|
||||
since="1.2"
|
||||
message="Avoid instantiating Boolean objects; reference Boolean.TRUE or Boolean.FALSE or call Boolean.valueOf() instead."
|
||||
class="net.sourceforge.pmd.lang.java.rule.performance.BooleanInstantiationRule"
|
||||
deprecated="true"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#booleaninstantiation">
|
||||
<description>
|
||||
Avoid instantiating Boolean objects; you can reference Boolean.TRUE, Boolean.FALSE, or call Boolean.valueOf() instead.
|
||||
Note that new Boolean() is deprecated since JDK 9 for that reason.
|
||||
|
||||
Deprecated since PMD 6.37.0, use {% rule java/bestpractices/PrimitiveWrapperInstantiation %} instead.
|
||||
</description>
|
||||
<priority>2</priority>
|
||||
<example>
|
||||
@@ -360,11 +363,14 @@ Boolean buz = Boolean.valueOf(false); // ...., just reference Boolean.FALSE;
|
||||
since="4.0"
|
||||
message="Avoid instantiating Byte objects. Call Byte.valueOf() instead"
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule"
|
||||
deprecated="true"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#byteinstantiation">
|
||||
<description>
|
||||
Calling new Byte() causes memory allocation that can be avoided by the static Byte.valueOf().
|
||||
It makes use of an internal cache that recycles earlier instances making it more memory efficient.
|
||||
Note that new Byte() is deprecated since JDK 9 for that reason.
|
||||
|
||||
Deprecated since PMD 6.37.0, use {% rule java/bestpractices/PrimitiveWrapperInstantiation %} instead.
|
||||
</description>
|
||||
<priority>2</priority>
|
||||
<properties>
|
||||
@@ -534,11 +540,14 @@ good.append("This is a long string, which is pre-sized");
|
||||
since="3.5"
|
||||
message="Avoid instantiating Integer objects. Call Integer.valueOf() instead."
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule"
|
||||
deprecated="true"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#integerinstantiation">
|
||||
<description>
|
||||
Calling new Integer() causes memory allocation that can be avoided by the static Integer.valueOf().
|
||||
It makes use of an internal cache that recycles earlier instances making it more memory efficient.
|
||||
Note that new Integer() is deprecated since JDK 9 for that reason.
|
||||
|
||||
Deprecated since PMD 6.37.0, use {% rule java/bestpractices/PrimitiveWrapperInstantiation %} instead.
|
||||
</description>
|
||||
<priority>2</priority>
|
||||
<properties>
|
||||
@@ -564,11 +573,14 @@ public class Foo {
|
||||
since="4.0"
|
||||
message="Avoid instantiating Long objects.Call Long.valueOf() instead"
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule"
|
||||
deprecated="true"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#longinstantiation">
|
||||
<description>
|
||||
Calling new Long() causes memory allocation that can be avoided by the static Long.valueOf().
|
||||
It makes use of an internal cache that recycles earlier instances making it more memory efficient.
|
||||
Note that new Long() is deprecated since JDK 9 for that reason.
|
||||
|
||||
Deprecated since PMD 6.37.0, use {% rule java/bestpractices/PrimitiveWrapperInstantiation %} instead.
|
||||
</description>
|
||||
<priority>2</priority>
|
||||
<properties>
|
||||
@@ -717,11 +729,14 @@ public class Foo {
|
||||
since="4.0"
|
||||
message="Avoid instantiating Short objects. Call Short.valueOf() instead"
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule"
|
||||
deprecated="true"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#shortinstantiation">
|
||||
<description>
|
||||
Calling new Short() causes memory allocation that can be avoided by the static Short.valueOf().
|
||||
It makes use of an internal cache that recycles earlier instances making it more memory efficient.
|
||||
Note that new Short() is deprecated since JDK 9 for that reason.
|
||||
|
||||
Deprecated since PMD 6.37.0, use {% rule java/bestpractices/PrimitiveWrapperInstantiation %} instead.
|
||||
</description>
|
||||
<priority>2</priority>
|
||||
<properties>
|
||||
@@ -831,11 +846,14 @@ public class Foo {
|
||||
since="3.8"
|
||||
message="Unnecessary wrapper object creation"
|
||||
class="net.sourceforge.pmd.lang.java.rule.performance.UnnecessaryWrapperObjectCreationRule"
|
||||
deprecated="true"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#unnecessarywrapperobjectcreation">
|
||||
<description>
|
||||
Most wrapper classes provide static conversion methods that avoid the need to create intermediate objects
|
||||
just to create the primitive forms. Using these avoids the cost of creating objects that also need to be
|
||||
garbage-collected later.
|
||||
|
||||
Deprecated since PMD 6.37.0. The planned replacement is not expected before PMD 7.0.0.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<example>
|
||||
|
||||
@@ -37,10 +37,12 @@
|
||||
<!-- <rule ref="category/java/bestpractices.xml/MethodReturnsInternalArray" /> -->
|
||||
<rule ref="category/java/bestpractices.xml/MissingOverride"/>
|
||||
<rule ref="category/java/bestpractices.xml/OneDeclarationPerLine"/>
|
||||
<rule ref="category/java/bestpractices.xml/PrimitiveWrapperInstantiation"/>
|
||||
<rule ref="category/java/bestpractices.xml/PreserveStackTrace"/>
|
||||
<!-- <rule ref="category/java/bestpractices.xml/ReplaceEnumerationWithIterator" /> -->
|
||||
<!-- <rule ref="category/java/bestpractices.xml/ReplaceHashtableWithMap" /> -->
|
||||
<!-- <rule ref="category/java/bestpractices.xml/ReplaceVectorWithList" /> -->
|
||||
<rule ref="category/java/bestpractices.xml/SimplifiableTestAssertion"/>
|
||||
<rule ref="category/java/bestpractices.xml/SwitchStmtsShouldHaveDefault"/>
|
||||
<!-- <rule ref="category/java/bestpractices.xml/SystemPrintln" /> -->
|
||||
<!-- <rule ref="category/java/bestpractices.xml/UnusedAssignment"/> -->
|
||||
@@ -48,10 +50,6 @@
|
||||
<rule ref="category/java/bestpractices.xml/UnusedLocalVariable"/>
|
||||
<rule ref="category/java/bestpractices.xml/UnusedPrivateField"/>
|
||||
<rule ref="category/java/bestpractices.xml/UnusedPrivateMethod"/>
|
||||
<rule ref="category/java/bestpractices.xml/UseAssertEqualsInsteadOfAssertTrue"/>
|
||||
<rule ref="category/java/bestpractices.xml/UseAssertNullInsteadOfAssertTrue"/>
|
||||
<rule ref="category/java/bestpractices.xml/UseAssertSameInsteadOfAssertTrue"/>
|
||||
<rule ref="category/java/bestpractices.xml/UseAssertTrueInsteadOfAssertEquals"/>
|
||||
<rule ref="category/java/bestpractices.xml/UseCollectionIsEmpty"/>
|
||||
<rule ref="category/java/bestpractices.xml/UseStandardCharsets" />
|
||||
<!-- <rule ref="category/java/bestpractices.xml/UseTryWithResources" /> -->
|
||||
@@ -154,7 +152,6 @@
|
||||
<!-- <rule ref="category/java/design.xml/NPathComplexity" /> -->
|
||||
<!-- <rule ref="category/java/design.xml/SignatureDeclareThrowsException" /> -->
|
||||
<rule ref="category/java/design.xml/SimplifiedTernary"/>
|
||||
<!-- <rule ref="category/java/design.xml/SimplifyBooleanAssertion" /> -->
|
||||
<!-- <rule ref="category/java/design.xml/SimplifyBooleanExpressions" /> -->
|
||||
<rule ref="category/java/design.xml/SimplifyBooleanReturns"/>
|
||||
<rule ref="category/java/design.xml/SimplifyConditional"/>
|
||||
@@ -300,23 +297,17 @@
|
||||
<!-- <rule ref="category/java/performance.xml/AvoidInstantiatingObjectsInLoops" /> -->
|
||||
<!-- <rule ref="category/java/performance.xml/AvoidUsingShortType"/> -->
|
||||
<rule ref="category/java/performance.xml/BigIntegerInstantiation"/>
|
||||
<rule ref="category/java/performance.xml/BooleanInstantiation"/>
|
||||
<!-- <rule ref="category/java/performance.xml/ByteInstantiation" /> -->
|
||||
<!-- <rule ref="category/java/performance.xml/ConsecutiveAppendsShouldReuse" /> -->
|
||||
<!-- <rule ref="category/java/performance.xml/ConsecutiveLiteralAppends" /> -->
|
||||
<!-- <rule ref="category/java/performance.xml/InefficientEmptyStringCheck" /> -->
|
||||
<!-- <rule ref="category/java/performance.xml/InefficientStringBuffering" /> -->
|
||||
<!-- <rule ref="category/java/performance.xml/InsufficientStringBufferDeclaration" /> -->
|
||||
<!-- <rule ref="category/java/performance.xml/IntegerInstantiation" /> -->
|
||||
<!-- <rule ref="category/java/performance.xml/LongInstantiation" /> -->
|
||||
<rule ref="category/java/performance.xml/OptimizableToArrayCall"/>
|
||||
<!--<rule ref="category/java/performance.xml/RedundantFieldInitializer"/>-->
|
||||
<!-- <rule ref="category/java/performance.xml/SimplifyStartsWith" /> -->
|
||||
<!-- <rule ref="category/java/performance.xml/ShortInstantiation" /> -->
|
||||
<!-- <rule ref="category/java/performance.xml/StringInstantiation" /> -->
|
||||
<!-- <rule ref="category/java/performance.xml/StringToString" /> -->
|
||||
<!--<rule ref="category/java/performance.xml/TooFewBranchesForASwitchStatement"/>-->
|
||||
<!-- <rule ref="category/java/performance.xml/UnnecessaryWrapperObjectCreation" /> -->
|
||||
<!-- <rule ref="category/java/performance.xml/UseArrayListInsteadOfVector" /> -->
|
||||
<!-- <rule ref="category/java/performance.xml/UseArraysAsList" /> -->
|
||||
<!-- <rule ref="category/java/performance.xml/UseIndexOfChar" /> -->
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.java;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import net.sourceforge.pmd.lang.Language;
|
||||
import net.sourceforge.pmd.lang.LanguageRegistry;
|
||||
import net.sourceforge.pmd.lang.LanguageVersion;
|
||||
|
||||
public class JavaLanguageModuleTest {
|
||||
private Language javaLanguage = LanguageRegistry.getLanguage(JavaLanguageModule.NAME);
|
||||
|
||||
@Test
|
||||
public void java9IsSmallerThanJava10() {
|
||||
LanguageVersion java9 = javaLanguage.getVersion("9");
|
||||
LanguageVersion java10 = javaLanguage.getVersion("10");
|
||||
|
||||
Assert.assertTrue("java9 should be smaller than java10", java9.compareTo(java10) < 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void previewVersionShouldBeGreaterThanNonPreview() {
|
||||
LanguageVersion java16 = javaLanguage.getVersion("16");
|
||||
LanguageVersion java16p = javaLanguage.getVersion("16-preview");
|
||||
|
||||
Assert.assertTrue("java16-preview should be greater than java16", java16p.compareTo(java16) > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompareToVersion() {
|
||||
LanguageVersion java9 = javaLanguage.getVersion("9");
|
||||
Assert.assertTrue("java9 should be smaller than java10", java9.compareToVersion("10") < 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allVersions() {
|
||||
List<LanguageVersion> versions = javaLanguage.getVersions();
|
||||
for (int i = 1; i < versions.size(); i++) {
|
||||
LanguageVersion previous = versions.get(i - 1);
|
||||
LanguageVersion current = versions.get(i);
|
||||
Assert.assertTrue("Version " + previous + " should be smaller than " + current,
|
||||
previous.compareTo(current) < 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.java.rule.bestpractices;
|
||||
|
||||
import net.sourceforge.pmd.testframework.PmdRuleTst;
|
||||
|
||||
public class PrimitiveWrapperInstantiationTest extends PmdRuleTst {
|
||||
// no additional unit tests
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.java.rule.bestpractices;
|
||||
|
||||
import net.sourceforge.pmd.testframework.PmdRuleTst;
|
||||
|
||||
public class SimplifiableTestAssertionTest extends PmdRuleTst {
|
||||
// no additional unit tests
|
||||
}
|
||||
+385
File diff suppressed because it is too large.
Load diff
+662
File diff suppressed because it is too large.
Load diff
+115
@@ -219,6 +219,7 @@ public class TryWithResources {
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>[java] UseTryWithResources - false negative for explicit close #2882</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
@@ -276,4 +277,118 @@ public class TryWithResources {
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<code-fragment id="issue-3235"><![CDATA[
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
|
||||
class Scratch {
|
||||
public static int count(AutoCloseable iterator) {
|
||||
int count = 0;
|
||||
try {
|
||||
count++;
|
||||
} finally {
|
||||
iterator.close();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
class Holder implements AutoCloseable {
|
||||
private Reader reader;
|
||||
public void close() throws IOException {
|
||||
try {
|
||||
someOtherActivity();
|
||||
} finally {
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
private void someOtherActivity() throws IOException {
|
||||
// do stuff
|
||||
}
|
||||
}
|
||||
]]></code-fragment>
|
||||
|
||||
<test-code>
|
||||
<description>[java] UseTryWithResources false positive when closeable is provided as a method argument or class field #3235 before java 9</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code-ref id="issue-3235"/>
|
||||
<source-type>java 1.8</source-type>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>[java] UseTryWithResources false positive when closeable is provided as a method argument or class field #3235</description>
|
||||
<expected-problems>2</expected-problems>
|
||||
<expected-linenumbers>7,19</expected-linenumbers>
|
||||
<code-ref id="issue-3235"/>
|
||||
</test-code>
|
||||
|
||||
<code-fragment id="issue-3235-with-local-var"><![CDATA[
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
|
||||
class Scratch {
|
||||
public static int count() {
|
||||
AutoCloseable iterator;
|
||||
int count = 0;
|
||||
try {
|
||||
count++;
|
||||
} finally {
|
||||
iterator.close();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
class Holder implements AutoCloseable {
|
||||
public void close() throws IOException {
|
||||
Reader reader;
|
||||
try {
|
||||
someOtherActivity();
|
||||
} finally {
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
private void someOtherActivity() throws IOException {
|
||||
// do stuff
|
||||
}
|
||||
}
|
||||
]]></code-fragment>
|
||||
|
||||
<test-code>
|
||||
<description>[java] UseTryWithResources with local var and before java 9 #3235</description>
|
||||
<expected-problems>2</expected-problems>
|
||||
<expected-linenumbers>8,20</expected-linenumbers>
|
||||
<code-ref id="issue-3235-with-local-var"/>
|
||||
<source-type>java 1.8</source-type>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>[java] UseTryWithResources with local var and latest java #3235</description>
|
||||
<expected-problems>2</expected-problems>
|
||||
<expected-linenumbers>8,20</expected-linenumbers>
|
||||
<code-ref id="issue-3235-with-local-var"/>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>NPE when determining closeTarget</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>6</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class UseTryWithResources {
|
||||
public void read(InputStream is, boolean close) throws IOException {
|
||||
try {
|
||||
is.read();
|
||||
} finally {
|
||||
if (close) {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
</test-data>
|
||||
Reference in new issue
Block a user