Skip to content

Commit

Permalink
Test various exceptions to variables being considered definitely unas…
Browse files Browse the repository at this point in the history
…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
stereotype441 authored and commit-bot@chromium.org committed Jul 10, 2020
1 parent 082a6e0 commit b91ff15
Show file tree
Hide file tree
Showing 5 changed files with 223 additions and 0 deletions.
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();
}
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();
}
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();
}
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);
}
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);
}

0 comments on commit b91ff15

Please sign in to comment.