Merge branch 'master' into uselessoverridingmethod-false-negative

This commit is contained in:
Clément Fournier committed 2020-06-12 17:36:38 +02:00
commit 6c51cec444
224 files changed
+653 -94

No files matched your search

+1 -1
View File
@@ -48,7 +48,7 @@ function pmd_code_uploadJavadoc() {
log_debug "$FUNCNAME pmdVersion=$pmdVersion basePath=$basePath"
for i in ${basePath}/*/target/*-javadoc.jar; do
for i in ${basePath}/*/target/*-javadoc.jar */*/target/*-javadoc.jar; do
pmd_code_uploadJavadocModule "$pmdVersion" "$i"
done
+1 -1
View File
@@ -88,7 +88,7 @@ echo "* Update **pmd-apex/src/main/resources/rulesets/apex/quickstart.xml** an
echo " **pmd-java/src/main/resources/rulesets/java/quickstart.xml** with the new rules."
echo
echo "* Update **docs/pages/next_major_development.md** with the API changes for"
echo " the new release based on the release notes"
echo " the new release based on the release notes. Also add any deprecated rules to the list."
echo
echo "* Update **../pmd.github.io/_config.yml** to mention the new release"
echo
+5
View File
@@ -226,6 +226,11 @@ class JavadocTag < Liquid::Tag
def self.fqcn_type(artifact_id, fqcn)
artifact_dir = File.join(BASE_PMD_DIR, artifact_id)
# special case for scala as we have a different directory structure there
if artifact_id =~ /scala/
artifact_dir = File.join(BASE_PMD_DIR, "pmd-scala-modules/pmd-scala-common")
end
src_dirs = [
File.join(artifact_dir, "src", "main", "java"),
File.join(artifact_dir, "target", "generated-sources", "javacc")
+6 -1
View File
@@ -86,9 +86,14 @@ class JDocNamespaceDeclaration < Liquid::Tag
expanded_fqcn += "." + fqcn_suffix
end
artifactId = resolved_nspace.first
if artifactId =~ /scala/
artifactId = "pmd-scala_2.13"
end
# Return the resolved artifactId + the expanded FQCN
[resolved_nspace.first, expanded_fqcn]
[artifactId, expanded_fqcn]
end
private
+70 -14
View File
@@ -4,17 +4,69 @@ permalink: pmd_next_major_development.html
keywords: changelog, release notes, deprecation, api changes
---
We're excited to bring you the next major version of PMD! Here are the major features and changes we're working on.
We're excited to bring you the next major version of PMD!
Here is a summary of what is planned for PMD 7.
To give us feedback or to suggest a new feature, drop us a line on [Gitter](https://gitter.im/pmd/pmd)!
## New Features
## Summary
TODO
### New Logo
## Java grammar changes
We decided it's time to have a modernized logo and get rid of the gun. This allows to include
the logo in anywhere without offense.
{% include note.html content="Current plans are listed [here](https://github.com/pmd/pmd/labels/in%3Aast) and in particular [here](https://github.com/pmd/pmd/issues/1019)" %}
The current tasks are listed here: [Integrate new PMD logo #1931](https://github.com/pmd/pmd/issues/1931)
### API
The API of PMD has been growing over the years and needs to be cleaned up. The goal is, to
have a clear separation between a well-defined API and the implementation, which is internal.
This should help us in future development. This however entails some incompatibilities and
deprecations, see also the sections [New API support guidelines](#new-api-support-guidelines) and
[Planned API removals](#planned-api-removals] below.
### Full Antlr Support
PMD 6 only supports JavaCC based grammars, but with [Antlr](https://www.antlr.org/) parsers
can be generated as well. PMD 7 adds full support for grammars written in Antlr, which allows
to leverage existing grammars.
The current tasks are listed here: [Support for ANTLR based grammars with Swift as an example language #2499](https://github.com/pmd/pmd/issues/2499)
### Documentation
We have quite some ideas how we want to improve the documentation. The goal is, that the documentation is
up to date and nearly complete. One big task is, how the built-in rules are presented, so that users
can easier see, what exactly is available and decide, which rules are useful for the project at hand.
The current tasks are listed here: [Documentations improvements tracker #1139](https://github.com/pmd/pmd/issues/1139)
### XPath
PMD 6 supports XPath 1.0 via the Jaxen library. This library is old and unmaintained creating some problems
(one of which is duplicated classes in the package `org.w3c.dom` which is a Java API actually).
Therefore XPath 1.0 support will be dropped and we upgrade our XPath 2.0 implementation with Saxon moving
on to Saxon HE. This will eventually add support in PMD for XPath 3.1.
The current tasks are listed here: [XPath Improvements for PMD 7 #2523](https://github.com/pmd/pmd/issues/2523)
### Java
Like the main PMD API, the Java AST has been growing over time and the grammar doesn't support
all edge cases (e.g. annotation are not supported everywhere). The goal is to simplify the AST by reducing
unnecessary nodes and abstractions and fix the parsing issues.
This helps in the end to provide a better type resolution implementation, but changing the AST is a breaking
API change.
Some first results of the Java AST changes are for now documented in the Wiki:
[Java clean changes](https://github.com/pmd/pmd/wiki/Java_clean_changes).
### Miscellaneous
There are also some small improvements, refactoring and internal tasks that are planned for PMD 7.
The current tasks are listed here: [PMD 7 Miscellaneous Tasks #2524](https://github.com/pmd/pmd/issues/2524)
## New API support guidelines
@@ -878,14 +930,18 @@ large projects, with many duplications, it was causing `OutOfMemoryError`s (see
and {% rule "java/bestpractices/PositionLiteralsFirstInCaseInsensitiveComparisons" %} (ruleset `java-bestpractices`)
have been deprecated in favor of the new rule {% rule "java/bestpractices/LiteralsFirstInComparisons" %}.
* The Java rule [`AvoidFinalLocalVariable`](https://pmd.github.io/pmd-6.16.0/pmd_rules_java_codestyle.html#avoidfinallocalvariable) (`java-codestyle`) has been deprecated
and will be removed with PMD 7.0.0. The rule is controversial and also contradicts other existing
rules such as [`LocalVariableCouldBeFinal`](https://pmd.github.io/pmd-6.16.0/pmd_rules_java_codestyle.html#localvariablecouldbefinal). If the goal is to avoid defining
constants in a scope smaller than the class, then the rule [`AvoidDuplicateLiterals`](https://pmd.github.io/pmd-6.16.0/pmd_rules_java_errorprone.html#avoidduplicateliterals)
should be used instead.
* The Apex rule [`VariableNamingConventions`](https://pmd.github.io/pmd-6.15.0/pmd_rules_apex_codestyle.html#variablenamingconventions) (`apex-codestyle`) has been deprecated and
will be removed with PMD 7.0.0. The rule is replaced by the more general rules
[`FieldNamingConventions`](https://pmd.github.io/pmd-6.15.0/pmd_rules_apex_codestyle.html#fieldnamingconventions),
[`FormalParameterNamingConventions`](https://pmd.github.io/pmd-6.15.0/pmd_rules_apex_codestyle.html#formalparameternamingconventions),
[`LocalVariableNamingConventions`](https://pmd.github.io/pmd-6.15.0/pmd_rules_apex_codestyle.html#localvariablenamingconventions), and
[`PropertyNamingConventions`](https://pmd.github.io/pmd-6.15.0/pmd_rules_apex_codestyle.html#propertynamingconventions).
* The Java rule [`LoggerIsNotStaticFinal`](https://pmd.github.io/pmd-6.15.0/pmd_rules_java_errorprone.html#loggerisnotstaticfinal) (`java-errorprone`) has been deprecated
and will be removed with PMD 7.0.0. The rule is replaced by [`ProperLogger`](https://pmd.github.io/pmd-6.15.0/pmd_rules_java_errorprone.html#properlogger).
+1 -1
View File
@@ -370,7 +370,7 @@ Here's a screenshot of CPD after running on the JDK 8 java.lang package:
## Suppression
Arbitrary blocks of code can be ignored through comments on **Java**, **C/C++**, **Dart**, **Go**, **Javascript**,
**Kotlin**, **Lua**, **Matlab**, **Objective-C**, **PL/SQL**, **Python** and **Swift** by including the keywords `CPD-OFF` and `CPD-ON`.
**Kotlin**, **Lua**, **Matlab**, **Objective-C**, **PL/SQL**, **Python**, **Swift** and **C#** by including the keywords `CPD-OFF` and `CPD-ON`.
```java
public Object someParameterizedFactoryMethod(int x) throws Exception {
+44
View File
@@ -14,14 +14,58 @@ This is a {{ site.pmd.release_type }} release.
### New and noteworthy
#### Scala cross compilation
Up until now the PMD Scala module has been compiled against scala 2.13 only by default.
However, this makes it impossible to use pmd as a library in scala projects,
that use scala 2.12, e.g. in sbt plugins. Therefore PMD now provides cross compiled pmd-scala
modules for both versions: **scala 2.12** and **scala 2.13**.
The new modules have new maven artifactIds. The old artifactId `net.sourceforge.pmd:pmd-scala:{{ site.pmd.version }}`
is still available, but is deprecated from now on. It has been demoted to be just a delegation to the new
`pmd-scala_2.13` module and will be removed eventually.
The coordinates for the new modules are:
```
<dependency>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd-scala_2.12</artifactId>
<version>{{ site.pmd.version }}</version>
</dependency>
<dependency>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd-scala_2.13</artifactId>
<version>{{ site.pmd.version }}</version>
</dependency>
```
The command line version of PMD continues to use **scala 2.13**.
#### New Rules
* The new Java Rule {% rule "java/codestyle/UnnecessaryCast" %} (`java-codestyle`)
finds casts that are unnecessary while accessing collection elements.
### Fixed Issues
* c#
* [#2551](https://github.com/pmd/pmd/issues/2551): \[c#] CPD suppression with comments doesn't work
* java-design
* [#2563](https://github.com/pmd/pmd/pull/2563): \[java] UselessOverridingMethod false negative with already public methods
* scala
* [#2547](https://github.com/pmd/pmd/pull/2547): \[scala] Add cross compilation for scala 2.12 and 2.13
### API Changes
* The maven module `net.sourceforge.pmd:pmd-scala` is deprecated. Use `net.sourceforge.pmd:pmd-scala_2.13`
or `net.sourceforge.pmd:pmd-scala_2.12` instead.
### External Contributions
* [#2547](https://github.com/pmd/pmd/pull/2547): \[scala] Add cross compilation for scala 2.12 and 2.13 - [João Ferreira](https://github.com/jtjeferreira)
* [#2567](https://github.com/pmd/pmd/pull/2567): \[c#] Fix CPD suppression with comments doesn't work - [Lixon Lookose](https://github.com/LixonLookose)
{% endtocmaker %}
+1
View File
@@ -9,6 +9,7 @@
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>6.25.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<properties>
+1
View File
@@ -8,6 +8,7 @@
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>6.25.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<properties>
+1
View File
@@ -8,6 +8,7 @@
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>6.25.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<build>
@@ -77,7 +77,7 @@ public class AntlrToken implements GenericToken {
}
public boolean isHidden() {
return token.getChannel() == Lexer.HIDDEN;
return !isDefault();
}
public boolean isDefault() {
@@ -0,0 +1,13 @@
<?xml version="1.0"?>
<ruleset name="6250"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
<description>
This ruleset contains links to rules that are new in PMD v6.25.0
</description>
<rule ref="category/java/codestyle.xml/UnnecessaryCast" />
</ruleset>
+1
View File
@@ -8,6 +8,7 @@
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>6.25.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<build>
+1
View File
@@ -8,6 +8,7 @@
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>6.25.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<build>
@@ -78,6 +78,18 @@ public class CsTokenizerTest {
assertEquals(5, tokens.size());
}
@Test
public void testIgnoreBetweenSpecialComments() {
tokenizer
.tokenize(
toSourceCode("// CPD-OFF\n" + "class Foo {\n" + " void bar() {\n" + " int a = 1 >> 2; \n"
+ " a += 1; \n" + " a++; \n" + " a /= 3e2; \n" + " float f = -3.1; \n"
+ " f *= 2; \n" + " bool b = ! (f == 2.0 || f >= 1.0 && f <= 2.0) \n"
+ " }\n" + "// CPD-ON\n" + "}"),
tokens);
assertEquals(2, tokens.size()); // "}" + EOF
}
@Test
public void testCommentsIgnored3() {
tokenizer.tokenize(toSourceCode("class Foo { /// class X /* aaa */ \n }"), tokens);
+1
View File
@@ -8,6 +8,7 @@
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>6.25.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<build>
+2 -1
View File
@@ -9,6 +9,7 @@
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>6.25.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<properties>
@@ -199,7 +200,7 @@
</dependency>
<dependency>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd-scala</artifactId>
<artifactId>pmd-scala_2.13</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
+1
View File
@@ -9,6 +9,7 @@
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>6.25.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<properties>
+1
View File
@@ -8,6 +8,7 @@
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>6.25.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<build>
+1
View File
@@ -8,6 +8,7 @@
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>6.25.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<build>
+1
View File
@@ -8,6 +8,7 @@
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>6.25.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<build>
+1
View File
@@ -8,6 +8,7 @@
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>6.25.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<build>
@@ -1,11 +1,12 @@
/**
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.java.rule.migrating;
package net.sourceforge.pmd.lang.java.rule.codestyle;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.sourceforge.pmd.lang.ast.Node;
@@ -13,10 +14,12 @@ import net.sourceforge.pmd.lang.java.ast.ASTCastExpression;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTLocalVariableDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTName;
import net.sourceforge.pmd.lang.java.ast.ASTTypeArgument;
import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
import net.sourceforge.pmd.lang.java.typeresolution.TypeHelper;
import net.sourceforge.pmd.lang.symboltable.NameOccurrence;
import net.sourceforge.pmd.lang.symboltable.ScopedNode;
/**
* This is a rule, that detects unnecessary casts when using Java 1.5 generics
@@ -34,7 +37,6 @@ import net.sourceforge.pmd.lang.symboltable.NameOccurrence;
* "http://sourceforge.net/p/pmd/discussion/188192/thread/276fd6f0">Java 5
* rules: Unnecessary casts/Iterators</a>
*/
// TODO This is not referenced by any RuleSet?
public class UnnecessaryCastRule extends AbstractJavaRule {
private static Set<String> implClassNames = new HashSet<>();
@@ -62,36 +64,67 @@ public class UnnecessaryCastRule extends AbstractJavaRule {
implClassNames.add("java.util.TreeSet");
implClassNames.add("java.util.TreeMap");
implClassNames.add("java.util.Vector");
implClassNames.add("Iterator");
implClassNames.add("java.util.Iterator");
}
@Override
public Object visit(ASTLocalVariableDeclaration node, Object data) {
return process(node, data);
process(node, data);
return super.visit(node, data);
}
@Override
public Object visit(ASTFieldDeclaration node, Object data) {
return process(node, data);
process(node, data);
return super.visit(node, data);
}
private Object process(Node node, Object data) {
ASTClassOrInterfaceType cit = node.getFirstDescendantOfType(ASTClassOrInterfaceType.class);
if (cit == null || !implClassNames.contains(cit.getImage())) {
return data;
private void process(Node node, Object data) {
ASTClassOrInterfaceType collectionType = node.getFirstDescendantOfType(ASTClassOrInterfaceType.class);
if (collectionType == null || !implClassNames.contains(collectionType.getImage())) {
return;
}
cit = cit.getFirstDescendantOfType(ASTClassOrInterfaceType.class);
ASTClassOrInterfaceType cit = getCollectionItemType(collectionType);
if (cit == null) {
return data;
return;
}
ASTVariableDeclaratorId decl = node.getFirstDescendantOfType(ASTVariableDeclaratorId.class);
List<NameOccurrence> usages = decl.getUsages();
for (NameOccurrence no : usages) {
ASTName name = (ASTName) no.getLocation();
Node n = name.getParent().getParent().getParent();
if (n instanceof ASTCastExpression) {
addViolation(data, n);
ASTCastExpression castExpression = findCastExpression(no.getLocation());
if (castExpression != null) {
ASTClassOrInterfaceType castTarget = castExpression.getFirstDescendantOfType(ASTClassOrInterfaceType.class);
if (castTarget != null
&& cit.getImage().equals(castTarget.getImage())
&& !castTarget.hasDescendantOfType(ASTTypeArgument.class)) {
addViolation(data, castExpression);
}
}
}
}
private ASTClassOrInterfaceType getCollectionItemType(ASTClassOrInterfaceType collectionType) {
if (TypeHelper.isA(collectionType, Map.class)) {
List<ASTClassOrInterfaceType> types = collectionType.findDescendantsOfType(ASTClassOrInterfaceType.class);
if (types.size() >= 2) {
return types.get(1); // the value type of the map
}
} else {
return collectionType.getFirstDescendantOfType(ASTClassOrInterfaceType.class);
}
return null;
}
private ASTCastExpression findCastExpression(ScopedNode usage) {
Node n = usage.getNthParent(2);
if (n instanceof ASTCastExpression) {
return (ASTCastExpression) n;
}
n = n.getParent();
if (n instanceof ASTCastExpression) {
return (ASTCastExpression) n;
}
return null;
}
}
@@ -1855,6 +1855,30 @@ public class Foo {
</example>
</rule>
<rule name="UnnecessaryCast"
language="java"
minimumLanguageVersion="1.5"
since="6.24.0"
message="Avoid unnecessary casts"
class="net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryCastRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#unnecessarycast">
<description>
This rule detects when a cast is unnecessary while accessing collection elements. This rule is mostly useful
for old java code before generics where introduced with java 1.5.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class UnnecessaryCastSample {
public void method() {
List<String> stringList = Arrays.asList("a", "b");
String element = (String) stringList.get(0); // this cast is unnecessary
String element2 = stringList.get(0);
}
}
]]>
</example>
</rule>
<rule name="UnnecessaryConstructor"
language="java"
@@ -105,6 +105,7 @@
<!-- <rule ref="category/java/codestyle.xml/SuspiciousConstantFieldName" /> -->
<!-- <rule ref="category/java/codestyle.xml/TooManyStaticImports" /> -->
<rule ref="category/java/codestyle.xml/UnnecessaryAnnotationValueElement"/>
<!-- <rule ref="category/java/codestyle.xml/UnnecessaryCast" /> -->
<rule ref="category/java/codestyle.xml/UnnecessaryConstructor"/>
<rule ref="category/java/codestyle.xml/UnnecessaryFullyQualifiedName"/>
<rule ref="category/java/codestyle.xml/UnnecessaryLocalBeforeReturn"/>
@@ -0,0 +1,12 @@
/*
* 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 UnnecessaryCastTest extends PmdRuleTst {
// no additional unit tests
}
@@ -0,0 +1,157 @@
<?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>Basic Violations</description>
<expected-problems>5</expected-problems>
<expected-linenumbers>12,15,18,23,28</expected-linenumbers>
<code><![CDATA[
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.uilt.HashMap;
public class UnnecessaryCastSample {
private Map<Integer, String> map = new HashMap<>();
public void localVars() {
List<String> stringList = Arrays.asList("a");
String element = (String) stringList.get(0);
List<Double> doubleList = new ArrayList<>();
Double number = (Double) doubleList.get(0);
Map<String, String> stringMap = new HashMap<>();
String mapData = (String) stringMap.get("a");
}
public void fields() {
map.put(1, "test");
String val = (String) map.get(1);
}
public void fields2() {
this.map.put(1, "test");
String val = (String) this.map.get(1);
}
}
]]></code>
</test-code>
<test-code>
<description>Without casts there should be no violation</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.uilt.HashMap;
public class UnnecessaryCastSample {
private Map<Integer, String> map = new HashMap<>();
public void localVars() {
List<String> stringList = Arrays.asList("a");
String element = stringList.get(0);
List<Double> doubleList = new ArrayList<>();
Double number = doubleList.get(0);
}
public void fields() {
map.put(1, "test");
String val = map.get(1);
}
public void fields2() {
this.map.put(1, "test");
String val = this.map.get(1);
}
}
]]></code>
</test-code>
<test-code>
<description>Unnecessary casts with iterator</description>
<expected-problems>2</expected-problems>
<expected-linenumbers>10,17</expected-linenumbers>
<code><![CDATA[
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class UnnecessaryCastSample {
public void localVars() {
List<String> stringList = Arrays.asList("a");
Iterator<String> stringIt = stringList.iterator();
while (stringIt.hasNext()) {
String element = (String) stringIt.next();
String element2 = stringIt.next();
}
List<Double> doubleList = new ArrayList<>();
Iterator<Double> doubleIt = doubleList.iterator();
while (doubleIt.hasNext()) {
Double number = (Double) doubleIt.next();
Double number2 = doubleIt.next();
}
}
}
]]></code>
</test-code>
<test-code>
<description>Avoid cast false-positives</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class UnnecessaryCastSample {
public void localVars() {
List<Number> numbers = Arrays.asList(1, 2, 3);
Integer myInt = (Integer) numbers.get(0);
List<Object> data = new ArrayList<>();
String item = (String) data.get(0);
Map<String, ?> map = new HashMap<>();
String dataFromMap = (String) map.get("foo");
}
}
]]></code>
</test-code>
<test-code>
<description>Avoid clone false-positive</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class UnnecessaryCastSample {
public void localVars() {
List<String> strings = new ArrayList<>();
List<String> copy = (List<String>) strings.clone();
}
}
]]></code>
</test-code>
<test-code>
<description>Necessary Map Cast (nested generics) false-positive</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class MapCasts {
private final Map<Class<?>, Map<String, ?>> resourceCaches = new ConcurrentHashMap<>(4);
@SuppressWarnings("unchecked")
public <T> Map<String, T> getResourceCache(Class<T> valueType) {
return (Map<String, T>) this.resourceCaches.computeIfAbsent(valueType, key -> new ConcurrentHashMap<>());
}
}
]]></code>
</test-code>
</test-data>
+1
View File
@@ -8,6 +8,7 @@
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>6.25.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<properties>
+1
View File
@@ -8,6 +8,7 @@
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>6.25.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<build>
+1
View File
@@ -8,6 +8,7 @@
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd</artifactId>
<version>6.25.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<build>
Loaded 30 of 224 files, more files were not shown because too many files have changed in this diff. Show more