diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/VarChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/VarChecker.java index e37f2b62728..bf3458d6ad2 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/VarChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/VarChecker.java @@ -17,6 +17,7 @@ package com.google.errorprone.bugpatterns; import static com.google.errorprone.BugPattern.SeverityLevel.WARNING; +import static com.google.errorprone.util.ASTHelpers.getAnnotationWithSimpleName; import static com.google.errorprone.util.ASTHelpers.isConsideredFinal; import com.google.errorprone.BugPattern; @@ -32,6 +33,7 @@ import com.sun.source.tree.Tree; import com.sun.source.tree.VariableTree; import com.sun.source.util.TreePath; +import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Source; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.tree.JCTree; @@ -57,6 +59,14 @@ public Description matchVariable(VariableTree tree, VisitorState state) { return Description.NO_MATCH; } if (ASTHelpers.hasAnnotation(sym, Var.class, state)) { + if ((sym.flags() & Flags.EFFECTIVELY_FINAL) != 0) { + return buildDescription(tree) + .setMessage("@Var variable is never modified") + .addFix( + SuggestedFix.delete( + getAnnotationWithSimpleName(tree.getModifiers().getAnnotations(), "Var"))) + .build(); + } return Description.NO_MATCH; } if (!ASTHelpers.getGeneratedBy(state).isEmpty()) { diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/VarCheckerTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/VarCheckerTest.java index c6abe39d45d..2871abe99e1 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/VarCheckerTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/VarCheckerTest.java @@ -371,4 +371,22 @@ public void notSuppressedByUnrelatedSuppressWarningsAnnotation() { "}") .doTest(); } + + @Test + public void effectivelyFinal() { + compilationHelper + .addSourceLines( + "Test.java", + "import com.google.errorprone.annotations.Var;", + "class Test {", + " int f(", + " // BUG: Diagnostic contains: @Var variable is never modified", + " @Var int x,", + " @Var int y) {", + " y++;", + " return x + y;", + " }", + "}") + .doTest(); + } }