Merge branch 'master' into pmd/7.0.x

This commit is contained in:
Andreas Dangel
2022-01-20 15:45:14 +01:00
11 changed files with 222 additions and 90 deletions

View File

@ -6529,6 +6529,15 @@
"contributions": [
"code"
]
},
{
"login": "gredler",
"name": "Daniel Gredler",
"avatar_url": "https://avatars.githubusercontent.com/u/178883?v=4",
"profile": "https://github.com/gredler",
"contributions": [
"code"
]
}
],
"contributorsPerLine": 7,

File diff suppressed because it is too large Load Diff

View File

@ -57,8 +57,11 @@ not support all features of the latest EcmaScript standard.
* [#3644](https://github.com/pmd/pmd/issues/3644): \[java] InvalidLogMessageFormat: false positives with logstash structured logging
* [#3686](https://github.com/pmd/pmd/issues/3686): \[java] ReturnEmptyCollectionRatherThanNull - false negative with conditioned returns
* [#3701](https://github.com/pmd/pmd/issues/3701): \[java] MissingStaticMethodInNonInstantiatableClass false positive with method inner classes
* [#3721](https://github.com/pmd/pmd/issues/3721): \[java] ReturnEmptyCollectionRatherThanNull - false positive with stream and lambda
* java-performance
* [#3492](https://github.com/pmd/pmd/issues/3492): \[java] UselessStringValueOf: False positive when there is no initial String to append to
* [#3639](https://github.com/pmd/pmd/issues/3639): \[java] UseStringBufferLength: false negative with empty string variable
* [#3712](https://github.com/pmd/pmd/issues/3712): \[java] InsufficientStringBufferDeclaration false positive with StringBuilder.setLength(0)
* javascript
* [#3703](https://github.com/pmd/pmd/issues/3703): \[javascript] Error - no Node adapter class registered for XmlPropRef
@ -74,9 +77,11 @@ not support all features of the latest EcmaScript standard.
* [#3713](https://github.com/pmd/pmd/pull/3713): \[java] Enhance UnnecessaryModifier to support records - [Vincent Galloy](https://github.com/vgalloy)
* [#3719](https://github.com/pmd/pmd/pull/3719): \[java] Upgrade log4j to 2.17.1 - [Daniel Paul Searles](https://github.com/squaresurf)
* [#3720](https://github.com/pmd/pmd/pull/3720): \[java] New rule: FinalParameterInAbstractMethod - [Vincent Galloy](https://github.com/vgalloy)
* [#3724](https://github.com/pmd/pmd/pull/3724): \[java] Fix for #3686 - fix FinalFieldCouldBeStatic - [Oleksii Dykov](https://github.com/dykov)
* [#3724](https://github.com/pmd/pmd/pull/3724): \[java] Fix for #3679 - fix FinalFieldCouldBeStatic - [Oleksii Dykov](https://github.com/dykov)
* [#3727](https://github.com/pmd/pmd/pull/3727): \[java] #3724 - fix FinalFieldCouldBeStatic: triggers only if the referenced name is static - [Oleksii Dykov](https://github.com/dykov)
* [#3742](https://github.com/pmd/pmd/pull/3742): \[java] Fix #3701 - fix MissingStaticMethodInNonInstantiatableClass for method local classes - [Oleksii Dykov](https://github.com/dykov)
* [#3744](https://github.com/pmd/pmd/pull/3744): \[core] Updated SaxonXPathRuleQueryTest.java - [Vyom Yadav](https://github.com/Vyom-Yadav)
* [#3745](https://github.com/pmd/pmd/pull/3745): \[java] Fix #3712: InsufficientStringBufferDeclaration setLength false positive - [Daniel Gredler](https://github.com/gredler)
{% endtocmaker %}

View File

@ -221,7 +221,6 @@ public class DeadLinksChecker {
}
@SuppressWarnings("PMD.ReturnEmptyCollectionRatherThanNull")
private Map<Path, List<String>> joinFutures(Map<Path, List<Future<String>>> map) {
Map<Path, List<String>> joined = new HashMap<>();

View File

@ -141,7 +141,7 @@ public class InsufficientStringBufferDeclarationRule extends AbstractJavaRulecha
} else if (usage.getParent() instanceof ASTAssignmentExpression) {
ASTAssignmentExpression assignment = (ASTAssignmentExpression) usage.getParent();
State newState = getConstructorCapacity(node, assignment.getRightOperand());
if (newState.rootNode != null) {
if (state.isInsufficient()) {
addViolation(data, state.rootNode, state.getParamsForViolation());

View File

@ -783,7 +783,8 @@ in each object at runtime.
[pmd-java:modifiers() = 'final']
[not(pmd-java:modifiers() = 'static')]
[not(.//Annotation[pmd-java:typeIs('lombok.Builder.Default')])]
/VariableDeclarator[NumericLiteral or StringLiteral or CharLiteral or BooleanLiteral or NullLiteral or VariableAccess or FieldAccess]
/VariableDeclarator[NumericLiteral or StringLiteral or CharLiteral or BooleanLiteral or NullLiteral
or VariableAccess or FieldAccess]
/VariableDeclaratorId
]]>
</value>

View File

@ -2648,11 +2648,12 @@ See Effective Java, 3rd Edition, Item 54: Return empty collections or arrays ins
<property name="xpath">
<value>
<![CDATA[
//MethodDeclaration
//ReturnStatement/NullLiteral
[ancestor::MethodDeclaration[1]
[ArrayType
or ClassOrInterfaceType[pmd-java:typeIs('java.util.Collection')
or pmd-java:typeIs('java.util.Map')]]
//ReturnStatement/NullLiteral
]
[not(./ancestor::LambdaExpression)]
[not(./ancestor::AnonymousClassDeclaration)]
]]>

View File

@ -175,6 +175,24 @@ class Clazz {
<code><![CDATA[
class Clazz {
public final int a = getValue();
}
]]></code>
</test-code>
<test-code>
<description>
#3724 - the rule should be triggered only if the referenced name is static
</description>
<expected-problems>1</expected-problems>
<expected-linenumbers>7</expected-linenumbers>
<code><![CDATA[
public class Foo {
private int nonStaticPrivate = 1; //no violation cause non-final
private final int nonStatic = nonStaticPrivate; //no violation cause referenced name is non-static
//private static final int staticFinal = nonStatic; //noncompliant: Non-static field 'nonStatic' cannot be referenced from a static context
private static int staticNonFinal = 1; //no violation cause non-final
private final int nonStatic2 = staticNonFinal; //violation because it could be static
}
]]></code>
</test-code>

View File

@ -179,4 +179,55 @@ public class Foo {
}
]]></code>
</test-code>
<test-code>
<description>[java] ReturnEmptyCollectionRatherThanNull - false positive with stream and lambda #3721</description>
<expected-problems>1</expected-problems>
<expected-linenumbers>37</expected-linenumbers>
<code><![CDATA[
import java.util.*;
import java.util.concurrent.Callable;
public class Foo {
private Map<Path, List<String>> joinFutures(Map<String, List<Future<String>>> map) {
Map<String, List<String>> joined = new HashMap<>();
for (String p : map.keySet()) {
List<String> evaluatedResult = map.get(p).stream()
.map(f -> {
try {
return f.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
return null; // <----- false positive here
}
})
.filter(Objects::nonNull)
.sorted(Comparator.naturalOrder())
.collect(Collectors.toList());
if (!evaluatedResult.isEmpty()) {
joined.put(p, evaluatedResult);
}
}
// checking basic lambdas and anonymous classes as well
Callable<Object> c = a -> { return null; }; // <----- false positive here
Callable<Object> c2 = new Callable<Object>() {
public Object call() {
return null; // <----- false positive here
}
};
Callable<List<String>> c3 = new Callable<List<String>>() {
public List<String> call() {
return null;
}
};
return joined;
}
}
]]></code>
</test-code>
</test-data>

View File

@ -1220,13 +1220,14 @@ public class FalsePositive {
<test-code>
<description>Calculated initial size in constructor</description>
<expected-problems>4</expected-problems>
<expected-linenumbers>10,34,44,61</expected-linenumbers>
<expected-problems>5</expected-problems>
<expected-linenumbers>10,34,44,61,88</expected-linenumbers>
<expected-messages>
<message>StringBuilder has been initialized with size 4, but has at least 5 characters appended.</message>
<message>StringBuilder has been initialized with size 5, but has at least 6 characters appended.</message>
<message>StringBuilder has been initialized with size 8, but has at least 10 characters appended.</message>
<message>StringBuilder has been initialized with size 8, but has at least 9 characters appended.</message>
<message>StringBuilder has been initialized with size 7, but has at least 8 characters appended.</message>
</expected-messages>
<code><![CDATA[
public class InsufficientStringBufferDeclaration {
@ -1296,6 +1297,30 @@ public class InsufficientStringBufferDeclaration {
sb.append('d'); // length is now 9
return sb.toString();
}
public String case9_sufficient_setLength() {
StringBuilder sb = new StringBuilder(4);
sb.append("xxxx");
sb.setLength(0); // length is 0, capacity is still 4
sb.append("aaaa");
return sb.toString();
}
public String case10_unknown_setLength(String in) {
StringBuilder sb = new StringBuilder(in.length()); // unknown
sb.append("xxxx");
sb.setLength(0); // length is 0, capacity is still unknown
sb.append("aaaa");
return sb.toString();
}
public String case11_unknown_ensureCapacity(String in) {
StringBuilder sb = new StringBuilder(in.length()); // unknown
sb.append("xxxx"); // length is 4
sb.ensureCapacity(7); // line 88 - length is still 4, new capacity now at least 7 -> violation here
sb.append("aaaa"); // length is 8
return sb.toString();
}
}
]]></code>
</test-code>

View File

@ -189,6 +189,28 @@ public class Ineffecient
{
return "Ineffecient";
}
}
]]></code>
</test-code>
<test-code>
<description>[java] UseStringBufferLength: false negative with empty string variable #3639</description>
<expected-problems>1</expected-problems>
<expected-linenumbers>5</expected-linenumbers>
<code><![CDATA[
public class Foo {
public void foo() {
StringBuffer sb = new StringBuffer("any_string");
final String nullStr = "";
if (sb.toString().equals(nullStr)) { // PMD should report a warning here
System.out.println("Buffer is empty");
}
// the preferred way
if (sb.length() == 0) {
System.out.println("Buffer is empty");
}
}
}
]]></code>
</test-code>