[java] UnusedAssignment false positive in record compact constructor
Fixes #4603
This commit is contained in:
3 files changed
+60
-1
No files matched your search
@@ -275,7 +275,8 @@ The rules have been moved into categories with PMD 6.
|
||||
* [#3751](https://github.com/pmd/pmd/issues/3751): \[java] Rename some node types
|
||||
* [#4628](https://github.com/pmd/pmd/pull/4628): \[java] Support loading classes from java runtime images
|
||||
* [#4753](https://github.com/pmd/pmd/issues/4753): \[java] PMD crashes while using generics and wildcards
|
||||
* java-bestpractives
|
||||
* java-bestpractices
|
||||
* [#4603](https://github.com/pmd/pmd/issues/4603): \[java] UnusedAssignment false positive in record compact constructor
|
||||
* [#4625](https://github.com/pmd/pmd/issues/4625): \[java] UnusedPrivateMethod false positive: Autoboxing into Number
|
||||
* java-codestyle
|
||||
* [#2847](https://github.com/pmd/pmd/issues/2847): \[java] New Rule: Use Explicit Types
|
||||
@@ -1406,6 +1407,7 @@ Language specific fixes:
|
||||
* [#4516](https://github.com/pmd/pmd/issues/4516): \[java] UnusedLocalVariable: false-negative with try-with-resources
|
||||
* [#4517](https://github.com/pmd/pmd/issues/4517): \[java] UnusedLocalVariable: false-negative with compound assignments
|
||||
* [#4518](https://github.com/pmd/pmd/issues/4518): \[java] UnusedLocalVariable: false-positive with multiple for-loop indices
|
||||
* [#4603](https://github.com/pmd/pmd/issues/4603): \[java] UnusedAssignment false positive in record compact constructor
|
||||
* [#4625](https://github.com/pmd/pmd/issues/4625): \[java] UnusedPrivateMethod false positive: Autoboxing into Number
|
||||
* [#4634](https://github.com/pmd/pmd/issues/4634): \[java] JUnit4TestShouldUseTestAnnotation false positive with TestNG
|
||||
* java-codestyle
|
||||
|
||||
@@ -54,6 +54,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTLocalVariableDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTLoopStatement;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodCall;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTRecordComponent;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTResourceList;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTStatement;
|
||||
@@ -818,6 +819,23 @@ public final class DataflowPass {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpanInfo visit(ASTCompactConstructorDeclaration node, SpanInfo data) {
|
||||
super.visit(node, data);
|
||||
|
||||
// mark any write to a variable that is named like a record component as usage
|
||||
// record compact constructors do an implicit assignment at the end.
|
||||
for (ASTRecordComponent component : node.getEnclosingType().getRecordComponents()) {
|
||||
node.descendants(ASTAssignmentExpression.class)
|
||||
.descendants(ASTVariableAccess.class)
|
||||
.filter(v -> v.getAccessType() == AccessType.WRITE)
|
||||
.filter(v -> v.getName().equals(component.getVarId().getName()))
|
||||
.forEach(varAccess -> data.use(varAccess.getReferencedSym(), null));
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the variable has an implicit initializer, that is not
|
||||
* an expression. For instance, formal parameters have a value
|
||||
|
||||
+39
@@ -3543,4 +3543,43 @@ public class UnusedAssignmentUnusedVariableFP {
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>[java] UnusedAssignment false positive in record compact constructor #4603</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(new TestRecord(2).foo());
|
||||
}
|
||||
}
|
||||
|
||||
record TestRecord(int foo) {
|
||||
TestRecord {
|
||||
// src/Main.java:10: UnusedAssignment: The value assigned to variable 'foo' is never used
|
||||
foo = Math.min(foo, 1); // <!--- violation here
|
||||
// implicit this.foo = foo;
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>[java] Verify explicit canonical record constructor #4603</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(new TestRecord(2).foo());
|
||||
}
|
||||
}
|
||||
|
||||
record TestRecord(int foo) {
|
||||
TestRecord(int foo) {
|
||||
foo = Math.min(foo, 1);
|
||||
this.foo = foo; // explicit
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
</test-data>
|
||||
Reference in new issue
Block a user