Fix object and predicate annotations

master
James Long 2016-12-30 13:32:43 -05:00
parent 6715abca76
commit e972a7f0b6
9 changed files with 86 additions and 60 deletions

View File

@ -37,6 +37,13 @@ module.exports = {
// }
// });
const ast = flowParser.parse(text);
if(ast.errors.length > 0) {
let msg = ast.errors[0].message + " on line " + ast.errors[0].loc.start.line
if(opts.filename) {
msg += " in file " + opts.filename;
}
throw new Error(msg);
}
const printer = new Printer({ tabWidth, wrapColumn: printWidth });
return printer.printGenerically(ast).code;

View File

@ -356,8 +356,7 @@ function genericPrintNoParens(path, options, print) {
softline,
")"
])),
path.call(print, "returnType"),
path.call(print, "predicate"),
printReturnType(path, print),
" ",
path.call(print, "body")
);
@ -378,6 +377,7 @@ function genericPrintNoParens(path, options, print) {
!n.rest &&
n.params[0].type === 'Identifier' &&
!n.params[0].typeAnnotation &&
!n.predicate &&
!n.returnType
) {
parts.push(path.call(print, "params", 0));
@ -386,7 +386,7 @@ function genericPrintNoParens(path, options, print) {
"(",
printFunctionParams(path, print),
")",
path.call(print, "returnType")
printReturnType(path, print)
);
}
@ -650,7 +650,8 @@ function genericPrintNoParens(path, options, print) {
join(concat([separator, line]), props)
])),
line,
rightBrace
rightBrace,
path.call(print, "typeAnnotation")
]));
}
@ -798,7 +799,7 @@ function genericPrintNoParens(path, options, print) {
" ",
printed[0],
indent(options.tabWidth,
join(concat([",", line]), printed.slice(1)))
concat(printed.slice(1).map(p => concat([",", line, p]))))
];
// We generally want to terminate all variable declarations with a
@ -1235,8 +1236,8 @@ function genericPrintNoParens(path, options, print) {
case "Line": // Esprima line comment.
return concat(["//", fromString(n.value, options)]);
// Type Annotations for Facebook Flow, typically stripped out or
// transformed away before printing.
// Type Annotations for Facebook Flow, typically stripped out or
// transformed away before printing.
case "TypeAnnotation":
if (n.typeAnnotation) {
if (n.typeAnnotation.type !== "FunctionTypeAnnotation") {
@ -1546,10 +1547,10 @@ function genericPrintNoParens(path, options, print) {
return "null";
case "InferredPredicate":
return ": %checks";
return "%checks";
case "DeclaredPredicate":
return concat([": %checks(", path.call(print, "value"), ")"]);
return concat(["%checks(", path.call(print, "value"), ")"]);
// Unhandled types below. If encountered, nodes of these types should
// be either left alone or desugared into AST types that are fully
@ -1680,7 +1681,7 @@ function printMethod(path, options, print) {
return printFunctionParams(valuePath, print);
}, "value"),
")",
path.call(print, "value", "returnType"),
path.call(p => printReturnType(p, print), "value"),
" ",
path.call(print, "value", "body")
);
@ -1766,7 +1767,7 @@ function printObjectMethod(path, options, print) {
"(",
printFunctionParams(path, print),
")",
path.call(print, "returnType"),
printReturnType(path, print),
" ",
path.call(print, "body")
);
@ -1774,6 +1775,20 @@ function printObjectMethod(path, options, print) {
return concat(parts);
}
function printReturnType(path, print) {
const n = path.getValue();
const parts = [path.call(print, "returnType")];
if(n.predicate) {
parts.push(
// The return type will already add the colon, but otherwise we
// need to do it ourselves
n.returnType ? " " : ": ",
path.call(print, "predicate")
);
}
return concat(parts);
}
function printExportDeclaration(path, options, print) {
var decl = path.getValue();
var parts = ["export "];

View File

@ -204,10 +204,10 @@ obj_rest();
obj_rest({});
obj_rest({ p: {} });
obj_rest({ p: { q: 0, r: null } });
function obj_prop_annot({ p } = { p: 0 }) {
function obj_prop_annot({ p }: { p: string } = { p: 0 }) {
(p: void);
}
var { p } = { p: 0 };
var { p }: { p: string } = { p: 0 };
(p: void);
function obj_prop_err({ x: { y } } = null) {
@ -221,21 +221,21 @@ function arr_elem_err([ x ] = null) {
function arr_rest_err([ ...a ] = null) {
}
function gen<T>(x: T, { p }): T {
function gen<T>(x: T, { p }: { p: T }): T {
return p;
}
obj_prop_fun(({}: { p?: { q?: null } }));
obj_prop_var(({}: { p?: { q?: null } }));
function obj_prop_opt({ p } = { p: 0 }) {
function obj_prop_opt({ p }: { p?: string } = { p: 0 }) {
}
function obj_prop_maybe({ p } = { p: 0 }) {
function obj_prop_maybe({ p }: { p: ?string } = { p: 0 }) {
}
function obj_prop_union({ p } = { p: true }) {
function obj_prop_union({ p }: { p: number | string } = { p: true }) {
}
function obj_prop_union2({ p } = { p: true }) {
function obj_prop_union2({ p }: { p: number } | { p: string } = { p: true }) {
}
function default_expr_scope({ a, b }) {
@ -351,11 +351,11 @@ function qux(_: { a: number }) {
}
qux({ a: \"\" });
function corge({ b }) {
function corge({ b }: { b: string }) {
}
corge({ b: 0 });
var { n } = { n: \"\" };
var { n }: { n: number } = { n: \"\" };
function test() {
var { foo } = { bar: 123 };
var { bar, baz } = { bar: 123 };
@ -392,23 +392,25 @@ exports[`test destructuring_param.js 1`] = `
return a + b;
}
function g(a, { a }) {
return a;
}
// TODO: These throw errors when parsing.
// function g(a, { a }) {
// return a;
// }
function h({ a, { b } }, { c }, { { d } }) {
return a + b + c + d;
}
// function h({ a, { b } }, { c }, { { d } }) {
// return a + b + c + d;
// }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// TODO: These throw errors when parsing.
// function g(a, { a }) {
// return a;
// }
// function h({ a, { b } }, { c }, { { d } }) {
// return a + b + c + d;
// }
function f(a, { b }) {
return a + b;
}
function g(a, { a }) {
return a;
}
function h({ a, { }, ,, c, ,, { d }) {
return a + b + c + d;
}
"
`;
@ -469,11 +471,11 @@ function arr_rest_pattern<X>([ _, ...a ] : ArrRest<X>) { // a: [X]
// o: { x: X }
// a: [X]
// a: [X]
function obj_pattern<X>({ prop }) {
function obj_pattern<X>({ prop }: { prop: X }) {
}
type Prop<X> = { prop: X };
function obj_pattern2<X>({ prop }) {
function obj_pattern2<X>({ prop }: Prop<X>) {
}
function arr_pattern<X>([ elem ]: X[]) {
@ -496,11 +498,11 @@ function rest_antipattern<T>(...t: T) {
function rest_pattern<X>(...r: X[]) {
}
function obj_rest_pattern<X>({ _, ...o }) {
function obj_rest_pattern<X>({ _, ...o }: { _: any; x: X }) {
o.x;
}
type ObjRest<X> = { _: any; x: X };
function obj_rest_pattern<X>({ _, ...o }) {
function obj_rest_pattern<X>({ _, ...o }: ObjRest<X>) {
o.x;
}
function arr_rest_pattern<X>([ _, ...a ]: [any, X]) {

View File

@ -2,10 +2,11 @@ function f(a, { b }) {
return a + b;
}
function g(a, { a }) {
return a;
}
// TODO: These throw errors when parsing.
// function g(a, { a }) {
// return a;
// }
function h({ a, { b } }, { c }, { { d } }) {
return a + b + c + d;
}
// function h({ a, { b } }, { c }, { { d } }) {
// return a + b + c + d;
// }

View File

@ -437,7 +437,7 @@ export var numberValue1 = 1, numberValue2 = 2;
* @providesModule ES6_ExportFrom_Source1
* @flow
*/
export var numberValue1 = 1numberValue2 = 2;
export var numberValue1 = 1, numberValue2 = 2;
"
`;
@ -453,7 +453,7 @@ export var numberValue1 = 1, numberValue2 = 2;
* @providesModule ES6_ExportFrom_Source2
* @flow
*/
export var numberValue1 = 1numberValue2 = 2;
export var numberValue1 = 1, numberValue2 = 2;
"
`;
@ -502,7 +502,7 @@ export class NumberGenerator {
return 42;
}
}
export var varDeclNumber1 = 1varDeclNumber2 = 2;
export var varDeclNumber1 = 1, varDeclNumber2 = 2;
export var { destructuredObjNumber } = { destructuredObjNumber: 1 };
export var [ destructuredArrNumber ] = [ 1 ];
"
@ -549,7 +549,7 @@ export class NumberGenerator2 {
return 42;
}
}
export var varDeclNumber3 = 1varDeclNumber4 = 2;
export var varDeclNumber3 = 1, varDeclNumber4 = 2;
export var { destructuredObjNumber2 } = { destructuredObjNumber2: 1 };
export var [ destructuredArrNumber2 ] = [ 1 ];
"

View File

@ -57,8 +57,8 @@ 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 => x.kind === \"A\"): Array<A>);
(my_filter(ab, x => 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>);
"
`;
@ -142,7 +142,7 @@ declare var d: mixed;
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 {
function is_string(x): boolean %checks {
return typeof x === \"string\";
}
function is_string_and_number(x, y): %checks {
@ -186,7 +186,7 @@ const b = my_filter(a, is_string);
declare var c: Array<mixed>;
const d = my_filter(c, is_string_regular);
(d: Array<string>);
function is_string(x): boolean: %checks {
function is_string(x): boolean %checks {
return typeof x === \"string\";
}
function is_string_regular(x): boolean {
@ -226,8 +226,8 @@ 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 => x.kind === \"A\"): Array<B>);
(my_filter(ab, x => 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>);
"
`;

View File

@ -407,7 +407,7 @@ function foo(x: string | Array<string>): string {
// Sanity check:
// - predicate functions cannot have bodies (can only be declarations)
// error: cannot use pred type here
function pred(x: mixed): boolean: %checks(typeof x === \"string\") {
function pred(x: mixed): boolean %checks(typeof x === \"string\") {
return typeof x === \"string\";
}
function foo(x: string | Array<string>): string {

View File

@ -35,7 +35,7 @@ var a2 = (x: mixed): %checks (x !== null) => { // Error: body form
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
// Error: body form
var a2 = (x: mixed) => {
var a2 = (x: mixed): %checks(x !== null) => {
var x = 1;
return x;
};
@ -56,7 +56,7 @@ var a2 = (x: mixed): %checks (x !== null) => x !== null;
function f5(x: mixed): %checks(x !== null) {
return x !== null;
}
var a2 = (x: mixed) => x !== null;
var a2 = (x: mixed): %checks(x !== null) => x !== null;
"
`;
@ -97,9 +97,10 @@ function f7(x: mixed): %checks {
return x !== null;
}
var a0 = (x: mixed) => x !== null;
var a1 = (x: mixed) => x !== null;
x => x !== null;
const insert_a_really_big_predicated_arrow_function_name_here = x => x !== null;
var a1 = (x: mixed): %checks => x !== null;
(x): %checks => x !== null;
const insert_a_really_big_predicated_arrow_function_name_here = (x): %checks => x !==
null;
declare var x;
x;
checks => 123;

View File

@ -88,8 +88,8 @@ function foo(x, y) {
var baz = function(why) {
return y + why;
};
var xy, z;
var tu = 5, v, w = 7;
var x, y, z;
var t, u = 5, v, w = 7;
}
foo(1, 2);
"