Skip to content

Commit 01024df

Browse files
scheglovcommit-bot@chromium.org
authored andcommitted
Issue 43200. Report ASSIGNMENT_TO_FINAL when 'final late' has an initializer.
Bug: #43200 Change-Id: Ib79b4e8246f8f67661212c3d107de961d72132b4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/161471 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent ab16d79 commit 01024df

File tree

6 files changed

+87
-36
lines changed

6 files changed

+87
-36
lines changed

pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,9 +265,9 @@ class AssignmentExpressionResolver {
265265
CompileTimeErrorCode.ASSIGNMENT_TO_CONST,
266266
left,
267267
);
268-
} else if (variable.isFinal && !variable.isLate) {
268+
} else if (variable.setter == null) {
269269
if (variable is FieldElement) {
270-
if (variable.setter == null && variable.isSynthetic) {
270+
if (variable.isSynthetic) {
271271
_errorReporter.reportErrorForNode(
272272
CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_NO_SETTER,
273273
left,

pkg/analyzer/lib/src/generated/error_verifier.dart

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1647,38 +1647,52 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
16471647
highlightedNode = expression.propertyName;
16481648
}
16491649
// check if element is assignable
1650-
Element toVariable(Element element) {
1651-
return element is PropertyAccessorElement ? element.variable : element;
1652-
}
1653-
1654-
element = toVariable(element);
16551650
if (element is VariableElement) {
16561651
if (element.isConst) {
16571652
_errorReporter.reportErrorForNode(
1658-
CompileTimeErrorCode.ASSIGNMENT_TO_CONST, expression);
1659-
} else if (element.isFinal && !element.isLate) {
1660-
if (element is FieldElementImpl) {
1661-
if (element.setter == null && element.isSynthetic) {
1653+
CompileTimeErrorCode.ASSIGNMENT_TO_CONST,
1654+
expression,
1655+
);
1656+
} else if (element.isFinal) {
1657+
if (_isNonNullableByDefault) {
1658+
// Handled during resolution, with flow analysis.
1659+
} else {
1660+
_errorReporter.reportErrorForNode(
1661+
CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL,
1662+
expression,
1663+
[element.name],
1664+
);
1665+
}
1666+
}
1667+
} else if (element is PropertyAccessorElement && element.isGetter) {
1668+
var variable = element.variable;
1669+
if (variable.isConst) {
1670+
_errorReporter.reportErrorForNode(
1671+
CompileTimeErrorCode.ASSIGNMENT_TO_CONST,
1672+
expression,
1673+
);
1674+
} else if (variable.setter == null) {
1675+
if (variable is FieldElement) {
1676+
if (variable.isSynthetic) {
16621677
_errorReporter.reportErrorForNode(
1663-
CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_NO_SETTER,
1664-
highlightedNode,
1665-
[element.name, element.enclosingElement.displayName]);
1678+
CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_NO_SETTER,
1679+
highlightedNode,
1680+
[variable.name, variable.enclosingElement.displayName],
1681+
);
16661682
} else {
16671683
_errorReporter.reportErrorForNode(
1668-
CompileTimeErrorCode.ASSIGNMENT_TO_FINAL,
1669-
highlightedNode,
1670-
[element.name]);
1684+
CompileTimeErrorCode.ASSIGNMENT_TO_FINAL,
1685+
highlightedNode,
1686+
[variable.name],
1687+
);
16711688
}
16721689
return;
16731690
}
1674-
if (_isNonNullableByDefault && element is PromotableElement) {
1675-
// Handled during resolution, with flow analysis.
1676-
} else {
1677-
_errorReporter.reportErrorForNode(
1678-
CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL,
1679-
highlightedNode,
1680-
[element.name]);
1681-
}
1691+
_errorReporter.reportErrorForNode(
1692+
CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL,
1693+
highlightedNode,
1694+
[variable.name],
1695+
);
16821696
}
16831697
} else if (element is FunctionElement) {
16841698
_errorReporter.reportErrorForNode(

pkg/analyzer/test/src/diagnostics/assignment_to_final_local_test.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,15 @@ void f(int value) {
160160
}
161161

162162
test_topLevelVariable_late() async {
163-
await assertNoErrorsInCode('''
163+
await assertErrorsInCode('''
164164
late final int a;
165165
late final int b = 0;
166166
void f() {
167167
a = 1;
168168
b = 1;
169169
}
170-
''');
170+
''', [
171+
error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 62, 1),
172+
]);
171173
}
172174
}

pkg/analyzer/test/src/diagnostics/assignment_to_final_test.dart

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,23 @@ f() {
4646
@reflectiveTest
4747
class AssignmentToFinalWithNullSafetyTest extends AssignmentToFinalTest
4848
with WithNullSafetyMixin {
49-
test_field_late() async {
50-
await assertNoErrorsInCode('''
49+
test_field_late_propertyAccess() async {
50+
await assertErrorsInCode('''
51+
class A {
52+
late final int a;
53+
late final int b = 0;
54+
void m() {
55+
this.a = 1;
56+
this.b = 1;
57+
}
58+
}
59+
''', [
60+
error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 92, 1),
61+
]);
62+
}
63+
64+
test_field_late_simpleIdentifier() async {
65+
await assertErrorsInCode('''
5166
class A {
5267
late final int a;
5368
late final int b = 0;
@@ -56,11 +71,29 @@ class A {
5671
b = 1;
5772
}
5873
}
59-
''');
74+
''', [
75+
error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 82, 1),
76+
]);
6077
}
6178

62-
test_field_static_late() async {
63-
await assertNoErrorsInCode('''
79+
test_field_static_final_late_prefixedIdentifier() async {
80+
await assertErrorsInCode('''
81+
class A {
82+
static late final int a;
83+
static late final int b = 0;
84+
}
85+
86+
void f() {
87+
A.a = 1;
88+
A.b = 1;
89+
}
90+
''', [
91+
error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 97, 1),
92+
]);
93+
}
94+
95+
test_field_static_final_late_simpleIdentifier() async {
96+
await assertErrorsInCode('''
6497
class A {
6598
static late final int a;
6699
static late final int b = 0;
@@ -69,7 +102,9 @@ class A {
69102
b = 1;
70103
}
71104
}
72-
''');
105+
''', [
106+
error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL, 96, 1),
107+
]);
73108
}
74109

75110
test_set_abstract_field_final_invalid() async {

tests/language/extension_methods/static_extension_getter_setter_conflicts_test.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ void test1() {
109109

110110
c1a.m1 = 0;
111111
// ^^
112-
// [analyzer] COMPILE_TIME_ERROR.ASSIGNMENT_TO_FINAL_LOCAL
112+
// [analyzer] COMPILE_TIME_ERROR.ASSIGNMENT_TO_FINAL_NO_SETTER
113113
// [cfe] The setter 'm1' isn't defined for the class 'C1<int>'.
114114

115115
c1a.m2;
@@ -195,7 +195,7 @@ void test1() {
195195

196196
c1c.m1 = 0;
197197
// ^^
198-
// [analyzer] COMPILE_TIME_ERROR.ASSIGNMENT_TO_FINAL_LOCAL
198+
// [analyzer] COMPILE_TIME_ERROR.ASSIGNMENT_TO_FINAL_NO_SETTER
199199
// [cfe] The setter 'm1' isn't defined for the class 'C1<Object>'.
200200

201201
c1c.m2;

tests/language_2/extension_methods/static_extension_getter_setter_conflicts_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ void test1() {
109109

110110
c1a.m1 = 0;
111111
// ^^
112-
// [analyzer] COMPILE_TIME_ERROR.ASSIGNMENT_TO_FINAL_LOCAL
112+
// [analyzer] COMPILE_TIME_ERROR.ASSIGNMENT_TO_FINAL_NO_SETTER
113113
// [cfe] The setter 'm1' isn't defined for the class 'C1<int>'.
114114

115115
c1a.m2;

0 commit comments

Comments
 (0)