Merge branch 'master' into 7.0.x
This commit is contained in:
@@ -53,10 +53,25 @@ The command line version of PMD continues to use **scala 2.13**.
|
||||
* The new Java Rule {% rule "java/codestyle/UnnecessaryCast" %} (`java-codestyle`)
|
||||
finds casts that are unnecessary while accessing collection elements.
|
||||
|
||||
|
||||
#### Modified rules
|
||||
|
||||
* The Java rule {% rule "java/codestyle/UseDiamondOperator" %} (`java-codestyle`) now by default
|
||||
finds unnecessary usages of type parameters, which are nested, involve wildcards and are used
|
||||
within a ternary operator. These usages are usually only unnecessary with Java8 and later, when
|
||||
the type inference in Java has been improved.
|
||||
|
||||
In order to avoid false positives when checking Java7 only code, the rule has the new property
|
||||
`java7Compatibility`, which is disabled by default. Settings this to "true" retains
|
||||
the old rule behaviour.
|
||||
|
||||
|
||||
### Fixed Issues
|
||||
|
||||
* c#
|
||||
* [#2551](https://github.com/pmd/pmd/issues/2551): \[c#] CPD suppression with comments doesn't work
|
||||
* java-codestyle
|
||||
* [#2545](https://github.com/pmd/pmd/issues/2545): \[java] UseDiamondOperator false negatives
|
||||
* java-design
|
||||
* [#2563](https://github.com/pmd/pmd/pull/2563): \[java] UselessOverridingMethod false negative with already public methods
|
||||
* scala
|
||||
|
@@ -1673,6 +1673,11 @@ Use the diamond operator to let the type be inferred automatically. With the Dia
|
||||
to avoid duplication of the type parameters.
|
||||
Instead, the compiler is now able to infer the parameter types for constructor calls,
|
||||
which makes the code also more readable.
|
||||
|
||||
The diamond operator has been introduced with java 7. However, type inference has been improved further
|
||||
with java8, rendering more type parameters unnecessary. This is only possible with java8 and the resulting
|
||||
code won't compile with java7. If you use java7, make sure to enable `java7Compatibility` for this rule to avoid
|
||||
false positives.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
@@ -1685,15 +1690,17 @@ which makes the code also more readable.
|
||||
|
|
||||
//StatementExpression[AssignmentOperator and PrimaryExpression/PrimaryPrefix[not(Expression)]]
|
||||
)
|
||||
/Expression/PrimaryExpression[not(PrimarySuffix) and not(ancestor::ArgumentList)]
|
||||
/(Expression | Expression[$java7Compatibility = false()]/ConditionalExpression | Expression[$java7Compatibility = false()]/ConditionalExpression/Expression)
|
||||
/PrimaryExpression[not(PrimarySuffix) and not(ancestor::ArgumentList)]
|
||||
/PrimaryPrefix
|
||||
/AllocationExpression
|
||||
[@AnonymousClass=false()]
|
||||
[ClassOrInterfaceType/TypeArguments[@Diamond=false() and not(TypeArgument//TypeArguments)]]
|
||||
[ClassOrInterfaceType/TypeArguments[@Diamond=false() and not($java7Compatibility = true() and .//TypeArgument[@Wildcard=true()])]]
|
||||
[not(ArrayDimsAndInits)]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
<property name="java7Compatibility" type="Boolean" description="If disabled, the rule shows also violations that are applicable for java8+" value="false" />
|
||||
</properties>
|
||||
<example>
|
||||
<![CDATA[
|
||||
|
@@ -6,8 +6,8 @@
|
||||
|
||||
<test-code>
|
||||
<description>Use Diamond</description>
|
||||
<expected-problems>2</expected-problems>
|
||||
<expected-linenumbers>6,11</expected-linenumbers>
|
||||
<expected-problems>3</expected-problems>
|
||||
<expected-linenumbers>6,9,10</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -17,7 +17,6 @@ public class Foo {
|
||||
List<String> strings = new ArrayList<String>();
|
||||
List<String> strings2 = new ArrayList<>();
|
||||
List<List<String>> strings3 = new ArrayList<>();
|
||||
// this is a known false negative, see at the bottom
|
||||
List<List<String>> strings4 = new ArrayList<List<List<String>>>();
|
||||
this.field = new ArrayList<String>();
|
||||
}
|
||||
@@ -139,35 +138,43 @@ class Foo {
|
||||
</test-code>
|
||||
|
||||
<!-- These tests depend on the Java version used -->
|
||||
<!-- For now we keep the old behaviour of ignoring type
|
||||
arguments that have type arguments themselves, ie we have
|
||||
false negatives. We can improve that with better type resolution
|
||||
<!-- For now we keep the old behaviour of Java 7 and ignoring type
|
||||
arguments which have wildcards involved, ie we have
|
||||
false negatives for Java8+. We can improve that with better type resolution
|
||||
in PMD 7. -->
|
||||
|
||||
<test-code regressionTest="false">
|
||||
<description>(J7) Version sensitive tests</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>6</expected-linenumbers>
|
||||
<test-code>
|
||||
<description>(J7) Version sensitive tests - avoid possible false positives on Java7</description>
|
||||
<rule-property name="java7Compatibility">true</rule-property>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public class Foo {
|
||||
private WeakReference<Class<?>> typeReference;
|
||||
public void foo() {
|
||||
// this should be positive in Java 8, negative in Java 7
|
||||
// in java 7: no violation, in java 8 violation
|
||||
typeReference = new WeakReference<Class<?>>(String.class);
|
||||
// this is because in java 7, new WeakReference<>(String.class) types as WeakReference<Class<String>>
|
||||
// which is incompatible with WeakReference<Class<?>>, whereas Java 8's type inference is better.
|
||||
typeReference = new WeakReference<Class<?>>(String.class);
|
||||
|
||||
// the following is the same:
|
||||
// in java 7: no violation, in java 8 violation
|
||||
Class<?> type = null;
|
||||
typeReference = new WeakReference<Class<?>>(type); // this should be positive on all versions
|
||||
typeReference = new WeakReference<Class<?>>(type);
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code regressionTest="false">
|
||||
<description>(J8) Version sensitive tests</description>
|
||||
<test-code>
|
||||
<description>(J8) Version sensitive tests - known false negatives on Java8+</description>
|
||||
<expected-problems>2</expected-problems>
|
||||
<expected-linenumbers>4,6</expected-linenumbers>
|
||||
<expected-linenumbers>6,8</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public class Foo {
|
||||
private WeakReference<Class<?>> typeReference;
|
||||
public void foo() {
|
||||
@@ -175,6 +182,51 @@ public class Foo {
|
||||
Class<?> type = null;
|
||||
typeReference = new WeakReference<Class<?>>(type); // pos
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>False negative for nested type parameters (#2545)</description>
|
||||
<rule-property name="java7Compatibility">true</rule-property>
|
||||
<expected-problems>3</expected-problems>
|
||||
<expected-linenumbers>7,8,17</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public class UseDiamondOperatorFalseNegative {
|
||||
List<Map<String,Object>> l = new ArrayList<Map<String,Object>>(); // FN
|
||||
WeakReference<Class<String>> typeReference = new WeakReference<Class<String>>(String.class); // FN
|
||||
WeakReference<Class<?>> typeReference2 = new WeakReference<Class<?>>(String.class); // FP
|
||||
|
||||
public void test() {
|
||||
final List<String> l2;
|
||||
l2 = true ? new ArrayList<String>() : new ArrayList<String>(); // FN twice for java8+, but for java7, this is ok!
|
||||
}
|
||||
|
||||
static {
|
||||
l = new ArrayList<Map<String,Object>>(); // FN
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>(J8+) False negative for Java8+ and ternary operator (#2545)</description>
|
||||
<expected-problems>2</expected-problems>
|
||||
<expected-linenumbers>7,7</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class UseDiamondOperatorFalseNegative {
|
||||
public void test() {
|
||||
final List<String> l2;
|
||||
l2 = true ? new ArrayList<String>() : new ArrayList<String>(); // FN twice for java8+, but for java7, this is ok!
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
Reference in New Issue
Block a user