I find it weird to put `{}` together. So I figured I would change it to have an empty line and ask for feedback :)

Beware: most of the test cases are not representative of real code, you almost never define blocks with no content in practice.
578 lines
8.9 KiB
Plaintext
578 lines
8.9 KiB
Plaintext
exports[`test abnormals.js 1`] = `
|
|
"/* @flow */
|
|
|
|
/* This test documents an issue we used to have with merging the environment of
|
|
* the try block and the catch block. The error variable, when inspected and in
|
|
* the presence of an abnormal, would sometimes kind of leak. It would hit an
|
|
* abnormal. It was weird.
|
|
*/
|
|
function foo() {
|
|
try {
|
|
} catch(error) {
|
|
if (error.foo === 4) {
|
|
throw error;
|
|
}
|
|
}
|
|
}
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
/* @flow */
|
|
|
|
/* This test documents an issue we used to have with merging the environment of
|
|
* the try block and the catch block. The error variable, when inspected and in
|
|
* the presence of an abnormal, would sometimes kind of leak. It would hit an
|
|
* abnormal. It was weird.
|
|
*/
|
|
function foo() {
|
|
try {
|
|
} catch (error) {
|
|
if (error.foo === 4) {
|
|
throw error;
|
|
}
|
|
}
|
|
}
|
|
"
|
|
`;
|
|
|
|
exports[`test init.js 1`] = `
|
|
"/***
|
|
* test initialization tracking of hoisted stuff
|
|
* @flow
|
|
*/
|
|
|
|
// for illustrative purposes only - Flow considers a throw possible
|
|
// anywhere within a block
|
|
function might_throw() {}
|
|
|
|
// local use of annotated var within try is ok
|
|
function f() {
|
|
try {
|
|
var x:number = 0;
|
|
var y:number = x;
|
|
} catch (e) {
|
|
}
|
|
}
|
|
|
|
// and within catch
|
|
function f() {
|
|
try {
|
|
} catch (e) {
|
|
var x:number = 0;
|
|
var y:number = x;
|
|
}
|
|
}
|
|
|
|
// but not across try/catch
|
|
function f() {
|
|
try {
|
|
might_throw();
|
|
var x:number = 0;
|
|
} catch (e) {
|
|
var y:number = x; // error
|
|
}
|
|
}
|
|
|
|
// or try/finally
|
|
function f() {
|
|
try {
|
|
might_throw();
|
|
var x:number = 0;
|
|
} finally {
|
|
var y:number = x; // error
|
|
}
|
|
}
|
|
|
|
// or catch/finally
|
|
function f() {
|
|
try {
|
|
} catch (e) {
|
|
var x:number = 0;
|
|
} finally {
|
|
var y:number = x; // error
|
|
}
|
|
}
|
|
|
|
// or try/catch/finally if init doesn\'t dominate
|
|
function f() {
|
|
try {
|
|
var x:number = 0;
|
|
} catch (e) {
|
|
might_throw();
|
|
var x:number = 0;
|
|
} finally {
|
|
var y:number = x; // error
|
|
}
|
|
}
|
|
|
|
// post-use ok because init dominates here
|
|
function f() {
|
|
try {
|
|
var x:number = 0;
|
|
} catch (e) {
|
|
might_throw(); // ...but if so, suffix is not reached
|
|
var x:number = 0;
|
|
}
|
|
var y:number = x;
|
|
}
|
|
|
|
// and here
|
|
function f() {
|
|
try {
|
|
} catch (e) {
|
|
} finally {
|
|
might_throw(); // ...but if so, suffix is not reached
|
|
var x:number = 0;
|
|
}
|
|
var y:number = x;
|
|
}
|
|
|
|
// and here
|
|
function f() {
|
|
try {
|
|
var x:number;
|
|
} catch (e) {
|
|
} finally {
|
|
might_throw(); // ...but if so, suffix is not reached
|
|
x = 0;
|
|
}
|
|
var y:number = x;
|
|
}
|
|
|
|
// and here, thank you JS for the wonder that is hoisting
|
|
function f() {
|
|
try {
|
|
} catch (e) {
|
|
var x:number;
|
|
} finally {
|
|
might_throw(); // ...but if so, suffix is not reached
|
|
x = 0;
|
|
}
|
|
var y:number = x;
|
|
}
|
|
|
|
// error if used prior to init
|
|
function f() {
|
|
var y:number = x; // error
|
|
try {
|
|
var x:number = 0;
|
|
} catch (e) {
|
|
}
|
|
}
|
|
|
|
// another non-dominated post
|
|
function f() {
|
|
try {
|
|
var x:number = 0;
|
|
} catch (e) {
|
|
}
|
|
var y:number = x; // error
|
|
}
|
|
|
|
// ditto
|
|
function f() {
|
|
try {
|
|
} catch (e) {
|
|
var x:number = 0;
|
|
}
|
|
var y:number = x; // error
|
|
}
|
|
|
|
// ditto
|
|
function f(b) {
|
|
try {
|
|
var x:number;
|
|
if (b) {
|
|
throw new Error();
|
|
}
|
|
x = 0;
|
|
} catch (e) {
|
|
}
|
|
var y:number = x; // error
|
|
}
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
/***
|
|
* test initialization tracking of hoisted stuff
|
|
* @flow
|
|
*/
|
|
|
|
// for illustrative purposes only - Flow considers a throw possible
|
|
// anywhere within a block
|
|
function might_throw() {
|
|
}
|
|
|
|
// local use of annotated var within try is ok
|
|
function f() {
|
|
try {
|
|
var x: number = 0;
|
|
var y: number = x;
|
|
} catch (e) {
|
|
}
|
|
}
|
|
|
|
// and within catch
|
|
function f() {
|
|
try {
|
|
} catch (e) {
|
|
var x: number = 0;
|
|
var y: number = x;
|
|
}
|
|
}
|
|
|
|
// but not across try/catch
|
|
function f() {
|
|
try {
|
|
might_throw();
|
|
var x: number = 0;
|
|
} catch (e) {
|
|
var y: number = x; // error
|
|
}
|
|
}
|
|
|
|
// or try/finally
|
|
function f() {
|
|
try {
|
|
might_throw();
|
|
var x: number = 0;
|
|
} finally {
|
|
var y: number = x; // error
|
|
}
|
|
}
|
|
|
|
// or catch/finally
|
|
function f() {
|
|
try {
|
|
} catch (e) {
|
|
var x: number = 0;
|
|
} finally {
|
|
var y: number = x; // error
|
|
}
|
|
}
|
|
|
|
// or try/catch/finally if init doesn\'t dominate
|
|
function f() {
|
|
try {
|
|
var x: number = 0;
|
|
} catch (e) {
|
|
might_throw();
|
|
var x: number = 0;
|
|
} finally {
|
|
var y: number = x; // error
|
|
}
|
|
}
|
|
|
|
// post-use ok because init dominates here
|
|
function f() {
|
|
try {
|
|
var x: number = 0;
|
|
} catch (e) {
|
|
might_throw();
|
|
// ...but if so, suffix is not reached
|
|
var x: number = 0;
|
|
}
|
|
var y: number = x;
|
|
}
|
|
|
|
// and here
|
|
function f() {
|
|
try {
|
|
} catch (e) {
|
|
} finally {
|
|
might_throw();
|
|
// ...but if so, suffix is not reached
|
|
var x: number = 0;
|
|
}
|
|
var y: number = x;
|
|
}
|
|
|
|
// and here
|
|
function f() {
|
|
try {
|
|
var x: number;
|
|
} catch (e) {
|
|
} finally {
|
|
might_throw();
|
|
// ...but if so, suffix is not reached
|
|
x = 0;
|
|
}
|
|
var y: number = x;
|
|
}
|
|
|
|
// and here, thank you JS for the wonder that is hoisting
|
|
function f() {
|
|
try {
|
|
} catch (e) {
|
|
var x: number;
|
|
} finally {
|
|
might_throw();
|
|
// ...but if so, suffix is not reached
|
|
x = 0;
|
|
}
|
|
var y: number = x;
|
|
}
|
|
|
|
// error if used prior to init
|
|
function f() {
|
|
var y: number = x;
|
|
// error
|
|
try {
|
|
var x: number = 0;
|
|
} catch (e) {
|
|
}
|
|
}
|
|
|
|
// another non-dominated post
|
|
function f() {
|
|
try {
|
|
var x: number = 0;
|
|
} catch (e) {
|
|
}
|
|
var y: number = x; // error
|
|
}
|
|
|
|
// ditto
|
|
function f() {
|
|
try {
|
|
} catch (e) {
|
|
var x: number = 0;
|
|
}
|
|
var y: number = x; // error
|
|
}
|
|
|
|
// ditto
|
|
function f(b) {
|
|
try {
|
|
var x: number;
|
|
if (b) {
|
|
throw new Error();
|
|
}
|
|
x = 0;
|
|
} catch (e) {
|
|
}
|
|
var y: number = x; // error
|
|
}
|
|
"
|
|
`;
|
|
|
|
exports[`test return.js 1`] = `
|
|
"/**
|
|
* @flow
|
|
*/
|
|
|
|
function foo(x: ?number): string {
|
|
try {
|
|
} catch (e) {
|
|
return \'bar\';
|
|
}
|
|
console.log();
|
|
return \'foo\';
|
|
}
|
|
|
|
function bar(): string {
|
|
try {
|
|
return \'foo\';
|
|
} catch (e) {
|
|
return \'bar\';
|
|
}
|
|
}
|
|
|
|
function baz(): string {
|
|
try {
|
|
throw new Error(\"foo\");
|
|
} catch (e) {
|
|
return \"foo\";
|
|
}
|
|
return \"bar\"; // unreachable
|
|
}
|
|
|
|
function qux(): string {
|
|
try {
|
|
throw new Error(\"foo\");
|
|
} catch (e) {
|
|
}
|
|
console.log();
|
|
return \'bar\';
|
|
}
|
|
|
|
function quux(): string {
|
|
try {
|
|
return qux();
|
|
} catch (e) {
|
|
}
|
|
return \'bar\';
|
|
}
|
|
|
|
function bliffl(): string {
|
|
try {
|
|
throw new Error(\"foo\");
|
|
} catch (e) {
|
|
return \"foo\";
|
|
} finally {
|
|
return \"bar\";
|
|
}
|
|
}
|
|
|
|
function corge(): string {
|
|
try {
|
|
return \'foo\';
|
|
} catch (e) {
|
|
throw new Error(\'bar\');
|
|
}
|
|
bar(); // unreachable
|
|
}
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
/**
|
|
* @flow
|
|
*/
|
|
|
|
function foo(x: ?number): string {
|
|
try {
|
|
} catch (e) {
|
|
return \"bar\";
|
|
}
|
|
console.log();
|
|
return \"foo\";
|
|
}
|
|
|
|
function bar(): string {
|
|
try {
|
|
return \"foo\";
|
|
} catch (e) {
|
|
return \"bar\";
|
|
}
|
|
}
|
|
|
|
function baz(): string {
|
|
try {
|
|
throw new Error(\"foo\");
|
|
} catch (e) {
|
|
return \"foo\";
|
|
}
|
|
return \"bar\"; // unreachable
|
|
}
|
|
|
|
function qux(): string {
|
|
try {
|
|
throw new Error(\"foo\");
|
|
} catch (e) {
|
|
}
|
|
console.log();
|
|
return \"bar\";
|
|
}
|
|
|
|
function quux(): string {
|
|
try {
|
|
return qux();
|
|
} catch (e) {
|
|
}
|
|
return \"bar\";
|
|
}
|
|
|
|
function bliffl(): string {
|
|
try {
|
|
throw new Error(\"foo\");
|
|
} catch (e) {
|
|
return \"foo\";
|
|
} finally {
|
|
return \"bar\";
|
|
}
|
|
}
|
|
|
|
function corge(): string {
|
|
try {
|
|
return \"foo\";
|
|
} catch (e) {
|
|
throw new Error(\"bar\");
|
|
}
|
|
bar(); // unreachable
|
|
}
|
|
"
|
|
`;
|
|
|
|
exports[`test test.js 1`] = `
|
|
"/***
|
|
* test env state tracking thru try/catch/finally
|
|
* @flow
|
|
*/
|
|
|
|
function foo() {
|
|
var x = 0;
|
|
var y;
|
|
try {
|
|
x = \"\";
|
|
} catch(e) {
|
|
x = false;
|
|
throw -1;
|
|
} finally {
|
|
y = {};
|
|
}
|
|
// here via [try; finally] only.
|
|
x(); // string ~/> function call (no num or bool error)
|
|
y(); // object ~/> function call (no uninitialized error)
|
|
}
|
|
|
|
function bar(response) {
|
|
var payload;
|
|
try {
|
|
payload = JSON.parse(response);
|
|
} catch (e) {
|
|
throw new Error(\'...\');
|
|
}
|
|
// here via [try] only.
|
|
if (payload.error) { // ok
|
|
// ...
|
|
}
|
|
}
|
|
|
|
function qux() {
|
|
var x = 5;
|
|
try {
|
|
throw -1;
|
|
} finally {
|
|
}
|
|
x(); // unreachable
|
|
}
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
/***
|
|
* test env state tracking thru try/catch/finally
|
|
* @flow
|
|
*/
|
|
|
|
function foo() {
|
|
var x = 0;
|
|
var y;
|
|
try {
|
|
x = \"\";
|
|
} catch (e) {
|
|
x = false;
|
|
throw -1;
|
|
} finally {
|
|
y = {};
|
|
}
|
|
// here via [try; finally] only.
|
|
x();
|
|
// string ~/> function call (no num or bool error)
|
|
y(); // object ~/> function call (no uninitialized error)
|
|
}
|
|
|
|
function bar(response) {
|
|
var payload;
|
|
try {
|
|
payload = JSON.parse(response);
|
|
} catch (e) {
|
|
throw new Error(\"...\");
|
|
}
|
|
// here via [try] only.
|
|
if (payload.error) {
|
|
}
|
|
}
|
|
|
|
function qux() {
|
|
var x = 5;
|
|
try {
|
|
throw -1;
|
|
} finally {
|
|
}
|
|
x(); // unreachable
|
|
}
|
|
"
|
|
`;
|