exports[`test function-bind.js 1`] = ` "// @flow // Sanity checks: // - use of bind in a position of a function predicate. // (This case should fall through, as method calls // are currently not supported.) The original behavior // (including \`havoc\`) should be retained. class C { m() { return true; } a: 1; n() { if(this.m.bind(this)) { this.a; } } } declare var m: Function; const o = { a: 1 }; if (m.bind(o)) { o.a; } class D { m: Function; n() { if(this.m({})) { } } } declare var m: Function; const x = \"\"; if (m.bind(this)(x)) { } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // @flow // Sanity checks: // - use of bind in a position of a function predicate. // (This case should fall through, as method calls // are currently not supported.) The original behavior // (including \`havoc\`) should be retained. class C { m() { return true; } a: 1; n() { if (this.m.bind(this)) { this.a; } } } declare var m: Function; const o = { a: 1 }; if (m.bind(o)) { o.a; } class D { m: Function; n() { if (this.m({})) { } } } declare var m: Function; const x = \"\"; if (m.bind(this)(x)) { } " `; exports[`test function-union.js 1`] = ` "// @flow declare function f1(x: mixed): boolean %checks(typeof x === \"string\"); declare function f2(x: mixed): boolean %checks(Array.isArray(x)); declare var cond: boolean; // Feature check: function foo(x: number | string | Array): number { var f = (cond) ? f1 : f2; if (f(x)) { return x.length; } else { return 1; } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // @flow declare function f1(x: mixed): boolean %checks(typeof x === \"string\"); declare function f2(x: mixed): boolean %checks(Array.isArray(x)); declare var cond: boolean; // Feature check: function foo(x: number | string | Array): number { var f = cond ? f1 : f2; if (f(x)) { return x.length; } else { return 1; } } " `; exports[`test is-string-decl.js 1`] = ` "// @flow declare function is_string(x: mixed): boolean %checks(typeof x === \"string\"); declare function is_number(x: mixed): boolean %checks(typeof x === \"number\"); // Feature check: function foo(x: string | Array): string { if (is_string(x)) { // The use of \`is_string\` as a conditional check // should guarantee the narrowing of the type of \`x\` // to string. return x; } else { // Accordingly the negation of the above check // guarantees that \`x\` here is an Array return x.join(); } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // @flow declare function is_string(x: mixed): boolean %checks(typeof x === \"string\"); declare function is_number(x: mixed): boolean %checks(typeof x === \"number\"); // Feature check: function foo(x: string | Array): string { if (is_string(x)) { // The use of \`is_string\` as a conditional check // should guarantee the narrowing of the type of \`x\` // to string. return x; } else { // Accordingly the negation of the above check // guarantees that \`x\` here is an Array return x.join(); } } " `; exports[`test logical-or.js 1`] = ` "// @flow // Sanity check: // - conditional functions do not affect behavior of conditional // expressions (e.g. \`||\`) declare function r(x: string): number; var s = \'a\'; var n = r(s) || 1; (n: number); var x = \"\"; if (x = r(s) || 1) { (x: number); } declare var dollars: mixed; function foo(x: mixed) { return 1; } (foo(dollars) || 0); (Number(dollars) || 0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // @flow // Sanity check: // - conditional functions do not affect behavior of conditional // expressions (e.g. \`||\`) declare function r(x: string): number; var s = \"a\"; var n = r(s) || 1; (n: number); var x = \"\"; if (x = r(s) || 1) { (x: number); } declare var dollars: mixed; function foo(x: mixed) { return 1; } foo(dollars) || 0; Number(dollars) || 0; " `; exports[`test object-invariant.js 1`] = ` "// @flow // Sanity check: // - preserving \`havoc\` semantics type Meeting = { organizer: ?Invitee, es: Array } type Invitee = { fbid: number } function f(_this: { m: ?Meeting }): string { if (!_this.m) { return \"0\"; } if (_this.m.es.some((a) => a.fbid === 0)) { } return \"3\"; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // @flow // Sanity check: // - preserving \`havoc\` semantics type Meeting = { organizer: ?Invitee, es: Array }; type Invitee = { fbid: number }; function f(_this: { m: ?Meeting }): string { if (!_this.m) { return \"0\"; } if (_this.m.es.some(a => a.fbid === 0)) { } return \"3\"; } " `; exports[`test orig-string-tag-check.js 1`] = ` "// @flow // The original first-order case function foo(x: string | Array): string { if (typeof x === \"string\") { return x; // [ERROR] x: Array doesn\'t match return type } else { return x.join(); // [ERROR] x: string doesn\'t have .join method } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // @flow // The original first-order case function foo(x: string | Array): string { if (typeof x === \"string\") { return x; // [ERROR] x: Array doesn\'t match return type } else { return x.join(); // [ERROR] x: string doesn\'t have .join method } } " `; exports[`test sanity-fall-through.js 1`] = ` "// @flow // Sanity check: // - we should still be getting an error at the second return statement declare function pred(x: T): boolean; function foo(s: Array): string { if (pred(s)) { return \"1\"; } return 1; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // @flow // Sanity check: // - we should still be getting an error at the second return statement declare function pred(x: T): boolean; function foo(s: Array): string { if (pred(s)) { return \"1\"; } return 1; } " `; exports[`test sanity-invalid-calls.js 1`] = ` "// @flow // Sanity check: // - invalid calls at predicate positions declare function pred(x: T): boolean; function foo(s: Array): string { if ((1)(s)) { return \"1\"; } if ((pred + 1)(\"s\")) { return \"1\"; } return \"1\" } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // @flow // Sanity check: // - invalid calls at predicate positions declare function pred(x: T): boolean; function foo(s: Array): string { if (1(s)) { return \"1\"; } if ((pred + 1)(\"s\")) { return \"1\"; } return \"1\"; } " `; exports[`test sanity-is-string-bug.js 1`] = ` "// @flow declare function is_string(x: mixed): boolean %checks(typeof x === \"string\"); declare function is_number(x: mixed): boolean %checks(typeof x === \"number\"); // Sanity check: // - Erroneous logic function bar(x: string | Array): string { if (is_number(x)) { return x; } else { return x.join(); // error: both string and Array can flow to x } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // @flow declare function is_string(x: mixed): boolean %checks(typeof x === \"string\"); declare function is_number(x: mixed): boolean %checks(typeof x === \"number\"); // Sanity check: // - Erroneous logic function bar(x: string | Array): string { if (is_number(x)) { return x; } else { return x.join(); // error: both string and Array can flow to x } } " `; exports[`test sanity-parameter-mismatch.js 1`] = ` "// @flow // Sanity check: make sure the parameters are checked as usual declare function foo( input: mixed, types: string | Array ): boolean %checks(typeof input === \"string\" || Array.isArray(input)); foo(3, 3); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // @flow // Sanity check: make sure the parameters are checked as usual declare function foo( input: mixed, types: string | Array ): boolean %checks(typeof input === \"string\" || Array.isArray(input)); foo(3, 3); " `; exports[`test sanity-pred-with-body.js 1`] = ` "// @flow // Sanity check: // - predicate functions cannot have bodies (can only be declarations) function pred(x: mixed): boolean %checks(typeof x === \"string\") { // error: cannot use pred type here return typeof x === \"string\"; } function foo(x: string | Array): string { if (pred(x)) { return x; } return \"1\" } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // @flow // Sanity check: // - predicate functions cannot have bodies (can only be declarations) function pred(x: mixed): boolean %checks(typeof x === \"string\") { // error: cannot use pred type here return typeof x === \"string\"; } function foo(x: string | Array): string { if (pred(x)) { return x; } return \"1\"; } " `; exports[`test sanity-return-type.js 1`] = ` "// @flow declare function f2(x: mixed): string %checks(Array.isArray(x)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // @flow declare function f2(x: mixed): string %checks(Array.isArray(x)); " `;