google / google/error-prone

Var false positive for record constructor modifications

Open
#4,936 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
7.2k
Forks
820
Avg merge
5h 9m
Merged PRs (30d)
50

Description

When a record's constructor body performs the assignment then the `Var` pattern emits a warning. If the advice is followed then the `IncompatibleModifiers` its produced. Here is a specific example of a refactoring which while unnecessary was simply more concise.

```java
public final class CombinedCsvReport implements Runnable {
private final ImmutableSortedMap inputFiles;
private final Path outputFile;
private final String metric;

public CombinedCsvReport(ImmutableMap inputFiles, String metric, Path outputFile) {
this.inputFiles = ImmutableSortedMap.copyOf(inputFiles);
this.outputFile = requireNonNull(outputFile);
this.metric = metric.replace('_', ' ');
}
```

The record avoids some of the boilerplate,
```java
public record CombinedCsvReport(ImmutableMap inputFiles,
String metric, Path outputFile) implements Runnable {

public CombinedCsvReport {
inputFiles = ImmutableSortedMap.copyOf(inputFiles);
metric = metric.replace('_', ' ');
requireNonNull(outputFile);
}
```

However the Var bug pattern thinks the field is modified rather than the argument.
```console
+ ./gradlew forbiddenApis -DforbiddenApis pmdJavaPoet pmdMain pmdCodeGen pmdJmh pmdTest -Dpmd spotbugsJavaPoet spotbugsMain spotbugsCodeGen spotbugsJmh spotbugsTest -Dspotbugs -q --no-build-cache
/Users/ben/projects/caffeine/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/report/csv/CombinedCsvReport.java:41: warning: [Var] Non-constant variable missing @Var annotation
public record CombinedCsvReport(ImmutableMap inputFiles,
^
(see https://errorprone.info/bugpattern/Var)
Did you mean 'public record CombinedCsvReport(@Var ImmutableMap inputFiles,'?
/Users/ben/projects/caffeine/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/report/csv/CombinedCsvReport.java:42: warning: [Var] Non-constant variable missing @Var annotation
String metric, Path outputFile) implements Runnable {
^
(see https://errorprone.info/bugpattern/Var)
Did you mean '@Var String metric, Path outputFile) implements Runnable {'?
```

When `@Var` is added then `IncompatibleModifiers` complains because the fields are final.
```console
+ ./gradlew forbiddenApis -DforbiddenApis pmdJavaPoet pmdMain pmdCodeGen pmdJmh pmdTest -Dpmd spotbugsJavaPoet spotbugsMain spotbugsCodeGen spotbugsJmh spotbugsTest -Dspotbugs -q
/Users/ben/projects/caffeine/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/report/csv/CombinedCsvReport.java:42: error: [IncompatibleModifiers] The annotation '@Var' has specified that it should not be used together with the following modifiers: [final]
public record CombinedCsvReport(@Var ImmutableMap inputFiles,
^
/Users/ben/projects/caffeine/simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/report/csv/CombinedCsvReport.java:43: error: [IncompatibleModifiers] The annotation '@Var' has specified that it should not be used together with the following modifiers: [final]
@Var String metric, Path outputFile) implements Runnable {
^
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.