forked from phoedos/pmd
Merge branch 'pr-1534'
This commit is contained in:
@ -25,6 +25,10 @@ This is a {{ site.pmd.release_type }} release.
|
||||
for loop variables that are reassigned. Changing the loop variables additionally to the loop itself can lead to
|
||||
hard-to-find bugs.
|
||||
|
||||
* The new Java rule {% rule "java/codestyle/UseDiamondOperator" %} (`java-codestyle`) looks for constructor
|
||||
calls with explicit type parameters. Since Java 1.7, these type parameters are not necessary anymore, as they
|
||||
can be inferred now.
|
||||
|
||||
#### Modified Rules
|
||||
|
||||
* The Java rule {% rule "java/codestyle/LocalVariableCouldBeFinal" %} (`java-codestyle`) has a new
|
||||
@ -41,6 +45,7 @@ This is a {{ site.pmd.release_type }} release.
|
||||
* [#1519](https://github.com/pmd/pmd/issues/1519): \[java] New rule: ForLoopVariableCount
|
||||
* java-codestyle
|
||||
* [#1513](https://github.com/pmd/pmd/issues/1513): \[java] LocalVariableCouldBeFinal: allow excluding the variable in a for-each loop
|
||||
* [#1517](https://github.com/pmd/pmd/issues/1517): \[java] New Rule: UseDiamondOperator
|
||||
* java-errorprone
|
||||
* [#1035](https://github.com/pmd/pmd/issues/1035): \[java] ReturnFromFinallyBlock: False positive on lambda expression in finally block
|
||||
* plsql
|
||||
@ -58,6 +63,7 @@ This is a {{ site.pmd.release_type }} release.
|
||||
* [#1520](https://github.com/pmd/pmd/pull/1520): \[java] New rule: ForLoopVariableCount: check the number of control variables in a for loop - [Kris Scheibe](https://github.com/kris-scheibe)
|
||||
* [#1521](https://github.com/pmd/pmd/pull/1521): \[java] Upgrade to ASM7 for JDK 11 support - [Mark Pritchard](https://github.com/markpritchard)
|
||||
* [#1530](https://github.com/pmd/pmd/pull/1530): \[java] New rule: AvoidReassigningLoopVariables - [Kris Scheibe](https://github.com/kris-scheibe)
|
||||
* [#1534](https://github.com/pmd/pmd/pull/1534): \[java] This is the change regarding the usediamondoperator #1517 - [hemanshu070](https://github.com/hemanshu070)
|
||||
|
||||
{% endtocmaker %}
|
||||
|
||||
|
@ -1911,6 +1911,45 @@ public class Foo {
|
||||
</example>
|
||||
</rule>
|
||||
|
||||
<rule name="UseDiamondOperator"
|
||||
language="java"
|
||||
since="6.11.0"
|
||||
message="Explicit type arguments can be replaced by Diamond Operator"
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#usediamondoperator"
|
||||
minimumLanguageVersion="1.7">
|
||||
<description>
|
||||
Use the diamond operator to let the type be inferred automatically. With the Diamond operator it is possible
|
||||
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.
|
||||
</description>
|
||||
<priority>1</priority>
|
||||
<properties>
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//VariableInitializer
|
||||
//PrimaryExpression[not(PrimarySuffix)]
|
||||
[not(ancestor::ArgumentList)]
|
||||
/PrimaryPrefix/AllocationExpression[ClassOrInterfaceType[@AnonymousClass='false']/TypeArguments//ReferenceType[not(.//TypeArguments)]]
|
||||
|
|
||||
//StatementExpression[AssignmentOperator][PrimaryExpression/PrimaryPrefix[not(Expression)]]
|
||||
//PrimaryExpression[not(PrimarySuffix)]
|
||||
[not(ancestor::ArgumentList)]
|
||||
/PrimaryPrefix/AllocationExpression[ClassOrInterfaceType[@AnonymousClass='false']/TypeArguments//ReferenceType[not(.//TypeArguments)]]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
</properties>
|
||||
<example>
|
||||
<![CDATA[
|
||||
List<String> strings = new ArrayList<String>(); // unnecessary duplication of type parameters
|
||||
List<String> stringsWithDiamond = new ArrayList<>(); // using the diamond operator is more concise
|
||||
]]>
|
||||
</example>
|
||||
</rule>
|
||||
|
||||
<rule name="UselessParentheses"
|
||||
language="java"
|
||||
since="5.0"
|
||||
|
@ -0,0 +1,11 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.java.rule.codestyle;
|
||||
|
||||
import net.sourceforge.pmd.testframework.PmdRuleTst;
|
||||
|
||||
public class UseDiamondOperator extends PmdRuleTst {
|
||||
// no additional unit tests
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
<?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>8,11</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
public class Foo {
|
||||
List<String> field;
|
||||
public void foo() {
|
||||
List<String> strings = new ArrayList<String>();
|
||||
List<String> strings2 = new ArrayList<>();
|
||||
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[
|
||||
public class Foo {
|
||||
private WeakReference<Class<?>> typeReference;
|
||||
public void foo() {
|
||||
Collections.sort(files, new Comparator<DataSource>() {
|
||||
@Override
|
||||
public int compare(DataSource left, DataSource right) {
|
||||
String leftString = left.getNiceFileName(useShortNames, inputPaths);
|
||||
String rightString = right.getNiceFileName(useShortNames, inputPaths);
|
||||
return leftString.compareTo(rightString);
|
||||
}
|
||||
});
|
||||
final TreeSet<Map.Entry<String, TimedResult>> sortedKeySet = new TreeSet<>(
|
||||
new Comparator<Map.Entry<String, TimedResult>>() {
|
||||
@Override
|
||||
public int compare(final Entry<String, TimedResult> o1, final Entry<String, TimedResult> o2) {
|
||||
return Long.compare(o1.getValue().selfTimeNanos.get(), o2.getValue().selfTimeNanos.get());
|
||||
}
|
||||
});
|
||||
new ThreadLocal<Queue<TimerEntry>>() {
|
||||
@Override
|
||||
protected Queue<TimerEntry> initialValue() {
|
||||
return Collections.asLifoQueue(new LinkedList<TimerEntry>());
|
||||
}
|
||||
};
|
||||
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() {
|
||||
return propertyValues == null ? new HashMap<PropertyDescriptor<?>, Object>() : new HashMap<>(propertyValues);
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
</test-data>
|
Reference in New Issue
Block a user