Do not put a newline on empty `{}` for functions (#447)

The original intent of it was for `if then else` and `try catch` as they aren't likely to be empty, but it accidentally caught function bodys, which have many valid reasons to be empty. Let's special case those out.
master
Christopher Chedeau 2017-01-24 09:37:01 -08:00 committed by James Long
parent 4c82f4a2ab
commit fb52e7a5c8
87 changed files with 314 additions and 661 deletions

View File

@ -449,7 +449,7 @@ function genericPrintNoParens(path, options, print) {
parts.push(path.call(print, "source"), ";"); parts.push(path.call(print, "source"), ";");
return concat(parts); return concat(parts);
case "BlockStatement": case "BlockStatement": {
var naked = path.call( var naked = path.call(
function(bodyPath) { function(bodyPath) {
return printStatementSequence(bodyPath, options, print); return printStatementSequence(bodyPath, options, print);
@ -460,6 +460,14 @@ function genericPrintNoParens(path, options, print) {
const hasContent = getFirstString(naked); const hasContent = getFirstString(naked);
const hasDirectives = n.directives && n.directives.length > 0; const hasDirectives = n.directives && n.directives.length > 0;
var parent = path.getParentNode();
if (!hasContent && !hasDirectives && !n.comments &&
(parent.type === "ArrowFunctionExpression" ||
parent.type === "FunctionExpression" ||
parent.type === "FunctionDeclaration")) {
return "{}";
}
parts.push("{"); parts.push("{");
// Babel 6 // Babel 6
@ -491,6 +499,7 @@ function genericPrintNoParens(path, options, print) {
parts.push(hardline, "}"); parts.push(hardline, "}");
return concat(parts); return concat(parts);
}
case "ReturnStatement": case "ReturnStatement":
parts.push("return"); parts.push("return");

View File

@ -30,8 +30,7 @@ function foo() {
bar(x); bar(x);
} }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function bar(x: number) { function bar(x: number) {}
}
function foo() { function foo() {
var x = null; var x = null;
if (x == null) return; if (x == null) return;

View File

@ -174,8 +174,7 @@ exports[`test issue-530.js 1`] = `
module.exports = foo; module.exports = foo;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function foo(...args: any) { function foo(...args: any) {}
}
module.exports = foo; module.exports = foo;
" "

View File

@ -93,11 +93,9 @@ let tests = [
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @providesModule Arith */ /* @providesModule Arith */
function num(x: number) { function num(x: number) {}
}
function str(x: string) { function str(x: string) {}
}
function foo() { function foo() {
var x = 0; var x = 0;
@ -291,8 +289,7 @@ y *= 2; // error
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */ /* @flow */
function num(x: number) { function num(x: number) {}
}
num(null * 1); num(null * 1);
num(1 * null); num(1 * null);

View File

@ -58,8 +58,7 @@ function from_test() {
} }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */ /* @flow */
function foo(x: string) { function foo(x: string) {}
}
var a = [ 0 ]; var a = [ 0 ];
var b = a.map(function(x) { var b = a.map(function(x) {

View File

@ -41,8 +41,7 @@ module.exports = \"arrays\";
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @providesModule Arrays */ /* @providesModule Arrays */
function foo(x: string) { function foo(x: string) {}
}
var a = []; var a = [];
a[0] = 1; a[0] = 1;

View File

@ -35,20 +35,13 @@ export default (() => {})();
new (() => {}); new (() => {});
if ((() => {}) ? 1 : 0) {} if ((() => {}) ? 1 : 0) {}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(a => { (a => {}).length;
}).length; typeof (() => {});
typeof (() => { export default (() => {})();
}); (() => {})()\`\`;
export default (() => { (() => {})\`\`;
})(); new (() => {})();
(() => { if ((() => {}) ? 1 : 0) {
})()\`\`;
(() => {
})\`\`;
new (() => {
})();
if ((() => {
}) ? 1 : 0) {
} }
" "
`; `;
@ -87,8 +80,7 @@ exports[`test long-call-no-args.js 1`] = `
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
veryLongCall( veryLongCall(
VERY_VERY_VERY_VERY_VERY_VERY_VERY_VERY_VERY_VERY_LONG_CONSTANT, VERY_VERY_VERY_VERY_VERY_VERY_VERY_VERY_VERY_VERY_LONG_CONSTANT,
() => { () => {}
}
); );
" "
`; `;

View File

@ -171,42 +171,24 @@ console.log(x.async);
var async = 3; var async = 3;
var y = { async }; var y = { async };
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
async function f() { async function f() {}
} async function ft<T>(a: T) {}
async function ft<T>(a: T) {
}
class C { class C {
async m() { async m() {}
} async mt<T>(a: T) {}
async mt<T>(a: T) { static async m(a) {}
} static async mt<T>(a: T) {}
static async m(a) {
}
static async mt<T>(a: T) {
}
} }
var e = async function() { var e = async function() {};
}; var et = async function<T>(a: T) {};
var et = async function<T>(a: T) {
};
var n = new (async function() { var n = new (async function() {})();
})();
var o = { var o = { async m() {} };
async m() { var ot = { async m<T>(a: T) {} };
} var oz = { async async() {} };
};
var ot = {
async m<T>(a: T) {
}
};
var oz = {
async async() {
}
};
var x = { async: 5 }; var x = { async: 5 };
console.log(x.async); console.log(x.async);
@ -254,8 +236,7 @@ async function foo2(): Promise<string> {
} }
async function foo3(): Promise<string> { async function foo3(): Promise<string> {
function bar() { function bar() {}
}
return bar(); return bar();
} }
" "

View File

@ -411,18 +411,14 @@ function var_var() {
// function x * // function x *
function function_toplevel() { function function_toplevel() {
function a() { function a() {}
} function a() {}
function a() {
}
} }
function function_block() { function function_block() {
{ {
function a() { function a() {}
} function a() {}
function a() {
}
} }
} }
@ -446,8 +442,7 @@ function type_shadow_nested_scope() {
} }
// fn params name clash // fn params name clash
function fn_params_name_clash(x, x /* error: x already bound */) { function fn_params_name_clash(x, x /* error: x already bound */) {}
}
function fn_params_clash_fn_binding(x, y) { function fn_params_clash_fn_binding(x, y) {
let x = 0; let x = 0;
// error: x already bound // error: x already bound

View File

@ -235,15 +235,13 @@ const o: MutationObserver = new MutationObserver(callback);
// correct // correct
new MutationObserver((arr: Array<MutationRecord>) => true); new MutationObserver((arr: Array<MutationRecord>) => true);
// correct // correct
new MutationObserver(() => { new MutationObserver(() => {});
});
// correct // correct
new MutationObserver(); new MutationObserver();
// incorrect // incorrect
new MutationObserver(42); new MutationObserver(42);
// incorrect // incorrect
new MutationObserver((n: number) => { new MutationObserver((n: number) => {});
});
// incorrect // incorrect
// observe // observe

View File

@ -4,8 +4,7 @@ foo(0, \"\");
function bar<X:number, Y:X>(x:X, y:Y): number { return y*0; } function bar<X:number, Y:X>(x:X, y:Y): number { return y*0; }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function foo<X, Y: X>(x: X, y: Y): void { function foo<X, Y: X>(x: X, y: Y): void {}
}
foo(0, \"\"); foo(0, \"\");
function bar<X: number, Y: X>(x: X, y: Y): number { function bar<X: number, Y: X>(x: X, y: Y): number {

View File

@ -64,8 +64,7 @@ class Foo<T> {
map<U>(callbackfn: () => U): Foo<U> { map<U>(callbackfn: () => U): Foo<U> {
return new Foo(); return new Foo();
} }
set(x: T): void { set(x: T): void {}
}
get(): T { get(): T {
return this.x; return this.x;
} }

View File

@ -106,15 +106,13 @@ var d: { (): string } = function(x: number): string {
}; };
// ...but subtyping rules still apply // ...but subtyping rules still apply
var e: { (x: any): void } = function() { var e: { (x: any): void } = function() {};
};
// arity // arity
var f: { (): mixed } = function(): string { var f: { (): mixed } = function(): string {
return \"hi\"; return \"hi\";
}; };
// return type // return type
var g: { (x: string): void } = function(x: mixed) { var g: { (x: string): void } = function(x: mixed) {};
};
// param type // param type
// A function can be an object // A function can be an object
@ -264,16 +262,13 @@ f.myProp = 123;
var c : { myProp: number } = f; var c : { myProp: number } = f;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Expecting properties that don\'t exist should be an error // Expecting properties that don\'t exist should be an error
var a: { someProp: number } = function() { var a: { someProp: number } = function() {};
};
// Expecting properties that do exist should be fine // Expecting properties that do exist should be fine
var b: { apply: Function } = function() { var b: { apply: Function } = function() {};
};
// Expecting properties in the functions statics should be fine // Expecting properties in the functions statics should be fine
var f = function() { var f = function() {};
};
f.myProp = 123; f.myProp = 123;
var c: { myProp: number } = f; var c: { myProp: number } = f;
" "
@ -316,8 +311,7 @@ var c: { (x: string): string } = x => x.toFixed();
var d: { (): string } = x => \"hi\"; var d: { (): string } = x => \"hi\";
// ...but subtyping rules still apply // ...but subtyping rules still apply
var e: { (x: any): void } = () => { var e: { (x: any): void } = () => {};
};
// arity // arity
var f: { (): mixed } = () => \"hi\"; var f: { (): mixed } = () => \"hi\";
// return type // return type

View File

@ -44,8 +44,7 @@ callable(0); // error, number ~> string
callable.call(null, 0); // error, number ~> string callable.call(null, 0); // error, number ~> string
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var x = Boolean(4); var x = Boolean(4);
function foo(fn: (value: any) => boolean) { function foo(fn: (value: any) => boolean) {}
}
foo(Boolean); foo(Boolean);
var dict: { [k: string]: any } = {}; var dict: { [k: string]: any } = {};

View File

@ -58,8 +58,7 @@ function* f() {
x = class extends (++b) {} x = class extends (++b) {}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// \"ArrowFunctionExpression\" // \"ArrowFunctionExpression\"
class a extends (() => { class a extends (() => {}) {}
}) {}
// \"AssignmentExpression\" // \"AssignmentExpression\"
class a extends (b = c) {} class a extends (b = c) {}
@ -82,8 +81,7 @@ class a extends class {} {}
class a extends (b ? c : d) {} class a extends (b ? c : d) {}
// \"FunctionExpression\" // \"FunctionExpression\"
class a extends function() { class a extends function() {} {}
} {}
// \"LogicalExpression\" // \"LogicalExpression\"
class a extends (b || c) {} class a extends (b || c) {}

View File

@ -64,20 +64,16 @@ module.exports = {
class A { class A {
static x: number; static x: number;
static y: string; static y: string;
static foo(x: number) { static foo(x: number) {}
} static bar(y: string) {}
static bar(y: string) {
}
} }
A.qux = function(x: string) { A.qux = function(x: string) {};
};
// error? // error?
class B extends A { class B extends A {
static x: string; static x: string;
// error? // error?
static foo(x: string) { static foo(x: string) {}
}
// error? // error?
static main() { static main() {
B.x = 0; B.x = 0;
@ -103,8 +99,7 @@ class B extends A {
class C<X> { class C<X> {
static x: X; static x: X;
static bar(x: X) { static bar(x: X) {}
}
static create(): C<*> { static create(): C<*> {
return new this(); return new this();
} }

View File

@ -69,8 +69,7 @@ class C<X> {
x: X; x: X;
} }
function foo<X>(c: C<X>, x: X) { function foo<X>(c: C<X>, x: X) {}
}
type O = { f: number }; type O = { f: number };

View File

@ -17,8 +17,7 @@ function foo(x: Class<A>): A {
} }
class B { class B {
constructor(_: any) { constructor(_: any) {}
}
} }
function bar(x: Class<B>): B { function bar(x: Class<B>): B {
return new x(); // error (too few args) return new x(); // error (too few args)

View File

@ -6,8 +6,7 @@ exports[`test A.js 1`] = `
module.exports = A; module.exports = A;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class A { class A {
foo(x: number): void { foo(x: number): void {}
}
} }
module.exports = A; module.exports = A;
@ -51,8 +50,7 @@ module.exports = C;
var B = require(\"./B\"); var B = require(\"./B\");
class C extends B { class C extends B {
foo(x: string): void { foo(x: string): void {}
}
} }
let c = new C(); let c = new C();

View File

@ -85,15 +85,13 @@ function local_meth() {
* @flow * @flow
*/ */
function takes_string(_: string) { function takes_string(_: string) {}
}
// global write from function // global write from function
// //
var global_x = \"hello\"; var global_x = \"hello\";
function global_f() { function global_f() {}
}
function global_g() { function global_g() {
global_x = 42; global_x = 42;
} }
@ -114,8 +112,7 @@ global_x = 42;
function local_func() { function local_func() {
var local_x = \"hello\"; var local_x = \"hello\";
function local_f() { function local_f() {}
}
function local_g() { function local_g() {
local_x = 42; local_x = 42;
} }
@ -136,8 +133,7 @@ function local_func() {
var global_y = \"hello\"; var global_y = \"hello\";
var global_o = { var global_o = {
f: function() { f: function() {},
},
g: function() { g: function() {
global_y = 42; global_y = 42;
} }
@ -160,8 +156,7 @@ function local_meth() {
var local_y = \"hello\"; var local_y = \"hello\";
var local_o = { var local_o = {
f: function() { f: function() {},
},
g: function() { g: function() {
local_y = 42; local_y = 42;
} }
@ -268,8 +263,7 @@ call_me();
*/ */
// global, anybody can call it at any time // global, anybody can call it at any time
var call_me: () => void = () => { var call_me: () => void = () => {};
};
function g(x: ?number) { function g(x: ?number) {
const const_x = x; const const_x = x;

View File

@ -113,8 +113,7 @@ function f(
someReallyLongArgument: WithSomeLongType, someReallyLongArgument: WithSomeLongType,
// Trailing comment should stay after // Trailing comment should stay after
someReallyLongArgument2: WithSomeLongType someReallyLongArgument2: WithSomeLongType
) { ) {}
}
// Comments should either stay at the end of the line or always before, but // Comments should either stay at the end of the line or always before, but
// not one before and one after. // not one before and one after.
@ -314,8 +313,7 @@ function f(
someReallyLongArgument: WithSomeLongType, someReallyLongArgument: WithSomeLongType,
// Trailing comment should stay after // Trailing comment should stay after
someReallyLongArgument2: WithSomeLongType someReallyLongArgument2: WithSomeLongType
) { ) {}
}
// Comments should either stay at the end of the line or always before, but // Comments should either stay at the end of the line or always before, but
// not one before and one after. // not one before and one after.

View File

@ -4,8 +4,7 @@ function f(x:string) { }
module.exports = f; module.exports = f;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function f(x: string) { function f(x: string) {}
}
module.exports = f; module.exports = f;
" "

View File

@ -4,8 +4,7 @@ exports[`test classes.js 1`] = `
} }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class c { class c {
[\"i\"]() { [\"i\"]() {}
}
} }
" "
`; `;

View File

@ -10,13 +10,11 @@ class D {
module.exports = C; module.exports = C;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class C { class C {
constructor() { constructor() {}
}
} }
class D { class D {
constructor(): number { constructor(): number {}
}
} }
module.exports = C; module.exports = C;

View File

@ -218,17 +218,13 @@ var {
(p: void); (p: void);
// error: string ~> void // error: string ~> void
function obj_prop_err({ x: { y } } = null) { function obj_prop_err({ x: { y } } = null) {}
}
// error: property \`x\` cannot be accessed on null // error: property \`x\` cannot be accessed on null
function obj_rest_err({ ...o } = 0) { function obj_rest_err({ ...o } = 0) {}
}
// error: expected object instead of number // error: expected object instead of number
function arr_elem_err([ x ] = null) { function arr_elem_err([ x ] = null) {}
}
// error: element 0 cannot be accessed on null // error: element 0 cannot be accessed on null
function arr_rest_err([ ...a ] = null) { function arr_rest_err([ ...a ] = null) {}
}
// error: expected array instead of null // error: expected array instead of null
function gen<T>(x: T, { p = x }: { p: T }): T { function gen<T>(x: T, { p = x }: { p: T }): T {
@ -242,19 +238,14 @@ obj_prop_var(({}: { p?: { q?: null } }));
// ok // ok
// union-like upper bounds preserved through destructuring // union-like upper bounds preserved through destructuring
function obj_prop_opt({ p }: { p?: string } = { p: 0 }) { function obj_prop_opt({ p }: { p?: string } = { p: 0 }) {}
} function obj_prop_maybe({ p }: { p: ?string } = { p: 0 }) {}
function obj_prop_maybe({ p }: { p: ?string } = { p: 0 }) { function obj_prop_union({ p }: { p: number | string } = { p: true }) {}
}
function obj_prop_union({ p }: { p: number | string } = { p: true }) {
}
// TODO: union-of-objects upper bounds preserved through destructuring // TODO: union-of-objects upper bounds preserved through destructuring
function obj_prop_union2({ p }: { p: number } | { p: string } = { p: true }) { function obj_prop_union2({ p }: { p: number } | { p: string } = { p: true }) {}
}
function default_expr_scope({ a, b = a }) { function default_expr_scope({ a, b = a }) {}
}
" "
`; `;
@ -360,11 +351,9 @@ bar({ x: \"\", y: 0 });
var spread = { y: \"\" }; var spread = { y: \"\" };
var extend: { x: number, y: string, z: boolean } = { x: 0, ...spread }; var extend: { x: number, y: string, z: boolean } = { x: 0, ...spread };
function qux(_: { a: number }) { function qux(_: { a: number }) {}
}
qux({ a: \"\" }); qux({ a: \"\" });
function corge({ b }: { b: string }) { function corge({ b }: { b: string }) {}
}
corge({ b: 0 }); corge({ b: 0 });
var { n }: { n: number } = { n: \"\" }; var { n }: { n: number } = { n: \"\" };
@ -484,35 +473,27 @@ function arr_rest_pattern<X>([ _, ...a ] : ArrRest<X>) { // a: [X]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow // @flow
function obj_pattern<X>({ prop }: { prop: X }) { function obj_pattern<X>({ prop }: { prop: X }) {}
}
// prop: X // prop: X
type Prop<X> = { prop: X }; type Prop<X> = { prop: X };
function obj_pattern2<X>({ prop }: Prop<X>) { function obj_pattern2<X>({ prop }: Prop<X>) {}
}
// prop: X // prop: X
function arr_pattern<X>([ elem ]: X[]) { function arr_pattern<X>([ elem ]: X[]) {}
}
// elem: X // elem: X
type Elem<X> = X[]; type Elem<X> = X[];
function arr_pattern2<X>([ elem ]: Elem<X>) { function arr_pattern2<X>([ elem ]: Elem<X>) {}
}
// elem: X // elem: X
function tup_pattern<X>([ proj ]: [X]) { function tup_pattern<X>([ proj ]: [X]) {}
}
// proj: X // proj: X
type Proj<X> = [X]; type Proj<X> = [X];
function tup_pattern2<X>([ proj ]: Proj<X>) { function tup_pattern2<X>([ proj ]: Proj<X>) {}
}
// proj: X // proj: X
function rest_antipattern<T>(...t: T) { function rest_antipattern<T>(...t: T) {}
}
// nonsense // nonsense
function rest_pattern<X>(...r: X[]) { function rest_pattern<X>(...r: X[]) {}
}
// r: X[] // r: X[]
function obj_rest_pattern<X>({ _, ...o }: { _: any, x: X }) { function obj_rest_pattern<X>({ _, ...o }: { _: any, x: X }) {

View File

@ -301,8 +301,7 @@ let tests = [
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow // @flow
let listener: EventListener = function(event: Event): void { let listener: EventListener = function(event: Event): void {};
};
let tests = [ let tests = [
// attachEvent // attachEvent
@ -424,26 +423,16 @@ let tests = [
function() { function() {
document.registerElement(\"custom-element\", { document.registerElement(\"custom-element\", {
prototype: Object.create(HTMLElement.prototype, { prototype: Object.create(HTMLElement.prototype, {
createdCallback: { createdCallback: { value: function createdCallback() {} },
value: function createdCallback() { attachedCallback: { value: function attachedCallback() {} },
} detachedCallback: { value: function detachedCallback() {} },
},
attachedCallback: {
value: function attachedCallback() {
}
},
detachedCallback: {
value: function detachedCallback() {
}
},
attributeChangedCallback: { attributeChangedCallback: {
value: function attributeChangedCallback( value: function attributeChangedCallback(
attributeLocalName, attributeLocalName,
oldAttributeValue, oldAttributeValue,
newAttributeValue, newAttributeValue,
attributeNamespace attributeNamespace
) { ) {}
}
} }
}) })
}); });
@ -452,19 +441,15 @@ let tests = [
function() { function() {
document.registerElement(\"custom-element\", { document.registerElement(\"custom-element\", {
prototype: Object.assign(Object.create(HTMLElement.prototype), { prototype: Object.assign(Object.create(HTMLElement.prototype), {
createdCallback() { createdCallback() {},
}, attachedCallback() {},
attachedCallback() { detachedCallback() {},
},
detachedCallback() {
},
attributeChangedCallback( attributeChangedCallback(
attributeLocalName, attributeLocalName,
oldAttributeValue, oldAttributeValue,
newAttributeValue, newAttributeValue,
attributeNamespace attributeNamespace
) { ) {}
}
}) })
}); });
}, },
@ -479,8 +464,7 @@ let tests = [
newVal: string, newVal: string,
// Error: This might be null // Error: This might be null
namespace: string namespace: string
) { ) {}
}
} }
}); });
} }

View File

@ -7,8 +7,7 @@ module.exports = num;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow // @flow
var num = 42; var num = 42;
function bar() { function bar() {}
}
bar(); bar();
module.exports = num; module.exports = num;
" "
@ -39,8 +38,7 @@ const idxResult = idx(obj, obj => obj.a.b.c.d);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow // @flow
var num = require(\"./import\"); var num = require(\"./import\");
function foo(x) { function foo(x) {}
}
foo(0); foo(0);
var a: string = num; var a: string = num;

View File

@ -36,10 +36,8 @@ class C5 {
new C5().m = new C5().m - 42; new C5().m = new C5().m - 42;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class C1 { class C1 {
m() { m() {}
} m() {}
m() {
}
} }
new C1().m(); new C1().m();
@ -48,17 +46,14 @@ class C2 {
get m() { get m() {
return 42; return 42;
} }
m() { m() {}
}
} }
new C2().m(); new C2().m();
class C3 { class C3 {
set m(x) { set m(x) {}
} m() {}
m() {
}
} }
new C3().m(); new C3().m();
@ -67,20 +62,17 @@ class C4 {
get m() { get m() {
return 42; return 42;
} }
set m(x: number) { set m(x: number) {}
}
} }
new C4().m = new C4().m - 42; new C4().m = new C4().m - 42;
class C5 { class C5 {
m() { m() {}
}
get m() { get m() {
return 42; return 42;
} }
set m(x: number) { set m(x: number) {}
}
} }
new C5().m = new C5().m - 42; new C5().m = new C5().m - 42;

View File

@ -1350,8 +1350,7 @@ import {
exports[`test export_default_arrow_expression.js 1`] = ` exports[`test export_default_arrow_expression.js 1`] = `
"export default () => {}; "export default () => {};
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export default () => { export default () => {};
};
" "
`; `;
@ -1379,32 +1378,28 @@ export default (class foobar {});
exports[`test export_default_function_declaration.js 1`] = ` exports[`test export_default_function_declaration.js 1`] = `
"export default function() {} "export default function() {}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export default function() { export default function() {}
}
" "
`; `;
exports[`test export_default_function_declaration_named.js 1`] = ` exports[`test export_default_function_declaration_named.js 1`] = `
"export default function f(){} "export default function f(){}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export default function f() { export default function f() {}
}
" "
`; `;
exports[`test export_default_function_expression.js 1`] = ` exports[`test export_default_function_expression.js 1`] = `
"export default (function() {}); "export default (function() {});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export default (function() { export default (function() {});
});
" "
`; `;
exports[`test export_default_function_expression_named.js 1`] = ` exports[`test export_default_function_expression_named.js 1`] = `
"export default (function f(){}) "export default (function f(){})
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export default (function f() { export default (function f() {});
});
" "
`; `;

View File

@ -79,8 +79,7 @@ let tests = [
}, },
// passed as a function // passed as a function
function(copyProperties: Object$Assign) { function(copyProperties: Object$Assign) {
function x(cb: Function) { function x(cb: Function) {}
}
x(copyProperties); x(copyProperties);
} }
]; ];
@ -206,8 +205,7 @@ let tests = [
}, },
// passed as a function // passed as a function
function(mergeInto: $Facebookism$MergeInto) { function(mergeInto: $Facebookism$MergeInto) {
function x(cb: Function) { function x(cb: Function) {}
}
x(mergeInto); x(mergeInto);
} }
]; ];

View File

@ -122,8 +122,7 @@ for (let v of e.entries()) {
const [ i, j ]: [string, string] = v; // correct const [ i, j ]: [string, string] = v; // correct
} }
e.getAll(\"content-type\").forEach((v: string) => { e.getAll(\"content-type\").forEach((v: string) => {}); // correct
}); // correct
" "
`; `;
@ -412,7 +411,6 @@ for (let v of e.entries()) {
const [ i, j ]: [string, string] = v; // correct const [ i, j ]: [string, string] = v; // correct
} }
e.getAll(\"key1\").forEach((v: string) => { e.getAll(\"key1\").forEach((v: string) => {}); // correct
}); // correct
" "
`; `;

View File

@ -317,8 +317,7 @@ function bad(x: Function, y: Object): void {
let tests = [ let tests = [
function(y: () => void, z: Function) { function(y: () => void, z: Function) {
function x() { function x() {}
}
(x.length: void); (x.length: void);
// error, it\'s a number // error, it\'s a number
(y.length: void); (y.length: void);
@ -333,8 +332,7 @@ let tests = [
(z.name: void); // error, it\'s a string (z.name: void); // error, it\'s a string
}, },
function(y: () => void, z: Function) { function(y: () => void, z: Function) {
function x() { function x() {}
}
x.length = \"foo\"; x.length = \"foo\";
// error, it\'s a number // error, it\'s a number
y.length = \"foo\"; y.length = \"foo\";
@ -373,23 +371,14 @@ new (function() {});
(function() {}); (function() {});
a = function f() {} || b; a = function f() {} || b;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
(function() { (function() {}).length;
}).length; typeof (function() {});
typeof (function() { export default (function() {})();
}); (function() {})()\`\`;
export default (function() { (function() {})\`\`;
})(); new (function() {})();
(function() { (function() {});
})()\`\`; a = function f() {} || b;
(function() {
})\`\`;
new (function() {
})();
(function() {
});
a = function f() {
} ||
b;
" "
`; `;

View File

@ -81,8 +81,7 @@ class D extends C {
// @flow // @flow
class C { class C {
override() { override() {}
}
} }
class D extends C { class D extends C {
@ -92,8 +91,7 @@ class D extends C {
bar() { bar() {
this.override; this.override;
} }
override() { override() {}
}
} }
" "
`; `;

View File

@ -79,19 +79,16 @@ class Foo {
get propWithMatchingGetterAndSetter(): number { get propWithMatchingGetterAndSetter(): number {
return 4; return 4;
} }
set propWithMatchingGetterAndSetter(x: number) { set propWithMatchingGetterAndSetter(x: number) {}
}
// The getter and setter need not have the same type - no error // The getter and setter need not have the same type - no error
get propWithSubtypingGetterAndSetter(): ?number { get propWithSubtypingGetterAndSetter(): ?number {
return 4; return 4;
} }
set propWithSubtypingGetterAndSetter(x: number) { set propWithSubtypingGetterAndSetter(x: number) {}
}
// The getter and setter need not have the same type - no error // The getter and setter need not have the same type - no error
set propWithSubtypingGetterAndSetterReordered(x: number) { set propWithSubtypingGetterAndSetterReordered(x: number) {}
}
get propWithSubtypingGetterAndSetterReordered(): ?number { get propWithSubtypingGetterAndSetterReordered(): ?number {
return 4; return 4;
} }
@ -99,8 +96,7 @@ class Foo {
get propWithMismatchingGetterAndSetter(): number { get propWithMismatchingGetterAndSetter(): number {
return 4; return 4;
} }
set propWithMismatchingGetterAndSetter(x: string) { set propWithMismatchingGetterAndSetter(x: string) {}
}
// doesn\'t match getter (OK) // doesn\'t match getter (OK)
propOverriddenWithGetter: number; propOverriddenWithGetter: number;
@ -109,8 +105,7 @@ class Foo {
} }
propOverriddenWithSetter: number; propOverriddenWithSetter: number;
set propOverriddenWithSetter(x: string) { set propOverriddenWithSetter(x: string) {}
}
} }
var foo = new Foo(); var foo = new Foo();
@ -231,17 +226,14 @@ var obj = {
get propWithMatchingGetterAndSetter(): number { get propWithMatchingGetterAndSetter(): number {
return 4; return 4;
}, },
set propWithMatchingGetterAndSetter(x: number) { set propWithMatchingGetterAndSetter(x: number) {},
},
// The getter and setter need not have the same type // The getter and setter need not have the same type
get propWithSubtypingGetterAndSetter(): ?number { get propWithSubtypingGetterAndSetter(): ?number {
return 4; return 4;
}, },
// OK // OK
set propWithSubtypingGetterAndSetter(x: number) { set propWithSubtypingGetterAndSetter(x: number) {},
}, set propWithSubtypingGetterAndSetterReordered(x: number) {},
set propWithSubtypingGetterAndSetterReordered(x: number) {
},
// OK // OK
get propWithSubtypingGetterAndSetterReordered(): ?number { get propWithSubtypingGetterAndSetterReordered(): ?number {
return 4; return 4;
@ -249,10 +241,8 @@ var obj = {
get exampleOfOrderOfGetterAndSetter(): A { get exampleOfOrderOfGetterAndSetter(): A {
return new A(); return new A();
}, },
set exampleOfOrderOfGetterAndSetter(x: B) { set exampleOfOrderOfGetterAndSetter(x: B) {},
}, set exampleOfOrderOfGetterAndSetterReordered(x: B) {},
set exampleOfOrderOfGetterAndSetterReordered(x: B) {
},
get exampleOfOrderOfGetterAndSetterReordered(): A { get exampleOfOrderOfGetterAndSetterReordered(): A {
return new A(); return new A();
} }
@ -430,8 +420,7 @@ class Base {
(class extends Base { (class extends Base {
// error: setter incompatible with read/write property // error: setter incompatible with read/write property
set x(value: B): void { set x(value: B): void {}
}
}); });
(class extends Base { (class extends Base {
@ -439,14 +428,12 @@ class Base {
get x(): C { get x(): C {
return c; return c;
} }
set x(value: A): void { set x(value: A): void {}
}
}); });
(class extends Base { (class extends Base {
// error: setter incompatible with read-only property // error: setter incompatible with read-only property
set pos(value: B): void { set pos(value: B): void {}
}
}); });
(class extends Base { (class extends Base {
@ -465,8 +452,7 @@ class Base {
(class extends Base { (class extends Base {
// ok: setter contravariant with write-only property // ok: setter contravariant with write-only property
set neg(value: A): void { set neg(value: A): void {}
}
}); });
(class extends Base { (class extends Base {

View File

@ -53,48 +53,42 @@ function _for_of(arr: Array<number>) {
function _if(b: () => boolean) { function _if(b: () => boolean) {
if (b()) { if (b()) {
var f = function() { var f = function() {};
};
} }
f(); // error, possibly undefined f(); // error, possibly undefined
} }
function _while(b: () => boolean) { function _while(b: () => boolean) {
while (b()) { while (b()) {
var f = function() { var f = function() {};
};
} }
f(); // error, possibly undefined f(); // error, possibly undefined
} }
function _do_while(b: () => boolean) { function _do_while(b: () => boolean) {
do { do {
var f = function() { var f = function() {};
};
} while (b()); } while (b());
f(); // ok f(); // ok
} }
function _for(n: number) { function _for(n: number) {
for (var i = 0; i < n; i++) { for (var i = 0; i < n; i++) {
var f = function() { var f = function() {};
};
} }
f(); // error, possibly undefined f(); // error, possibly undefined
} }
function _for_in(obj: Object) { function _for_in(obj: Object) {
for (var p in obj) { for (var p in obj) {
var f = function() { var f = function() {};
};
} }
f(); // error, possibly undefined f(); // error, possibly undefined
} }
function _for_of(arr: Array<number>) { function _for_of(arr: Array<number>) {
for (var x of arr) { for (var x of arr) {
var f = function() { var f = function() {};
};
} }
f(); // error, possibly undefined f(); // error, possibly undefined
} }

View File

@ -190,13 +190,11 @@ declare class C {
new C().bar((x: string) => { }); // error, number ~/~> string new C().bar((x: string) => { }); // error, number ~/~> string
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
interface I { foo(x: number): void } interface I { foo(x: number): void }
(function foo(x: number) { (function foo(x: number) {}: I);
}: I);
// error, property \`foo\` not found function // error, property \`foo\` not found function
declare class C { bar(i: I): void, bar(f: (x: number) => void): void } declare class C { bar(i: I): void, bar(f: (x: number) => void): void }
new C().bar((x: string) => { new C().bar((x: string) => {}); // error, number ~/~> string
}); // error, number ~/~> string
" "
`; `;

View File

@ -38,8 +38,7 @@ for (var y in this) {
} }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var a = [ true, false ]; var a = [ true, false ];
function foo(x) { function foo(x) {}
}
for (var i = 0; i < 3; i++) { for (var i = 0; i < 3; i++) {
foo(a[i]); foo(a[i]);

View File

@ -37,14 +37,12 @@ var red:string = tuple[indices.red]; // error: tuple[0] is a number
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var APIKeys = require(\"./enum\"); var APIKeys = require(\"./enum\");
// object that maps \"AGE\" to \"age\", \"NAME\" to \"name\" // object that maps \"AGE\" to \"age\", \"NAME\" to \"name\"
function foo(x: $Keys<typeof APIKeys>) { function foo(x: $Keys<typeof APIKeys>) {}
}
foo(\"AGE\"); foo(\"AGE\");
foo(\"LOCATION\"); foo(\"LOCATION\");
// error // error
function bar(x: $Keys<{ age: number }>) { function bar(x: $Keys<{ age: number }>) {}
}
bar(APIKeys.AGE); bar(APIKeys.AGE);
// not an error: APIKeys.AGE = \"age\" // not an error: APIKeys.AGE = \"age\"
bar(APIKeys.NAME); bar(APIKeys.NAME);

View File

@ -159,8 +159,7 @@ var x: string = 0;
var x: number = 1; var x: number = 1;
//declare var T: $Type<number | Array<T>>; //declare var T: $Type<number | Array<T>>;
function foo(p: boolean) { function foo(p: boolean) {}
}
function sorry(really: boolean) { function sorry(really: boolean) {
if (really) { if (really) {

View File

@ -36,12 +36,9 @@ function f(x) {
f(foo); f(foo);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class C { class C {
C() { C() {}
} foo() {}
foo() { static bar() {}
}
static bar() {
}
qux() { qux() {
this.constructor.x; this.constructor.x;
} }

View File

@ -21,8 +21,7 @@ module.exports = {};
var A = { x: true, ...{} }; var A = { x: true, ...{} };
module.exports.cls = A; module.exports.cls = A;
function f(x: boolean) { function f(x: boolean) {}
}
module.exports.fn = f; module.exports.fn = f;
A.y = \"?\"; A.y = \"?\";
@ -147,8 +146,7 @@ module.exports = {obj: o};
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @providesModule E */ /* @providesModule E */
function h(x: number) { function h(x: number) {}
}
var proto = { fn: h }; var proto = { fn: h };
var o = Object.create(proto); var o = Object.create(proto);

View File

@ -41,8 +41,7 @@ module.exports = f;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */ /* @flow */
function g(x: string) { function g(x: string) {}
}
//function f(x) { g(x); return x; } //function f(x) { g(x); return x; }
//function f(x:number) { g(x); return x; } //function f(x:number) { g(x); return x; }

View File

@ -42,8 +42,7 @@ var o2: Foo = new Foo();
function Foo() { function Foo() {
this.x = 0; this.x = 0;
} }
Foo.prototype.m = function() { Foo.prototype.m = function() {};
};
var o1: { x: number, m(): void } = new Foo(); var o1: { x: number, m(): void } = new Foo();
@ -58,8 +57,7 @@ class D extends C { }
var d: { +m: () => void } = new D(); var d: { +m: () => void } = new D();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class C { class C {
m() { m() {}
}
} }
class D extends C {} class D extends C {}

View File

@ -121,8 +121,7 @@ class Qux {
return this.w; return this.w;
} }
fooqux(x: number) { fooqux(x: number) {}
}
} }
module.exports = Qux; module.exports = Qux;

View File

@ -59,8 +59,7 @@ module.exports = true;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @providesModule Condition */ /* @providesModule Condition */
function f(x: number) { function f(x: number) {}
}
function g() { function g() {
return 42 || \"hello\"; return 42 || \"hello\";
} }
@ -86,8 +85,7 @@ function bar() {
} }
class C { class C {
qux() { qux() {}
}
} }
function foo() { function foo() {
@ -140,8 +138,7 @@ module.exports = FlowSA;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @providesModule FlowSA */ /* @providesModule FlowSA */
function check(x: string) { function check(x: string) {}
}
function FlowSA() { function FlowSA() {
var x = 0; var x = 0;
@ -198,18 +195,15 @@ module.exports = \"sigma\";
/* @providesModule Sigma */ /* @providesModule Sigma */
class A { class A {
a() { a() {}
}
} }
class B extends A { class B extends A {
b() { b() {}
}
} }
class C extends B { class C extends B {
c() { c() {}
}
} }
function bar(x: B) { function bar(x: B) {
@ -234,8 +228,7 @@ function foo(x: A) {
} }
class D { class D {
d() { d() {}
}
} }
function baz(x: D) { function baz(x: D) {

View File

@ -31,8 +31,7 @@ module.exports = { foo: (\"\": number) };
/*@flow*/ /*@flow*/
// import type { T } from \'...\' // import type { T } from \'...\'
type T = (x: number) => void; type T = (x: number) => void;
var f: T = function(x: string): void { var f: T = function(x: string): void {};
};
type Map<X, Y> = (x: X) => Y; type Map<X, Y> = (x: X) => Y;

View File

@ -44,18 +44,14 @@ var data = \"foo\";
ls.stdin.write(data); ls.stdin.write(data);
ls.stdin.write(data, \"utf-8\"); ls.stdin.write(data, \"utf-8\");
ls.stdin.write(data, () => { ls.stdin.write(data, () => {});
}); ls.stdin.write(data, \"utf-8\", () => {});
ls.stdin.write(data, \"utf-8\", () => {
});
ls.stdin.end(); ls.stdin.end();
ls.stdin.end(data); ls.stdin.end(data);
ls.stdin.end(data, \"utf-8\"); ls.stdin.end(data, \"utf-8\");
ls.stdin.end(data, () => { ls.stdin.end(data, () => {});
}); ls.stdin.end(data, \"utf-8\", () => {});
ls.stdin.end(data, \"utf-8\", () => {
});
var ws = fs.createWriteStream(\"/dev/null\"); var ws = fs.createWriteStream(\"/dev/null\");
ls.stdout.pipe(ws).end(); ls.stdout.pipe(ws).end();

View File

@ -42,11 +42,9 @@ function bar(): ?string {
return null; return null;
} }
function qux(x: string) { function qux(x: string) {}
}
function corge(x: number) { function corge(x: number) {}
}
var x = bar(); var x = bar();
// x: ?string // x: ?string
@ -76,15 +74,12 @@ bar(\'hmm\');
function fn(data: ?{}) {} function fn(data: ?{}) {}
fn({some: \'literal\'}); fn({some: \'literal\'});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function foo(x: ?string) { function foo(x: ?string) {}
} function bar(x: ?number) {}
function bar(x: ?number) {
}
foo(\"hmm\"); foo(\"hmm\");
bar(\"hmm\"); bar(\"hmm\");
function fn(data: ?{}) { function fn(data: ?{}) {}
}
fn({ some: \"literal\" }); fn({ some: \"literal\" });
" "
`; `;

View File

@ -4,10 +4,7 @@ exports[`test a.js 1`] = `
module.exports = { a() {} };~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ module.exports = { a() {} };~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */ /* @flow */
module.exports = { module.exports = { a() {} };
a() {
}
};
" "
`; `;
@ -22,14 +19,7 @@ module.exports = b;
/* @flow */ /* @flow */
var a = require(\"./a\"); var a = require(\"./a\");
var b = Object.assign( var b = Object.assign({ bar() {}, ...{} }, a);
{
bar() {
},
...{}
},
a
);
b.a(); b.a();
// works here // works here
module.exports = b; module.exports = b;
@ -207,8 +197,7 @@ var any: Object = {};
// error, Array<string> // error, Array<string>
class Foo { class Foo {
prop: string; prop: string;
foo() { foo() {}
}
} }
// constructor and foo not enumerable // constructor and foo not enumerable
(Object.keys(new Foo()): Array<\"error\">); (Object.keys(new Foo()): Array<\"error\">);
@ -216,8 +205,7 @@ class Foo {
// error: prop ~> error // error: prop ~> error
class Bar extends Foo { class Bar extends Foo {
bar_prop: string; bar_prop: string;
bar() { bar() {}
}
} }
// only own enumerable props // only own enumerable props
(Object.keys(new Bar()): Array<\"error\">); // error: bar_prop ~> error (Object.keys(new Bar()): Array<\"error\">); // error: bar_prop ~> error
@ -411,14 +399,10 @@ var k : Object = a.constructor;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */ /* @flow */
function takesABool(x: boolean) { function takesABool(x: boolean) {}
} function takesAString(x: string) {}
function takesAString(x: string) { function takesANumber(x: number) {}
} function takesAnObject(x: Object) {}
function takesANumber(x: number) {
}
function takesAnObject(x: Object) {
}
class Foo {} class Foo {}
@ -473,8 +457,7 @@ takesAString(y.toString());
// ... on a primitive // ... on a primitive
(123).toString(); (123).toString();
(123).toString; (123).toString;
(123).toString = function() { (123).toString = function() {};
};
// error // error
(123).toString(2); (123).toString(2);
(123).toString(\"foo\"); (123).toString(\"foo\");

View File

@ -39,8 +39,7 @@ bliffl.corge;
// error // error
bliffl.constructor = baz; bliffl.constructor = baz;
// error // error
bliffl.toString = function() { bliffl.toString = function() {};
};
// error // error
baz.baz = 0; baz.baz = 0;

View File

@ -27,12 +27,10 @@ class C {
x<T>(x: T = 0) {} x<T>(x: T = 0) {}
} }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function x<T>(x: T = 0) { function x<T>(x: T = 0) {}
}
class C { class C {
x<T>(x: T = 0) { x<T>(x: T = 0) {}
}
} }
" "
`; `;
@ -267,8 +265,7 @@ function testOptionalNullableProperty(obj: { x?: ?string }): string {
} }
function testOptionalNullableFlowingToNullable(x?: ?string): ?string { function testOptionalNullableFlowingToNullable(x?: ?string): ?string {
var f = function(y: ?string) { var f = function(y: ?string) {};
};
f(x); f(x);
} }
" "
@ -298,8 +295,7 @@ function bar(x = \"bar\"): string {
} }
bar(undefined); // ok bar(undefined); // ok
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function foo(x?: number) { function foo(x?: number) {}
}
foo(undefined); foo(undefined);
// ok // ok

View File

@ -24,8 +24,7 @@ y = o;
o.foo = 0; o.foo = 0;
// future widening is constrained // future widening is constrained
function bar(config: { foo?: number }) { function bar(config: { foo?: number }) {}
}
bar({}); bar({});
bar({ foo: \"\" }); bar({ foo: \"\" });
" "

View File

@ -24,8 +24,7 @@ function f6(x: mixed): %checks (x !== null) { }
// Error: no return statement // Error: no return statement
function f6(x: mixed): %checks(x !== null) { function f6(x: mixed): %checks(x !== null) {}
}
" "
`; `;

View File

@ -589,8 +589,7 @@ Promise
// TODO: resolvedPromise<T> -> catch() -> then():T // TODO: resolvedPromise<T> -> catch() -> then():T
Promise Promise
.resolve(0) .resolve(0)
.catch(function(err) { .catch(function(err) {})
})
.then(function(num) { .then(function(num) {
var a: number = num; var a: number = num;

View File

@ -197,18 +197,8 @@ var Example = React.createClass({
propTypes: { func: React.PropTypes.func.isRequired } propTypes: { func: React.PropTypes.func.isRequired }
}); });
var ok_void = ( var ok_void = <Example func={() => {}} />;
<Example var ok_args = <Example func={x => {}} />;
func={() => {
}}
/>
);
var ok_args = (
<Example
func={x => {
}}
/>
);
var ok_retval = <Example func={() => 1} />; var ok_retval = <Example func={() => 1} />;
var fail_mistyped = <Example func={2} />; var fail_mistyped = <Example func={2} />;

View File

@ -15,8 +15,7 @@ var Z = 0;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import React from \"react\"; import React from \"react\";
function F(props: { foo: string }) { function F(props: { foo: string }) {}
}
<F />; <F />;
/* error: missing \`foo\`*/ /* error: missing \`foo\`*/
<F foo={0} />; <F foo={0} />;
@ -25,8 +24,7 @@ function F(props: { foo: string }) {
// ok // ok
// props subtyping is property-wise covariant // props subtyping is property-wise covariant
function G(props: { foo: string | numner }) { function G(props: { foo: string | numner }) {}
}
<G foo=\"\" />; <G foo=\"\" />;
// ok // ok

View File

@ -130,8 +130,7 @@ export function foo(props: { x: number }) { }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow // @flow
export function foo(props: { x: number }) { export function foo(props: { x: number }) {}
}
" "
`; `;

View File

@ -5,7 +5,6 @@ export function foo(props: { y: number }) { }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow // @flow
export function foo(props: { y: number }) { export function foo(props: { y: number }) {}
}
" "
`; `;

View File

@ -208,8 +208,7 @@ function testLiteralProperty(a: A) {
type A = { \"b_c\": ?string }; type A = { \"b_c\": ?string };
function stuff(str: string) { function stuff(str: string) {}
}
function testProperty(a: A) { function testProperty(a: A) {
if (a.b_c) { if (a.b_c) {
@ -601,8 +600,7 @@ function def_assign_setprop_nohavoc(obj: Obj, obj2: Obj2) {
type Obj = { p: number | string }; type Obj = { p: number | string };
function f() { function f() {}
}
function def_assign_function_havoc(obj: Obj) { function def_assign_function_havoc(obj: Obj) {
obj.p = 10; obj.p = 10;
@ -799,8 +797,7 @@ function foo5() {
o.p(); o.p();
} }
function _foo5() { function _foo5() {
o.p = function() { o.p = function() {};
};
} }
} }
@ -958,10 +955,8 @@ function arr0(x: mixed) {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */ /* @flow */
function takesNumber(x: number) { function takesNumber(x: number) {}
} function takesString(x: string) {}
function takesString(x: string) {
}
function num(x: mixed) { function num(x: mixed) {
if (typeof x === \"number\") { if (typeof x === \"number\") {
@ -1726,8 +1721,7 @@ function bar(b) {
var z: string = x; var z: string = x;
} }
function maybe_throw() { function maybe_throw() {}
}
function qux() { function qux() {
var x = 0; var x = 0;
try { try {

View File

@ -7,8 +7,7 @@ foo(\"\");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var a = 0; var a = 0;
function foo(x) { function foo(x) {}
}
foo(\"\"); foo(\"\");
" "

View File

@ -74,8 +74,7 @@ require(\"not a module name\");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow // @flow
function require() { function require() {}
}
require(\"not a module name\"); require(\"not a module name\");
" "
`; `;
@ -132,10 +131,8 @@ require.call(null, \"DoesNotExist\");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */ /* @flow */
function takesANumber(num: number): void { function takesANumber(num: number): void {}
} function takesAString(str: string): void {}
function takesAString(str: string): void {
}
// @providesModule // @providesModule
var A = require(\"A\"); var A = require(\"A\");

View File

@ -86,8 +86,7 @@ var notB: Object = B;
requireLazy(); requireLazy();
// Error: No args // Error: No args
requireLazy([ nope ], function() { requireLazy([ nope ], function() {});
});
// Error: Non-stringliteral args // Error: Non-stringliteral args
requireLazy([ \"A\" ]); // Error: No calback expression requireLazy([ \"A\" ]); // Error: No calback expression
" "

View File

@ -27,8 +27,7 @@ declare class C {
function f( function f(
superSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperLong, superSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperSuperLong,
...args ...args
) { ) {}
}
declare class C { declare class C {
f( f(

View File

@ -37,8 +37,7 @@ module.exports = C;
//module.exports = fn; //module.exports = fn;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class C { class C {
foo() { foo() {}
}
bar() { bar() {
return; return;
} }

View File

@ -24,8 +24,7 @@ function Bar() {
var bar: number = new Bar(); var bar: number = new Bar();
// error (returns new object) // error (returns new object)
function Qux() { function Qux() {}
}
var qux: number = new Qux(); var qux: number = new Qux();
// error (returns new object) // error (returns new object)

View File

@ -41,8 +41,7 @@ var export_o: { x:any; } = o; // awkward type cast
module.exports = export_o; module.exports = export_o;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function Foo() { function Foo() {}
}
var o = new Foo(); var o = new Foo();
var x: number = o.x; var x: number = o.x;

View File

@ -3,8 +3,7 @@ exports[`test shebang.js 1`] = `
function a() {} function a() {}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#!/usr/bin/env node #!/usr/bin/env node
function a() { function a() {}
}
" "
`; `;
@ -15,7 +14,6 @@ function a() {}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#!/usr/bin/env node #!/usr/bin/env node
function a() { function a() {}
}
" "
`; `;

View File

@ -127,8 +127,7 @@ bar(3);
// error // error
type ComparatorResult = -1 | 0 | 1; type ComparatorResult = -1 | 0 | 1;
function sort(fn: (x: any, y: any) => ComparatorResult) { function sort(fn: (x: any, y: any) => ComparatorResult) {}
}
sort((x, y) => -1); sort((x, y) => -1);
" "
`; `;

View File

@ -74,8 +74,7 @@ foo({foo: 42});
function foo(o) { function foo(o) {
bar({ ...o }); bar({ ...o });
} }
function bar(_: { foo: number }) { function bar(_: { foo: number }) {}
}
foo({ foo: 42 }); foo({ foo: 42 });
" "
`; `;
@ -119,8 +118,7 @@ function test(...nums: Array<number>) {}
test(0, ...[1, 2, 3]); test(0, ...[1, 2, 3]);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */ /* @flow */
function test(...nums: Array<number>) { function test(...nums: Array<number>) {}
}
test(0, ...[ 1, 2, 3 ]); test(0, ...[ 1, 2, 3 ]);
" "

View File

@ -10,8 +10,7 @@ C.g(0);
var x:number = C.x; var x:number = C.x;
C.x = 0;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C.x = 0;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class C { class C {
static f(x: number) { static f(x: number) {}
}
static x: string; static x: string;
} }
@ -32,8 +31,7 @@ C.g = function(x) { return x; };
var x:string = new C().f(); var x:string = new C().f();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function C() { function C() {}
}
C.prototype.f = function() { C.prototype.f = function() {
return C.g(0); return C.g(0);
}; };

View File

@ -15,8 +15,7 @@ class B extends A {
foo(x: A): A { foo(x: A): A {
return x; return x;
} }
bar(x) { bar(x) {}
}
qux<X, Y>(x: X, y: Y): X { qux<X, Y>(x: X, y: Y): X {
return x; return x;
} }

View File

@ -223,8 +223,7 @@ class I_ {
constructor(leaked_this) { constructor(leaked_this) {
leaked_this.foo(); leaked_this.foo();
} }
foo() { foo() {}
}
} }
class I extends I_ { class I extends I_ {
constructor() { constructor() {
@ -238,8 +237,7 @@ class J_ extends J__ {
closure_leaking_this(); closure_leaking_this();
super(); super();
} }
foo() { foo() {}
}
} }
class J extends J_ { class J extends J_ {
constructor() { constructor() {
@ -257,8 +255,7 @@ class K_ {
constructor(closure_leaking_this) { constructor(closure_leaking_this) {
this.closure_leaking_this = closure_leaking_this; this.closure_leaking_this = closure_leaking_this;
} }
foo() { foo() {}
}
} }
class K extends K_ { class K extends K_ {
constructor() { constructor() {
@ -362,13 +359,11 @@ class B extends A {
} }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class A { class A {
constructor(x: number) { constructor(x: number) {}
}
static staticMethod(x: string): string { static staticMethod(x: string): string {
return x; return x;
} }
f(x: string) { f(x: string) {}
}
} }
class B extends A { class B extends A {

View File

@ -74,8 +74,7 @@ function runTest(y: number): void {
); );
} }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function takesAString(x: string): void { function takesAString(x: string): void {}
}
function runTest(y: number): void { function runTest(y: number): void {
takesAString( takesAString(

View File

@ -61,8 +61,7 @@ function a() {
} }
} }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const c = () => { const c = () => {};
};
function a() { function a() {
return function b() { return function b() {
@ -89,8 +88,7 @@ function a() {
} }
} }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const c = () => { const c = () => {};
};
function a() { function a() {
return function b() { return function b() {

View File

@ -88,8 +88,7 @@ function* f() {
} }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// \"ArrowFunctionExpression\" // \"ArrowFunctionExpression\"
(() => { (() => {})\`\`;
})\`\`;
// \"AssignmentExpression\" // \"AssignmentExpression\"
(b = c)\`\`; (b = c)\`\`;
@ -112,8 +111,7 @@ b()\`\`;
(b ? c : d)\`\`; (b ? c : d)\`\`;
// \"FunctionExpression\" // \"FunctionExpression\"
(function() { (function() {})\`\`;
})\`\`;
// \"LogicalExpression\" // \"LogicalExpression\"
(b || c)\`\`; (b || c)\`\`;

View File

@ -69,8 +69,7 @@ F.prototype.m = function() {
this.y = 0; this.y = 0;
}; };
function foo(p: string) { function foo(p: string) {}
}
var o1 = new F(); var o1 = new F();
// sets o1.x to 0 // sets o1.x to 0
@ -199,8 +198,7 @@ var j = g();
// error, since return type of bar is C, not the type of \`this\` // error, since return type of bar is C, not the type of \`this\`
class E { class E {
foo(x: number) { foo(x: number) {}
}
} }
class F extends E { class F extends E {
foo() { foo() {

View File

@ -90,13 +90,11 @@ var d = new D();
// sneaky // sneaky
class A { class A {
foo<X: this>(that: X) { foo<X: this>(that: X) {} // error: can\'t hide contravariance using a bound
} // error: can\'t hide contravariance using a bound
} }
class B extends A { class B extends A {
foo<Y: this>(that: Y) { foo<Y: this>(that: Y) {} // error (see above, catches hidden override)
} // error (see above, catches hidden override)
} }
// covariance checks on this type in invariant positions // covariance checks on this type in invariant positions
@ -104,15 +102,13 @@ class Invariant {
out_object(): { _: this } { out_object(): { _: this } {
return { _: this }; return { _: this };
} }
in_object(_: { _: this }) { in_object(_: { _: this }) {}
}
inout_object: { _: this }; inout_object: { _: this };
out_array(): Array<this> { out_array(): Array<this> {
return [ this ]; return [ this ];
} }
in_array(_: Array<this>) { in_array(_: Array<this>) {}
}
inout_array: Array<this>; inout_array: Array<this>;
} }
@ -122,16 +118,14 @@ class Misc {
out_set(): Set<this> { out_set(): Set<this> {
return new Set().add(this); return new Set().add(this);
} }
in_set(_: Set<this>) { in_set(_: Set<this>) {}
}
inout_set: Set<this>; inout_set: Set<this>;
// Promise<X> has covariant X // Promise<X> has covariant X
async out_promise(): Promise<this> { async out_promise(): Promise<this> {
return this; return this;
} }
in_promise(_: Promise<this>) { in_promise(_: Promise<this>) {}
}
inout_promise: Promise<this>; inout_promise: Promise<this>;
// Generator<X,Y,Z> has covariant X, covariant Y, contravariant Z // Generator<X,Y,Z> has covariant X, covariant Y, contravariant Z
@ -139,8 +133,7 @@ class Misc {
yield this; yield this;
return this; return this;
} }
in_generator(_: Generator<this, this, this>) { in_generator(_: Generator<this, this, this>) {}
}
inout_generator: Generator<this, this, this>; inout_generator: Generator<this, this, this>;
} }
" "
@ -529,10 +522,8 @@ class Base2 {
return this.bar(); return this.bar();
} }
corge(that: this) { corge(that: this) {}
} grault(that: Base2) {}
grault(that: Base2) {
}
} }
class Inherit2 extends Base2 {} class Inherit2 extends Base2 {}
@ -552,12 +543,10 @@ class Override2 extends Base2 {
} }
// error (cf. OK above) // error (cf. OK above)
// see exploit below // see exploit below
corge(that: this) { corge(that: this) {}
}
// error // error
// see exploit below // see exploit below
grault(that: this) { grault(that: this) {} // error, too
} // error, too
} }
class InheritOverride2 extends Override2 {} class InheritOverride2 extends Override2 {}

View File

@ -21,24 +21,21 @@ function double(n) { return n * 2 }
f3(double); f3(double);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// arg/param type mismatch on arg 0 // arg/param type mismatch on arg 0
function g0(y: string) { function g0(y: string) {}
}
function f0(x) { function f0(x) {
g0(x); g0(x);
} }
f0(0); f0(0);
// ...on arg n // ...on arg n
function g1(a: string, b: string) { function g1(a: string, b: string) {}
}
function f1(x, y) { function f1(x, y) {
g1(x, y); g1(x, y);
} }
f1(\"hey\", 0); f1(\"hey\", 0);
// h/o call with function expr // h/o call with function expr
function g2(ylam: (s: string) => number) { function g2(ylam: (s: string) => number) {}
}
function f2(xlam) { function f2(xlam) {
g2(xlam); g2(xlam);
} }
@ -47,8 +44,7 @@ f2(function(x) {
}); });
// h/o call with function def // h/o call with function def
function g3(ylam: (s: string) => number) { function g3(ylam: (s: string) => number) {}
}
function f3(xlam) { function f3(xlam) {
g3(xlam); g3(xlam);
} }

View File

@ -11,8 +11,7 @@ a(
a(\'value\', \'value2\', a(\'long-nested-value\', \'long-nested-value2\', \'long-nested-value3\')); a(\'value\', \'value2\', a(\'long-nested-value\', \'long-nested-value2\', \'long-nested-value3\'));
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const a = (param1, param2, param3) => { const a = (param1, param2, param3) => {};
};
a(\"value\", \"value2\", \"value3\"); a(\"value\", \"value2\", \"value3\");
@ -43,8 +42,7 @@ a(
a(\'value\', \'value2\', a(\'long-nested-value\', \'long-nested-value2\', \'long-nested-value3\')); a(\'value\', \'value2\', a(\'long-nested-value\', \'long-nested-value2\', \'long-nested-value3\'));
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const a = (param1, param2, param3) => { const a = (param1, param2, param3) => {};
};
a(\"value\", \"value2\", \"value3\"); a(\"value\", \"value2\", \"value3\");

View File

@ -196,8 +196,7 @@ function f(b) {
// for illustrative purposes only - Flow considers a throw possible // for illustrative purposes only - Flow considers a throw possible
// anywhere within a block // anywhere within a block
function might_throw() { function might_throw() {}
}
// local use of annotated var within try is ok // local use of annotated var within try is ok
function f() { function f() {

View File

@ -49,8 +49,7 @@ foo([ {} ]); // error, too few elements in array passed to a tuple
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */ /* @flow */
function foo(a: [Object, Object]) { function foo(a: [Object, Object]) {}
}
foo([ {} ]); // error, too few elements in array passed to a tuple foo([ {} ]); // error, too few elements in array passed to a tuple
" "

View File

@ -59,10 +59,7 @@ const y = {
// foo(): void {} // foo(): void {}
// } // }
const y = { const y = { bar(): void {} };
bar(): void {
}
};
" "
`; `;
@ -135,8 +132,7 @@ module.exports = num;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow // @flow
var num = 42; var num = 42;
function bar() { function bar() {}
}
bar(); bar();
module.exports = num; module.exports = num;
" "
@ -254,8 +250,7 @@ const w:MyNum = 42;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow // @flow
var str = require(\"./import\"); var str = require(\"./import\");
function foo() { function foo() {}
}
foo(); foo();
str; str;

View File

@ -15,8 +15,7 @@ class C<T> {
this.b(a); // error: A ~> incompatible instance of T this.b(a); // error: A ~> incompatible instance of T
} }
b(x: T) { b(x: T) {}
}
} }
" "
`; `;
@ -37,8 +36,7 @@ f(0); // ok
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function f<T>(a: T) { function f<T>(a: T) {
function g<U>(b: U, c: T = a) { function g<U>(b: U, c: T = a) {
function h(d: U = b) { function h(d: U = b) {}
}
h(); h();
// ok // ok
h(b); h(b);

View File

@ -23,8 +23,7 @@ function doSomethingAsync(): Promise<void> {
} }
// simpler repro to show that too few args are fine when expecting void // simpler repro to show that too few args are fine when expecting void
function foo(x: void) { function foo(x: void) {}
}
foo(); foo();
" "
`; `;
@ -52,8 +51,7 @@ function bar() {
if (x) x.bar(); if (x) x.bar();
} }
function qux(x?: number, y: string = \"\", z) { function qux(x?: number, y: string = \"\", z) {}
}
" "
`; `;

View File

@ -110,27 +110,8 @@ myclass.myfun([\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", function (ar) {}
declare class Myclass { myfun(myarray: Array<Function | string>): any } declare class Myclass { myfun(myarray: Array<Function | string>): any }
declare var myclass: Myclass; declare var myclass: Myclass;
myclass.myfun([ myclass.myfun([ \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", function(ar) {} ]);
\"1\", myclass.myfun([ \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", function(ar) {} ]);
\"2\",
\"3\",
\"4\",
\"5\",
\"6\",
function(ar) {
}
]);
myclass.myfun([
\"1\",
\"2\",
\"3\",
\"4\",
\"5\",
\"6\",
\"7\",
function(ar) {
}
]);
" "
`; `;
@ -343,8 +324,7 @@ type Foo<X: ?C> = Array<X>;
// workaround // workaround
var x: Array<C> = []; var x: Array<C> = [];
var y: Array<?C> = []; var y: Array<?C> = [];
function foo<X>(x: Foo<X>) { function foo<X>(x: Foo<X>) {}
}
foo(x); foo(x);
foo(y); foo(y);
@ -356,8 +336,7 @@ type Bar = () => C | string;
function f() { function f() {
return \"\"; return \"\";
} }
function bar(x: Bar) { function bar(x: Bar) {}
}
bar(f); bar(f);
" "
`; `;
@ -431,8 +410,7 @@ function corge(b) {
new F().foo(x); new F().foo(x);
} }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function bar(x: Document | string): void { function bar(x: Document | string): void {}
}
bar(0); bar(0);
class C {} class C {}
@ -441,11 +419,9 @@ function CD(b) {
var E = b ? C : D; var E = b ? C : D;
var c: C = new E(); var c: C = new E();
// error, since E could be D, and D is not a subtype of C // error, since E could be D, and D is not a subtype of C
function qux(e: E) { function qux(e: E) {}
}
// this annotation is an error: is it C, or is it D? // this annotation is an error: is it C, or is it D?
function qux2(e: C | D) { function qux2(e: C | D) {}
}
// OK // OK
qux2(new C()); qux2(new C());
} }

View File

@ -155,8 +155,7 @@ function node(content: ?Foobar | String | Array<String>) {
/* @flow */ /* @flow */
import type { Foobar } from \"./issue-1455-helper\"; import type { Foobar } from \"./issue-1455-helper\";
function create(content: ?Foobar | String | Array<String>) { function create(content: ?Foobar | String | Array<String>) {}
}
function node(content: ?Foobar | String | Array<String>) { function node(content: ?Foobar | String | Array<String>) {
create(content); create(content);
@ -490,8 +489,7 @@ type B4 = string;
///////////////////////////////////////////// /////////////////////////////////////////////
// similar example with class instance types // similar example with class instance types
///////////////////////////////////////////// /////////////////////////////////////////////
function inst(a: A5 | A6) { function inst(a: A5 | A6) {}
}
class B5 {} class B5 {}
class B6 {} class B6 {}
@ -591,8 +589,7 @@ type B6 = string;
// example with object types // example with object types
////////////////////////////// //////////////////////////////
function obj(a: { x: number } | { x: string }) { function obj(a: { x: number } | { x: string }) {}
}
obj(({ x: \"\" }: A1)); obj(({ x: \"\" }: A1));
@ -603,8 +600,7 @@ type B1 = string;
/////////////////////////////////////// ///////////////////////////////////////
// similar example with function types // similar example with function types
/////////////////////////////////////// ///////////////////////////////////////
function fun(a: (() => number) | (() => string)) { function fun(a: (() => number) | (() => string)) {}
}
fun((() => \"\": A2)); fun((() => \"\": A2));
@ -617,8 +613,7 @@ type B2 = string;
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
class C<X> {} class C<X> {}
function inst(a: C<number> | C<string>) { function inst(a: C<number> | C<string>) {}
}
inst((new C(): A3)); inst((new C(): A3));
@ -629,12 +624,8 @@ type B3 = string;
///////////////////////////////////////////// /////////////////////////////////////////////
// similar example with generic type aliases // similar example with generic type aliases
///////////////////////////////////////////// /////////////////////////////////////////////
function alias(a: T<number> | T<string>) { function alias(a: T<number> | T<string>) {}
} alias({ x: (x: V<B4>) => {} });
alias({
x: (x: V<B4>) => {
}
});
type T<X> = { x: U<X> }; type T<X> = { x: U<X> };
type U<X> = (x: V<X>) => void; type U<X> = (x: V<X>) => void;
@ -643,8 +634,7 @@ type V<X> = X;
type B4 = string; type B4 = string;
// class statics // class statics
function stat(a: { x: number } | { x: string }) { function stat(a: { x: number } | { x: string }) {}
}
class D { class D {
static x: B5; static x: B5;
@ -655,8 +645,7 @@ stat(D);
type B5 = string; type B5 = string;
// tuples // tuples
function tup(a: [number, boolean] | [string, boolean]) { function tup(a: [number, boolean] | [string, boolean]) {}
}
tup(([ \"\", false ]: A6)); tup(([ \"\", false ]: A6));
@ -706,13 +695,9 @@ type B2 = string;
// example with function types // example with function types
/////////////////////////////// ///////////////////////////////
function fun(a: ((x: number) => void) | ((x: string) => void)) { function fun(a: ((x: number) => void) | ((x: string) => void)) {}
}
fun( fun((x => {}: A1));
(x => {
}: A1)
);
type A1 = (x: B1) => void; type A1 = (x: B1) => void;
@ -721,8 +706,7 @@ type B1 = string;
//////////////////////////// ////////////////////////////
// example with array types // example with array types
//////////////////////////// ////////////////////////////
function arr(a: number[] | string[]) { function arr(a: number[] | string[]) {}
}
arr(([]: A2)); arr(([]: A2));
@ -780,11 +764,9 @@ type B2 = string;
// example with function types // example with function types
/////////////////////////////// ///////////////////////////////
function fun(a: ((x: number) => void) | ((x: string) => void)) { function fun(a: ((x: number) => void) | ((x: string) => void)) {}
}
const a1 = (x => { const a1 = (x => {}: A1);
}: A1);
fun(a1); fun(a1);
function fun_call(x: string) { function fun_call(x: string) {
@ -798,8 +780,7 @@ type B1 = string;
//////////////////////////// ////////////////////////////
// example with array types // example with array types
//////////////////////////// ////////////////////////////
function arr(a: number[] | string[]) { function arr(a: number[] | string[]) {}
}
const a2 = ([]: A2); const a2 = ([]: A2);
arr(a2); arr(a2);
@ -856,8 +837,7 @@ function arr_set(x: string, i: number) { a2[i] = x; }
// example with function types // example with function types
/////////////////////////////// ///////////////////////////////
function fun(a: ((x: number) => number) | ((x: string) => string)) { function fun(a: ((x: number) => number) | ((x: string) => string)) {}
}
function a1(x) { function a1(x) {
return x; return x;
@ -871,8 +851,7 @@ function fun_call(x: string): string {
///////////////////////////// /////////////////////////////
// example with array types // example with array types
///////////////////////////// /////////////////////////////
function arr(a: number[] | string[]) { function arr(a: number[] | string[]) {}
}
var a2 = []; var a2 = [];
arr(a2); arr(a2);
@ -981,8 +960,7 @@ type PG<X> = { x: X, y?: PG<X> };
// recursive types // recursive types
//////////////////// ////////////////////
function rec(x: F1 | F2) { function rec(x: F1 | F2) {}
}
rec({ x: 0 }); rec({ x: 0 });
type F1 = G1; type F1 = G1;
@ -995,8 +973,7 @@ type H2 = number;
/////////////////////////////// ///////////////////////////////
// polymorphic recursive types // polymorphic recursive types
/////////////////////////////// ///////////////////////////////
function polyrec(x: PF<number> | PF<string>) { function polyrec(x: PF<number> | PF<string>) {}
}
rec({ x: 0 }); rec({ x: 0 });
type PF<X> = PG<X>; type PF<X> = PG<X>;
@ -1039,8 +1016,7 @@ type H2_ = number;
// nested union types // nested union types
////////////////////// //////////////////////
function rec(x: F1 | F2) { function rec(x: F1 | F2) {}
}
rec({ x: 0 }); rec({ x: 0 });
type F1 = G1 | G1_; type F1 = G1 | G1_;
@ -1088,8 +1064,7 @@ function square(x? = 0) {
return x * x; return x * x;
} }
function foo(f: ((_: ?number) => ?number) | (() => void)) { function foo(f: ((_: ?number) => ?number) | (() => void)) {}
}
foo((x): number => square(x)); foo((x): number => square(x));
" "
`; `;
@ -1177,8 +1152,7 @@ function id<X>(x: X): X {
///////////////////////// /////////////////////////
// primitive annotations // primitive annotations
///////////////////////// /////////////////////////
function check_prim(_: number | string) { function check_prim(_: number | string) {}
}
// ok // ok
check_prim(\"\"); check_prim(\"\");
@ -1191,8 +1165,7 @@ check_prim(id(\"\"));
////////////////////////////// //////////////////////////////
class C {} class C {}
class D {} class D {}
function check_inst(_: C | D) { function check_inst(_: C | D) {}
}
// ok // ok
check_inst(new D()); check_inst(new D());
@ -1203,8 +1176,7 @@ check_inst(id(new C()));
//////////////////////// ////////////////////////
// function annotations // function annotations
//////////////////////// ////////////////////////
function check_fun(_: ((_: number) => number) | ((_: string) => string)) { function check_fun(_: ((_: number) => number) | ((_: string) => string)) {}
}
// help! // help!
check_fun(x => x); check_fun(x => x);
@ -1212,8 +1184,7 @@ check_fun(x => x);
////////////////////// //////////////////////
// object annotations // object annotations
////////////////////// //////////////////////
function check_obj(_: { x: number } | { x: string }) { function check_obj(_: { x: number } | { x: string }) {}
}
// ok // ok
check_obj({ x: \"\" }); check_obj({ x: \"\" });
@ -1224,8 +1195,7 @@ check_obj({ x: id(\"\") });
///////////////////// /////////////////////
// array annotations // array annotations
///////////////////// /////////////////////
function check_arr(_: number[] | string[]) { function check_arr(_: number[] | string[]) {}
}
// ok // ok
check_arr([ \"\" ]); check_arr([ \"\" ]);
@ -1237,8 +1207,7 @@ check_arr([ id(\"\") ]);
// generic class instance annotations // generic class instance annotations
////////////////////////////////////// //////////////////////////////////////
class P<X> {} class P<X> {}
function check_poly_inst(_: P<number> | P<string>) { function check_poly_inst(_: P<number> | P<string>) {}
}
// help! // help!
check_poly_inst(new P()); check_poly_inst(new P());
@ -1356,8 +1325,7 @@ function foo(c: C<number>) {
declare class C<X> { get(): X } declare class C<X> { get(): X }
function union(o: { x: string } | { x: number }) { function union(o: { x: string } | { x: number }) {}
}
function foo(c: C<number>) { function foo(c: C<number>) {
union({ x: c.get() }); union({ x: c.get() });
@ -1396,8 +1364,7 @@ bar(() => { });
// functions as objects // functions as objects
function foo<X>(target: EventTarget) { function foo<X>(target: EventTarget) {
target.addEventListener(\"click\", e => { target.addEventListener(\"click\", e => {});
});
} }
declare class EventTarget { declare class EventTarget {
@ -1412,11 +1379,9 @@ type EventHandler = (event: Event) => mixed;
type KeyboardEventHandler = (event: KeyboardEvent) => mixed; type KeyboardEventHandler = (event: KeyboardEvent) => mixed;
// example where globals are not yet resolved // example where globals are not yet resolved
function bar(x: (() => void) | { x: number }) { function bar(x: (() => void) | { x: number }) {}
}
bar(() => { bar(() => {});
});
" "
`; `;
@ -1449,12 +1414,10 @@ type Foo = T | (() => boolean);
type Bar = number | (() => string) | (() => boolean); type Bar = number | (() => string) | (() => boolean);
function foo(x: Foo) { function foo(x: Foo) {}
}
foo(() => qux()); foo(() => qux());
function bar(x: Bar) { function bar(x: Bar) {}
}
bar(() => qux()); bar(() => qux());
var x = false; var x = false;

View File

@ -82,8 +82,7 @@ class C {
return new C(); return new C();
} }
} }
function blah() { function blah() {}
}
var node: ?C = new C(); var node: ?C = new C();
while (node) { while (node) {
var parent = node.m(); var parent = node.m();