Skip to content

Commit 6e98e56

Browse files
Closure Teamcopybara-github
authored andcommitted
Allow public fields with the @final JsDoc to be assigned once inside a constructor.
Originally, the `CheckAccessControls` pass did not support field assignment inside of a constructor and would throw the `JSC_FINAL_PROPERTY_OVERRIDEN` error. We now allow unassigned public fields with the `@final` JsDoc to be assigned once in the constructor. Allowing public fields to be recognized puts the team closer to flipping the flag to turn on public fields for google3. PiperOrigin-RevId: 553601386
1 parent 4a040b4 commit 6e98e56

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

src/com/google/javascript/jscomp/CheckAccessControls.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1368,7 +1368,7 @@ public final String getReadableTypeNameOrDefault() {
13681368
builder
13691369
.setName(sourceNode.getString())
13701370
.setReceiverType(typeRegistry.getNativeObjectType(JSTypeNative.UNKNOWN_TYPE))
1371-
.setMutation(true)
1371+
.setMutation(!(sourceNode.isMemberFieldDef() && !sourceNode.hasChildren()))
13721372
.setDeclaration(true)
13731373
// TODO(b/113704668): This definition is way too loose. It was used to prevent
13741374
// breakages during refactoring and should be tightened.

test/com/google/javascript/jscomp/CheckAccessControlsTest.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,68 @@ protected CompilerOptions getOptions() {
7979
return options;
8080
}
8181

82+
@Test
83+
public void testOverrideAllowed() {
84+
testSame(
85+
lines(
86+
"class Foo {", //
87+
" /** @final*/ x;",
88+
" constructor() {",
89+
" this.x = 5;",
90+
" }",
91+
"}"));
92+
}
93+
94+
@Test
95+
public void testMultipleFieldsOverrideAllowed() {
96+
testSame(
97+
lines(
98+
"class Bar {", //
99+
" /** @final*/ a;",
100+
" /** @final */ b;",
101+
" constructor() {",
102+
" this.a = 1;",
103+
" this.b = 2;",
104+
" }",
105+
"}"));
106+
}
107+
108+
@Test
109+
public void testFieldOverrideNotAllowed() {
110+
testError(
111+
lines(
112+
"class Bar {", //
113+
" /** @final*/ a;",
114+
" constructor() {",
115+
" this.a = 1;",
116+
" this.a = 2;",
117+
" }",
118+
"}"),
119+
FINAL_PROPERTY_OVERRIDDEN);
120+
121+
testError(
122+
lines(
123+
"class Bar {", //
124+
" /** @final*/ a = 5;",
125+
" constructor() {",
126+
" this.a = 1;",
127+
" }",
128+
"}"),
129+
FINAL_PROPERTY_OVERRIDDEN);
130+
}
131+
132+
@Test
133+
public void testThisAssignmentInConstructor() {
134+
testSame(
135+
lines(
136+
"class Foo {", //
137+
" constructor() {",
138+
" /** @const {number} */ this.x;",
139+
" this.x = 4;",
140+
" }",
141+
"}"));
142+
}
143+
82144
@Test
83145
public void testWarningInNormalClass() {
84146
test(

0 commit comments

Comments
 (0)