Skip to content

Commit 09bc0cc

Browse files
scheglovcommit-bot@chromium.org
authored andcommitted
Issue 38734. Don't report IMPLICIT_THIS_REFERENCE_IN_INITIALIZER for late fields.
Bug: #38734 Change-Id: If942d831cf4c64c873026cb2010406656d20565b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/123688 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
1 parent 60c34ac commit 09bc0cc

File tree

2 files changed

+91
-25
lines changed

2 files changed

+91
-25
lines changed

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

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -140,15 +140,9 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
140140

141141
/**
142142
* A flag indicating whether the visitor is currently within an instance
143-
* variable declaration.
143+
* variable declaration, which is not `late`.
144144
*/
145-
bool _isInInstanceVariableDeclaration = false;
146-
147-
/**
148-
* A flag indicating whether the visitor is currently within an instance
149-
* variable initializer.
150-
*/
151-
bool _isInInstanceVariableInitializer = false;
145+
bool _isInInstanceNotLateVariableDeclaration = false;
152146

153147
/**
154148
* A flag indicating whether the visitor is currently within a constructor
@@ -320,8 +314,6 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
320314
_isEnclosingConstructorConst = false;
321315
_isInCatchClause = false;
322316
_isInStaticVariableDeclaration = false;
323-
_isInInstanceVariableDeclaration = false;
324-
_isInInstanceVariableInitializer = false;
325317
_isInConstructorInitializer = false;
326318
_isInStaticMethod = false;
327319
_boolType = _typeProvider.boolType;
@@ -724,21 +716,22 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
724716

725717
@override
726718
void visitFieldDeclaration(FieldDeclaration node) {
719+
var fields = node.fields;
727720
_isInStaticVariableDeclaration = node.isStatic;
728-
_isInInstanceVariableDeclaration = !_isInStaticVariableDeclaration;
729-
if (_isInInstanceVariableDeclaration) {
730-
VariableDeclarationList variables = node.fields;
731-
if (variables.isConst) {
721+
_isInInstanceNotLateVariableDeclaration =
722+
!node.isStatic && !node.fields.isLate;
723+
if (!_isInStaticVariableDeclaration) {
724+
if (fields.isConst) {
732725
_errorReporter.reportErrorForToken(
733-
CompileTimeErrorCode.CONST_INSTANCE_FIELD, variables.keyword);
726+
CompileTimeErrorCode.CONST_INSTANCE_FIELD, fields.keyword);
734727
}
735728
}
736729
try {
737730
_checkForNotInitializedNonNullableStaticField(node);
738731
super.visitFieldDeclaration(node);
739732
} finally {
740733
_isInStaticVariableDeclaration = false;
741-
_isInInstanceVariableDeclaration = false;
734+
_isInInstanceNotLateVariableDeclaration = false;
742735
}
743736
}
744737

@@ -1375,14 +1368,11 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
13751368
// visit initializer
13761369
String name = nameNode.name;
13771370
_namesForReferenceToDeclaredVariableInInitializer.add(name);
1378-
bool wasInInstanceVariableInitializer = _isInInstanceVariableInitializer;
1379-
_isInInstanceVariableInitializer = _isInInstanceVariableDeclaration;
13801371
try {
13811372
if (initializerNode != null) {
13821373
initializerNode.accept(this);
13831374
}
13841375
} finally {
1385-
_isInInstanceVariableInitializer = wasInInstanceVariableInitializer;
13861376
_namesForReferenceToDeclaredVariableInInitializer.remove(name);
13871377
}
13881378
// declare the variable
@@ -3233,10 +3223,13 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
32333223
*/
32343224
void _checkForImplicitThisReferenceInInitializer(
32353225
SimpleIdentifier identifier) {
3226+
if (_isInComment) {
3227+
return;
3228+
}
32363229
if (!_isInConstructorInitializer &&
32373230
!_isInStaticMethod &&
32383231
!_isInFactory &&
3239-
!_isInInstanceVariableInitializer &&
3232+
!_isInInstanceNotLateVariableDeclaration &&
32403233
!_isInStaticVariableDeclaration) {
32413234
return;
32423235
}
@@ -3255,12 +3248,8 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
32553248
if (enclosingElement is! ClassElement) {
32563249
return;
32573250
}
3258-
// comment
3259-
AstNode parent = identifier.parent;
3260-
if (parent is CommentReference) {
3261-
return;
3262-
}
32633251
// qualified method invocation
3252+
AstNode parent = identifier.parent;
32643253
if (parent is MethodInvocation) {
32653254
if (identical(parent.methodName, identifier) &&
32663255
parent.realTarget != null) {

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

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,42 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
import 'package:analyzer/dart/analysis/features.dart';
56
import 'package:analyzer/src/error/codes.dart';
7+
import 'package:analyzer/src/generated/engine.dart';
68
import 'package:test_reflective_loader/test_reflective_loader.dart';
79

810
import '../dart/resolution/driver_resolution.dart';
911

1012
main() {
1113
defineReflectiveSuite(() {
1214
defineReflectiveTests(ImplicitThisReferenceInInitializerTest);
15+
defineReflectiveTests(ImplicitThisReferenceInInitializerWithNnbdTest);
1316
});
1417
}
1518

1619
@reflectiveTest
1720
class ImplicitThisReferenceInInitializerTest extends DriverResolutionTest {
21+
test_class_field_commentReference_prefixedIdentifier() async {
22+
await assertNoErrorsInCode(r'''
23+
class A {
24+
int a = 0;
25+
/// foo [a.isEven] bar
26+
int x = 1;
27+
}
28+
''');
29+
}
30+
31+
test_class_field_commentReference_simpleIdentifier() async {
32+
await assertNoErrorsInCode(r'''
33+
class A {
34+
int a = 0;
35+
/// foo [a] bar
36+
int x = 1;
37+
}
38+
''');
39+
}
40+
1841
test_constructorName() async {
1942
await assertNoErrorsInCode(r'''
2043
class A {
@@ -227,3 +250,57 @@ class A<T> {
227250
''');
228251
}
229252
}
253+
254+
@reflectiveTest
255+
class ImplicitThisReferenceInInitializerWithNnbdTest
256+
extends ImplicitThisReferenceInInitializerTest {
257+
@override
258+
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
259+
..contextFeatures = FeatureSet.forTesting(
260+
sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]);
261+
262+
test_class_field_late_invokeInstanceMethod() async {
263+
await assertNoErrorsInCode(r'''
264+
class A {
265+
late int x = foo();
266+
int foo() => 0;
267+
}
268+
''');
269+
}
270+
271+
test_class_field_late_invokeStaticMethod() async {
272+
await assertNoErrorsInCode(r'''
273+
class A {
274+
late int x = foo();
275+
static int foo() => 0;
276+
}
277+
''');
278+
}
279+
280+
test_class_field_late_readInstanceField() async {
281+
await assertNoErrorsInCode(r'''
282+
class A {
283+
int a = 0;
284+
late int x = a;
285+
}
286+
''');
287+
}
288+
289+
test_class_field_late_readStaticField() async {
290+
await assertNoErrorsInCode(r'''
291+
class A {
292+
static int a = 0;
293+
late int x = a;
294+
}
295+
''');
296+
}
297+
298+
test_mixin_field_late_readInstanceField() async {
299+
await assertNoErrorsInCode(r'''
300+
mixin M {
301+
int a = 0;
302+
late int x = a;
303+
}
304+
''');
305+
}
306+
}

0 commit comments

Comments
 (0)