Skip to content

Commit be4e826

Browse files
java-team-github-botError Prone Team
authored andcommitted
Support @CompileTimeConstant for enum fields.
The support for *class* fields was introduced in unknown commit. This CL merely extends it to enum fields, considering the similarity between them. There is also a feature request b/149290598 filed a few years back. Specifically, this CL aims to support the following use case (taken from b/149290598): ``` public class Example { public enum ExampleEnum { A("a"), B("b"); @CompileTimeConstant final String s; ExampleEnum(@CompileTimeConstant final String s) { this.s = s; } void invokeCtcMethod() { ctcMethod(s); } private void ctcMethod(@CompileTimeConstant String string) {} } } ``` PiperOrigin-RevId: 529230341
1 parent c76f797 commit be4e826

File tree

3 files changed

+75
-3
lines changed

3 files changed

+75
-3
lines changed

check_api/src/main/java/com/google/errorprone/matchers/CompileTimeConstantExpressionMatcher.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,12 @@ protected Boolean defaultAction(Tree node, Void unused) {
131131
Symbol.VarSymbol varSymbol = (Symbol.VarSymbol) getSymbol(node);
132132
Symbol owner = varSymbol.owner;
133133
ElementKind ownerKind = owner.getKind();
134-
// Check that the identifier is a formal method/constructor parameter or a class
134+
// Check that the identifier is a formal method/constructor parameter, or a class/enum
135135
// field.
136136
if (ownerKind != ElementKind.METHOD
137137
&& ownerKind != ElementKind.CONSTRUCTOR
138-
&& ownerKind != ElementKind.CLASS) {
138+
&& ownerKind != ElementKind.CLASS
139+
&& ownerKind != ElementKind.ENUM) {
139140
return false;
140141
}
141142
// Check that the symbol is final

core/src/main/java/com/google/errorprone/bugpatterns/CompileTimeConstantChecker.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,8 @@ public Description matchAssignment(AssignmentTree node, VisitorState state) {
238238
if (assignedSymbol == null || assignedSymbol.owner == null) {
239239
return Description.NO_MATCH;
240240
}
241-
if (assignedSymbol.owner.getKind() != ElementKind.CLASS) {
241+
if (assignedSymbol.owner.getKind() != ElementKind.CLASS
242+
&& assignedSymbol.owner.getKind() != ElementKind.ENUM) {
242243
return Description.NO_MATCH;
243244
}
244245
if (!hasCompileTimeConstantAnnotation(state, assignedSymbol)) {

core/src/test/java/com/google/errorprone/bugpatterns/CompileTimeConstantCheckerTest.java

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,76 @@ public void noDiagnostic_whenInvokingMethodWithFinalField() {
570570
.doTest();
571571
}
572572

573+
@Test
574+
public void reportsDiagnostic_whenConstantEnumFieldDeclaredWithoutFinal() {
575+
compilationHelper
576+
.addSourceLines(
577+
"Test.java",
578+
"import com.google.errorprone.annotations.CompileTimeConstant;",
579+
"public enum Test {",
580+
" A(\"A\");",
581+
" // BUG: Diagnostic contains: . Did you mean to make 's' final?",
582+
" @CompileTimeConstant String s;",
583+
" Test(@CompileTimeConstant String s) {",
584+
" this.s = s;",
585+
" }",
586+
"}")
587+
.doTest();
588+
}
589+
590+
@Test
591+
public void noDiagnostic_whenConstantEnumFieldDeclaredFinal() {
592+
compilationHelper
593+
.addSourceLines(
594+
"Test.java",
595+
"import com.google.errorprone.annotations.CompileTimeConstant;",
596+
"public enum Test {",
597+
" A(\"A\");",
598+
" @CompileTimeConstant final String s;",
599+
" Test(@CompileTimeConstant String s) {",
600+
" this.s = s;",
601+
" }",
602+
"}")
603+
.doTest();
604+
}
605+
606+
@Test
607+
public void reportsDiagnostic_whenInitialisingFinalEnumFieldWithNonConstant() {
608+
compilationHelper
609+
.addSourceLines(
610+
"Test.java",
611+
"import com.google.errorprone.annotations.CompileTimeConstant;",
612+
"public enum Test {",
613+
" A(\"A\");",
614+
" @CompileTimeConstant final String s;",
615+
" Test(String s) {",
616+
" // BUG: Diagnostic contains: Non-compile-time constant expression",
617+
" this.s = s;",
618+
" }",
619+
"}")
620+
.doTest();
621+
}
622+
623+
@Test
624+
public void noDiagnostic_whenInvokingMethodWithFinalEnumField() {
625+
compilationHelper
626+
.addSourceLines(
627+
"Test.java",
628+
"import com.google.errorprone.annotations.CompileTimeConstant;",
629+
"public enum Test {",
630+
" A(\"A\");",
631+
" @CompileTimeConstant final String s;",
632+
" Test(@CompileTimeConstant String s) {",
633+
" this.s = s;",
634+
" }",
635+
" void invokeCTCMethod() {",
636+
" ctcMethod(s);",
637+
" }",
638+
" void ctcMethod(@CompileTimeConstant String s) {}",
639+
"}")
640+
.doTest();
641+
}
642+
573643
@Test
574644
public void nonConstantField_positive() {
575645
compilationHelper

0 commit comments

Comments
 (0)