prettier/tests/flow/init/let.js

158 lines
3.1 KiB
JavaScript

/**
* test initialization tracking for lets
* @flow
*/
// deferred init on annotated lets is ok
function linear_deferred_init() {
let x:number;
x = 0;
let y:number = x;
}
// use of let before init gives undefined
function linear_pre_init() {
let x:number;
let y:?number = x; // ok
let z:number = x; // error
x = 0;
let w:number = x; // ok
}
// self-references in let bindings are not ok
function self_init() {
let x = x; // 'x' not initialized!
}
// use of let after partial init (non-exhaustive if) gives undefined
function if_partial_post_init(b) {
let x:number;
if (b) {
x = 0;
}
var y:number = x; // error, possibly uninitialized
}
// use of let after guaranteed init (exhaustive if) is ok
function if_post_init(b) {
let x:number;
if (b) {
x = 0;
} else {
x = 1;
}
var y:number = x;
}
// use of let after partial init (non-exhaustive switch) gives undefined
function switch_partial_post_init(i) {
let x:number;
switch (i) {
case 0:
x = 0;
break;
case 1:
x = 1;
break;
}
var y:number = x; // error, possibly uninitialized
}
// use of let after guaranteed init (exhaustive switch) is ok
function switch_post_init(i) {
let 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
}
// use in a switch after a skipped decl is an error
function switch_scoped_init_2(i) {
switch (i) {
case 0:
let x:number;
case 1:
let y:number = x; // error, skipped declaration
}
}
// while leaves it possibly uninitialized
function while_post_init(b) {
let x:number;
while (b) {
x = 0;
}
var y:number = x; // error
}
// do-while is ok, because loop is guaranteed to run at least once
function do_while_post_init(b) {
let x:number;
do {
x = 0;
} while (b);
var y:number = x; // ok
}
// for-in leaves it possibly uninitialized
function for_in_post_init() {
var x:number;
for (var p in {}) {
x = 0;
}
var y:number = x; // error
}
// for-of leaves it possibly uninitialized
function for_of_post_init() {
var x:number;
for (var x of []) {
x = 0;
}
var y:number = x; // error
}
// use of let after guaranteed init (exhaustive switch + throw) is ok
function switch_post_init2(i): number {
let bar;
switch (i) {
case 1:
bar = 3;
break;
default:
throw new Error('Invalid state');
}
return bar; // ok, definitely initialized
}
// use of let after guaranteed init (exhaustive switch + throw) is ok
function switch_post_init2(i): number {
let bar;
switch (i) {
case 1:
bar = 3;
break;
default:
throw new Error('Invalid state');
}
return bar; // ok, definitely initialized
}
// reference of a let-binding is permitted in a sub-closure within the init expr
function sub_closure_init_reference() {
let x = function() { return x; };
const y = function() { return y; };
// var-bindings can reference each other cyclically since they do not incur a
// TDZ (...even though this is weird...)
var z = z;
}