Rename the error code for not assigned potentially non-nullable local variable.
R=brianwilkerson@google.com, paulberry@google.com
Change-Id: Id377fc7693975137c72593fa76dd50df6ef1d5db
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/107189
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index f8b3c13..515584d 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -235,9 +235,9 @@
CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT,
CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR,
CompileTimeErrorCode.NON_SYNC_FACTORY,
+ CompileTimeErrorCode.NOT_ASSIGNED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS,
CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_TOP_LEVEL_VARIABLE,
- CompileTimeErrorCode.NOT_INITIALIZED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
CompileTimeErrorCode.NOT_ITERABLE_SPREAD,
CompileTimeErrorCode.NOT_MAP_SPREAD,
CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD,
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 791135a..d1312e3 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -2437,6 +2437,24 @@
"Factory bodies can't use 'async', 'async*', or 'sync*'.");
/**
+ * It is an error if a potentially non-nullable local variable which has no
+ * initializer expression and is not marked `late` is used before it is
+ * definitely assigned.
+ *
+ * Parameters:
+ * 0: the name of the variable that is invalid
+ */
+ static const CompileTimeErrorCode
+ NOT_ASSIGNED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE =
+ const CompileTimeErrorCode(
+ 'NOT_ASSIGNED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE',
+ "Non-nullable local variable '{0}' must be assigned before "
+ "it can be used.",
+ correction: "Try giving it an initializer expression, "
+ "or ensure that it is assigned on every execution path, "
+ "or mark it 'late'.");
+
+ /**
* 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m < h</i>
* or if <i>m > n</i>.
*
@@ -2467,25 +2485,6 @@
correction: "Try adding an initializer expression.");
/**
- * It is an error if a potentially non-nullable local variable which has no
- * initializer expression and is not marked `late` is used before it is
- * definitely assigned.
- *
- * TODO(scheglov) Update the code and the message when implement definite
- * assignment analysis.
- *
- * Parameters:
- * 0: the name of the variable that is invalid
- */
- static const CompileTimeErrorCode
- NOT_INITIALIZED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE =
- const CompileTimeErrorCode(
- 'NOT_INITIALIZED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE',
- "Non-nullable local variable '{0}' must be initialized.",
- correction:
- "Try giving it an initializer expression, or mark it 'late'.");
-
- /**
* No parameters.
*/
// #### Description
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 4bfcbba..880545a 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -1445,7 +1445,7 @@
@override
void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
_checkForFinalNotInitialized(node.variables);
- _checkForNotInitializedPotentiallyNonNullableLocalVariable(node.variables);
+ _checkForNotAssignedPotentiallyNonNullableLocalVariable(node.variables);
super.visitVariableDeclarationStatement(node);
}
@@ -3374,77 +3374,6 @@
}
}
- void _checkForNotInitializedPotentiallyNonNullableLocalVariable(
- VariableDeclarationList node,
- ) {
- // Const and final checked separately.
- if (node.isConst || node.isFinal) {
- return;
- }
-
- if (!_isNonNullable) {
- return;
- }
-
- if (node.isLate) {
- return;
- }
-
- if (node.type == null) {
- return;
- }
- var type = node.type.type;
-
- if (!_typeSystem.isPotentiallyNonNullable(type)) {
- return;
- }
-
- for (var variable in node.variables) {
- if (variable.initializer == null &&
- flowAnalysisResult.readBeforeWritten
- .contains(variable.declaredElement)) {
- _errorReporter.reportErrorForNode(
- CompileTimeErrorCode
- .NOT_INITIALIZED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
- variable.name,
- [variable.name.name],
- );
- }
- }
- }
-
- void _checkForNotInitializedNonNullableTopLevelVariable(
- VariableDeclarationList node,
- ) {
- // Const and final checked separately.
- if (node.isConst || node.isFinal) {
- return;
- }
-
- if (!_isNonNullable) {
- return;
- }
-
- if (node.type == null) {
- return;
- }
- var type = node.type.type;
-
- if (!_typeSystem.isPotentiallyNonNullable(type)) {
- return;
- }
-
- for (var variable in node.variables) {
- if (variable.initializer == null) {
- _errorReporter.reportErrorForNode(
- CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_TOP_LEVEL_VARIABLE,
- variable.name,
- [variable.name.name],
- );
- }
- }
- }
-
/**
* If there are no constructors in the given [members], verify that all
* final fields are initialized. Cases in which there is at least one
@@ -4750,6 +4679,77 @@
}
}
+ void _checkForNotAssignedPotentiallyNonNullableLocalVariable(
+ VariableDeclarationList node,
+ ) {
+ // Const and final checked separately.
+ if (node.isConst || node.isFinal) {
+ return;
+ }
+
+ if (!_isNonNullable) {
+ return;
+ }
+
+ if (node.isLate) {
+ return;
+ }
+
+ if (node.type == null) {
+ return;
+ }
+ var type = node.type.type;
+
+ if (!_typeSystem.isPotentiallyNonNullable(type)) {
+ return;
+ }
+
+ for (var variable in node.variables) {
+ if (variable.initializer == null &&
+ flowAnalysisResult.readBeforeWritten
+ .contains(variable.declaredElement)) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode
+ .NOT_ASSIGNED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
+ variable.name,
+ [variable.name.name],
+ );
+ }
+ }
+ }
+
+ void _checkForNotInitializedNonNullableTopLevelVariable(
+ VariableDeclarationList node,
+ ) {
+ // Const and final checked separately.
+ if (node.isConst || node.isFinal) {
+ return;
+ }
+
+ if (!_isNonNullable) {
+ return;
+ }
+
+ if (node.type == null) {
+ return;
+ }
+ var type = node.type.type;
+
+ if (!_typeSystem.isPotentiallyNonNullable(type)) {
+ return;
+ }
+
+ for (var variable in node.variables) {
+ if (variable.initializer == null) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_TOP_LEVEL_VARIABLE,
+ variable.name,
+ [variable.name.name],
+ );
+ }
+ }
+ }
+
/**
* Check for illegal derefences of nullables, ie, "unchecked" usages of
* nullable values. Note that *any* usage of a null value is an "unchecked"
diff --git a/pkg/analyzer/test/src/diagnostics/not_initialized_potentially_non_nullable_local_variable_test.dart b/pkg/analyzer/test/src/diagnostics/not_assigned_potentially_non_nullable_local_variable_test.dart
similarity index 92%
rename from pkg/analyzer/test/src/diagnostics/not_initialized_potentially_non_nullable_local_variable_test.dart
rename to pkg/analyzer/test/src/diagnostics/not_assigned_potentially_non_nullable_local_variable_test.dart
index 5a63b51..b824db2 100644
--- a/pkg/analyzer/test/src/diagnostics/not_initialized_potentially_non_nullable_local_variable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/not_assigned_potentially_non_nullable_local_variable_test.dart
@@ -46,7 +46,7 @@
''', [
error(
CompileTimeErrorCode
- .NOT_INITIALIZED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
+ .NOT_ASSIGNED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
23,
1),
]);
@@ -109,7 +109,7 @@
''', [
error(
CompileTimeErrorCode
- .NOT_INITIALIZED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
+ .NOT_ASSIGNED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
12,
1),
]);
@@ -124,7 +124,7 @@
''', [
error(
CompileTimeErrorCode
- .NOT_INITIALIZED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
+ .NOT_ASSIGNED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
13,
1),
]);
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 61643d4..bfd21cf 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -96,10 +96,10 @@
import 'non_constant_spread_expression_from_deferred_library_test.dart'
as non_constant_spread_expression_from_deferred_library;
import 'non_null_opt_out_test.dart' as non_null_opt_out;
+import 'not_assigned_potentially_non_nullable_local_variable_test.dart'
+ as not_assigned_potentially_non_nullable_local_variable;
import 'not_initialized_non_nullable_top_level_variable_test.dart'
as not_initialized_non_nullable_top_level_variable;
-import 'not_initialized_potentially_non_nullable_local_variable_test.dart'
- as not_initialized_potentially_non_nullable_local_variable;
import 'not_iterable_spread_test.dart' as not_iterable_spread;
import 'not_map_spread_test.dart' as not_map_spread;
import 'not_null_aware_null_spread_test.dart' as not_null_aware_null_spread;
@@ -239,8 +239,8 @@
non_constant_set_element_from_deferred_library.main();
non_constant_spread_expression_from_deferred_library.main();
non_null_opt_out.main();
+ not_assigned_potentially_non_nullable_local_variable.main();
not_initialized_non_nullable_top_level_variable.main();
- not_initialized_potentially_non_nullable_local_variable.main();
not_iterable_spread.main();
not_map_spread.main();
not_null_aware_null_spread.main();
diff --git a/tests/language_2/nnbd/static_errors/not_assigned_local_initializer_test.dart b/tests/language_2/nnbd/static_errors/not_assigned_local_initializer_test.dart
new file mode 100644
index 0000000..ba9f896
--- /dev/null
+++ b/tests/language_2/nnbd/static_errors/not_assigned_local_initializer_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// It is an error if a potentially non-nullable local variable which has no
+// initializer expression and is not marked `late` is used before it is
+// definitely assigned.
+
+// This test check cases when the variable is only initialized (or not)
+// at its declaration, and there are no other assignments.
+
+void main() {
+ int v; v; //# 01: compile-time error
+ int v; //# 02: ok
+ int v = 0; v; //# 03: ok
+ late int v; v; //# 04: ok
+ late int v = 0; v; //# 05: ok
+ int? v; v; //# 06: ok
+ int? v = 0; v; //# 07: ok
+
+}
+
+f<T>(T a) {
+ T v; v; //# 08: compile-time error
+ T v; //# 09: ok
+ T v = a; v; //# 10: ok
+ late T v; v; //# 11: ok
+ late T v = a; v; //# 12: ok
+ T? v; v; //# 13: ok
+ T? v = a; v; //# 14: ok
+}
diff --git a/tests/language_2/nnbd/static_errors/not_initialized_potentially_non_nullable_local_test.dart b/tests/language_2/nnbd/static_errors/not_initialized_potentially_non_nullable_local_test.dart
deleted file mode 100644
index 45fc654..0000000
--- a/tests/language_2/nnbd/static_errors/not_initialized_potentially_non_nullable_local_test.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// SharedOptions=--enable-experiment=non-nullable
-
-// It is an error if a potentially non-nullable local variable which has no
-// initializer expression and is not marked `late` is used before it is
-// definitely assigned.
-// TODO(scheglov) Update once we implement definite assignment analysis.
-
-void main() {
- int v; v; //# 01: compile-time error
- int v; //# 02: ok
- int v = 0; //# 03: ok
- late int v; //# 04: ok
- late int v = 0; //# 05: ok
- int? v; //# 06: ok
- int? v = 0; //# 07: ok
-
-}
-
-f<T>(T a) {
- T v; v; //# 08: compile-time error
- T v = a; //# 09: ok
- late T v; //# 10: ok
- late T v = a; //# 11: ok
- T? v; //# 12: ok
- T? v = a; //# 13: ok
-}