Add type parameters on anon functions
parent
e972a7f0b6
commit
ed57110ef5
|
@ -340,12 +340,12 @@ function genericPrintNoParens(path, options, print) {
|
|||
if (n.id) {
|
||||
parts.push(
|
||||
" ",
|
||||
path.call(print, "id"),
|
||||
path.call(print, "typeParameters")
|
||||
path.call(print, "id")
|
||||
);
|
||||
}
|
||||
|
||||
parts.push(
|
||||
path.call(print, "typeParameters"),
|
||||
group(concat([
|
||||
"(",
|
||||
indent(options.tabWidth,
|
||||
|
|
|
@ -265,7 +265,7 @@ function insertMany<K, V>(
|
|||
}
|
||||
class Foo<A> {
|
||||
bar<B>() {
|
||||
return function(a: A, b: B, c: C): void {
|
||||
return function<C>(a: A, b: B, c: C): void {
|
||||
([ a, b, c ]: [A, B, C]);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -187,7 +187,7 @@ class C {
|
|||
var e = async function() {
|
||||
|
||||
};
|
||||
var et = async function(a: T) {
|
||||
var et = async function<T>(a: T) {
|
||||
|
||||
};
|
||||
var n = new async function() {
|
||||
|
@ -487,7 +487,7 @@ class C {
|
|||
var e = async function() {
|
||||
await 1;
|
||||
};
|
||||
var et = async function(a: T) {
|
||||
var et = async function<T>(a: T) {
|
||||
await 1;
|
||||
};
|
||||
var n = new async function() {
|
||||
|
|
|
@ -78,7 +78,7 @@ async function* readLines(path) {
|
|||
}
|
||||
|
||||
async function f() {
|
||||
for await (const line of readLines(\"/path/to/file\")) {
|
||||
for await (const line of readLines("/path/to/file")) {
|
||||
(line: void); // error: string ~> void
|
||||
}
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ async function* readLines(path) {
|
|||
}
|
||||
}
|
||||
async function f() {
|
||||
for await (const line of readLines(\"/path/to/file\")) {
|
||||
for await (const line of readLines("/path/to/file")) {
|
||||
(line: void);
|
||||
}
|
||||
}
|
||||
|
@ -107,13 +107,13 @@ async function f() {
|
|||
exports[`test return.js 1`] = `
|
||||
"declare var gen: AsyncGenerator<void,string,void>;
|
||||
|
||||
// You can pass whatever you like to return, it doesn\'t need to be related to
|
||||
// the AsyncGenerator\'s return type
|
||||
// You can pass whatever you like to return, it doesn't need to be related to
|
||||
// the AsyncGenerator's return type
|
||||
gen.return(0).then(result => {
|
||||
(result.value: void); // error: string | number ~> void
|
||||
});
|
||||
|
||||
// However, a generator can \"refuse\" the return by catching an exception and
|
||||
// However, a generator can "refuse" the return by catching an exception and
|
||||
// yielding or returning internally.
|
||||
async function *refuse_return() {
|
||||
try {
|
||||
|
@ -122,16 +122,16 @@ async function *refuse_return() {
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
refuse_return().return(\"string\").then(result => {
|
||||
refuse_return().return("string").then(result => {
|
||||
if (result.done) {
|
||||
(result.value: string); // error: number | void ~> string
|
||||
}
|
||||
});
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// You can pass whatever you like to return, it doesn\'t need to be related to
|
||||
// the AsyncGenerator\'s return type
|
||||
// You can pass whatever you like to return, it doesn't need to be related to
|
||||
// the AsyncGenerator's return type
|
||||
// error: string | number ~> void
|
||||
// However, a generator can \"refuse\" the return by catching an exception and
|
||||
// However, a generator can "refuse" the return by catching an exception and
|
||||
// yielding or returning internally.
|
||||
// error: number | void ~> string
|
||||
declare var gen: AsyncGenerator<void, string, void>;
|
||||
|
@ -147,7 +147,7 @@ async function* refuse_return() {
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
refuse_return().return(\"string\").then(
|
||||
refuse_return().return("string").then(
|
||||
result => {
|
||||
if (result.done) {
|
||||
(result.value: string);
|
||||
|
@ -167,7 +167,7 @@ exports[`test throw.js 1`] = `
|
|||
}
|
||||
|
||||
(async () => {
|
||||
catch_return().throw(\"\").then(({value}) => {
|
||||
catch_return().throw("").then(({value}) => {
|
||||
if (value !== undefined) {
|
||||
(value: void); // error: number ~> void
|
||||
}
|
||||
|
@ -184,7 +184,7 @@ async function *yield_return() {
|
|||
}
|
||||
|
||||
(async () => {
|
||||
yield_return().throw(\"\").then(({value}) => {
|
||||
yield_return().throw("").then(({value}) => {
|
||||
if (value !== undefined) {
|
||||
(value: void); // error: number ~> void
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ async function* catch_return() {
|
|||
}
|
||||
}
|
||||
async () => {
|
||||
catch_return().throw(\"\").then(
|
||||
catch_return().throw("").then(
|
||||
({ value }) => {
|
||||
if (value !== undefined) {
|
||||
(value: void);
|
||||
|
@ -218,7 +218,7 @@ async function* yield_return() {
|
|||
}
|
||||
}
|
||||
async () => {
|
||||
yield_return().throw(\"\").then(
|
||||
yield_return().throw("").then(
|
||||
({ value }) => {
|
||||
if (value !== undefined) {
|
||||
(value: void);
|
||||
|
|
|
@ -38,13 +38,13 @@ function foo8<U>(x:U,y):U {
|
|||
/*
|
||||
foo8(0,void 0);
|
||||
*/
|
||||
var foo1 = function(x: T): T {
|
||||
var foo1 = function<T>(x: T): T {
|
||||
return x;
|
||||
};
|
||||
function foo2<T, S>(x: T): S {
|
||||
return x;
|
||||
}
|
||||
var foo3 = function(x: T): T {
|
||||
var foo3 = function<T>(x: T): T {
|
||||
return foo3(x);
|
||||
};
|
||||
function foo4<T, S>(x: T): S {
|
||||
|
@ -54,7 +54,7 @@ var x = [ ];
|
|||
function foo5<T>(): Array<T> {
|
||||
return x;
|
||||
}
|
||||
var foo6 = function(x: R): R {
|
||||
var foo6 = function<R>(x: R): R {
|
||||
return foo1(x);
|
||||
};
|
||||
function foo7<R>(x: R): R {
|
||||
|
|
|
@ -10,7 +10,7 @@ const barr = my_filter(arr, is_string);
|
|||
(barr: Array<string>);
|
||||
|
||||
function is_string(x): %checks {
|
||||
return typeof x === \"string\";
|
||||
return typeof x === "string";
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// @flow
|
||||
|
@ -21,7 +21,7 @@ declare var arr: Array<mixed>;
|
|||
const barr = my_filter(arr, is_string);
|
||||
(barr: Array<string>);
|
||||
function is_string(x): %checks {
|
||||
return typeof x === \"string\";
|
||||
return typeof x === "string";
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
@ -34,16 +34,16 @@ exports[`test filter-union.js 1`] = `
|
|||
|
||||
declare function my_filter<T, P: $Pred<1>>(v: Array<T>, cb: P): Array<$Refine<T,P,1>>;
|
||||
|
||||
type A = { kind: \'A\', u: number }
|
||||
type B = { kind: \'B\', v: string }
|
||||
type C = { kind: \'C\', y: boolean }
|
||||
type D = { kind: \'D\', x: boolean }
|
||||
type E = { kind: \'E\', y: boolean }
|
||||
type A = { kind: 'A', u: number }
|
||||
type B = { kind: 'B', v: string }
|
||||
type C = { kind: 'C', y: boolean }
|
||||
type D = { kind: 'D', x: boolean }
|
||||
type E = { kind: 'E', y: boolean }
|
||||
|
||||
declare var ab: Array<A|B|C>;
|
||||
|
||||
(my_filter(ab, (x): %checks => x.kind === \'A\'): Array<A>); // OK
|
||||
(my_filter(ab, (x): %checks => x.kind !== \'A\'): Array<B|C>); // OK
|
||||
(my_filter(ab, (x): %checks => x.kind === 'A'): Array<A>); // OK
|
||||
(my_filter(ab, (x): %checks => x.kind !== 'A'): Array<B|C>); // OK
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// @flow
|
||||
// Filter the contents of an array
|
||||
|
@ -51,14 +51,14 @@ declare var ab: Array<A|B|C>;
|
|||
// OK
|
||||
declare function my_filter<T, P: $Pred<1>>(v: Array<T>,
|
||||
cb: P): Array<$Refine<T, P, 1>>;
|
||||
type A = { kind: \"A\"; u: number };
|
||||
type B = { kind: \"B\"; v: string };
|
||||
type C = { kind: \"C\"; y: boolean };
|
||||
type D = { kind: \"D\"; x: boolean };
|
||||
type E = { kind: \"E\"; y: boolean };
|
||||
type A = { kind: "A"; u: number };
|
||||
type B = { kind: "B"; v: string };
|
||||
type C = { kind: "C"; y: boolean };
|
||||
type D = { kind: "D"; x: boolean };
|
||||
type E = { kind: "E"; y: boolean };
|
||||
declare var ab: Array<A | B | C>;
|
||||
(my_filter(ab, (x): %checks => x.kind === \"A\"): Array<A>);
|
||||
(my_filter(ab, (x): %checks => x.kind !== \"A\"): Array<B | C>);
|
||||
(my_filter(ab, (x): %checks => x.kind === "A"): Array<A>);
|
||||
(my_filter(ab, (x): %checks => x.kind !== "A"): Array<B | C>);
|
||||
"
|
||||
`;
|
||||
|
||||
|
@ -66,7 +66,7 @@ exports[`test refine.js 1`] = `
|
|||
"// @flow
|
||||
|
||||
/*
|
||||
$Pred<N> is an \"abstract predicate type\", i.e. denotes a (function) type that
|
||||
$Pred<N> is an "abstract predicate type", i.e. denotes a (function) type that
|
||||
refines N variables. So if \`cb\` is a function, then it should be refining
|
||||
exactly N argument. It is abstract in that we do not need to specify:
|
||||
(a) which variables are going to be refined (just the number), or (b) what
|
||||
|
@ -103,16 +103,16 @@ declare function refine2<T, P: $Pred<2>>(v: T, w: T, cb: P): $Refine<T,P,1>;
|
|||
// { if (cb(v, w)) { return w; } else { throw new Error(); } }
|
||||
|
||||
function is_string(x): boolean %checks {
|
||||
return typeof x === \"string\";
|
||||
return typeof x === "string";
|
||||
}
|
||||
|
||||
function is_string_and_number(x, y): %checks {
|
||||
return typeof x === \"string\" && typeof y === \"number\";
|
||||
return typeof x === "string" && typeof y === "number";
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// @flow
|
||||
/*
|
||||
$Pred<N> is an \"abstract predicate type\", i.e. denotes a (function) type that
|
||||
$Pred<N> is an "abstract predicate type", i.e. denotes a (function) type that
|
||||
refines N variables. So if \`cb\` is a function, then it should be refining
|
||||
exactly N argument. It is abstract in that we do not need to specify:
|
||||
(a) which variables are going to be refined (just the number), or (b) what
|
||||
|
@ -143,10 +143,10 @@ var e = refine2(c, d, is_string_and_number);
|
|||
(e: string);
|
||||
declare function refine2<T, P: $Pred<2>>(v: T, w: T, cb: P): $Refine<T, P, 1>;
|
||||
function is_string(x): boolean %checks {
|
||||
return typeof x === \"string\";
|
||||
return typeof x === "string";
|
||||
}
|
||||
function is_string_and_number(x, y): %checks {
|
||||
return typeof x === \"string\" && typeof y === \"number\";
|
||||
return typeof x === "string" && typeof y === "number";
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
@ -168,11 +168,11 @@ const d = my_filter(c, is_string_regular);
|
|||
(d: Array<string>);
|
||||
|
||||
function is_string(x): boolean %checks {
|
||||
return typeof x === \"string\";
|
||||
return typeof x === "string";
|
||||
}
|
||||
|
||||
function is_string_regular(x): boolean {
|
||||
return typeof x === \"string\";
|
||||
return typeof x === "string";
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// @flow
|
||||
|
@ -187,10 +187,10 @@ declare var c: Array<mixed>;
|
|||
const d = my_filter(c, is_string_regular);
|
||||
(d: Array<string>);
|
||||
function is_string(x): boolean %checks {
|
||||
return typeof x === \"string\";
|
||||
return typeof x === "string";
|
||||
}
|
||||
function is_string_regular(x): boolean {
|
||||
return typeof x === \"string\";
|
||||
return typeof x === "string";
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
@ -203,16 +203,16 @@ exports[`test sanity-filter-union.js 1`] = `
|
|||
|
||||
declare function my_filter<T, P: $Pred<1>>(v: Array<T>, cb: P): Array<$Refine<T,P,1>>;
|
||||
|
||||
type A = { kind: \'A\', u: number }
|
||||
type B = { kind: \'B\', v: string }
|
||||
type C = { kind: \'C\', y: boolean }
|
||||
type D = { kind: \'D\', x: boolean }
|
||||
type E = { kind: \'E\', y: boolean }
|
||||
type A = { kind: 'A', u: number }
|
||||
type B = { kind: 'B', v: string }
|
||||
type C = { kind: 'C', y: boolean }
|
||||
type D = { kind: 'D', x: boolean }
|
||||
type E = { kind: 'E', y: boolean }
|
||||
|
||||
declare var ab: Array<A|B|C>;
|
||||
|
||||
(my_filter(ab, (x): %checks => x.kind === \'A\'): Array<B>); // ERROR
|
||||
(my_filter(ab, (x): %checks => x.kind !== \'A\'): Array<A|C>); // ERROR
|
||||
(my_filter(ab, (x): %checks => x.kind === 'A'): Array<B>); // ERROR
|
||||
(my_filter(ab, (x): %checks => x.kind !== 'A'): Array<A|C>); // ERROR
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// @flow
|
||||
// Filter the contents of an array
|
||||
|
@ -220,14 +220,14 @@ declare var ab: Array<A|B|C>;
|
|||
// ERROR
|
||||
declare function my_filter<T, P: $Pred<1>>(v: Array<T>,
|
||||
cb: P): Array<$Refine<T, P, 1>>;
|
||||
type A = { kind: \"A\"; u: number };
|
||||
type B = { kind: \"B\"; v: string };
|
||||
type C = { kind: \"C\"; y: boolean };
|
||||
type D = { kind: \"D\"; x: boolean };
|
||||
type E = { kind: \"E\"; y: boolean };
|
||||
type A = { kind: "A"; u: number };
|
||||
type B = { kind: "B"; v: string };
|
||||
type C = { kind: "C"; y: boolean };
|
||||
type D = { kind: "D"; x: boolean };
|
||||
type E = { kind: "E"; y: boolean };
|
||||
declare var ab: Array<A | B | C>;
|
||||
(my_filter(ab, (x): %checks => x.kind === \"A\"): Array<B>);
|
||||
(my_filter(ab, (x): %checks => x.kind !== \"A\"): Array<A | C>);
|
||||
(my_filter(ab, (x): %checks => x.kind === "A"): Array<B>);
|
||||
(my_filter(ab, (x): %checks => x.kind !== "A"): Array<A | C>);
|
||||
"
|
||||
`;
|
||||
|
||||
|
@ -254,7 +254,7 @@ var e = refine3(c, d, e, is_string_and_number);
|
|||
(e: string);
|
||||
|
||||
function is_string_and_number(x, y): %checks {
|
||||
return typeof x === \"string\" && typeof y === \"number\";
|
||||
return typeof x === "string" && typeof y === "number";
|
||||
}
|
||||
|
||||
|
||||
|
@ -266,15 +266,15 @@ var e = refine(a, is_string_regular); // ERROR: is_string_regular is not a
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function is_string(x): %checks {
|
||||
return typeof x === \"string\";
|
||||
return typeof x === "string";
|
||||
}
|
||||
|
||||
function is_string_regular(x) {
|
||||
return typeof x === \"string\";
|
||||
return typeof x === "string";
|
||||
}
|
||||
|
||||
function is_string_and_number(x, y): %checks {
|
||||
return typeof x === \"string\" && typeof y === \"number\";
|
||||
return typeof x === "string" && typeof y === "number";
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// @flow
|
||||
|
@ -300,18 +300,18 @@ cb: P): $Refine<T, P, 1>;
|
|||
var e = refine3(c, d, e, is_string_and_number);
|
||||
(e: string);
|
||||
function is_string_and_number(x, y): %checks {
|
||||
return typeof x === \"string\" && typeof y === \"number\";
|
||||
return typeof x === "string" && typeof y === "number";
|
||||
}
|
||||
var e = refine(a, is_string_regular);
|
||||
(e: number);
|
||||
function is_string(x): %checks {
|
||||
return typeof x === \"string\";
|
||||
return typeof x === "string";
|
||||
}
|
||||
function is_string_regular(x) {
|
||||
return typeof x === \"string\";
|
||||
return typeof x === "string";
|
||||
}
|
||||
function is_string_and_number(x, y): %checks {
|
||||
return typeof x === \"string\" && typeof y === \"number\";
|
||||
return typeof x === "string" && typeof y === "number";
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -11,7 +11,7 @@ function run_spec(dirname) {
|
|||
|
||||
if (!RUN_AST_TESTS) {
|
||||
const source = read(path);
|
||||
const output = prettyprint(source);
|
||||
const output = prettyprint(source, path);
|
||||
test(filename, () => {
|
||||
expect(source + '~'.repeat(80) + '\n' + output).toMatchSnapshot();
|
||||
});
|
||||
|
@ -24,7 +24,7 @@ function run_spec(dirname) {
|
|||
let ppast;
|
||||
let pperr = null;
|
||||
try {
|
||||
ppast = parse(prettyprint(source));
|
||||
ppast = parse(prettyprint(source, path));
|
||||
}
|
||||
catch(e) {
|
||||
pperr = e.stack;
|
||||
|
@ -68,8 +68,8 @@ function parse(string) {
|
|||
return stripLocation(flowParser.parse(string));
|
||||
}
|
||||
|
||||
function prettyprint(src) {
|
||||
return jscodefmt.format(src);
|
||||
function prettyprint(src, filename) {
|
||||
return jscodefmt.format(src, { filename });
|
||||
}
|
||||
|
||||
function read(filename) {
|
||||
|
|
Loading…
Reference in New Issue