diff --git a/tests/language/nnbd/flow_analysis/late_var_assigned_in_try_test.dart b/tests/language/nnbd/flow_analysis/late_var_assigned_in_try_test.dart new file mode 100644 index 0000000000000..f0fca1a4c7ed7 --- /dev/null +++ b/tests/language/nnbd/flow_analysis/late_var_assigned_in_try_test.dart @@ -0,0 +1,34 @@ +// Copyright (c) 2020, 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. + +// This test verifies that when a late variable is assigned in a try block and +// read in a catch or finally block, that there is no compile-time error, +// because the assignment might happen prior to the exception occurring. + +// SharedOptions=--enable-experiment=non-nullable +import 'package:expect/expect.dart'; + +void tryCatch() { + late int x; + try { + x = 10; + throw 'foo'; + } catch (_) { + Expect.equals(x, 10); + } +} + +void tryFinally() { + late int x; + try { + x = 10; + } finally { + Expect.equals(x, 10); + } +} + +main() { + tryCatch(); + tryFinally(); +} diff --git a/tests/language/nnbd/flow_analysis/late_var_used_before_assignment_in_local_function_ok_test.dart b/tests/language/nnbd/flow_analysis/late_var_used_before_assignment_in_local_function_ok_test.dart new file mode 100644 index 0000000000000..aaf6a877f480e --- /dev/null +++ b/tests/language/nnbd/flow_analysis/late_var_used_before_assignment_in_local_function_ok_test.dart @@ -0,0 +1,60 @@ +// Copyright (c) 2020, 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. + +// This test verifies that when a late variable might be read prior to its first +// assignment, but the semantics of local functions allow for the possibility +// that the assignment might occur before the read, that there is no +// compile-time error. + +// SharedOptions=--enable-experiment=non-nullable +import 'package:expect/expect.dart'; + +// First scenario: the variable is written inside the function, and the read +// happens after the function is created. +void writeInFunction() { + late int x; + void f() { + x = 10; + } + + f(); + Expect.equals(x, 10); +} + +void writeInClosure() { + late int x; + var f = () { + x = 10; + }; + f(); + Expect.equals(x, 10); +} + +// Second scenario: the variable is written outside the function, and the read +// happens inside the function. +void readInFunction() { + late int x; + void f() { + Expect.equals(x, 10); + } + + x = 10; + f(); +} + +void readInClosure() { + late int x; + var f = () { + Expect.equals(x, 10); + }; + x = 10; + f(); +} + +main() { + writeInFunction(); + writeInClosure(); + readInFunction(); + readInClosure(); +} diff --git a/tests/language/nnbd/flow_analysis/late_var_used_before_assignment_in_loop_test.dart b/tests/language/nnbd/flow_analysis/late_var_used_before_assignment_in_loop_test.dart new file mode 100644 index 0000000000000..09eef1ce31e7e --- /dev/null +++ b/tests/language/nnbd/flow_analysis/late_var_used_before_assignment_in_loop_test.dart @@ -0,0 +1,70 @@ +// Copyright (c) 2020, 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. + +// This test verifies that when a late variable is read prior to its first +// assignment, but the read and the assignment occur within the body of a loop, +// that there is no compile-time error, because the assignment may happen in an +// earlier iteration than the read. + +// SharedOptions=--enable-experiment=non-nullable +import 'package:expect/expect.dart'; + +void forLoop() { + late int x; + for (int i = 0; i < 2; i++) { + if (i == 1) { + Expect.equals(x, 10); + } + if (i == 0) { + x = 10; + } + } +} + +void forEach() { + late int x; + for (bool b in [false, true]) { + if (b) { + Expect.equals(x, 10); + } + if (!b) { + x = 10; + } + } +} + +void whileLoop() { + late int x; + int i = 0; + while (i < 2) { + if (i == 1) { + Expect.equals(x, 10); + } + if (i == 0) { + x = 10; + } + i++; + } +} + +void doLoop() { + late int x; + int i = 0; + do { + if (i == 1) { + Expect.equals(x, 10); + } + if (i == 0) { + x = 10; + } + i++; + } while (i < 2); +} + +main() { + forLoop(); + forEach(); + whileLoop(); + doLoop(); +} diff --git a/tests/language/nnbd/flow_analysis/late_var_used_before_assignment_in_switch_error_test.dart b/tests/language/nnbd/flow_analysis/late_var_used_before_assignment_in_switch_error_test.dart new file mode 100644 index 0000000000000..59b5a20fa9bd2 --- /dev/null +++ b/tests/language/nnbd/flow_analysis/late_var_used_before_assignment_in_switch_error_test.dart @@ -0,0 +1,31 @@ +// Copyright (c) 2020, 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. + +// This test verifies that when a late variable is read prior to its first +// assignment, and the read occurs within the body of an unlabelled case block, +// and the assignment occurs elsewhere in the switch, that there is a +// compile-time error, because the variable is unassigned on all possible +// control flow paths to the read. + +// SharedOptions=--enable-experiment=non-nullable +import 'package:expect/expect.dart'; + +void switchBad(int value) { + late int x; + switch (value) { + case 0: + Expect.equals(x, 10); + // ^ + // [analyzer] COMPILE_TIME_ERROR.DEFINITELY_UNASSIGNED_LATE_LOCAL_VARIABLE + // [cfe] Non-nullable late variable 'x' without initializer is definitely unassigned. + break; + case 1: + x = 10; + break; + } +} + +main() { + switchBad(1); +} diff --git a/tests/language/nnbd/flow_analysis/late_var_used_before_assignment_in_switch_test.dart b/tests/language/nnbd/flow_analysis/late_var_used_before_assignment_in_switch_test.dart new file mode 100644 index 0000000000000..edb6b6ec4f846 --- /dev/null +++ b/tests/language/nnbd/flow_analysis/late_var_used_before_assignment_in_switch_test.dart @@ -0,0 +1,28 @@ +// Copyright (c) 2020, 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. + +// This test verifies that when a late variable is read prior to its first +// assignment, but the read occurs within the body of a labelled case block, and +// the assignment occurs somewhere in the switch, that there is no compile-time +// error, because the assignment may happen prior to a branch to the label. + +// SharedOptions=--enable-experiment=non-nullable +import 'package:expect/expect.dart'; + +void switchOk(int one) { + late int x; + switch (one) { + L: + case 0: + Expect.equals(x, 10); + break; + case 1: + x = 10; + continue L; + } +} + +main() { + switchOk(1); +}