Merge branch 'pr-2392'
[java] Fix UseDiamondOperator false positive inside lambda #2392
This commit is contained in:
@ -41,6 +41,8 @@ Note that XPath 1.0 support, the default XPath version, is deprecated since PMD
|
|||||||
* [#2399](https://github.com/pmd/pmd/issues/2399): \[apex] ApexCRUDViolation: false positive with security enforced with line break
|
* [#2399](https://github.com/pmd/pmd/issues/2399): \[apex] ApexCRUDViolation: false positive with security enforced with line break
|
||||||
* java
|
* java
|
||||||
* [#2378](https://github.com/pmd/pmd/issues/2378): \[java] AbstractJUnitRule has bad performance on large code bases
|
* [#2378](https://github.com/pmd/pmd/issues/2378): \[java] AbstractJUnitRule has bad performance on large code bases
|
||||||
|
* java-codestyle
|
||||||
|
* [#1723](https://github.com/pmd/pmd/issues/1723): \[java] UseDiamondOperator false-positive inside lambda
|
||||||
* java-design
|
* java-design
|
||||||
* [#2390](https://github.com/pmd/pmd/issues/2390): \[java] AbstractClassWithoutAnyMethod: missing violation for nested classes
|
* [#2390](https://github.com/pmd/pmd/issues/2390): \[java] AbstractClassWithoutAnyMethod: missing violation for nested classes
|
||||||
|
|
||||||
|
@ -1967,18 +1967,21 @@ which makes the code also more readable.
|
|||||||
</description>
|
</description>
|
||||||
<priority>3</priority>
|
<priority>3</priority>
|
||||||
<properties>
|
<properties>
|
||||||
|
<property name="version" value="2.0" />
|
||||||
<property name="xpath">
|
<property name="xpath">
|
||||||
<value>
|
<value>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
//VariableInitializer[preceding-sibling::VariableDeclaratorId[1]/@TypeInferred="false"]
|
(
|
||||||
//PrimaryExpression[not(PrimarySuffix)]
|
//VariableInitializer[preceding-sibling::VariableDeclaratorId[1]/@TypeInferred=false()]
|
||||||
[not(ancestor::ArgumentList)]
|
|
||||||
/PrimaryPrefix/AllocationExpression[ClassOrInterfaceType[@AnonymousClass='false']/TypeArguments//ReferenceType[not(.//TypeArguments)]]
|
|
||||||
|
|
|
|
||||||
//StatementExpression[AssignmentOperator][PrimaryExpression/PrimaryPrefix[not(Expression)]]
|
//StatementExpression[AssignmentOperator and PrimaryExpression/PrimaryPrefix[not(Expression)]]
|
||||||
//PrimaryExpression[not(PrimarySuffix)]
|
)
|
||||||
[not(ancestor::ArgumentList)]
|
/Expression/PrimaryExpression[not(PrimarySuffix) and not(ancestor::ArgumentList)]
|
||||||
/PrimaryPrefix/AllocationExpression[ClassOrInterfaceType[@AnonymousClass='false']/TypeArguments//ReferenceType[not(.//TypeArguments)]]
|
/PrimaryPrefix
|
||||||
|
/AllocationExpression
|
||||||
|
[@AnonymousClass=false()]
|
||||||
|
[ClassOrInterfaceType/TypeArguments[@Diamond=false() and not(TypeArgument//TypeArguments)]]
|
||||||
|
[not(ArrayDimsAndInits)]
|
||||||
]]>
|
]]>
|
||||||
</value>
|
</value>
|
||||||
</property>
|
</property>
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<test-data
|
<test-data xmlns="http://pmd.sourceforge.net/rule-tests"
|
||||||
xmlns="http://pmd.sourceforge.net/rule-tests"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests http://pmd.sourceforge.net/rule-tests_1_0_0.xsd">
|
||||||
xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests http://pmd.sourceforge.net/rule-tests_1_0_0.xsd">
|
<test-code>
|
||||||
<test-code>
|
<description>Use Diamond</description>
|
||||||
<description>Use Diamond</description>
|
<expected-problems>2</expected-problems>
|
||||||
<expected-problems>2</expected-problems>
|
<expected-linenumbers>6,11</expected-linenumbers>
|
||||||
<expected-linenumbers>6,8</expected-linenumbers>
|
<code><![CDATA[
|
||||||
<code><![CDATA[
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
public class Foo {
|
public class Foo {
|
||||||
@ -15,17 +14,20 @@ public class Foo {
|
|||||||
public void foo() {
|
public void foo() {
|
||||||
List<String> strings = new ArrayList<String>();
|
List<String> strings = new ArrayList<String>();
|
||||||
List<String> strings2 = new ArrayList<>();
|
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>();
|
this.field = new ArrayList<String>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]]></code>
|
]]></code>
|
||||||
</test-code>
|
</test-code>
|
||||||
<test-code>
|
|
||||||
<description>False positive cases: anonymous classes, methods calls</description>
|
<test-code>
|
||||||
<expected-problems>0</expected-problems>
|
<description>False positive cases: anonymous classes, methods calls</description>
|
||||||
<code><![CDATA[
|
<expected-problems>0</expected-problems>
|
||||||
|
<code><![CDATA[
|
||||||
public class Foo {
|
public class Foo {
|
||||||
private WeakReference<Class<?>> typeReference;
|
|
||||||
public void foo() {
|
public void foo() {
|
||||||
Collections.sort(files, new Comparator<DataSource>() {
|
Collections.sort(files, new Comparator<DataSource>() {
|
||||||
@Override
|
@Override
|
||||||
@ -49,8 +51,6 @@ public class Foo {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
Iterator<Node> EMPTY_ITERATOR = new ArrayList<Node>().iterator();
|
Iterator<Node> EMPTY_ITERATOR = new ArrayList<Node>().iterator();
|
||||||
Class<?> type = null;
|
|
||||||
typeReference = new WeakReference<Class<?>>(type);
|
|
||||||
((ListNode<E>) rev).reverseCache = new SoftReference<ImmutableList<E>>(this);
|
((ListNode<E>) rev).reverseCache = new SoftReference<ImmutableList<E>>(this);
|
||||||
}
|
}
|
||||||
public Map<PropertyDescriptor<?>, Object> getOverriddenPropertiesByPropertyDescriptor() {
|
public Map<PropertyDescriptor<?>, Object> getOverriddenPropertiesByPropertyDescriptor() {
|
||||||
@ -58,12 +58,13 @@ public class Foo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
]]></code>
|
]]></code>
|
||||||
</test-code>
|
</test-code>
|
||||||
<test-code>
|
|
||||||
<description>#1624[java] UseDiamondOperator doesn't work with var</description>
|
<test-code>
|
||||||
<expected-problems>1</expected-problems>
|
<description>#1624[java] UseDiamondOperator doesn't work with var</description>
|
||||||
<expected-linenumbers>6</expected-linenumbers>
|
<expected-problems>1</expected-problems>
|
||||||
<code><![CDATA[
|
<expected-linenumbers>6</expected-linenumbers>
|
||||||
|
<code><![CDATA[
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
public class Buzz {
|
public class Buzz {
|
||||||
public void buzz() {
|
public void buzz() {
|
||||||
@ -72,13 +73,14 @@ public class Buzz {
|
|||||||
f = new ArrayList<String>(); // flagged by rule
|
f = new ArrayList<String>(); // flagged by rule
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]]></code>
|
]]></code>
|
||||||
</test-code>
|
</test-code>
|
||||||
<test-code>
|
|
||||||
<description>Multiple initializations in a single declaration</description>
|
<test-code>
|
||||||
<expected-problems>1</expected-problems>
|
<description>Multiple initializations in a single declaration</description>
|
||||||
<expected-linenumbers>6</expected-linenumbers>
|
<expected-problems>1</expected-problems>
|
||||||
<code><![CDATA[
|
<expected-linenumbers>6</expected-linenumbers>
|
||||||
|
<code><![CDATA[
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
public class Buzz {
|
public class Buzz {
|
||||||
@ -88,6 +90,93 @@ public class Buzz {
|
|||||||
baz = new ArrayList<>(); // ok
|
baz = new ArrayList<>(); // ok
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]]></code>
|
]]></code>
|
||||||
</test-code>
|
</test-code>
|
||||||
</test-data>
|
|
||||||
|
<test-code>
|
||||||
|
<description>#1723 FP with var inside lambda (declaration)</description>
|
||||||
|
<expected-problems>0</expected-problems>
|
||||||
|
<code><![CDATA[
|
||||||
|
class Foo {
|
||||||
|
{
|
||||||
|
Runnable someAction = () -> {
|
||||||
|
var foo = new ArrayList<String>(5); // ok
|
||||||
|
System.err.println(foo);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]]></code>
|
||||||
|
</test-code>
|
||||||
|
|
||||||
|
<test-code>
|
||||||
|
<description>#1723 FP with var inside lambda (assignment)</description>
|
||||||
|
<expected-problems>0</expected-problems>
|
||||||
|
<code><![CDATA[
|
||||||
|
class Foo {
|
||||||
|
{
|
||||||
|
Runnable someAction;
|
||||||
|
someAction = () -> {
|
||||||
|
var foo = new ArrayList<String>(5); // ok
|
||||||
|
System.err.println(foo);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]]></code>
|
||||||
|
</test-code>
|
||||||
|
|
||||||
|
<test-code>
|
||||||
|
<description>FP with array creation</description>
|
||||||
|
<expected-problems>0</expected-problems>
|
||||||
|
<code><![CDATA[
|
||||||
|
class Foo {
|
||||||
|
{
|
||||||
|
Class<?> c = new Class<?>[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]]></code>
|
||||||
|
</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
|
||||||
|
in PMD 7. -->
|
||||||
|
|
||||||
|
<test-code regressionTest="false">
|
||||||
|
<description>(J7) Version sensitive tests</description>
|
||||||
|
<expected-problems>1</expected-problems>
|
||||||
|
<expected-linenumbers>6</expected-linenumbers>
|
||||||
|
<code><![CDATA[
|
||||||
|
public class Foo {
|
||||||
|
private WeakReference<Class<?>> typeReference;
|
||||||
|
public void foo() {
|
||||||
|
// this should be positive in Java 8, negative in Java 7
|
||||||
|
// 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);
|
||||||
|
Class<?> type = null;
|
||||||
|
typeReference = new WeakReference<Class<?>>(type); // this should be positive on all versions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]]></code>
|
||||||
|
<source-type>java 1.7</source-type>
|
||||||
|
</test-code>
|
||||||
|
|
||||||
|
<test-code regressionTest="false">
|
||||||
|
<description>(J8) Version sensitive tests</description>
|
||||||
|
<expected-problems>2</expected-problems>
|
||||||
|
<expected-linenumbers>4,6</expected-linenumbers>
|
||||||
|
<code><![CDATA[
|
||||||
|
public class Foo {
|
||||||
|
private WeakReference<Class<?>> typeReference;
|
||||||
|
public void foo() {
|
||||||
|
typeReference = new WeakReference<Class<?>>(String.class); // pos
|
||||||
|
Class<?> type = null;
|
||||||
|
typeReference = new WeakReference<Class<?>>(type); // pos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]]></code>
|
||||||
|
<source-type>java 1.8</source-type>
|
||||||
|
</test-code>
|
||||||
|
|
||||||
|
</test-data>
|
Reference in New Issue
Block a user