-
Notifications
You must be signed in to change notification settings - Fork 6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Test various exceptions to variables being considered definitely unas…
…signed. There are several scenarios in which the flow analysis implementation needs to be careful to mark variables as "not definitely unassigned", even though they are not definitely assigned. These scenarios are handled by the implementation but not yet properly spec'ed. Prior to updating the spec, I wanted to make sure we had adequate test cases. Change-Id: Id3f82279e0686f9cccfabd834396f05b8b28bcab Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/153825 Reviewed-by: Bob Nystrom <rnystrom@google.com> Commit-Queue: Paul Berry <paulberry@google.com>
- Loading branch information
1 parent
082a6e0
commit b91ff15
Showing
5 changed files
with
223 additions
and
0 deletions.
There are no files selected for viewing
34 changes: 34 additions & 0 deletions
34
tests/language/nnbd/flow_analysis/late_var_assigned_in_try_test.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(); | ||
} |
60 changes: 60 additions & 0 deletions
60
...anguage/nnbd/flow_analysis/late_var_used_before_assignment_in_local_function_ok_test.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(); | ||
} |
70 changes: 70 additions & 0 deletions
70
tests/language/nnbd/flow_analysis/late_var_used_before_assignment_in_loop_test.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(); | ||
} |
31 changes: 31 additions & 0 deletions
31
tests/language/nnbd/flow_analysis/late_var_used_before_assignment_in_switch_error_test.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} |
28 changes: 28 additions & 0 deletions
28
tests/language/nnbd/flow_analysis/late_var_used_before_assignment_in_switch_test.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} |