Skip to content

Commit

Permalink
Merge pull request #4839 from adangel/issue-4603-UnusedAssignment-rec…
Browse files Browse the repository at this point in the history
…ords

[java] UnusedAssignment false positive in record compact constructor
  • Loading branch information
jsotuyod committed Feb 29, 2024
2 parents 3b0dd7a + f0cbbdd commit f90d222
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 1 deletion.
4 changes: 3 additions & 1 deletion docs/pages/release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
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;
Expand Down Expand Up @@ -818,6 +819,23 @@ public SpanInfo visit(ASTVariableDeclarator node, SpanInfo data) {
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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>

0 comments on commit f90d222

Please sign in to comment.