- This brings in the flow test suite that contains a ton of JavaScript parsing edge cases - This creates snapshot tests using the pretty printer for all of them - If uncomment `RUN_AST_TESTS` line in `tests/run_specs.js`, it checks ast(pretty_print(x)) == ast(x). Right now, "178 failed, 197 passed, 375 of 377 total". So half of the tests are not passing, most of them are crashes and many of the rest are subtle issues.
269 lines
4.7 KiB
JavaScript
269 lines
4.7 KiB
JavaScript
/**
|
|
* test initialization tracking for vars
|
|
* note: for try/catch/finally, see tests/try/init.js
|
|
* @flow
|
|
*/
|
|
|
|
// deferred init on annotated vars is ok
|
|
function linear_deferred_init() {
|
|
var x:number;
|
|
x = 0;
|
|
var y:number = x;
|
|
}
|
|
|
|
// ...but use of var before init gives undefined
|
|
function linear_pre_init() {
|
|
var x:number;
|
|
var y:number = x; // error
|
|
}
|
|
|
|
// local use of annotated vars in an if is ok
|
|
function if_scoped_init(b) {
|
|
if (b) {
|
|
var x:number = 0;
|
|
var y:number = x;
|
|
}
|
|
}
|
|
|
|
// but not across if/else
|
|
function if_else_partial_init(b) {
|
|
if (b) {
|
|
var x:number = 0;
|
|
} else {
|
|
var y:number = x; // error
|
|
}
|
|
}
|
|
|
|
// use of var before if gives undefined
|
|
function if_pre_init(b) {
|
|
var y:number = x; // error
|
|
if (b) {
|
|
var x:number = 0;
|
|
}
|
|
}
|
|
|
|
// ...and after
|
|
function if_partial_post_init(b) {
|
|
if (b) {
|
|
var x:number = 0;
|
|
}
|
|
var y:number = x; // error
|
|
}
|
|
|
|
// ...unless both branches have initialized
|
|
function if_post_init(b) {
|
|
if (b) {
|
|
var x:number = 0;
|
|
} else {
|
|
var x:number = 1;
|
|
}
|
|
var y:number = x;
|
|
}
|
|
|
|
// use of var after partial init (non-exhaustive if) gives undefined
|
|
function if_partial_post_init(b) {
|
|
var x:number;
|
|
if (b) {
|
|
x = 0;
|
|
}
|
|
var y:number = x; // error, possibly uninitialized
|
|
}
|
|
|
|
// use of var after guaranteed init (exhaustive if) is ok
|
|
function if_post_init(b) {
|
|
var x:number;
|
|
if (b) {
|
|
x = 0;
|
|
} else {
|
|
x = 1;
|
|
}
|
|
var y:number = x;
|
|
}
|
|
|
|
// use of var after partial init (non-exhaustive switch) gives undefined
|
|
function switch_partial_post_init(i) {
|
|
var x:number;
|
|
switch (i) {
|
|
case 0:
|
|
x = 0;
|
|
break;
|
|
case 1:
|
|
x = 1;
|
|
break;
|
|
}
|
|
var y:number = x; // error, possibly uninitialized
|
|
}
|
|
|
|
// use of var after guaranteed init (exhaustive switch) is ok
|
|
function switch_post_init(i) {
|
|
var x:number;
|
|
switch (i) {
|
|
case 0:
|
|
x = 0;
|
|
break;
|
|
case 1:
|
|
x = 1;
|
|
break;
|
|
default:
|
|
x = 2;
|
|
}
|
|
var y:number = x; // no error, all cases covered
|
|
}
|
|
|
|
// local use of annotated var in switch is ok
|
|
function switch_scoped_init_1(i) {
|
|
switch (i) {
|
|
case 0:
|
|
var x:number = 0;
|
|
var y:number = x;
|
|
}
|
|
}
|
|
|
|
// ...but use of var before switch gives undefined
|
|
function switch_scoped_init_2(i) {
|
|
var y:number = x; // error
|
|
switch (i) {
|
|
case 0:
|
|
var x:number = 0;
|
|
}
|
|
}
|
|
|
|
// ...and after
|
|
function switch_scoped_init_3(i) {
|
|
switch (i) {
|
|
case 0:
|
|
var x:number = 0;
|
|
}
|
|
var y:number = x; // error
|
|
}
|
|
|
|
// ...and in a fallthrough case without initialization
|
|
function switch_scoped_init_4(i) {
|
|
switch (i) {
|
|
case 0:
|
|
var x:number = 0;
|
|
case 1:
|
|
var y:number = x; // error
|
|
}
|
|
}
|
|
|
|
// local use of annotated var in while is ok
|
|
function while_scoped_init(b) {
|
|
while (b) {
|
|
var x:number = 0;
|
|
var y:number = x;
|
|
}
|
|
}
|
|
|
|
// ...but use of var before while gives undefined
|
|
function while_pre_init(b) {
|
|
var y:number = x; // error
|
|
while (b) {
|
|
var x:number = 0;
|
|
}
|
|
}
|
|
|
|
// ...and after
|
|
function while_post_init(b) {
|
|
while (b) {
|
|
var x:number = 0;
|
|
}
|
|
var y:number = x; // error
|
|
}
|
|
|
|
// local use of annotated var in do-while is ok
|
|
function do_while_scoped_init(b) {
|
|
do {
|
|
var x:number = 0;
|
|
var y:number = x;
|
|
} while (b);
|
|
}
|
|
|
|
// ...but use before do-while gives undefined
|
|
function do_while_pre_init(b) {
|
|
var y:number = x; // error
|
|
do {
|
|
var x:number = 0;
|
|
} while (b);
|
|
}
|
|
|
|
// after is ok, because loop is guaranteed to run
|
|
function do_while_post_init(b) {
|
|
do {
|
|
var x:number = 0;
|
|
} while (b);
|
|
var y:number = x;
|
|
}
|
|
|
|
// local use of annotated var in for is ok
|
|
function for_scoped_init(b) {
|
|
for (;b;) {
|
|
var x:number = 0;
|
|
var y:number = x;
|
|
}
|
|
}
|
|
|
|
// ...but use before for gives undefined
|
|
function for_pre_init(b) {
|
|
var y:number = x; // error
|
|
for (;b;) {
|
|
var x:number = 0;
|
|
}
|
|
}
|
|
|
|
// ...and after
|
|
function for_post_init(b) {
|
|
for (;b;) {
|
|
var x:number = 0;
|
|
}
|
|
var y:number = x; // error
|
|
}
|
|
|
|
// local use of annotated var in for-in is ok
|
|
function for_in_scoped_init() {
|
|
for (var p in { a:1, b: 2 }) {
|
|
var x:number = 0;
|
|
var y:number = x;
|
|
}
|
|
}
|
|
|
|
// ...but use before while gives undefined
|
|
function for_in_pre_init() {
|
|
var y:number = x; // error
|
|
for (var p in { a:1, b: 2 }) {
|
|
var x:number = 0;
|
|
}
|
|
}
|
|
|
|
// ...and after
|
|
function for_in_post_init() {
|
|
for (var p in { a:1, b: 2 }) {
|
|
var x:number = 0;
|
|
}
|
|
var y:number = x; // error
|
|
}
|
|
|
|
// local use of annotated var in for-of is ok
|
|
function for_of_scoped_init() {
|
|
for (var x of [1, 2, 3]) {
|
|
var x:number = 0;
|
|
var y:number = x;
|
|
}
|
|
}
|
|
|
|
// ...but use before while gives undefined
|
|
function for_in_pre_init() {
|
|
var y:number = x; // error
|
|
for (var x of [1, 2, 3]) {
|
|
var x:number = 0;
|
|
}
|
|
}
|
|
|
|
// ...and after
|
|
function for_in_post_init() {
|
|
for (var x of [1, 2, 3]) {
|
|
var x:number = 0;
|
|
}
|
|
var y:number = x; // error
|
|
}
|