Merge branch 'pr-2392'

[java] Fix UseDiamondOperator false positive inside lambda #2392
This commit is contained in:
Andreas Dangel
2020-04-04 10:44:32 +02:00
3 changed files with 136 additions and 42 deletions

View File

@ -1967,18 +1967,21 @@ which makes the code also more readable.
</description>
<priority>3</priority>
<properties>
<property name="version" value="2.0" />
<property name="xpath">
<value>
<![CDATA[
//VariableInitializer[preceding-sibling::VariableDeclaratorId[1]/@TypeInferred="false"]
//PrimaryExpression[not(PrimarySuffix)]
[not(ancestor::ArgumentList)]
/PrimaryPrefix/AllocationExpression[ClassOrInterfaceType[@AnonymousClass='false']/TypeArguments//ReferenceType[not(.//TypeArguments)]]
(
//VariableInitializer[preceding-sibling::VariableDeclaratorId[1]/@TypeInferred=false()]
|
//StatementExpression[AssignmentOperator][PrimaryExpression/PrimaryPrefix[not(Expression)]]
//PrimaryExpression[not(PrimarySuffix)]
[not(ancestor::ArgumentList)]
/PrimaryPrefix/AllocationExpression[ClassOrInterfaceType[@AnonymousClass='false']/TypeArguments//ReferenceType[not(.//TypeArguments)]]
//StatementExpression[AssignmentOperator and PrimaryExpression/PrimaryPrefix[not(Expression)]]
)
/Expression/PrimaryExpression[not(PrimarySuffix) and not(ancestor::ArgumentList)]
/PrimaryPrefix
/AllocationExpression
[@AnonymousClass=false()]
[ClassOrInterfaceType/TypeArguments[@Diamond=false() and not(TypeArgument//TypeArguments)]]
[not(ArrayDimsAndInits)]
]]>
</value>
</property>

View File

@ -1,13 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<test-data
xmlns="http://pmd.sourceforge.net/rule-tests"
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">
<test-code>
<description>Use Diamond</description>
<expected-problems>2</expected-problems>
<expected-linenumbers>6,8</expected-linenumbers>
<code><![CDATA[
<test-data xmlns="http://pmd.sourceforge.net/rule-tests"
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">
<test-code>
<description>Use Diamond</description>
<expected-problems>2</expected-problems>
<expected-linenumbers>6,11</expected-linenumbers>
<code><![CDATA[
import java.util.ArrayList;
import java.util.List;
public class Foo {
@ -15,17 +14,20 @@ public class Foo {
public void 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>();
}
}
]]></code>
</test-code>
<test-code>
<description>False positive cases: anonymous classes, methods calls</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
]]></code>
</test-code>
<test-code>
<description>False positive cases: anonymous classes, methods calls</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
private WeakReference<Class<?>> typeReference;
public void foo() {
Collections.sort(files, new Comparator<DataSource>() {
@Override
@ -49,8 +51,6 @@ public class Foo {
}
};
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);
}
public Map<PropertyDescriptor<?>, Object> getOverriddenPropertiesByPropertyDescriptor() {
@ -58,12 +58,13 @@ public class Foo {
}
}
]]></code>
</test-code>
<test-code>
<description>#1624[java] UseDiamondOperator doesn't work with var</description>
<expected-problems>1</expected-problems>
<expected-linenumbers>6</expected-linenumbers>
<code><![CDATA[
</test-code>
<test-code>
<description>#1624[java] UseDiamondOperator doesn't work with var</description>
<expected-problems>1</expected-problems>
<expected-linenumbers>6</expected-linenumbers>
<code><![CDATA[
import java.util.ArrayList;
public class Buzz {
public void buzz() {
@ -72,13 +73,14 @@ public class Buzz {
f = new ArrayList<String>(); // flagged by rule
}
}
]]></code>
</test-code>
<test-code>
<description>Multiple initializations in a single declaration</description>
<expected-problems>1</expected-problems>
<expected-linenumbers>6</expected-linenumbers>
<code><![CDATA[
]]></code>
</test-code>
<test-code>
<description>Multiple initializations in a single declaration</description>
<expected-problems>1</expected-problems>
<expected-linenumbers>6</expected-linenumbers>
<code><![CDATA[
import java.util.ArrayList;
import java.util.List;
public class Buzz {
@ -88,6 +90,93 @@ public class Buzz {
baz = new ArrayList<>(); // ok
}
}
]]></code>
</test-code>
</test-data>
]]></code>
</test-code>
<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>