diff --git a/check_api/src/main/java/com/google/errorprone/matchers/CompileTimeConstantExpressionMatcher.java b/check_api/src/main/java/com/google/errorprone/matchers/CompileTimeConstantExpressionMatcher.java index 259bbecf162..f98abdac0fd 100644 --- a/check_api/src/main/java/com/google/errorprone/matchers/CompileTimeConstantExpressionMatcher.java +++ b/check_api/src/main/java/com/google/errorprone/matchers/CompileTimeConstantExpressionMatcher.java @@ -131,11 +131,12 @@ protected Boolean defaultAction(Tree node, Void unused) { Symbol.VarSymbol varSymbol = (Symbol.VarSymbol) getSymbol(node); Symbol owner = varSymbol.owner; ElementKind ownerKind = owner.getKind(); - // Check that the identifier is a formal method/constructor parameter or a class + // Check that the identifier is a formal method/constructor parameter, or a class/enum // field. if (ownerKind != ElementKind.METHOD && ownerKind != ElementKind.CONSTRUCTOR - && ownerKind != ElementKind.CLASS) { + && ownerKind != ElementKind.CLASS + && ownerKind != ElementKind.ENUM) { return false; } // Check that the symbol is final diff --git a/core/src/main/java/com/google/errorprone/bugpatterns/CompileTimeConstantChecker.java b/core/src/main/java/com/google/errorprone/bugpatterns/CompileTimeConstantChecker.java index f6aa7ad6ae8..c83e64c4c42 100644 --- a/core/src/main/java/com/google/errorprone/bugpatterns/CompileTimeConstantChecker.java +++ b/core/src/main/java/com/google/errorprone/bugpatterns/CompileTimeConstantChecker.java @@ -238,7 +238,8 @@ public Description matchAssignment(AssignmentTree node, VisitorState state) { if (assignedSymbol == null || assignedSymbol.owner == null) { return Description.NO_MATCH; } - if (assignedSymbol.owner.getKind() != ElementKind.CLASS) { + if (assignedSymbol.owner.getKind() != ElementKind.CLASS + && assignedSymbol.owner.getKind() != ElementKind.ENUM) { return Description.NO_MATCH; } if (!hasCompileTimeConstantAnnotation(state, assignedSymbol)) { diff --git a/core/src/test/java/com/google/errorprone/bugpatterns/CompileTimeConstantCheckerTest.java b/core/src/test/java/com/google/errorprone/bugpatterns/CompileTimeConstantCheckerTest.java index 6f27f96a9aa..44eac0ab581 100644 --- a/core/src/test/java/com/google/errorprone/bugpatterns/CompileTimeConstantCheckerTest.java +++ b/core/src/test/java/com/google/errorprone/bugpatterns/CompileTimeConstantCheckerTest.java @@ -570,6 +570,76 @@ public void noDiagnostic_whenInvokingMethodWithFinalField() { .doTest(); } + @Test + public void reportsDiagnostic_whenConstantEnumFieldDeclaredWithoutFinal() { + compilationHelper + .addSourceLines( + "Test.java", + "import com.google.errorprone.annotations.CompileTimeConstant;", + "public enum Test {", + " A(\"A\");", + " // BUG: Diagnostic contains: . Did you mean to make 's' final?", + " @CompileTimeConstant String s;", + " Test(@CompileTimeConstant String s) {", + " this.s = s;", + " }", + "}") + .doTest(); + } + + @Test + public void noDiagnostic_whenConstantEnumFieldDeclaredFinal() { + compilationHelper + .addSourceLines( + "Test.java", + "import com.google.errorprone.annotations.CompileTimeConstant;", + "public enum Test {", + " A(\"A\");", + " @CompileTimeConstant final String s;", + " Test(@CompileTimeConstant String s) {", + " this.s = s;", + " }", + "}") + .doTest(); + } + + @Test + public void reportsDiagnostic_whenInitialisingFinalEnumFieldWithNonConstant() { + compilationHelper + .addSourceLines( + "Test.java", + "import com.google.errorprone.annotations.CompileTimeConstant;", + "public enum Test {", + " A(\"A\");", + " @CompileTimeConstant final String s;", + " Test(String s) {", + " // BUG: Diagnostic contains: Non-compile-time constant expression", + " this.s = s;", + " }", + "}") + .doTest(); + } + + @Test + public void noDiagnostic_whenInvokingMethodWithFinalEnumField() { + compilationHelper + .addSourceLines( + "Test.java", + "import com.google.errorprone.annotations.CompileTimeConstant;", + "public enum Test {", + " A(\"A\");", + " @CompileTimeConstant final String s;", + " Test(@CompileTimeConstant String s) {", + " this.s = s;", + " }", + " void invokeCTCMethod() {", + " ctcMethod(s);", + " }", + " void ctcMethod(@CompileTimeConstant String s) {}", + "}") + .doTest(); + } + @Test public void nonConstantField_positive() { compilationHelper