update snapshots

master
James Long 2016-12-27 13:29:31 -05:00
parent 599e5821c1
commit 9acd34d67d
382 changed files with 20711 additions and 24957 deletions

View File

@ -7,21 +7,17 @@ function bar() {
L: do { continue L; } while(false)
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:925
if (endsWithBrace(doBody))
^
ReferenceError: endsWithBrace is not defined
at genericPrintNoParens (/src/printer.js:925:11)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:963:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
function foo() {
while ([object Boolean]) {
break;
}
}
function bar() {
L:
do {
continue L;
} while ([object Boolean]);
}
"
`;
@ -37,91 +33,10 @@ function bar(x: number) {
}
function foo() {
var x = null;
if (x == null)
var x = [object Null];
if (x == [object Null])
return;
bar(x);
}
"
`;
exports[`test toplevel_break.js 1`] = `
"// @flow
break; // error, illegal
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unsyntactic break (3:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp$1.parseBreakContinueStatement (/node_modules/babylon/lib/index.js:1843:44)
at Parser.pp$1.parseStatement (/node_modules/babylon/lib/index.js:1703:19)
at Parser.parseStatement (/node_modules/babylon/lib/index.js:5224:22)
at Parser.pp$1.parseBlockBody (/node_modules/babylon/lib/index.js:2139:21)
at Parser.pp$1.parseTopLevel (/node_modules/babylon/lib/index.js:1651:8)
at Parser.parse (/node_modules/babylon/lib/index.js:1543:17)
at Object.parse$1 [as parse] (/node_modules/babylon/lib/index.js:6472:37)
at Object.parse (/index.js:34:26)
at Object.parse (/node_modules/recast/lib/parser.js:26:34)
"
`;
exports[`test toplevel_continue.js 1`] = `
"// @flow
continue; // error, illegal
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unsyntactic continue (3:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp$1.parseBreakContinueStatement (/node_modules/babylon/lib/index.js:1843:44)
at Parser.pp$1.parseStatement (/node_modules/babylon/lib/index.js:1703:19)
at Parser.parseStatement (/node_modules/babylon/lib/index.js:5224:22)
at Parser.pp$1.parseBlockBody (/node_modules/babylon/lib/index.js:2139:21)
at Parser.pp$1.parseTopLevel (/node_modules/babylon/lib/index.js:1651:8)
at Parser.parse (/node_modules/babylon/lib/index.js:1543:17)
at Object.parse$1 [as parse] (/node_modules/babylon/lib/index.js:6472:37)
at Object.parse (/index.js:34:26)
at Object.parse (/node_modules/recast/lib/parser.js:26:34)
"
`;
exports[`test toplevel_return.js 1`] = `
"// @flow
return; // error, illegal
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: \'return\' outside of function (3:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp$1.parseReturnStatement (/node_modules/babylon/lib/index.js:1939:10)
at Parser.pp$1.parseStatement (/node_modules/babylon/lib/index.js:1722:19)
at Parser.parseStatement (/node_modules/babylon/lib/index.js:5224:22)
at Parser.pp$1.parseBlockBody (/node_modules/babylon/lib/index.js:2139:21)
at Parser.pp$1.parseTopLevel (/node_modules/babylon/lib/index.js:1651:8)
at Parser.parse (/node_modules/babylon/lib/index.js:1543:17)
at Object.parse$1 [as parse] (/node_modules/babylon/lib/index.js:6472:37)
at Object.parse (/index.js:34:26)
at Object.parse (/node_modules/recast/lib/parser.js:26:34)
"
`;
exports[`test toplevel_throw.js 1`] = `
"// @flow
throw new Error(\'foo\'); // no error
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
throw new Error(\"foo\");// no error
"
`;

View File

@ -1,3 +0,0 @@
// @flow
break; // error, illegal

View File

@ -1,3 +0,0 @@
// @flow
continue; // error, illegal

View File

@ -1,3 +0,0 @@
// @flow
return; // error, illegal

View File

@ -1,3 +0,0 @@
// @flow
throw new Error('foo'); // no error

View File

@ -6,12 +6,12 @@ var bar: (str:number, i:number)=> string = foo;
var qux = function(str:string, i:number):number { return foo(str,i); }
var obj: {str:string; i:number; j:boolean} = {str: \"...\", i: \"...\", k: false};
var obj: {str:string; i:number; j:boolean} = {str: "...", i: "...", k: false};
var arr: Array<number> = [1,2,\"...\"];
var arr: Array<number> = [1,2,"..."];
// array sugar
var array: number[] = [1,2,\"...\"];
var array: number[] = [1,2,"..."];
var matrix: number[][] = [[1,2],[3,4]];
var matrix_parens: (number[])[] = matrix;
@ -21,15 +21,15 @@ var nullable_array_parens: ?(number[]) = nullable_array;
var array_of_nullable: (?number)[] = [null, 3];
var array_of_tuple: [number, string][] = [[0, \"foo\"], [1, \"bar\"]];
var array_of_tuple: [number, string][] = [[0, "foo"], [1, "bar"]];
var array_of_tuple_parens: ([number, string])[] = array_of_tuple;
type ObjType = { \'bar-foo\': string; \'foo-bar\': number; };
var test_obj: ObjType = { \'bar-foo\': \'23\' };
type ObjType = { 'bar-foo': string; 'foo-bar': number; };
var test_obj: ObjType = { 'bar-foo': '23' };
// param type annos are strict UBs like var type annos
function param_anno(n:number):void {
n = \"hey\"; // error
n = "hey"; // error
}
// another error on param UB, more typical of www (mis)use-cases
@ -38,7 +38,7 @@ function param_anno2(
batchRequests: Array<{method: string; path: string; params: ?Object}>,
): void {
// error below, since we\'re assigning elements to batchRequests
// error below, since we're assigning elements to batchRequests
// which lack a path property.
// just assign result to new var instead of reassigning to param.
@ -60,21 +60,69 @@ var zer : null = null;
function foobar(n : ?number) : number | null | void { return n; }
function barfoo(n : number | null | void) : ?number { return n; }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1348
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1348:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1254:25)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// array sugar
// param type annos are strict UBs like var type annos
// error
// another error on param UB, more typical of www (mis)use-cases
// this one cribbed from API.atlas.js
// error below, since we're assigning elements to batchRequests
// which lack a path property.
// just assign result to new var instead of reassigning to param.
// Transform the requests to the format the Graph API expects.
// ...
function foo(str: string, i: number): string {
return str;
}
var bar: (str: number, i: number) => string = foo;
var qux = function(str: string, i: number): number {
return foo(str, i);
};
var obj: { str: string, i: number, j: boolean } = {
str: "...",
i: "...",
k: [object Boolean]
};
var arr: Array<number> = [ [object Number], [object Number], "..." ];
var array: number[] = [ [object Number], [object Number], "..." ];
var matrix: number[][] = [
[ [object Number], [object Number] ],
[ [object Number], [object Number] ]
];
var matrix_parens: number[][] = matrix;
var nullable_array: ?number[] = [object Null];
var nullable_array_parens: ?number[] = nullable_array;
var array_of_nullable: ?number[] = [ [object Null], [object Number] ];
var array_of_tuple: [][] = [
[ [object Number], "foo" ],
[ [object Number], "bar" ]
];
var array_of_tuple_parens: [][] = array_of_tuple;
type ObjType = { "bar-foo": string, "foo-bar": number };
var test_obj: ObjType = { "bar-foo": "23" };
function param_anno(n: number): void {
n = "hey";
}
function param_anno2(
batchRequests: Array<{ method: string, path: string, params: ?Object }>
): void {
batchRequests = batchRequests.map(
request => {
return {
method: request.method,
params: request.params,
relative_url: request.path
};
}
);
}
var toz: null = [object Number];
var zer: null = [object Null];
function foobar(n: ?number): number | null | void {
return n;
}
function barfoo(n: number | null | void): ?number {
return n;
}
"
`;
@ -94,19 +142,23 @@ function foo() {
class MyClass { } // looked up above
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
let myClassInstance: MyClass = null;// forward ref ok, null ~> class error
// forward ref ok, null ~> class error
// forward ref ok, null ~> class error
// looked up above
// ok (no confusion across scopes)
// looked up above
let myClassInstance: MyClass = [object Null];
function bar(): MyClass {
return null;// forward ref ok, null ~> class error
return [object Null];
}
class MyClass {}// looked up above
class MyClass {}
function foo() {
let myClassInstance: MyClass = mk();// ok (no confusion across scopes)
let myClassInstance: MyClass = mk();
function mk() {
return new MyClass();
}
class MyClass {}// looked up above
class MyClass {}
}
"
`;
@ -115,11 +167,10 @@ exports[`test issue-530.js 1`] = `
module.exports = foo;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function foo(...args) {
function foo(...args: any) {
}
module.exports = foo;
"
`;
@ -132,7 +183,7 @@ exports[`test leak.js 1`] = `
* annotation for y and stop. We should type the body of bar() with the type
* annotation of y.
*
* However, the leaky type annotation meant that we were flowing x\'s type to y
* However, the leaky type annotation meant that we were flowing x's type to y
* and type checking the body of bar() using the stricter dictionary type,
* leading to an error.
*/
@ -154,7 +205,7 @@ function bar(y: MyObj): string {
* annotation for y and stop. We should type the body of bar() with the type
* annotation of y.
*
* However, the leaky type annotation meant that we were flowing x\'s type to y
* However, the leaky type annotation meant that we were flowing x's type to y
* and type checking the body of bar() using the stricter dictionary type,
* leading to an error.
*/
@ -165,7 +216,6 @@ function foo(x: { [key: string]: mixed }) {
function bar(y: MyObj): string {
return y.foo;
}
"
`;
@ -175,7 +225,6 @@ module.exports = (C: any);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class C {}
module.exports = (C: any);
"
`;
@ -205,30 +254,34 @@ class Foo<A> {
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1479:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// hypothetical immutable map
type Merge<T> = : (a: T, b: T) => T;
declare class Map {
(): Map<K, V>,
insertWith: : (fn: Merge<V>, k: K, v: V) => Map<K, V>
}
declare function foldr(fn: (a: A, b: B) => B, b: B, as: A[]): B;
function insertMany<K, V>(merge: Merge<V>, vs: [][], m: Map<K, V>): Map<K, V> {
function f([ k, v ], m: Map<K, V>): Map<K, V> {
return m.insertWith(merge, k, v);
}
return foldr(f, m, vs);
}
class Foo<A> {
bar<B>() {
return function(a: A, b: B, c: C): void {
([ a, b, c ]: []);
};
}
}
"
`;
exports[`test test.js 1`] = `
"var C = require(\'./other\');
"var C = require('./other');
((0: C): string);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var C = require(\"./other\");
((0: C): string);
var C = require("./other");
(([object Number]: C): string);
"
`;

View File

@ -13,10 +13,9 @@ type T = any;
export default class {
p: T;
constructor() {
this.p = 0;
this.p = [object Number];
}
}
"
`;
@ -27,10 +26,10 @@ class B extends A {
p: string; // OK, string ~> any
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// OK, string ~> any
import A from "./A";
class B extends A {
p: string;// OK, string ~> any
p: string;
}
"
`;

View File

@ -22,10 +22,9 @@ import type T from "T";
export default class {
p: T;
constructor() {
this.p = 0;
this.p = [object Number];
}
}
"
`;
@ -43,11 +42,11 @@ class B extends A {
/**
* @flow
*/
// OK, string ~> any
import A from "A";
class B extends A {
p: string;// OK, string ~> any
p: string;
}
"
`;
@ -56,7 +55,9 @@ exports[`test T.js 1`] = `
* @providesModule T
*/
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* @providesModule T
*/
"
`;

View File

@ -19,10 +19,9 @@ function bar(x: any): mixed {
function qux(x: mixed): any {
return x;
}
var x: string = foo(0);
var y: string = bar(0);
var z: string = qux(0);
var x: string = foo([object Number]);
var y: string = bar([object Number]);
var z: string = qux([object Number]);
"
`;
@ -33,7 +32,6 @@ module.exports = ((x: any) => x: any);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
module.exports = ((x: any) => x: any);
"
`;
@ -58,21 +56,31 @@ var y:string = bar(0);
var z:string = qux(0);
var w:string = baz(0);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
/*
FlowFixMe is a synonym for any, used by the Flow team to
signal a needed mod to JS devs.
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
@flow
*/
// no param
// param (info only)
// ...params are still checked. unknown type
function foo(x: $FlowFixMe): $FlowFixMe {
return x;
}
function bar(x: $FlowFixMe): mixed {
return x;
}
function qux(x: $FlowFixMe<number>): $FlowFixMe<number> {
return x;
}
function baz(x: $FlowFixMe<nnumber>): $FlowFixMe<number> {
return x;
}
var x: string = foo([object Number]);
var y: string = bar([object Number]);
var z: string = qux([object Number]);
var w: string = baz([object Number]);
"
`;
@ -97,21 +105,31 @@ var y:string = bar(0);
var z:string = qux(0);
var w:string = baz(0);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
/*
$FlowIssue is a synonym for any, used by JS devs to signal
a potential typechecker bug to the Flow team.
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
@flow
*/
// no param
// param (info only)
// ...params are still checked. unknown type
function foo(x: $FlowIssue): $FlowIssue {
return x;
}
function bar(x: $FlowIssue): mixed {
return x;
}
function qux(x: $FlowIssue<number>): $FlowIssue<number> {
return x;
}
function baz(x: $FlowIssue<nnumber>): $FlowIssue<number> {
return x;
}
var x: string = foo([object Number]);
var y: string = bar([object Number]);
var z: string = qux([object Number]);
var w: string = baz([object Number]);
"
`;
@ -122,7 +140,6 @@ module.exports = (x) => x;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
module.exports = x => x;
"
`;
@ -139,35 +156,42 @@ function foo(c: C, x: any): string {
return c.bar(0, y); // should be able to select first case and error
}
var any_fun1 = require(\'./nonflowfile\');
var any_fun1 = require('./nonflowfile');
function bar1(x: mixed) {
if (any_fun1(x)) {
(x: boolean);
}
}
var any_fun2 = require(\'./anyexportflowfile\');
var any_fun2 = require('./anyexportflowfile');
function bar2(x: mixed) {
if (any_fun2(x)) {
(x: boolean);
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1348
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1348:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1452:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// @flow
// should be able to select first case and error
declare class C {
bar: : (n1: number, n2: number) => number,
bar: : (s1: string, s2: string) => string
}
function foo(c: C, x: any): string {
let y = x.y;
return c.bar([object Number], y);
}
var any_fun1 = require("./nonflowfile");
function bar1(x: mixed) {
if (any_fun1(x)) {
(x: boolean);
}
}
var any_fun2 = require("./anyexportflowfile");
function bar2(x: mixed) {
if (any_fun2(x)) {
(x: boolean);
}
}
"
`;
@ -197,6 +221,5 @@ function foo(o: ?AsyncRequest) {
var n: number = o;
}
}
"
`;

View File

@ -8,7 +8,7 @@ function str(x:string) { }
function foo() {
var x = 0;
var y = \"...\";
var y = "...";
var z = {};
num(x+x);
num(x+y); // error
@ -54,20 +54,20 @@ num(true + null); // === 1
num(undefined + true); // === NaN
num(true + undefined); // === NaN
str(\"foo\" + true); // error
str(true + \"foo\"); // error
str(\"foo\" + null); // error
str(null + \"foo\"); // error
str(\"foo\" + undefined); // error
str(undefined + \"foo\"); // error
str("foo" + true); // error
str(true + "foo"); // error
str("foo" + null); // error
str(null + "foo"); // error
str("foo" + undefined); // error
str(undefined + "foo"); // error
let tests = [
function(x: mixed, y: mixed) {
(x + y); // error
(x + 0); // error
(0 + x); // error
(x + \"\"); // error
(\"\" + x); // error
(x + ""); // error
("" + x); // error
(x + {}); // error
({} + x); // error
},
@ -78,8 +78,8 @@ let tests = [
function() {
((1 + {}): number); // error: object !~> number
(({} + 1): number); // error: object !~> number
((\"1\" + {}): string); // error: object !~> string
(({} + \"1\"): string); // error: object !~> string
(("1" + {}): string); // error: object !~> string
(({} + "1"): string); // error: object !~> string
},
function(x: any, y: number, z: string) {
@ -92,6 +92,46 @@ let tests = [
];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @providesModule Arith */
// error
// error
// error
// test MaybeT(NumT)
// test OptionalT(NumT)
// test OptionalT(MaybeT(NumT))
// === 0
// === NaN
// === 1
// === 1
// === NaN
// === NaN
// === 1
// === 1
// === NaN
// === NaN
// error
// error
// error
// error
// error
// error
// error
// error
// error
// error
// error
// error
// error
// when one side is a string or number and the other is invalid, we
// assume you are expecting a string or number (respectively), rather than
// erroring twice saying number !~> string and obj !~> string.
// error: object !~> number
// error: object !~> number
// error: object !~> string
// error: object !~> string
// ok
// ok
// error, string ~> empty
// error, string ~> empty
function num(x: number) {
}
@ -99,79 +139,72 @@ function str(x: string) {
}
function foo() {
var x = 0;
var y = \"...\";
var x = [object Number];
var y = "...";
var z = {};
num(x + x);
num(x + y);// error
num(x + y);
str(x + y);
str(x + x);// error
str(z + y);// error
str(x + x);
str(z + y);
}
// test MaybeT(NumT)
function bar0(x: ?number, y: number) {
num(x + y);
}
function bar1(x: number, y: ?number) {
num(x + y);
}
// test OptionalT(NumT)
function bar2(x: number, y: number) {
num(x + y);
}
function bar3(x: number, y: number) {
num(x + y);
}
// test OptionalT(MaybeT(NumT))
function bar4(x: ?number, y: number) {
num(x + y);
}
function bar5(x: number, y: ?number) {
num(x + y);
}
num(null + null);// === 0
num(undefined + undefined);// === NaN
num(null + 1);// === 1
num(1 + null);// === 1
num(undefined + 1);// === NaN
num(1 + undefined);// === NaN
num(null + true);// === 1
num(true + null);// === 1
num(undefined + true);// === NaN
num(true + undefined);// === NaN
str(\"foo\" + true);// error
str(true + \"foo\");// error
str(\"foo\" + null);// error
str(null + \"foo\");// error
str(\"foo\" + undefined);// error
str(undefined + \"foo\");// error
num([object Null] + [object Null]);
num(undefined + undefined);
num([object Null] + [object Number]);
num([object Number] + [object Null]);
num(undefined + [object Number]);
num([object Number] + undefined);
num([object Null] + [object Boolean]);
num([object Boolean] + [object Null]);
num(undefined + [object Boolean]);
num([object Boolean] + undefined);
str("foo" + [object Boolean]);
str([object Boolean] + "foo");
str("foo" + [object Null]);
str([object Null] + "foo");
str("foo" + undefined);
str(undefined + "foo");
let tests = [
function(x: mixed, y: mixed) {
x + y;// error
x + 0;// error
0 + x;// error
x + \"\";// error
\"\" + x;// error
x + {};// error
({}) + x;// error
x + y;
x + [object Number];
[object Number] + x;
x + "";
"" + x;
x + {};
({}) + x;
},
// when one side is a string or number and the other is invalid, we
// assume you are expecting a string or number (respectively), rather than
// erroring twice saying number !~> string and obj !~> string.
function() {
(1 + {}: number);// error: object !~> number
({} + 1: number);// error: object !~> number
(\"1\" + {}: string);// error: object !~> string
({} + \"1\": string);// error: object !~> string
([object Number] + {}: number);
({} + [object Number]: number);
("1" + {}: string);
({} + "1": string);
},
function(x: any, y: number, z: string) {
(x + y: string);// ok
(y + x: string);// ok
(x + z: empty);// error, string ~> empty
(z + x: empty);// error, string ~> empty
(x + y: string);
(y + x: string);
(x + z: empty);
(z + x: empty);
}
];
"
`;
@ -181,7 +214,7 @@ exports[`test exponent.js 1`] = `
let x: number = 2 ** 3;
x **= 4;
let y: string = \"123\";
let y: string = "123";
y **= 2; // error
1 + 2 ** 3 + 4;
@ -189,14 +222,14 @@ y **= 2; // error
(-2) ** 2;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
let x: number = 2 ** 3;
x **= 4;
let y: string = \"123\";
y **= 2;// error
1 + 2 ** 3 + 4;
2 ** 2;
-2 ** 2;
// error
let x: number = [object Number] ** [object Number];
x **= [object Number];
let y: string = "123";
y **= [object Number];
[object Number] + [object Number] ** [object Number] + [object Number];
[object Number] ** [object Number];
-[object Number] ** [object Number];
"
`;
@ -209,21 +242,27 @@ function f<A,B>(a: A, b: B): A {return b + a; } // error
function f<A,B>(a: A, b: B): B {return a + b; } // error
function f<A,B>(a: A, b: B): B {return b + a; } // error
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:340:16)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
/* @flow */
// error
// error
// error
// error
// error
function f<A>(a: A): A {
return a + a;
}
function f<A, B>(a: A, b: B): A {
return a + b;
}
function f<A, B>(a: A, b: B): A {
return b + a;
}
function f<A, B>(a: A, b: B): B {
return a + b;
}
function f<A, B>(a: A, b: B): B {
return b + a;
}
"
`;
@ -238,20 +277,20 @@ num(1 * null);
let x: number = 2 * 3;
x *= 4;
let y: string = \"123\";
let y: string = "123";
y *= 2; // error
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
// error
function num(x: number) {
}
num(null * 1);
num(1 * null);
let x: number = 2 * 3;
x *= 4;
let y: string = \"123\";
y *= 2;// error
num([object Null] * [object Number]);
num([object Number] * [object Null]);
let x: number = [object Number] * [object Number];
x *= [object Number];
let y: string = "123";
y *= [object Number];
"
`;
@ -259,14 +298,14 @@ exports[`test relational.js 1`] = `
"/* @flow */
(1 < 2);
(1 < \"foo\"); // error
(\"foo\" < 1); // error
(\"foo\" < \"bar\");
(1 < "foo"); // error
("foo" < 1); // error
("foo" < "bar");
(1 < {foo: 1}); // error
({foo: 1} < 1); // error
({foo: 1} < {foo: 1}); // error
(\"foo\" < {foo: 1}); // error
({foo: 1} < \"foo\"); // error
("foo" < {foo: 1}); // error
({foo: 1} < "foo"); // error
var x = (null : ?number);
(1 < x); // 2 errors: null !~> number; undefined !~> number
@ -288,24 +327,37 @@ let tests = [
];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
1 < 2;
1 < \"foo\";// error
\"foo\" < 1;// error
\"foo\" < \"bar\";
1 < { foo: 1 };// error
({ foo: 1 }) < 1;// error
({ foo: 1 }) < { foo: 1 };// error
\"foo\" < { foo: 1 };// error
({ foo: 1 }) < \"foo\";// error
var x = (null: ?number);
1 < x;// 2 errors: null !~> number; undefined !~> number
x < 1;// 2 errors: null !~> number; undefined !~> number
null < null;// error
undefined < null;// error
null < undefined;// error
undefined < undefined;// error
NaN < 1;
1 < NaN;
// error
// error
// error
// error
// error
// error
// error
// 2 errors: null !~> number; undefined !~> number
// 2 errors: null !~> number; undefined !~> number
// error
// error
// error
// error
[object Number] < [object Number];
[object Number] < "foo";
"foo" < [object Number];
"foo" < "bar";
[object Number] < { foo: [object Number] };
({ foo: [object Number] }) < [object Number];
({ foo: [object Number] }) < { foo: [object Number] };
"foo" < { foo: [object Number] };
({ foo: [object Number] }) < "foo";
var x = ([object Null]: ?number);
[object Number] < x;
x < [object Number];
[object Null] < [object Null];
undefined < [object Null];
[object Null] < undefined;
undefined < undefined;
NaN < [object Number];
[object Number] < NaN;
NaN < NaN;
let tests = [
function(x: any, y: number, z: string) {
@ -313,6 +365,5 @@ let tests = [
x > z;
}
];
"
`;

View File

@ -9,21 +9,13 @@ function filterOutSmall (arr: Array<?number>): Array<?number> {
return arr.filter(num => num && num > 10)
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:340:16)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
/* @flow */
function filterOutVoids<T>(arr: Array<?T>): Array<T> {
return arr.filter(Boolean);
}
function filterOutSmall(arr: Array<?number>): Array<?number> {
return arr.filter(num => num && num > [object Number]);
}
"
`;
@ -32,7 +24,7 @@ exports[`test test2.js 1`] = `
function filterItems(items: Array<string|number>): Array<string|number> {
return items.map(item => {
if (typeof item === \'string\') {
if (typeof item === 'string') {
return item.length > 2 ? item : null;
} else {
return item*10;
@ -40,24 +32,25 @@ function filterItems(items: Array<string|number>): Array<string|number> {
}).filter(Boolean);
}
const filteredItems = filterItems([\'foo\', \'b\', 1, 2]);
const filteredItems = filterItems(['foo', 'b', 1, 2]);
console.log(filteredItems);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1530
return fromString(\" | \").join(path.map(print, \"types\"));
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1530:32)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.map (/src/fast-path.js:167:19)
at genericPrintNoParens (/src/printer.js:1497:36)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
/* @flow */
function filterItems(items: Array<string | number>): Array<string | number> {
return items.map(
item => {
if (typeof item === "string") {
return (item.length > [object Number] ? item : [object Null]);
} else {
return item * [object Number];
}
}
).filter(Boolean);
}
const filteredItems = filterItems(
[ "foo", "b", [object Number], [object Number] ]
);
console.log(filteredItems);
"
`;

View File

@ -5,23 +5,15 @@ var C = [1,2,3];
B.sort((a, b) => a - b);
C.sort((a, b) => a - b);
var x: Array<string> = [\'1\', \'2\'];
var y: Array<string> = [\'3\', ...x];
var x: Array<string> = ['1', '2'];
var y: Array<string> = ['3', ...x];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
var A = [ [object Number], [object Number], [object Number] ];
var B = [ ...A ];
var C = [ [object Number], [object Number], [object Number] ];
B.sort((a, b) => a - b);
C.sort((a, b) => a - b);
var x: Array<string> = [ "1", "2" ];
var y: Array<string> = [ "3", ...x ];
"
`;

View File

@ -3,23 +3,23 @@ exports[`test array_lib.js 1`] = `
function foo(x:string) { }
var a = [0];
var b = a.map(function (x) { foo(x); return \"\" + x; });
var b = a.map(function (x) { foo(x); return "" + x; });
var c: number = a[0];
var d: number = b[0];
var e:Array<string> = a.reverse();
var f = [\"\"];
var f = [""];
var g:number = f.map(function () { return 0; })[0];
var h: Array<number> = [1,2,3];
var i: Array<string> = [\'a\', \'b\', \'c\'];
var i: Array<string> = ['a', 'b', 'c'];
var j: Array<number | string> = h.concat(i);
var k: Array<number> = h.concat(h);
var l: Array<number> = h.concat(1,2,3);
var m: Array<number | string> = h.concat(\'a\', \'b\', \'c\');
var n: Array<number> = h.concat(\'a\', \'b\', \'c\'); // Error
var m: Array<number | string> = h.concat('a', 'b', 'c');
var n: Array<number> = h.concat('a', 'b', 'c'); // Error
function reduce_test() {
/* Adapted from the following source:
@ -44,33 +44,117 @@ function reduce_test() {
/* Added later, because the above is insufficient */
// acc is element type of array when no init is provided
[\"\"].reduce((acc, str) => acc * str.length); // error, string ~> number
[\"\"].reduceRight((acc, str) => acc * str.length); // error, string ~> number
[""].reduce((acc, str) => acc * str.length); // error, string ~> number
[""].reduceRight((acc, str) => acc * str.length); // error, string ~> number
}
function from_test() {
var a: Array<string> = Array.from([1, 2, 3], function(val, index) {
return index % 2 ? \"foo\" : String(val);
return index % 2 ? "foo" : String(val);
});
var b: Array<string> = Array.from([1, 2, 3], function(val) {
return String(val);
});
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
/* @flow */
// Error
/* Adapted from the following source:
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
*/
/* Added later, because the above is insufficient */
// acc is element type of array when no init is provided
// error, string ~> number
// error, string ~> number
function foo(x: string) {
}
var a = [ [object Number] ];
var b = a.map(
function(x) {
foo(x);
return "" + x;
}
);
var c: number = a[[object Number]];
var d: number = b[[object Number]];
var e: Array<string> = a.reverse();
var f = [ "" ];
var g: number = f.map(
function() {
return [object Number];
}
)[[object Number]];
var h: Array<number> = [ [object Number], [object Number], [object Number] ];
var i: Array<string> = [ "a", "b", "c" ];
var j: Array<number | string> = h.concat(i);
var k: Array<number> = h.concat(h);
var l: Array<number> = h.concat(
[object Number],
[object Number],
[object Number]
);
var m: Array<number | string> = h.concat("a", "b", "c");
var n: Array<number> = h.concat("a", "b", "c");
function reduce_test() {
[
[object Number],
[object Number],
[object Number],
[object Number],
[object Number]
].reduce(
function(previousValue, currentValue, index, array) {
return previousValue + currentValue + array[index];
}
);
[
[object Number],
[object Number],
[object Number],
[object Number],
[object Number]
].reduce(
function(previousValue, currentValue, index, array) {
return previousValue + currentValue + array[index];
},
[object Number]
);
var total = [
[object Number],
[object Number],
[object Number],
[object Number]
].reduce(
function(a, b) {
return a + b;
}
);
var flattened = [
[ [object Number], [object Number] ],
[ [object Number], [object Number] ],
[ [object Number], [object Number] ]
].reduce(
function(a, b) {
return a.concat(b);
}
);
[ "" ].reduce((acc, str) => acc * str.length);
[ "" ].reduceRight((acc, str) => acc * str.length);
}
function from_test() {
var a: Array<string> = Array.from(
[ [object Number], [object Number], [object Number] ],
function(val, index) {
return (index % [object Number] ? "foo" : String(val));
}
);
var b: Array<string> = Array.from(
[ [object Number], [object Number], [object Number] ],
function(val) {
return String(val);
}
);
}
"
`;

View File

@ -6,7 +6,7 @@ function foo(x:string) { }
var a = [];
a[0] = 1;
a[1] = \"...\";
a[1] = "...";
foo(a[1]);
var y;
@ -32,28 +32,63 @@ var abig2: Array<{x:number; y:number}> = [
{x:0, y:0},
{x:0, y:0},
{x:0, y:0, a:true},
{x:0, y:0, b:\"hey\"},
{x:0, y:0, b:"hey"},
{x:0, y:0, c:1},
{x:0, y:0, c:\"hey\"}
{x:0, y:0, c:"hey"}
];
module.exports = \"arrays\";
module.exports = "arrays";
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
/* @providesModule Arrays */
// for literals, composite element type is union of individuals
// note: test both tuple and non-tuple inferred literals
function foo(x: string) {
}
var a = [ ];
a[[object Number]] = [object Number];
a[[object Number]] = "...";
foo(a[[object Number]]);
var y;
a.forEach(x => y = x);
var alittle: Array<?number> = [
[object Number],
[object Number],
[object Number],
[object Number],
[object Null]
];
var abig: Array<?number> = [
[object Number],
[object Number],
[object Number],
[object Number],
[object Number],
[object Number],
[object Number],
[object Number],
[object Null]
];
var abig2: Array<{ x: number, y: number }> = [
{ x: [object Number], y: [object Number] },
{ x: [object Number], y: [object Number] },
{ x: [object Number], y: [object Number] },
{ x: [object Number], y: [object Number] },
{ x: [object Number], y: [object Number] },
{ x: [object Number], y: [object Number] },
{ x: [object Number], y: [object Number] },
{ x: [object Number], y: [object Number] },
{ x: [object Number], y: [object Number] },
{ x: [object Number], y: [object Number] },
{ x: [object Number], y: [object Number] },
{ x: [object Number], y: [object Number] },
{ x: [object Number], y: [object Number] },
{ x: [object Number], y: [object Number], a: [object Boolean] },
{ x: [object Number], y: [object Number], b: "hey" },
{ x: [object Number], y: [object Number], c: [object Number] },
{ x: [object Number], y: [object Number], c: "hey" }
];
module.exports = "arrays";
"
`;
@ -66,12 +101,12 @@ var day = new Date;
arr[day] = 0;
(arr[day]: string); // error: number ~> string
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var arr = [ ];
var day = new Date();
// Date instances are numeric (see Flow_js.numeric) and thus can index into
// arrays.
arr[day] = 0;
(arr[day]: string);// error: number ~> string
// error: number ~> string
var arr = [ ];
var day = new Date();
arr[day] = [object Number];
(arr[day]: string);
"
`;

View File

@ -9,23 +9,18 @@ var bad = (x: number): string => x; // Error!
var ident = <T>(x: T): T => x;
(ident(1): number);
(ident(\"hi\"): number); // Error
(ident("hi"): number); // Error
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:367:25)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
/**
* @flow
*/
// Error!
// Error
var add = (x: number, y: number): number => x + y;
var bad = (x: number): string => x;
var ident = <T>(x: T): T => x;
(ident([object Number]): number);
(ident("hi"): number);
"
`;
@ -36,25 +31,19 @@ exports[`test arrows.js 1`] = `
): Image {
var maxPixelWidth = maxWidth;
//images = images.sort(function (a, b) { return a.width - b.width });
images = images.sort((a, b) => (a.width - b.width) + \"\");
images = images.sort((a, b) => (a.width - b.width) + "");
return images.find(image => image.width >= maxPixelWidth) ||
images[images.length - 1];
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
//images = images.sort(function (a, b) { return a.width - b.width });
function selectBestEffortImageForWidth(
maxWidth: number, images: Array<Image>
): Image {
var maxPixelWidth = maxWidth;
images = images.sort((a, b) => a.width - b.width + "");
return images.find(image => image.width >= maxPixelWidth) ||
images[images.length - [object Number]];
}
"
`;

View File

@ -3,7 +3,7 @@ exports[`test foo.js 1`] = `
/asdf/g;
// JSX also requires a lexer mode change
<div attr1=\'42\' attr2={\'asdf\'} >asdf</div>;
<div attr1='42' attr2={'asdf'} >asdf</div>;
// Async arrow functions require backtracking
var a = async () => 42;
@ -15,20 +15,16 @@ var a: number = 42;
var var
a;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (14:4)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$2.parseBindingAtom (/node_modules/babylon/lib/index.js:2929:12)
at Parser.pp$1.parseVarHead (/node_modules/babylon/lib/index.js:2226:18)
at Parser.parseVarHead (/node_modules/babylon/lib/index.js:5611:13)
at Parser.pp$1.parseVar (/node_modules/babylon/lib/index.js:2209:10)
at Parser.pp$1.parseVarStatement (/node_modules/babylon/lib/index.js:2042:8)
at Parser.pp$1.parseStatement (/node_modules/babylon/lib/index.js:1735:19)
at Parser.parseStatement (/node_modules/babylon/lib/index.js:5224:22)
at Parser.pp$1.parseBlockBody (/node_modules/babylon/lib/index.js:2139:21)
/* Regex literals require a lexer mode change*/
/* JSX also requires a lexer mode change*/
// Async arrow functions require backtracking
// Type annotations have a special lex mode
// Token stream should continue even with parse errors
[object RegExp];
<div attr1="42" attr2={"asdf"}>asdf</div>;
var a = async () => [object Number];
var a: number = [object Number];
var var;
a;
"
`;

View File

@ -1,8 +1,8 @@
exports[`test async.js 1`] = `
"// @flow
// \"For async functions, a Promise<T> is returned,
// and the type of return expressions must be T.\"
// "For async functions, a Promise<T> is returned,
// and the type of return expressions must be T."
//
async function f0(): Promise<number> {
@ -27,7 +27,7 @@ async function f3(p: Promise<number>): Promise<number> {
}
// TODO: this is one of those bad generic errors, currently:
// \"inconsistent use of library definitions\" with two core.js locs
// "inconsistent use of library definitions" with two core.js locs
async function f4(p: Promise<number>): Promise<bool> {
return await p; // error, number != bool
}
@ -52,28 +52,63 @@ class C {
var obj = { f: async () => await 1 };
var objf : () => Promise<number> = obj.f;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// @flow
// "For async functions, a Promise<T> is returned,
// and the type of return expressions must be T."
//
// error, number != bool
// await: (p: Promise<T> | T) => T
//
// TODO: this is one of those bad generic errors, currently:
// "inconsistent use of library definitions" with two core.js locs
// error, number != bool
// async arrow functions
//
// async methods
//
// error, void != Promise<void>
// async function props
async function f0(): Promise<number> {
return [object Number];
}
async function f1(): Promise<boolean> {
return [object Number];
}
async function f2(p: Promise<number>): Promise<number> {
var x: number = await p;
var y: number = await [object Number];
return x + y;
}
async function f3(p: Promise<number>): Promise<number> {
return await p;
}
async function f4(p: Promise<number>): Promise<boolean> {
return await p;
}
var f5: () => Promise<number> = async () => await [object Number];
class C {
async m() {
return [object Number];
}
async mt<T>(a: T): Promise<T> {
return a;
}
static async m(a): void {
await a;
}
static async mt<T>(a: T): Promise<T> {
return a;
}
}
var obj = { f: async () => await [object Number] };
var objf: () => Promise<number> = obj.f;
"
`;
exports[`test async_base_class.js 1`] = `
"// This is kind of weird, but it should parse. This works in babel without the
// parens around (await promise). From the es6 and async/await specs I (nmote)
// am not clear on whether it should. In any case it\'s a strange corner case
// am not clear on whether it should. In any case it's a strange corner case
// that is probably not important to support.
class C {};
@ -86,21 +121,20 @@ async function foo() {
return Bar;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// This is kind of weird, but it should parse. This works in babel without the
// parens around (await promise). From the es6 and async/await specs I (nmote)
// am not clear on whether it should. In any case it's a strange corner case
// that is probably not important to support.
class C {}
var P: Promise<Class<C>> = new Promise(
function(resolve, reject) {
resolve(C);
}
);
async function foo() {
class Bar extends await P {}
return Bar;
}
"
`;
@ -130,21 +164,54 @@ console.log(x.async);
var async = 3;
var y = { async };
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:340:16)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
async function f() {
}
async function ft<T>(a: T) {
}
class C {
async m() {
}
async mt<T>(a: T) {
}
static async m(a) {
}
static async mt<T>(a: T) {
}
}
var e = async function() {
};
var et = async function(a: T) {
};
var n = new async function() {
}();
var o = {
async m() {
}
};
var ot = {
async m<T>(a: T) {
}
};
var oz = {
async async() {
}
};
var x = { async: [object Number] };
console.log(x.async);
var async = [object Number];
var y = { async };
"
`;
@ -153,21 +220,9 @@ exports[`test async_promise.js 1`] = `
return Promise.resolve(1);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
async function f(): Promise<number> {
return Promise.resolve([object Number]);
}
"
`;
@ -187,21 +242,19 @@ async function foo3(): Promise<string> {
return bar();
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// @flow
async function foo1(): Promise<string> {
return;
}
async function foo2(): Promise<string> {
return undefined;
}
async function foo3(): Promise<string> {
function bar() {
}
return bar();
}
"
`;
@ -232,7 +285,7 @@ function test1() {
function test2() {
async function voidoid1() {
console.log(\"HEY\");
console.log("HEY");
}
var voidoid2: () => Promise<void> = voidoid1; // ok
@ -245,7 +298,7 @@ function test2() {
function test3() {
async function voidoid4(): Promise<void> { // ok
console.log(\"HEY\");
console.log("HEY");
}
}
@ -256,32 +309,70 @@ function test3() {
function test4() {
async function voidoid5(): void { // error, void != Promise<void>
console.log(\"HEY\");
console.log("HEY");
}
}
function test5() {
async function voidoid6()
: Promise<number> { // error, number != void
console.log(\"HEY\");
console.log("HEY");
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1348
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1348:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1254:25)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// @flow
// misc basic
// valid
// Error: number ~> string
//
// void returns:
//
// inference should produce return type Promise<void>
// in the absence of an explicit return
//
// ok
// error, void != Promise<void>
// annotated return type of Promise<void> should work
//
// ok
// other annotated return types should fail
// (note: misannotated return types with explicit
// return statements are covered in async.js)
//
// error, void != Promise<void>
// error, number != void
function test1() {
async function foo() {
return [object Number];
}
async function bar() {
var a = await foo();
var b: number = a;
var c: string = a;
}
}
function test2() {
async function voidoid1() {
console.log("HEY");
}
var voidoid2: () => Promise<void> = voidoid1;
var voidoid3: () => void = voidoid1;
}
function test3() {
async function voidoid4(): Promise<void> {
console.log("HEY");
}
}
function test4() {
async function voidoid5(): void {
console.log("HEY");
}
}
function test5() {
async function voidoid6(): Promise<number> {
console.log("HEY");
}
}
"
`;
@ -290,9 +381,9 @@ exports[`test async3.js 1`] = `
/**
* test nested-promise unwrapping.
* Note: currently we don\'t do this properly in the underlying
* Note: currently we don't do this properly in the underlying
* type of the Promise class, which causes spurious errors to
* be raised here. Once that\'s fixed, the errors here will go
* be raised here. Once that's fixed, the errors here will go
* away.
*/
@ -322,29 +413,28 @@ async function baz() {
// @flow
/**
* test nested-promise unwrapping.
* Note: currently we don\'t do this properly in the underlying
* Note: currently we don't do this properly in the underlying
* type of the Promise class, which causes spurious errors to
* be raised here. Once that\'s fixed, the errors here will go
* be raised here. Once that's fixed, the errors here will go
* away.
*/
// a should now be typed as number, but is in fact
// Promise<number> until nested-promise unwrap is fixed
// TODO this is valid code, but currently gives Promise ~> number error
// due to lack of transitive Promise unwrap.
// should be number ~> string error, but currently gives
// Promise ~> string error for the same reason
async function foo() {
return 42;
return [object Number];
}
async function bar() {
return foo();
}
async function baz() {
// a should now be typed as number, but is in fact
// Promise<number> until nested-promise unwrap is fixed
var a = await bar();
// TODO this is valid code, but currently gives Promise ~> number error
// due to lack of transitive Promise unwrap.
var b: number = a;
// should be number ~> string error, but currently gives
// Promise ~> string error for the same reason
var c: string = a;
}
"
`;
@ -356,21 +446,12 @@ function f() {
await 1;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: await is a reserved word (5:2)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp$3.checkReservedWord (/node_modules/babylon/lib/index.js:4143:10)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4121:12)
at Parser.pp$3.parseExprAtom (/node_modules/babylon/lib/index.js:3490:21)
at Parser.parseExprAtom (/node_modules/babylon/lib/index.js:6408:22)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3337:19)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
// note: currently, await-within-async enforcement is a
// done by the parser, which bails after a single error.
function f() {
await;
[object Number];
}
"
`;
@ -382,21 +463,12 @@ function f(x) { return x; }
f(await 1);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: await is a reserved word (6:2)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp$3.checkReservedWord (/node_modules/babylon/lib/index.js:4143:10)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4121:12)
at Parser.pp$3.parseExprAtom (/node_modules/babylon/lib/index.js:3490:21)
at Parser.parseExprAtom (/node_modules/babylon/lib/index.js:6408:22)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3337:19)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
// note: currently, await-within-async enforcement is a
// done by the parser, which bails after a single error.
function f(x) {
return x;
}
f(await);
"
`;
@ -408,21 +480,12 @@ async function f(x) { return x; }
f(await 1);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: await is a reserved word (6:2)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp$3.checkReservedWord (/node_modules/babylon/lib/index.js:4143:10)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4121:12)
at Parser.pp$3.parseExprAtom (/node_modules/babylon/lib/index.js:3490:21)
at Parser.parseExprAtom (/node_modules/babylon/lib/index.js:6408:22)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3337:19)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
// note: currently, await-within-async enforcement is a
// done by the parser, which bails after a single error.
async function f(x) {
return x;
}
f(await);
"
`;
@ -452,20 +515,53 @@ console.log(x.await);
var await = 3;
var y = { await };
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: await is a reserved word (23:4)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp$3.checkReservedWord (/node_modules/babylon/lib/index.js:4143:10)
at Parser.pp$2.checkLVal (/node_modules/babylon/lib/index.js:2990:12)
at Parser.checkLVal (/node_modules/babylon/lib/index.js:5446:22)
at Parser.pp$1.parseVarHead (/node_modules/babylon/lib/index.js:2227:8)
at Parser.parseVarHead (/node_modules/babylon/lib/index.js:5611:13)
at Parser.pp$1.parseVar (/node_modules/babylon/lib/index.js:2209:10)
at Parser.pp$1.parseVarStatement (/node_modules/babylon/lib/index.js:2042:8)
at Parser.pp$1.parseStatement (/node_modules/babylon/lib/index.js:1735:19)
at Parser.parseStatement (/node_modules/babylon/lib/index.js:5224:22)
async function f() {
await [object Number];
}
async function ft<T>(a: T) {
await [object Number];
}
class C {
async m() {
await [object Number];
}
async mt<T>(a: T) {
await [object Number];
}
static async m(a) {
await [object Number];
}
static async mt<T>(a: T) {
await [object Number];
}
}
var e = async function() {
await [object Number];
};
var et = async function(a: T) {
await [object Number];
};
var n = new async function() {
await [object Number];
}();
var o = {
async m() {
await [object Number];
}
};
var ot = {
async m<T>(a: T) {
await [object Number];
}
};
var oz = {
async async(async) {
await async;
}
};
var x = { await: [object Number] };
console.log(x.await);
var await = [object Number];
var y = { await };
"
`;

View File

@ -26,31 +26,33 @@ async function *delegate_return() {
var x: void = yield *inner(); // error: number ~> void
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// error: number ~> void
// error: number ~> void
// error: number ~> void
async function* delegate_next() {
async function* inner() {
var x: void = yield;// error: number ~> void
var x: void = yield;
}
yield* inner();
}
delegate_next().next(0);
delegate_next().next([object Number]);
async function* delegate_yield() {
async function* inner() {
yield 0;
yield [object Number];
}
yield* inner();
}
async () => {
for await (const x of delegate_yield()) {
(x: void);// error: number ~> void
(x: void);
}
};
async function* delegate_return() {
async function* inner() {
return 0;
return [object Number];
}
var x: void = yield* inner();// error: number ~> void
var x: void = yield* inner();
}
"
`;
@ -76,39 +78,46 @@ 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
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1391
fromString(\", \").join(path.map(print, \"extends\"))
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1391:28)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at /src/printer.js:1601:18
at FastPath.map (/src/fast-path.js:167:19)
at printStatementSequence (/src/printer.js:1586:8)
at /src/printer.js:238:16
at FastPath.call (/src/fast-path.js:113:16)
// error: string ~> void
interface File extends {
readLine: : () => Promise<string>,
close: : () => void,
EOF: boolean
}
declare function fileOpen(path: string): Promise<File>;
async function* readLines(path) {
let file: File = await fileOpen(path);
try {
while (!file.EOF) {
yield await file.readLine();
}
} finally {
file.close();
}
}
async function f() {
for await (const line of readLines("/path/to/file")) {
(line: void);
}
}
"
`;
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 {
@ -117,27 +126,38 @@ 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
}
});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// 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
// yielding or returning internally.
// error: number | void ~> string
declare var gen: AsyncGenerator<void, string, void>;
gen.return([object Number]).then(
result => {
(result.value: void);
}
);
async function* refuse_return() {
try {
yield [object Number];
} finally {
return [object Number];
}
}
refuse_return().return("string").then(
result => {
if (result.done) {
(result.value: string);
}
}
);
"
`;
@ -151,7 +171,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
}
@ -168,46 +188,47 @@ async function *yield_return() {
}
(async () => {
yield_return().throw(\"\").then(({value}) => {
yield_return().throw("").then(({value}) => {
if (value !== undefined) {
(value: void); // error: number ~> void
}
});
});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// error: number ~> void
// error: number ~> void
async function* catch_return() {
try {
yield 0;
yield [object Number];
} catch (e) {
return e;
}
}
async () => {
catch_return().throw(\"\").then(
catch_return().throw("").then(
({ value }) => {
if (value !== undefined) {
(value: void);// error: number ~> void
(value: void);
}
}
);
};
async function* yield_return() {
try {
yield 0;
yield [object Number];
return;
} catch (e) {
yield e;
}
}
async () => {
yield_return().throw(\"\").then(
yield_return().throw("").then(
({ value }) => {
if (value !== undefined) {
(value: void);// error: number ~> void
(value: void);
}
}
);
};
"
`;

View File

@ -1,582 +0,0 @@
exports[`test bar.js 1`] = `
"// @flow
var o = require(\'./unknown\');
o.x.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (5:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test bool.js 1`] = `
"// @flow
true.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (4:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test customfun.js 1`] = `
"// @flow
declare var idx: $Facebookism$Idx;
declare var merge: $Facebookism$Merge;
declare var mergeDeepInto: $Facebookism$MergeDeepInto;
declare var mergeInto: $Facebookism$MergeInto;
declare var mixin: $Facebookism$Mixin;
declare var objectGetPrototypeOf: Object$GetPrototypeOf
declare var objectAssign: Object$Assign
m
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
declare var idx: $Facebookism$Idx;
declare var merge: $Facebookism$Merge;
declare var mergeDeepInto: $Facebookism$MergeDeepInto;
declare var mergeInto: $Facebookism$MergeInto;
declare var mixin: $Facebookism$Mixin;
declare var objectGetPrototypeOf: Object$GetPrototypeOf;
declare var objectAssign: Object$Assign;
m;
"
`;
exports[`test foo.js 1`] = `
"/**
* @flow
*/
var obj = {
num: 123,
str: \'hello\',
};
obj.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (11:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test foo_parse_fail.js 1`] = `
"/**
* @flow
*/
var obj = {
num: 123,
str: \'hello\',
};
console.log(obj.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (11:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test fun.js 1`] = `
"/* @flow */
function foo(f: () => number) {
f.
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (5:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test function_builtins.js 1`] = `
"/* @flow */
function foo(f: Function) {
f.
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (5:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test generics.js 1`] = `
"// @flow
class C<X> { }
function foo(o: { cn: C<number> }) {
o.
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (7:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test if.js 1`] = `
"// @flow
const x = \'\';
if (x.)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (3:6)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test issue-1368.js 1`] = `
"/* @flow */
class Test {
prop: number;
constructor(prop: number) {
this.prop = prop;
}
}
class ExtendTest extends Test {
extended: string;
constructor(extended: string) {
super(10);
this.extended = extended;
}
method() {
this.prop = 12;
this./* here */
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (21:2)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test jsx1.js 1`] = `
"// @flow
var React = require(\'react\');
class C extends React.Component {
props: { x: number };
}
<C
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:5687
throw jsxError || err;
^
SyntaxError: Unexpected token (9:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$8.jsxParseIdentifier (/node_modules/babylon/lib/index.js:6199:10)
at Parser.pp$8.jsxParseNamespacedName (/node_modules/babylon/lib/index.js:6210:19)
at Parser.pp$8.jsxParseAttribute (/node_modules/babylon/lib/index.js:6305:20)
at Parser.pp$8.jsxParseOpeningElementAt (/node_modules/babylon/lib/index.js:6317:31)
at Parser.pp$8.jsxParseElementAt (/node_modules/babylon/lib/index.js:6339:29)
at Parser.pp$8.jsxParseElement (/node_modules/babylon/lib/index.js:6394:15)
at Parser.parseExprAtom (/node_modules/babylon/lib/index.js:6406:21)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3337:19)
"
`;
exports[`test jsx2.js 1`] = `
"// @flow
var React = require(\'react\');
class C extends React.Component {
props: { x: number, y: string };
}
<C x = 0,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:5687
throw jsxError || err;
^
SyntaxError: JSX value should be either an expression or a quoted JSX text (8:7)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp$8.jsxParseAttributeValue (/node_modules/babylon/lib/index.js:6255:12)
at Parser.pp$8.jsxParseAttribute (/node_modules/babylon/lib/index.js:6306:42)
at Parser.pp$8.jsxParseOpeningElementAt (/node_modules/babylon/lib/index.js:6317:31)
at Parser.pp$8.jsxParseElementAt (/node_modules/babylon/lib/index.js:6339:29)
at Parser.pp$8.jsxParseElement (/node_modules/babylon/lib/index.js:6394:15)
at Parser.parseExprAtom (/node_modules/babylon/lib/index.js:6406:21)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3337:19)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
"
`;
exports[`test num.js 1`] = `
"// @flow
var num = 123;
num.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (5:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test object_builtins.js 1`] = `
"/* @flow */
function foo(o: Object) {
o.
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (5:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test optional.js 1`] = `
"// @flow
function foo(obj: { x?: string, f: (x?: string) => void, o: { x?: string } }) {
return obj.
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (5:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test override.js 1`] = `
"// @flow
class C {
override(): number | string { return 0; }
}
class D extends C {
foo() { return this.override() }
override(): string { return \"\"; }
bar() { this.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (11:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test qux.js 1`] = `
"// @flow
class C { x: number; }
var c: C = new C;
c.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (7:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test str.js 1`] = `
"// @flow
\"hello\".
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (4:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test this.js 1`] = `
"/* @flow */
// issue #1197
class Foo {
baz: string;
bar() {}
hello() {
this.
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (9:2)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test typeparams.js 1`] = `
"// @flow
class Bounds<N: number, F: () => N> {
foo: F;
bar() {
this.foo().
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (7:2)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test union.js 1`] = `
"/* @flow */
function foo(a: boolean, x: { bar: string }, y: Object) {
var z;
if (a) {
z = x;
} else {
z = y;
}
z.
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (11:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseIdentifier (/node_modules/babylon/lib/index.js:4128:10)
at Parser.pp$3.parseSubscripts (/node_modules/babylon/lib/index.js:3360:30)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3347:15)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
"
`;
exports[`test unknown.js 1`] = `
"// @noflow
module.exports = { x: { y: \"\" } };
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @noflow
module.exports = { x: { y: \"\" } };
"
`;

View File

@ -2,6 +2,5 @@ exports[`test client.js 1`] = `
"var y:number = x;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var y: number = x;
"
`;

View File

@ -2,6 +2,5 @@ exports[`test lib.js 1`] = `
"declare var x: string;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
declare var x: string;
"
`;

View File

@ -55,58 +55,70 @@ let tests = [
]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
// objects on RHS
// arrays on RHS
// primitive classes on RHS
// primitives on RHS
// error
// error
// error
// error
// bogus stuff on LHS
// error
// error
// error
// error
// error
// in predicates
// error
// error, !'foo' is a boolean
// annotations on RHS
// ok
// error
let tests = [
// objects on RHS
function() {
"foo" in {};
"foo" in { foo: null };
0 in {};
0 in { "0": null };
"foo" in { foo: [object Null] };
[object Number] in {};
[object Number] in { "0": [object Null] };
},
// arrays on RHS
function() {
"foo" in [ ];
0 in [ ];
[object Number] in [ ];
"length" in [ ];
},
// primitive classes on RHS
function() {
"foo" in new String("bar");
"foo" in new Number(123);
"foo" in new Number([object Number]);
},
// primitives on RHS
function() {
"foo" in 123;// error
"foo" in "bar";// error
"foo" in void 0;// error
"foo" in null;// error
"foo" in [object Number];
"foo" in "bar";
"foo" in void [object Number];
"foo" in [object Null];
},
// bogus stuff on LHS
function() {
null in {};// error
void 0 in {};// error
({}) in {};// error
[ ] in {};// error
false in [ ];// error
[object Null] in {};
void [object Number] in {};
({}) in {};
[ ] in {};
[object Boolean] in [ ];
},
// in predicates
function() {
if ("foo" in 123) {
if ("foo" in [object Number]) {
}// error
}
if (!"foo" in {}) {
}// error, !'foo' is a boolean
}
if (!("foo" in {})) {
}
},
// annotations on RHS
function(x: Object, y: mixed) {
"foo" in x;// ok
"foo" in y;// error
"foo" in x;
"foo" in y;
}
];
"
`;

View File

@ -17,8 +17,8 @@ x &= 0;
// regression tests -- OK to assign consts like this:
const { foo } = { foo: \"foo\" }
const [ bar ] = [\"bar\"];
const { foo } = { foo: "foo" }
const [ bar ] = ["bar"];
(foo: number); // error: string ~> number
(bar: number); // error: string ~> number
@ -27,30 +27,32 @@ for (const { baz } of bazzes) {
(baz: number); // error: string ~> number
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const x = 0;
// errors: const cannot be reassigned
// regression tests -- OK to assign consts like this:
// error: string ~> number
// error: string ~> number
// error: string ~> number
const x = [object Number];
x++;
x--;
x += 0;
x -= 0;
x /= 0;
x %= 0;
x <<= 0;
x >>= 0;
x >>>= 0;
x |= 0;
x ^= 0;
x &= 0;
// regression tests -- OK to assign consts like this:
const { foo } = { foo: \"foo\" };
const [ bar ] = [ \"bar\" ];
(foo: number);// error: string ~> number
(bar: number);// error: string ~> number
x += [object Number];
x -= [object Number];
x /= [object Number];
x %= [object Number];
x <<= [object Number];
x >>= [object Number];
x >>>= [object Number];
x |= [object Number];
x ^= [object Number];
x &= [object Number];
const { foo } = { foo: "foo" };
const [ bar ] = [ "bar" ];
(foo: number);
(bar: number);
declare var bazzes: { baz: string }[];
for (const { baz } of bazzes) {
(baz: number);// error: string ~> number
(baz: number);
}
"
`;
@ -95,7 +97,7 @@ function type_var() {
function type_reassign() {
type A = number;
A = 42; // error: type alias ref\'d from value pos
A = 42; // error: type alias ref'd from value pos
}
// class x *
@ -253,21 +255,207 @@ function fn_params_clash_fn_binding(x,y) {
var y = 0; // OK
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Argument name clash in strict mode (193:33)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp$2.checkLVal (/node_modules/babylon/lib/index.js:3007:16)
at Parser.checkLVal (/node_modules/babylon/lib/index.js:5446:22)
at Parser.pp$3.parseFunctionBody (/node_modules/babylon/lib/index.js:4072:12)
at Parser.parseFunctionBody (/node_modules/babylon/lib/index.js:5211:20)
at Parser.pp$1.parseFunction (/node_modules/babylon/lib/index.js:2257:8)
at Parser.pp$1.parseFunctionStatement (/node_modules/babylon/lib/index.js:1926:15)
at Parser.pp$1.parseStatement (/node_modules/babylon/lib/index.js:1712:19)
at Parser.parseStatement (/node_modules/babylon/lib/index.js:5224:22)
at Parser.pp$1.parseBlockBody (/node_modules/babylon/lib/index.js:2139:21)
/* @flow
* test errors on illegal rebinding/reassignment
*
* type class let const var (reassign)
* type x x x x x x
* class x x x x x
* let x x x x x
* const x x x x x x
* var x x x x
*/
// type x *
// error: name already bound
// error: name already bound
// error: name already bound
// error: name already bound
// error: name already bound
// error: type alias ref'd from value pos
// class x *
// error: name already bound
// error: name already bound
// error: name already bound
// error: name already bound
// error: name already bound
// let x *
// error: name already bound
// error: name already bound
// error: name already bound
// error: name already bound
// error: name already bound
// const x *
// error: name already bound
// error: name already bound
// error: name already bound
// error: name already bound
// error: name already bound
// error: cannot be reassigned
// var x *
// error: name already bound
// error: name already bound
// error: name already bound
// error: name already bound
// OK
// function x *
// OK
// error: name already bound
// corner cases
// error: name already bound
// error: name already bound
// fn params name clash
/* error: x already bound */
// error: x already bound
// OK
function type_type() {
type A = number;
type A = number;
}
function type_class() {
type A = number;
class A {}
}
function type_let() {
type A = number;
let A = [object Number];
}
function type_const() {
type A = number;
const A = [object Number];
}
function type_var() {
type A = number;
var A = [object Number];
}
function type_reassign() {
type A = number;
A = [object Number];
}
function class_type() {
class A {}
type A = number;
}
function class_class() {
class A {}
class A {}
}
function class_let() {
class A {}
let A = [object Number];
}
function class_const() {
class A {}
const A = [object Number];
}
function class_var() {
class A {}
var A = [object Number];
}
function let_type() {
let A = [object Number];
type A = number;
}
function let_class() {
let A = [object Number];
class A {}
}
function let_let() {
let A = [object Number];
let A = [object Number];
}
function let_const() {
let A = [object Number];
const A = [object Number];
}
function let_var() {
let A = [object Number];
var A = [object Number];
}
function const_type() {
const A = [object Number];
type A = number;
}
function const_class() {
const A = [object Number];
class A {}
}
function const_let() {
const A = [object Number];
let A = [object Number];
}
function const_const() {
const A = [object Number];
const A = [object Number];
}
function const_var() {
const A = [object Number];
var A = [object Number];
}
function const_reassign() {
const A = [object Number];
A = [object Number];
}
function var_type() {
var A = [object Number];
type A = number;
}
function var_class() {
var A = [object Number];
class A {}
}
function var_let() {
var A = [object Number];
let A = [object Number];
}
function var_const() {
var A = [object Number];
const A = [object Number];
}
function var_var() {
var A = [object Number];
var A = [object Number];
}
function function_toplevel() {
function a() {
}
function a() {
}
}
function function_block() {
{
function a() {
}
function a() {
}
}
}
function var_shadow_nested_scope() {
{
let x = [object Number];
{
var x = [object Number];
}
}
}
function type_shadow_nested_scope() {
{
let x = [object Number];
{
type x = string;
}
}
}
function fn_params_name_clash(x, x) {
}
function fn_params_clash_fn_binding(x, y) {
let x = [object Number];
var y = [object Number];
}
"
`;
@ -276,8 +464,8 @@ exports[`test scope.js 1`] = `
let a: number = 0;
var b: number = 0;
{
let a = \"\"; // ok: local to block
var b = \"\"; // error: string ~> number
let a = ""; // ok: local to block
var b = ""; // error: string ~> number
}
}
@ -285,12 +473,12 @@ function switch_scope(x: string) {
let a: number = 0;
var b: number = 0;
switch (x) {
case \"foo\":
let a = \"\"; // ok: local to switch
var b = \"\"; // error: string ~> number
case "foo":
let a = ""; // ok: local to switch
var b = ""; // error: string ~> number
break;
case \"bar\":
let a = \"\"; // error: a already bound in switch
case "bar":
let a = ""; // error: a already bound in switch
break;
}
}
@ -301,43 +489,43 @@ function switch_scope(x: string) {
function switch_scope2(x: number) {
switch (x) {
case 0:
a = \"\"; // error: assign before declaration
a = ""; // error: assign before declaration
break;
case 1:
var b = a; // error: use before declaration
break;
case 2:
let a = \"\";
let a = "";
break;
case 3:
a = \"\"; // error: skipped initializer
a = ""; // error: skipped initializer
break;
case 4:
var c:string = a; // error: skipped initializer
break;
}
a = \"\"; // error: a no longer in scope
a = ""; // error: a no longer in scope
}
function try_scope() {
let a: number = 0;
try {
let a = \"\"; // ok
let a = ""; // ok
} catch (e) {
let a = \"\"; // ok
let a = ""; // ok
} finally {
let a = \"\"; // ok
let a = ""; // ok
}
}
function for_scope_let() {
let a: number = 0;
for (let a = \"\" /* ok: local to init */;;) {}
for (let a = "" /* ok: local to init */;;) {}
}
function for_scope_var() {
var a: number = 0;
for (var a = \"\" /* error: string ~> number */;;) {}
for (var a = "" /* error: string ~> number */;;) {}
}
function for_in_scope_let(o: Object) {
@ -371,7 +559,7 @@ function default_param_1() {
function default_param_2() {
// fn body bindings not visible from param scope
let a = \"\";
let a = "";
function f0(x = () => a): number {
let a = 0;
return x(); // error: string ~> number
@ -382,21 +570,136 @@ function default_param_2() {
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1020
}, \"consequent\").indent(options.tabWidth));
^
TypeError: path.call(...).indent is not a function
at genericPrintNoParens (/src/printer.js:1020:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.map (/src/fast-path.js:167:19)
at genericPrintNoParens (/src/printer.js:1005:36)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// ok: local to block
// error: string ~> number
// ok: local to switch
// error: string ~> number
// error: a already bound in switch
// a switch is a single lexical scope, so lets and non-disjoint
// cases can mix in odd ways. our support for edge cases is not
// yet perfect.
// error: assign before declaration
// error: use before declaration
// error: skipped initializer
// error: skipped initializer
// error: a no longer in scope
// ok
// ok
// ok
/* ok: local to init */
/* error: string ~> number */
/* ok: local to init */
/* error: string ~> number */
/* ok: local to init */
/* error: string ~> number */
// function binding in scope in default expr
// error: number ~> string
// fn body bindings not visible from param scope
// error: string ~> number
/* error: cannot resolve b */
function block_scope() {
let a: number = [object Number];
var b: number = [object Number];
{
let a = "";
var b = "";
}
}
function switch_scope(x: string) {
let a: number = [object Number];
var b: number = [object Number];
switch (x) {
case "foo":
let a = "";
var b = "";
break;
case "bar":
let a = "";
break;
}
}
function switch_scope2(x: number) {
switch (x) {
case [object Number]:
a = "";
break;
case [object Number]:
var b = a;
break;
case [object Number]:
let a = "";
break;
case [object Number]:
a = "";
break;
case [object Number]:
var c: string = a;
break;
}
a = "";
}
function try_scope() {
let a: number = [object Number];
try {
let a = "";
} catch (e) {
let a = "";
} finally {
let a = "";
}
}
function for_scope_let() {
let a: number = [object Number];
for (let a = ""; ; ) {
}
}
function for_scope_var() {
var a: number = [object Number];
for (var a = ""; ; ) {
}
}
function for_in_scope_let(o: Object) {
let a: number = [object Number];
for (let a in o) {
}
}
function for_in_scope_var(o: Object) {
var a: number = [object Number];
for (var a in o) {
}
}
function for_of_scope_let(xs: string[]) {
let a: number = [object Number];
for (let a of xs) {
}
}
function for_of_scope_var(xs: string[]) {
var a: number = [object Number];
for (var a of xs) {
}
}
function default_param_1() {
function f(x: () => string = f): number {
return [object Number];
}
}
function default_param_2() {
let a = "";
function f0(x = () => a): number {
let a = [object Number];
return x();
}
function f1(x = b): number {
let b = [object Number];
return x;
}
}
"
`;
@ -417,7 +720,7 @@ type T2 = number;
// while let is in TDZ.
// - allow forward refs to lets from type positions.
//
// currently we\'re too lenient about TDZ in closures -
// currently we're too lenient about TDZ in closures -
// from value positions, we currently enforce TDZ only in-scope.
// this is unsound - a let or const may remain uninitialized when
// a lambda runs. But a simple conservative approach would prohibit
@ -455,12 +758,12 @@ function f3() {
function foo() { return 0; }
}
var s2: string = foo(); // ok, hoisted outer not clobbered
function foo() { return \"\"; }
function foo() { return ""; }
}
// out-of-scope TDZ not enforced. sometimes right...
function f4() {
function g() { return x + c; } // ok, g doesn\'t run in TDZ
function g() { return x + c; } // ok, g doesn't run in TDZ
let x = 0;
const c = 0;
}
@ -468,7 +771,7 @@ function f4() {
// ...sometimes wrong
function f5() {
function g() { return x; }
g(); // should error, but doesn\'t currently
g(); // should error, but doesn't currently
let x = 0;
const c = 0;
}
@ -488,8 +791,8 @@ var z: C = new C(); // ok
// --- vars ---
// it\'s possible to annotate a var with a non-maybe type,
// but leave it uninitialized until later (as long as it\'s
// it's possible to annotate a var with a non-maybe type,
// but leave it uninitialized until later (as long as it's
// initialized before use)
var a: number; // not an error per se - only if used before init
@ -505,90 +808,105 @@ f(a); // ok, a: number (not ?number)
/** @flow */
// -- types ---
// type aliases are hoisted and always available
type T1 = T2;// ok
type T2 = number;
// ok
// --- lets ---
// to be correct, we would
// - not allow forward refs to lets from value positions,
// while let is in TDZ.
// - allow forward refs to lets from type positions.
//
// currently we\'re too lenient about TDZ in closures -
// currently we're too lenient about TDZ in closures -
// from value positions, we currently enforce TDZ only in-scope.
// this is unsound - a let or const may remain uninitialized when
// a lambda runs. But a simple conservative approach would prohibit
// forward references to let/consts from within lambdas entirely,
// which would be annoying. TODO
function f0() {
var v = x * c;// errors, let + const referenced before decl
let x = 0;
const c = 0;
}
function f1(b) {
x = 10;// error, attempt to write to let before decl
let x = 0;
if (b) {
y = 10;// error, attempt to write to let before decl
let y = 0;
}
}
function f2() {
{
var v = x * c;// errors, let + const referenced before decl
}
let x = 0;
const c = 0;
}
// errors, let + const referenced before decl
// error, attempt to write to let before decl
// error, attempt to write to let before decl
// errors, let + const referenced before decl
// functions are let-scoped and hoisted
function f3() {
var s: string = foo();// ok, finds hoisted outer
{
var n: number = foo();// ok, finds hoisted inner
function foo() {
return 0;
}
}
var s2: string = foo();// ok, hoisted outer not clobbered
function foo() {
return \"\";
}
}
// ok, finds hoisted outer
// ok, finds hoisted inner
// ok, hoisted outer not clobbered
// out-of-scope TDZ not enforced. sometimes right...
function f4() {
function g() {
return x + c;
}// ok, g doesn\'t run in TDZ
let x = 0;
const c = 0;
}
// ok, g doesn't run in TDZ
// ...sometimes wrong
function f5() {
function g() {
return x;
}
g();// should error, but doesn\'t currently
let x = 0;
const c = 0;
}
// should error, but doesn't currently
// - from type positions, we currently error on forward refs to any
// value (i.e., class or function). this is a basic flaw in our
// phasing of AST traversal, and will be fixed.
//
var x: C;// ok
var y = new C();// error: let ref before decl from value position
class C {}
var z: C = new C();// ok
// ok
// error: let ref before decl from value position
// ok
// --- vars ---
// it\'s possible to annotate a var with a non-maybe type,
// but leave it uninitialized until later (as long as it\'s
// it's possible to annotate a var with a non-maybe type,
// but leave it uninitialized until later (as long as it's
// initialized before use)
var a: number;// not an error per se - only if used before init
// not an error per se - only if used before init
// error: undefined ~/> number
// ok, a: number (not ?number)
type T1 = T2;
type T2 = number;
function f0() {
var v = x * c;
let x = [object Number];
const c = [object Number];
}
function f1(b) {
x = [object Number];
let x = [object Number];
if (b) {
y = [object Number];
let y = [object Number];
}
}
function f2() {
{
var v = x * c;
}
let x = [object Number];
const c = [object Number];
}
function f3() {
var s: string = foo();
{
var n: number = foo();
function foo() {
return [object Number];
}
}
var s2: string = foo();
function foo() {
return "";
}
}
function f4() {
function g() {
return x + c;
}
let x = [object Number];
const c = [object Number];
}
function f5() {
function g() {
return x;
}
g();
let x = [object Number];
const c = [object Number];
}
var x: C;
var y = new C();
class C {}
var z: C = new C();
var a: number;
function f(n: number) {
return n;
}
f(a);// error: undefined ~/> number
a = 10;
f(a);// ok, a: number (not ?number)
f(a);
a = [object Number];
f(a);
"
`;

View File

@ -3,53 +3,53 @@ exports[`test FormData.js 1`] = `
// constructor
const a: FormData = new FormData(); // correct
new FormData(\'\'); // incorrect
new FormData(document.createElement(\'input\')); // incorrect
new FormData(document.createElement(\'form\')); // correct
new FormData(''); // incorrect
new FormData(document.createElement('input')); // incorrect
new FormData(document.createElement('form')); // correct
// has
const b: boolean = a.has(\'foo\'); // correct
const b: boolean = a.has('foo'); // correct
// get
const c: ?(string | File) = a.get(\'foo\'); // correct
const d: string = a.get(\'foo\'); // incorrect
const e: Blob = a.get(\'foo\'); // incorrect
const f: ?(string | File | Blob) = a.get(\'foo\'); // incorrect
const c: ?(string | File) = a.get('foo'); // correct
const d: string = a.get('foo'); // incorrect
const e: Blob = a.get('foo'); // incorrect
const f: ?(string | File | Blob) = a.get('foo'); // incorrect
a.get(2); // incorrect
// getAll
const a1: Array<string | File> = a.getAll(\'foo\'); // correct
const a2: Array<string | File | number> = a.getAll(\'foo\'); // incorrect
const a3: Array<string | Blob | File> = a.getAll(\'foo\'); // incorrect
const a1: Array<string | File> = a.getAll('foo'); // correct
const a2: Array<string | File | number> = a.getAll('foo'); // incorrect
const a3: Array<string | Blob | File> = a.getAll('foo'); // incorrect
a.getAll(23); // incorrect
// set
a.set(\'foo\', \'bar\'); // correct
a.set(\'foo\', {}); // incorrect
a.set(2, \'bar\'); // incorrect
a.set(\'foo\', \'bar\', \'baz\'); // incorrect
a.set(\'bar\', new File([], \'q\')) // correct
a.set(\'bar\', new File([], \'q\'), \'x\') // correct
a.set(\'bar\', new File([], \'q\'), 2) // incorrect
a.set(\'bar\', new Blob) // correct
a.set(\'bar\', new Blob, \'x\') // correct
a.set(\'bar\', new Blob, 2) // incorrect
a.set('foo', 'bar'); // correct
a.set('foo', {}); // incorrect
a.set(2, 'bar'); // incorrect
a.set('foo', 'bar', 'baz'); // incorrect
a.set('bar', new File([], 'q')) // correct
a.set('bar', new File([], 'q'), 'x') // correct
a.set('bar', new File([], 'q'), 2) // incorrect
a.set('bar', new Blob) // correct
a.set('bar', new Blob, 'x') // correct
a.set('bar', new Blob, 2) // incorrect
// append
a.append(\'foo\', \'bar\'); // correct
a.append(\'foo\', {}); // incorrect
a.append(2, \'bar\'); // incorrect
a.append(\'foo\', \'bar\', \'baz\'); // incorrect
a.append(\'foo\', \'bar\'); // incorrect
a.append(\'bar\', new File([], \'q\')) // correct
a.append(\'bar\', new File([], \'q\'), \'x\') // correct
a.append(\'bar\', new File([], \'q\'), 2) // incorrect
a.append(\'bar\', new Blob) // correct
a.append(\'bar\', new Blob, \'x\') // correct
a.append(\'bar\', new Blob, 2) // incorrect
a.append('foo', 'bar'); // correct
a.append('foo', {}); // incorrect
a.append(2, 'bar'); // incorrect
a.append('foo', 'bar', 'baz'); // incorrect
a.append('foo', 'bar'); // incorrect
a.append('bar', new File([], 'q')) // correct
a.append('bar', new File([], 'q'), 'x') // correct
a.append('bar', new File([], 'q'), 2) // incorrect
a.append('bar', new Blob) // correct
a.append('bar', new Blob, 'x') // correct
a.append('bar', new Blob, 2) // incorrect
// delete
a.delete(\'xx\'); // correct
a.delete('xx'); // correct
a.delete(3); // incorrect
// keys
@ -67,21 +67,127 @@ for (let [x, y]: [number, string] of a.entries()) {} // incorrect
for (let [x, y]: [string, number] of a.entries()) {} // incorrect
for (let [x, y]: [number, number] of a.entries()) {} // incorrect
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1530
return fromString(\" | \").join(path.map(print, \"types\"));
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1530:32)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1412:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
/* @flow */
// constructor
// correct
// incorrect
// incorrect
// correct
// has
// correct
// get
// correct
// incorrect
// incorrect
// incorrect
// incorrect
// getAll
// correct
// incorrect
// incorrect
// incorrect
// set
// correct
// incorrect
// incorrect
// incorrect
// correct
// correct
// incorrect
// correct
// correct
// incorrect
// append
// correct
// incorrect
// incorrect
// incorrect
// incorrect
// correct
// correct
// incorrect
// correct
// correct
// incorrect
// delete
// correct
// incorrect
// keys
// correct
// incorrect
// values
// correct
// incorrect
// entries
// correct
// incorrect
// incorrect
// incorrect
// incorrect
const a: FormData = new FormData();
new FormData("");
new FormData(document.createElement("input"));
new FormData(document.createElement("form"));
const b: boolean = a.has("foo");
const c: ?(string | File) = a.get("foo");
const d: string = a.get("foo");
const e: Blob = a.get("foo");
const f: ?(string | File | Blob) = a.get("foo");
a.get([object Number]);
const a1: Array<string | File> = a.getAll("foo");
const a2: Array<string | File | number> = a.getAll("foo");
const a3: Array<string | Blob | File> = a.getAll("foo");
a.getAll([object Number]);
a.set("foo", "bar");
a.set("foo", {});
a.set([object Number], "bar");
a.set("foo", "bar", "baz");
a.set("bar", new File([ ], "q"));
a.set("bar", new File([ ], "q"), "x");
a.set("bar", new File([ ], "q"), [object Number]);
a.set("bar", new Blob());
a.set("bar", new Blob(), "x");
a.set("bar", new Blob(), [object Number]);
a.append("foo", "bar");
a.append("foo", {});
a.append([object Number], "bar");
a.append("foo", "bar", "baz");
a.append("foo", "bar");
a.append("bar", new File([ ], "q"));
a.append("bar", new File([ ], "q"), "x");
a.append("bar", new File([ ], "q"), [object Number]);
a.append("bar", new Blob());
a.append("bar", new Blob(), "x");
a.append("bar", new Blob(), [object Number]);
a.delete("xx");
a.delete([object Number]);
for (let x: string of a.keys()) {
}
for (let x: number of a.keys()) {
}
for (let x: string | File of a.values()) {
}
for (let x: string | File | Blob of a.values()) {
}
for (let [ x, y ] of a.entries()) {
}
for (let [ x, y ] of a.entries()) {
}
for (let [ x, y ] of a.entries()) {
}
for (let [ x, y ] of a.entries()) {
}
for (let [ x, y ] of a.entries()) {
}
"
`;
@ -100,11 +206,11 @@ new MutationObserver(42); // incorrect
new MutationObserver((n: number) => {}); // incorrect
// observe
const div = document.createElement(\'div\');
o.observe(div, { attributes: true, attributeFilter: [\'style\'] }); // correct
const div = document.createElement('div');
o.observe(div, { attributes: true, attributeFilter: ['style'] }); // correct
o.observe(div, { characterData: true, invalid: true }); // correct
o.observe(); // incorrect
o.observe(\'invalid\'); // incorrect
o.observe('invalid'); // incorrect
o.observe(div); // incorrect
o.observe(div, {}); // incorrect
o.observe(div, { subtree: true }); // incorrect
@ -116,20 +222,59 @@ o.takeRecords(); // correct
// disconnect
o.disconnect(); // correct
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
/* @flow */
// constructor
// correct
// correct
// correct
// incorrect
// incorrect
// incorrect
// observe
// correct
// correct
// incorrect
// incorrect
// incorrect
// incorrect
// incorrect
// incorrect
// takeRecords
// correct
// disconnect
// correct
function callback(
arr: Array<MutationRecord>, observer: MutationObserver
): void {
return;
}
const o: MutationObserver = new MutationObserver(callback);
new MutationObserver((arr: Array<MutationRecord>) => [object Boolean]);
new MutationObserver(
() => {
}
);
new MutationObserver();
new MutationObserver([object Number]);
new MutationObserver(
(n: number) => {
}
);
const div = document.createElement("div");
o.observe(div, { attributes: [object Boolean], attributeFilter: [ "style" ] });
o.observe(div, { characterData: [object Boolean], invalid: [object Boolean] });
o.observe();
o.observe("invalid");
o.observe(div);
o.observe(div, {});
o.observe(div, { subtree: [object Boolean] });
o.observe(
div,
{ attributes: [object Boolean], attributeFilter: [object Boolean] }
);
o.takeRecords();
o.disconnect();
"
`;

View File

@ -1,24 +1,16 @@
exports[`test scope.js 1`] = `
"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 { return y*0; }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:340:16)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
function foo<X, Y: X>(x: X, y: Y): void {
}
foo([object Number], "");
function bar<X: number, Y: X>(x: X, y: Y): number {
return y * [object Number];
}
"
`;
@ -41,7 +33,7 @@ class C<T: number> {
}
function example<T: {x: number}>(o: T): T { o.x = 0; return o; }
var obj1: {x: number; y: string} = example({x: 0, y: \"\"});
var obj1: {x: number; y: string} = example({x: 0, y: ""});
var obj2: {x: number} = example({x: 0});
var c: C<string> = new C; // error, since T = string is incompatible with number
@ -49,20 +41,38 @@ var q: number = c.qux(0);
/* 2 more errors, since argument U = number is incompatible with T = string, and
* result T = string is incompatible with number */
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:340:16)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// OK
// error
// OK
// error, since T: number and U: number does not imply U: T
// OK, since T: number and U: T implies U: number
// error
// OK, since U: T
// error, since T = string is incompatible with number
/* 2 more errors, since argument U = number is incompatible with T = string, and
* result T = string is incompatible with number */
function foo<T: number>(x: T): T {
var _ = x * [object Number];
var y: string = x;
return x;
}
class C<T: number> {
bar<U: number>(x: U): T {
return x;
}
qux<U: T>(x: U): T {
var _ = x * [object Number];
var y: string = x;
return x;
}
}
function example<T: { x: number }>(o: T): T {
o.x = [object Number];
return o;
}
var obj1: { x: number, y: string } = example({ x: [object Number], y: "" });
var obj2: { x: number } = example({ x: [object Number] });
var c: C<string> = new C();
var q: number = c.qux([object Number]);
"
`;

View File

@ -3,7 +3,7 @@ exports[`test break.js 1`] = `
var x = b ? null: false;
var z;
while(b) {
if (x == null) { z = \"\"; break; }
if (x == null) { z = ""; break; }
var y:number = x; // error: boolean !~> number
}
var w:number = z; // 2 errors: ?string !~> number
@ -12,10 +12,10 @@ exports[`test break.js 1`] = `
function bar(b) {
var x = b ? null: false;
if (x == null) return;
switch (\"\") {
switch ("") {
case 0:
var y:number = x; // error: boolean !~> number
x = \"\";
x = "";
case 1:
var z:number = x; // 2 errors: (boolean | string) !~> number
break;
@ -27,10 +27,10 @@ function bar(b) {
function bar2(b) {
var x = b ? null: false;
if (x == null) return;
switch (\"\") {
switch ("") {
case 0: {
let y:number = x; // error: boolean !~> number
x = \"\";
x = "";
}
case 1: {
let z:number = x; // 2 errors: (boolean | string) !~> number
@ -45,7 +45,7 @@ function qux(b) {
var z = 0;
while(b) {
var y:number = z;
if (b) { z = \"\"; continue; } // error: string !~> number
if (b) { z = ""; continue; } // error: string !~> number
z = 0;
}
var w:number = z; // error: string !~> number
@ -54,10 +54,10 @@ function qux(b) {
// same basic test as foo(), but with const. probes the
// logic that still uses havoc to do env resets.
function test_const() {
let st: string = \'abc\';
let st: string = 'abc';
for (let i = 1; i < 100; i++) {
const fooRes: ?string = \"HEY\";
const fooRes: ?string = "HEY";
if (!fooRes) {
break;
}
@ -68,20 +68,87 @@ function test_const() {
return st;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1020
}, \"consequent\").indent(options.tabWidth));
^
TypeError: path.call(...).indent is not a function
at genericPrintNoParens (/src/printer.js:1020:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.map (/src/fast-path.js:167:19)
at genericPrintNoParens (/src/printer.js:1005:36)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// error: boolean !~> number
// 2 errors: ?string !~> number
// error: boolean !~> number
// 2 errors: (boolean | string) !~> number
// 2 errors: (boolean | string) !~> number
// error: boolean !~> number
// 2 errors: (boolean | string) !~> number
// 2 errors: (boolean | string) !~> number
// error: string !~> number
// error: string !~> number
// same basic test as foo(), but with const. probes the
// logic that still uses havoc to do env resets.
// no error
function foo(b) {
var x = (b ? [object Null] : [object Boolean]);
var z;
while (b) {
if (x == [object Null]) {
z = "";
break;
}
var y: number = x;
}
var w: number = z;
}
function bar(b) {
var x = (b ? [object Null] : [object Boolean]);
if (x == [object Null])
return;
switch ("") {
case [object Number]:
var y: number = x;
x = "";
case [object Number]:
var z: number = x;
break;
case [object Number]:
}
var w: number = x;
}
function bar2(b) {
var x = (b ? [object Null] : [object Boolean]);
if (x == [object Null])
return;
switch ("") {
case [object Number]:
{
let y: number = x;
x = "";
}
case [object Number]:
{
let z: number = x;
break;
}
case [object Number]:
}
var w: number = x;
}
function qux(b) {
var z = [object Number];
while (b) {
var y: number = z;
if (b) {
z = "";
continue;
}
z = [object Number];
}
var w: number = z;
}
function test_const() {
let st: string = "abc";
for (let i = [object Number]; i < [object Number]; i++) {
const fooRes: ?string = "HEY";
if (!fooRes) {
break;
}
st = fooRes;
}
return st;
}
"
`;

View File

@ -3,10 +3,9 @@ exports[`test test.js 1`] = `
(o.foo: string);
module.exports = o;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var o = Object.freeze({ foo: 0 });
var o = Object.freeze({ foo: [object Number] });
(o.foo: string);
module.exports = o;
"
`;
@ -16,6 +15,5 @@ exports[`test test2.js 1`] = `
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var o = require("./test");
(o.foo: string);
"
`;

View File

@ -1,50 +1,52 @@
exports[`test array.js 1`] = `
"var a = [\"...\"];
"var a = ["..."];
var b = a.map (function (x) { return 0; });
var c: string = b[0]; // error: number !~> string
var array = [];
function f() {
array = array.map (function () { return \"...\"; });
array = array.map (function () { return "..."; });
var x:number = array[0]; // error: string !~> number
}
var Foo = require(\'./genericfoo\');
var Foo = require('./genericfoo');
var foo = new Foo();
function g() {
var foo1 = foo.map (function() { return \"...\"; });
var foo1 = foo.map (function() { return "..."; });
var x:number = foo1.get(); // error: string !~> number
foo = foo1;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var a = [ \"...\" ];
// error: number !~> string
// error: string !~> number
// error: string !~> number
var a = [ "..." ];
var b = a.map(
function(x) {
return 0;
return [object Number];
}
);
var c: string = b[0];// error: number !~> string
var c: string = b[[object Number]];
var array = [ ];
function f() {
array = array.map(
function() {
return \"...\";
return "...";
}
);
var x: number = array[0];// error: string !~> number
var x: number = array[[object Number]];
}
var Foo = require(\"./genericfoo\");
var Foo = require("./genericfoo");
var foo = new Foo();
function g() {
var foo1 = foo.map(
function() {
return \"...\";
return "...";
}
);
var x: number = foo1.get();// error: string !~> number
var x: number = foo1.get();
foo = foo1;
}
"
`;
@ -59,20 +61,21 @@ exports[`test genericfoo.js 1`] = `
module.exports = Foo;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1172:16)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
class Foo<T> {
x: T;
self(): Foo<T> {
return this;
}
map<U>(callbackfn: () => U): Foo<U> {
return new Foo();
}
set(x: T): void {
}
get(): T {
return this.x;
}
}
module.exports = Foo;
"
`;

View File

@ -11,7 +11,7 @@ function b(f: { (): string }): number {
// ...or if the param type is wrong
function c(f: { (x: number): number }): number {
return f(\"hello\");
return f("hello");
}
// ...or if the arity is wrong
@ -30,61 +30,92 @@ function f(): number {
return x();
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1348
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1348:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1425:19)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// You should be able to call objects with call properties
// ...and get an error if the return type is wrong
// ...or if the param type is wrong
// ...or if the arity is wrong
// ...or if there is no call property
// Make sure we complain even if the object literal is unsealed.
function a(f: { (): string }, g: { (x: number): string }): string {
return f() + g([object Number]);
}
function b(f: { (): string }): number {
return f();
}
function c(f: { (x: number): number }): number {
return f("hello");
}
function d(f: { (x: number): number }): number {
return f();
}
function e(f: {}): number {
return f();
}
function f(): number {
var x = {};
return x();
}
"
`;
exports[`test B.js 1`] = `
"// You should be able to use a function as an object with a call property
var a: { (x: number): string } = function (x: number): string { return \"hi\"; };
var a: { (x: number): string } = function (x: number): string { return "hi"; };
// ...and it should notice when the return type is wrong
var b: { (x: number): number } = function (x: number): string { return \"hi\"; };
var b: { (x: number): number } = function (x: number): string { return "hi"; };
// ...or if the param type is wrong
var c: { (x: string): string } = function (x: number): string { return \"hi\"; };
var c: { (x: string): string } = function (x: number): string { return "hi"; };
// ...or if the arity is wrong
var d: { (): string } = function (x: number): string { return \"hi\"; };
var d: { (): string } = function (x: number): string { return "hi"; };
// ...but subtyping rules still apply
var e: { (x: any): void } = function() { } // arity
var f: { (): mixed } = function(): string { return \"hi\" } // return type
var f: { (): mixed } = function(): string { return "hi" } // return type
var g: { (x: string): void } = function(x: mixed) { } // param type
// A function can be an object
var y : {} = function (x: number): string { return \"hi\"; };
var z : Object = function (x: number): string { return \"hi\"; };
var y : {} = function (x: number): string { return "hi"; };
var z : Object = function (x: number): string { return "hi"; };
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1348
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1348:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1425:19)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// You should be able to use a function as an object with a call property
// ...and it should notice when the return type is wrong
// ...or if the param type is wrong
// ...or if the arity is wrong
// ...but subtyping rules still apply
// arity
// return type
// param type
// A function can be an object
var a: { (x: number): string } = function(x: number): string {
return "hi";
};
var b: { (x: number): number } = function(x: number): string {
return "hi";
};
var c: { (x: string): string } = function(x: number): string {
return "hi";
};
var d: { (): string } = function(x: number): string {
return "hi";
};
var e: { (x: any): void } = function() {
};
var f: { (): mixed } = function(): string {
return "hi";
};
var g: { (x: string): void } = function(x: mixed) {
};
var y: {} = function(x: number): string {
return "hi";
};
var z: Object = function(x: number): string {
return "hi";
};
"
`;
@ -109,7 +140,7 @@ function d(x: { (z: number): string }): () => string {
return x;
}
// ...or if it doesn\'t have a call property
// ...or if it doesn't have a call property
function e(x: {}): () => string {
return x;
}
@ -124,21 +155,35 @@ function g(x: {}): Function {
return x; // error
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1348
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1348:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1425:19)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// You should be able to use an object as a function
// ...and it should notice when the return type is wrong
// ...or if the param type is wrong
// ...or if the arity is wrong
// ...or if it doesn't have a call property
// AnyFunT should also be allowed
// ... but only if the object is callable
// error
function a(x: { (z: number): string }): (z: number) => string {
return x;
}
function b(x: { (z: number): string }): (z: number) => number {
return x;
}
function c(x: { (z: number): string }): (z: string) => string {
return x;
}
function d(x: { (z: number): string }): () => string {
return x;
}
function e(x: {}): () => string {
return x;
}
function f(x: { (z: number): string }): Function {
return x;
}
function g(x: {}): Function {
return x;
}
"
`;
@ -150,11 +195,11 @@ function a(f: { (): string; (x: number): string }): string {
// It should be fine when a function satisfies them all
var b: { (): string; (x: number): string } =
function (x?: number): string { return \"hi\"; };
function (x?: number): string { return "hi"; };
// ...but should notice when a function doesn\'t satisfy them all
// ...but should notice when a function doesn't satisfy them all
var c: { (): string; (x: number): string } =
function (x: number): string { return \"hi\"; };
function (x: number): string { return "hi"; };
// Only one call property needs to match the function
function d(x: { (): string; (x: number): string }): () => string {
@ -166,26 +211,31 @@ function e(x: { (): string; (x: number): string }): () => number {
return x;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1348
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1348:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1425:19)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// Multiple call properties should also be supported
// It should be fine when a function satisfies them all
// ...but should notice when a function doesn't satisfy them all
// Only one call property needs to match the function
// ...but you need at least one
function a(f: { (): string, (x: number): string }): string {
return f() + f([object Number]);
}
var b: { (): string, (x: number): string } = function(x: number): string {
return "hi";
};
var c: { (): string, (x: number): string } = function(x: number): string {
return "hi";
};
function d(x: { (): string, (x: number): string }): () => string {
return x;
}
function e(x: { (): string, (x: number): string }): () => number {
return x;
}
"
`;
exports[`test E.js 1`] = `
"// 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 () {};
// Expecting properties that do exist should be fine
@ -196,21 +246,20 @@ var f = function () {};
f.myProp = 123;
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
// Expecting properties that do exist should be fine
// Expecting properties in the functions statics should be fine
var a: { someProp: number } = function() {
};
// Expecting properties that do exist should be fine
var b: { apply: Function } = function() {
};
// Expecting properties in the functions statics should be fine
var f = function() {
};
f.myProp = 123;
f.myProp = [object Number];
var c: { myProp: number } = f;
"
`;
@ -220,37 +269,44 @@ exports[`test F.js 1`] = `
var a: { (x: number): string } = (x) => x.toString()
// ...and it should notice when the return type is wrong
var b: { (x: number): number } = (x) => \"hi\"
var b: { (x: number): number } = (x) => "hi"
// ...or if the param type is wrong
var c: { (x: string): string } = (x) => x.toFixed()
// ...or if the arity is wrong
var d: { (): string } = (x) => \"hi\"
var d: { (): string } = (x) => "hi"
// ...but subtyping rules still apply
var e: { (x: any): void } = () => { } // arity
var f: { (): mixed } = () => \"hi\" // return type
var f: { (): mixed } = () => "hi" // return type
var g: { (x: Date): void } = (x) => { x * 2 } // param type (date < number)
// A function can be an object
var y : {} = (x) => \"hi\"
var z : Object = (x) => \"hi\"
var y : {} = (x) => "hi"
var z : Object = (x) => "hi"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1348
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1348:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1425:19)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// You should be able to use an arrow function as an object with a call property
// ...and it should notice when the return type is wrong
// ...or if the param type is wrong
// ...or if the arity is wrong
// ...but subtyping rules still apply
// arity
// return type
// param type (date < number)
// A function can be an object
var a: { (x: number): string } = x => x.toString();
var b: { (x: number): number } = x => "hi";
var c: { (x: string): string } = x => x.toFixed();
var d: { (): string } = x => "hi";
var e: { (x: any): void } = () => {
};
var f: { (): mixed } = () => "hi";
var g: { (x: Date): void } = x => {
x * [object Number];
};
var y: {} = x => "hi";
var z: Object = x => "hi";
"
`;

View File

@ -10,21 +10,11 @@ function f(x) {
(f: F);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1348
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1348:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1425:19)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
type F = { (x: string): number, p?: string };
function f(x) {
return x.length;
}
(f: F);
"
`;
@ -51,20 +41,25 @@ declare var callable: Callable;
callable(0); // error, number ~> string
callable.call(null, 0); // error, number ~> string
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1348
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1348:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1254:25)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// error, callable signature not found
// error, number ~> string
// error, number ~> string
// error, number ~> string
// error, number ~> string
var x = Boolean([object Number]);
function foo(fn: (value: any) => boolean) {
}
foo(Boolean);
var dict: { [k: string]: any } = {};
dict();
interface ICall extends { (x: string): void }
declare var icall: ICall;
icall([object Number]);
icall.call([object Null], [object Number]);
type Callable = { (x: string): void };
declare var callable: Callable;
callable([object Number]);
callable.call([object Null], [object Number]);
"
`;

View File

@ -1,8 +1,7 @@
exports[`test not_flow.js 1`] = `
"1 * \'foo\';
"1 * 'foo';
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 * \"foo\";
[object Number] * "foo";
"
`;
@ -11,20 +10,7 @@ exports[`test syntax_error.js 1`] = `
(
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token (4:0)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp$3.parseExprAtom (/node_modules/babylon/lib/index.js:3592:12)
at Parser.parseExprAtom (/node_modules/babylon/lib/index.js:6408:22)
at Parser.pp$3.parseExprSubscripts (/node_modules/babylon/lib/index.js:3337:19)
at Parser.pp$3.parseMaybeUnary (/node_modules/babylon/lib/index.js:3317:19)
at Parser.pp$3.parseExprOps (/node_modules/babylon/lib/index.js:3247:19)
at Parser.pp$3.parseMaybeConditional (/node_modules/babylon/lib/index.js:3224:19)
at Parser.pp$3.parseMaybeAssign (/node_modules/babylon/lib/index.js:3187:19)
at Parser.parseMaybeAssign (/node_modules/babylon/lib/index.js:5700:20)
/* @flow */
[object Null];
"
`;

View File

@ -7,14 +7,14 @@ class Base {
initializedField = 42;
initializedFieldWithThis = this.initializedField;
annotatedInitializedFieldValid: ?number = 42;
annotatedInitializedFieldInvalid: number = \'asdf\'; // Error: string ~> number
annotatedInitializedFieldInvalid: number = 'asdf'; // Error: string ~> number
static unannotatedField;
static annotatedField: number;
static initializedField = \'asdf\';
static initializedField = 'asdf';
static initializedFieldWithThis = this.initializedField;
static annotatedInitializedFieldValid: ?number = 42;
static annotatedInitializedFieldInvalid: number = \'asdf\'; // Error: string ~> number
static annotatedInitializedFieldInvalid: number = 'asdf'; // Error: string ~> number
}
var o = new Base();
@ -73,69 +73,98 @@ var o = new Base();
(Base.annotatedInitializedFieldInvalid: string); // Error: number ~> string
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
class Base {
unannotatedField;
annotatedField: number;
initializedField = 42;
initializedFieldWithThis = this.initializedField;
annotatedInitializedFieldValid: ?number = 42;
annotatedInitializedFieldInvalid: number = \"asdf\";// Error: string ~> number
static unannotatedField;
static annotatedField: number;
static initializedField = \"asdf\";
static initializedFieldWithThis = this.initializedField;
static annotatedInitializedFieldValid: ?number = 42;
static annotatedInitializedFieldInvalid: number = \"asdf\";// Error: string ~> number
}
var o = new Base();
// Error: string ~> number
// Error: string ~> number
/**
* Unannotated fields are open.
*/
(o.unannotatedField: string);
(o.unannotatedField: number);
(Base.unannotatedField: string);
(Base.unannotatedField: number);
/**
* Annotated (but uninitialized) fields still have a type.
*/
(o.annotatedField: number);
(o.annotatedField: string);// Error: number ~> string
(Base.annotatedField: number);
(Base.annotatedField: string);// Error: number ~> string
// Error: number ~> string
// Error: number ~> string
/**
* Initialized (but unannotated) fields assume the type of their initializer.
*/
(o.initializedField: number);
(o.initializedField: string);// Error: number ~> string
(Base.initializedField: string);
(Base.initializedField: number);// Error: string ~> number
// Error: number ~> string
// Error: string ~> number
/**
* Initialized fields can reference \`this\`.
*/
(o.initializedFieldWithThis: number);
(o.initializedFieldWithThis: string);// Error: number ~> string
(Base.initializedFieldWithThis: string);
(Base.initializedFieldWithThis: number);// Error: string ~> number
// Error: number ~> string
// Error: string ~> number
/**
* Initialized + annotated fields take the type of the annotation.
* (Note that this matters when the annotation is more general than the type of
* the initializer)
*/
(o.annotatedInitializedFieldValid: ?number);
(o.annotatedInitializedFieldValid: number);// Error: ?number ~> number
(Base.annotatedInitializedFieldValid: ?number);
(Base.annotatedInitializedFieldValid: number);// Error: ?number ~> number
// Error: ?number ~> number
// Error: ?number ~> number
/**
* Initialized + annotated fields where the init/annot combo is a mismatch
* should assume the type of the annotation.
*
* (This happens in addition to erroring at the site of initialization)
*/
(o.annotatedInitializedFieldInvalid: number);
(o.annotatedInitializedFieldInvalid: string);// Error: number ~> string
(Base.annotatedInitializedFieldInvalid: number);
(Base.annotatedInitializedFieldInvalid: string);// Error: number ~> string
// Error: number ~> string
// Error: number ~> string
class Base {
unannotatedField;
annotatedField: number;
initializedField;
=(;,
=,
.,
;,
:,
=,
;,
:,
=,
;,
unannotatedField,
static,
:,
;,
initializedField = "asdf",
static,
=,
.,
;,
annotatedInitializedFieldValid: ?number = [object Number],
static,
:,
=,
;,
var,
=,
Base) {
(o.unannotatedField: string);
(o.unannotatedField: number);
(Base.unannotatedField: string);
(Base.unannotatedField: number);
(o.annotatedField: number);
(o.annotatedField: string);
(Base.annotatedField: number);
(Base.annotatedField: string);
(o.initializedField: number);
(o.initializedField: string);
(Base.initializedField: string);
(Base.initializedField: number);
(o.initializedFieldWithThis: number);
(o.initializedFieldWithThis: string);
(Base.initializedFieldWithThis: string);
(Base.initializedFieldWithThis: number);
(o.annotatedInitializedFieldValid: ?number);
(o.annotatedInitializedFieldValid: number);
(Base.annotatedInitializedFieldValid: ?number);
(Base.annotatedInitializedFieldValid: number);
(o.annotatedInitializedFieldInvalid: number);
(o.annotatedInitializedFieldInvalid: string);
(Base.annotatedInitializedFieldInvalid: number);
(Base.annotatedInitializedFieldInvalid: string);
}
}
"
`;
@ -148,14 +177,14 @@ class Base {
base_initializedField = 42;
base_initializedFieldWithThis = this.base_initializedField;
base_annotatedInitializedFieldValid: ?number = 42;
base_annotatedInitializedFieldInvalid: number = \'asdf\'; // Error: string ~> number
base_annotatedInitializedFieldInvalid: number = 'asdf'; // Error: string ~> number
static base_unannotatedField;
static base_annotatedField: number;
static base_initializedField = \'asdf\';
static base_initializedField = 'asdf';
static base_initializedFieldWithThis = this.base_initializedField;
static base_annotatedInitializedFieldValid: ?number = 42;
static base_annotatedInitializedFieldInvalid: number = \'asdf\'; // Error: string ~> number
static base_annotatedInitializedFieldInvalid: number = 'asdf'; // Error: string ~> number
inherited_initializer = 42;
static inherited_initializer = 42;
@ -167,14 +196,14 @@ class Child extends Base {
child_initializedField = 42;
child_initializedFieldWithThis = this.child_initializedField;
child_annotatedInitializedFieldValid: ?number = 42;
child_annotatedInitializedFieldInvalid: number = \'asdf\'; // Error: string ~> number
child_annotatedInitializedFieldInvalid: number = 'asdf'; // Error: string ~> number
static child_unannotatedField;
static child_annotatedField: number;
static child_initializedField = \'asdf\';
static child_initializedField = 'asdf';
static child_initializedFieldWithThis = this.child_initializedField;
static child_annotatedInitializedFieldValid: ?number = 42;
static child_annotatedInitializedFieldInvalid: number = \'asdf\'; // Error: string ~> number
static child_annotatedInitializedFieldInvalid: number = 'asdf'; // Error: string ~> number
inherited_initializer;
static inherited_initializer;
@ -276,119 +305,171 @@ var o = new Child();
(Child.inherited_initializer: string); // Error: number ~> string
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
class Base {
base_unannotatedField;
base_annotatedField: number;
base_initializedField = 42;
base_initializedFieldWithThis = this.base_initializedField;
base_annotatedInitializedFieldValid: ?number = 42;
base_annotatedInitializedFieldInvalid: number = \"asdf\";// Error: string ~> number
static base_unannotatedField;
static base_annotatedField: number;
static base_initializedField = \"asdf\";
static base_initializedFieldWithThis = this.base_initializedField;
static base_annotatedInitializedFieldValid: ?number = 42;
static base_annotatedInitializedFieldInvalid: number = \"asdf\";// Error: string ~> number
inherited_initializer = 42;
static inherited_initializer = 42;
}
class Child extends Base {
child_unannotatedField;
child_annotatedField: number;
child_initializedField = 42;
child_initializedFieldWithThis = this.child_initializedField;
child_annotatedInitializedFieldValid: ?number = 42;
child_annotatedInitializedFieldInvalid: number = \"asdf\";// Error: string ~> number
static child_unannotatedField;
static child_annotatedField: number;
static child_initializedField = \"asdf\";
static child_initializedFieldWithThis = this.child_initializedField;
static child_annotatedInitializedFieldValid: ?number = 42;
static child_annotatedInitializedFieldInvalid: number = \"asdf\";// Error: string ~> number
inherited_initializer;
static inherited_initializer;
}
var o = new Child();
// Error: string ~> number
// Error: string ~> number
// Error: string ~> number
// Error: string ~> number
/**
* Unannotated fields are open.
*/
(o.base_unannotatedField: string);
(o.base_unannotatedField: number);
(Child.base_unannotatedField: string);
(Child.base_unannotatedField: number);
(o.child_unannotatedField: string);
(o.child_unannotatedField: number);
(Child.child_unannotatedField: string);
(Child.child_unannotatedField: number);
/**
* Annotated (but uninitialized) fields still have a type.
*/
(o.base_annotatedField: number);
(o.base_annotatedField: string);// Error: number ~> string
(Child.base_annotatedField: number);
(Child.base_annotatedField: string);// Error: number ~> string
(o.child_annotatedField: number);
(o.child_annotatedField: string);// Error: number ~> string
(Child.child_annotatedField: number);
(Child.child_annotatedField: string);// Error: number ~> string
// Error: number ~> string
// Error: number ~> string
// Error: number ~> string
// Error: number ~> string
/**
* Initialized (but unannotated) fields assume the type of their initializer.
*/
(o.base_initializedField: number);
(o.base_initializedField: string);// Error: number ~> string
(Child.base_initializedField: string);
(Child.base_initializedField: number);// Error: string ~> number
(o.child_initializedField: number);
(o.child_initializedField: string);// Error: number ~> string
(Child.child_initializedField: string);
(Child.child_initializedField: number);// Error: string ~> number
// Error: number ~> string
// Error: string ~> number
// Error: number ~> string
// Error: string ~> number
/**
* Initialized fields can reference \`this\`.
*/
(o.base_initializedFieldWithThis: number);
(o.base_initializedFieldWithThis: string);// Error: number ~> string
(Child.base_initializedFieldWithThis: string);
(Child.base_initializedFieldWithThis: number);// Error: string ~> number
(o.child_initializedFieldWithThis: number);
(o.child_initializedFieldWithThis: string);// Error: number ~> string
(Child.child_initializedFieldWithThis: string);
(Child.child_initializedFieldWithThis: number);// Error: string ~> number
// Error: number ~> string
// Error: string ~> number
// Error: number ~> string
// Error: string ~> number
/**
* Initialized + annotated fields take the type of the annotation.
* (Note that this matters when the annotation is more general than the type of
* the initializer)
*/
(o.base_annotatedInitializedFieldValid: ?number);
(o.base_annotatedInitializedFieldValid: number);// Error: ?number ~> number
(Child.base_annotatedInitializedFieldValid: ?number);
(Child.base_annotatedInitializedFieldValid: number);// Error: ?number ~> number
(o.child_annotatedInitializedFieldValid: ?number);
(o.child_annotatedInitializedFieldValid: number);// Error: ?number ~> number
(Child.child_annotatedInitializedFieldValid: ?number);
(Child.child_annotatedInitializedFieldValid: number);// Error: ?number ~> number
// Error: ?number ~> number
// Error: ?number ~> number
// Error: ?number ~> number
// Error: ?number ~> number
/**
* Initialized + annotated fields where the init/annot combo is a mismatch
* should assume the type of the annotation.
*
* (This happens in addition to erroring at the site of initialization)
*/
(o.base_annotatedInitializedFieldInvalid: number);
(o.base_annotatedInitializedFieldInvalid: string);// Error: number ~> string
(Child.base_annotatedInitializedFieldInvalid: number);
(Child.base_annotatedInitializedFieldInvalid: string);// Error: number ~> string
(o.child_annotatedInitializedFieldInvalid: number);
(o.child_annotatedInitializedFieldInvalid: string);// Error: number ~> string
(Child.child_annotatedInitializedFieldInvalid: number);
(Child.child_annotatedInitializedFieldInvalid: string);// Error: number ~> string
// Error: number ~> string
// Error: number ~> string
// Error: number ~> string
// Error: number ~> string
/**
* Derived fields without an initializer that shadow base fields *with* an
* initializer should have the type of the base field.
*/
(o.inherited_initializer: number);
(o.inherited_initializer: string);// Error: number ~> string
(Child.inherited_initializer: number);
(Child.inherited_initializer: string);// Error: number ~> string
// Error: number ~> string
// Error: number ~> string
class Base {
base_unannotatedField;
base_annotatedField: number;
base_initializedField;
=(;,
=,
.,
;,
:,
=,
;,
:,
=,
;,
base_unannotatedField,
static,
:,
;,
base_initializedField = "asdf",
static,
=,
.,
;,
base_annotatedInitializedFieldValid: ?number = [object Number],
static,
:,
=,
;,
=,
;,
inherited_initializer = [object Number],
},
Child,
Base,
child_unannotatedField,
child_annotatedField: number,
child_initializedField = [object Number],
child_initializedFieldWithThis = this.child_initializedField,
child_annotatedInitializedFieldValid: ?number = [object Number],
child_annotatedInitializedFieldInvalid: number = "asdf",
static,
;,
child_annotatedField: number,
static,
=,
;,
child_initializedFieldWithThis = this.child_initializedField,
static,
:,
=,
;,
child_annotatedInitializedFieldInvalid: number = "asdf",
inherited_initializer,
static,
;,
var,
=,
Child) {
(o.base_unannotatedField: string);
(o.base_unannotatedField: number);
(Child.base_unannotatedField: string);
(Child.base_unannotatedField: number);
(o.child_unannotatedField: string);
(o.child_unannotatedField: number);
(Child.child_unannotatedField: string);
(Child.child_unannotatedField: number);
(o.base_annotatedField: number);
(o.base_annotatedField: string);
(Child.base_annotatedField: number);
(Child.base_annotatedField: string);
(o.child_annotatedField: number);
(o.child_annotatedField: string);
(Child.child_annotatedField: number);
(Child.child_annotatedField: string);
(o.base_initializedField: number);
(o.base_initializedField: string);
(Child.base_initializedField: string);
(Child.base_initializedField: number);
(o.child_initializedField: number);
(o.child_initializedField: string);
(Child.child_initializedField: string);
(Child.child_initializedField: number);
(o.base_initializedFieldWithThis: number);
(o.base_initializedFieldWithThis: string);
(Child.base_initializedFieldWithThis: string);
(Child.base_initializedFieldWithThis: number);
(o.child_initializedFieldWithThis: number);
(o.child_initializedFieldWithThis: string);
(Child.child_initializedFieldWithThis: string);
(Child.child_initializedFieldWithThis: number);
(o.base_annotatedInitializedFieldValid: ?number);
(o.base_annotatedInitializedFieldValid: number);
(Child.base_annotatedInitializedFieldValid: ?number);
(Child.base_annotatedInitializedFieldValid: number);
(o.child_annotatedInitializedFieldValid: ?number);
(o.child_annotatedInitializedFieldValid: number);
(Child.child_annotatedInitializedFieldValid: ?number);
(Child.child_annotatedInitializedFieldValid: number);
(o.base_annotatedInitializedFieldInvalid: number);
(o.base_annotatedInitializedFieldInvalid: string);
(Child.base_annotatedInitializedFieldInvalid: number);
(Child.base_annotatedInitializedFieldInvalid: string);
(o.child_annotatedInitializedFieldInvalid: number);
(o.child_annotatedInitializedFieldInvalid: string);
(Child.child_annotatedInitializedFieldInvalid: number);
(Child.child_annotatedInitializedFieldInvalid: string);
(o.inherited_initializer: number);
(o.inherited_initializer: string);
(Child.inherited_initializer: number);
(Child.inherited_initializer: string);
}
}
"
`;
@ -414,7 +495,7 @@ ClassAnnotated.p = 42;
/**
* It\'s always an error to initialized a generically-typed field with an
* It's always an error to initialized a generically-typed field with an
* expression of any type other than the generic itself.
*/
class ClassGenericInitialized<T, U> {
@ -425,21 +506,41 @@ class ClassGenericInitialized<T, U> {
static valid: T = ((42:any):T);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1172:16)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// @flow
/**
* Fields annotated with a generic should assume a type once the type param
* is instantiated.
*/
// Error: number ~> string
// Error: number ~> string
/**
* It's always an error to initialized a generically-typed field with an
* expression of any type other than the generic itself.
*/
// Error: number ~> Generic<T>
// Error: number ~> Generic<T>
class ClassAnnotated<T> {
p: T;
static p: T;
}
var o1 = new ClassAnnotated();
o1.p = [object Number];
(o1.p: number);
(o1.p: string);
ClassAnnotated.p = [object Number];
(ClassAnnotated.p: number);
(ClassAnnotated.p: string);
class ClassGenericInitialized<T, U> {
invalid: T;
=(;, :, =, (, :): T {
static;
invalid:
T = [object Number];
static;
valid:
T = (([object Number]: any): T);
}
}
"
`;
@ -458,7 +559,7 @@ class Foo {
static selfTypedInit = new Foo();
constructor() {
var someVar = \'asdf\';
var someVar = 'asdf';
}
}
@ -486,38 +587,51 @@ class Foo {
(Foo.selfTypedInit: number); // Error: Foo ~> number
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
var someVar = 42;
class Foo {
outer = someVar;
selfTyped: Foo;
selfTypedInit = new Foo();
static outer = someVar;
static selfTyped: Foo;
static selfTypedInit = new Foo();
constructor() {
var someVar = \"asdf\";
}
}
/**
* Field initializers execute in a scope immediately under the scope outside the
* class definition.
*/
(new Foo().outer: number);
(new Foo().outer: string);// Error: number ~> string
(Foo.outer: number);
(Foo.outer: string);// Error: number ~> string
// Error: number ~> string
// Error: number ~> string
/**
* Field initializers should be able to refer to the class type in their type
* annotations.
*/
(new Foo().selfTyped: Foo);
(new Foo().selfTyped: number);// Error: Foo ~> number
(Foo.selfTyped: Foo);
(Foo.selfTyped: number);// Error: Foo ~> number
(new Foo().selfTypedInit: Foo);
(new Foo().selfTypedInit: number);// Error: Foo ~> number
(Foo.selfTypedInit: Foo);
(Foo.selfTypedInit: number);// Error: Foo ~> number
// Error: Foo ~> number
// Error: Foo ~> number
// Error: Foo ~> number
// Error: Foo ~> number
var someVar = [object Number];
class Foo {
outer;
=(;, :, ;, =, Foo) {
static;
outer = someVar;
static;
selfTyped:
Foo;
static;
selfTypedInit = new Foo();
constructor();
{
var someVar = "asdf";
}
}
((Foo) {
outer:
number;
(new Foo().outer: string);
(Foo.outer: number);
(Foo.outer: string);
(new Foo().selfTyped: Foo);
(new Foo().selfTyped: number);
(Foo.selfTyped: Foo);
(Foo.selfTyped: number);
(new Foo().selfTypedInit: Foo);
(new Foo().selfTypedInit: number);
(Foo.selfTypedInit: Foo);
(Foo.selfTypedInit: number);
}
}
"
`;

View File

@ -18,6 +18,7 @@ class Bar extends Foo {
/**
* @flow
*/
// error
class Foo {
_method(): string {
return "this is private";
@ -25,10 +26,9 @@ class Foo {
}
class Bar extends Foo {
test() {
(this._method(): string);// error
(this._method(): string);
}
}
"
`;
@ -54,6 +54,7 @@ class Bar extends Foo {
* @flow
* @preventMunge
*/
// ok
class Foo {
_method(): string {
return "this is not private";
@ -61,9 +62,8 @@ class Foo {
}
class Bar extends Foo {
test() {
(this._method(): string);// ok
(this._method(): string);
}
}
"
`;

View File

@ -12,9 +12,9 @@ class B extends A {
static foo(x: string) { } // error?
static main() {
B.x = 0; // error
B.x = \"\";
B.x = "";
B.foo(0); // error
B.foo(\"\");
B.foo("");
B.y = 0; // error
B.bar(0); // error
B.qux(0); // error
@ -61,20 +61,78 @@ module.exports = {
A: A, B: B, C: C, D: D, E: E
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1172:16)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// error?
// error?
// error?
// error
// error
// error
// error
// error
// error B ~> number
// error?
// error
// error
// note: above classdefs are sufficiently annotated to export
class A {
static x: number;
static y: string;
static foo(x: number) {
}
static bar(y: string) {
}
}
A.qux = function(x: string) {
};
class B extends A {
static x: string;
static foo(x: string) {
}
static main() {
B.x = [object Number];
B.x = "";
B.foo([object Number]);
B.foo("");
B.y = [object Number];
B.bar([object Number]);
B.qux([object Number]);
}
static create(): A {
return new this();
}
static badCreate(): number {
return new this();
}
}
class C<X> {
static x: X;
static bar(x: X) {
}
static create(): C<*> {
return new this();
}
}
class D extends C<string> {
static main() {
D.foo([object Number]);
D.bar([object Number]);
}
}
var d: C<*> = D.create();
(new A(): typeof A);
(B: typeof A);
class E {
static x: number;
static foo(): string {
this.bar();
return this.x;
}
}
module.exports = { A: A, B: B, C: C, D: D, E: E };
"
`;

View File

@ -9,13 +9,12 @@ module.exports = { A, B };
class A {}
class B {}
module.exports = { A, B };
"
`;
exports[`test test2.js 1`] = `
"/* @flow */
var I = require(\"./test.js\");
var I = require("./test.js");
class C extends I.A {}
@ -23,11 +22,10 @@ var x: I.A = new C();
var y: I.B = new C();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
var I = require(\"./test.js\");
var I = require("./test.js");
class C extends I.A {}
var x: I.A = new C();
var y: I.B = new C();
"
`;
@ -39,21 +37,13 @@ class C<X, Y, Z> extends B {}
var c: C<number, string, Array<bool>> = new C; // none of the type args matter
var a: A<string, number, Array<bool>> = c; // the third type arg is incorrect
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1172:16)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// none of the type args matter
// the third type arg is incorrect
class A<X, Y, Z> {}
class B extends A<string, number, boolean> {}
class C<X, Y, Z> extends B {}
var c: C<number, string, Array<boolean>> = new C();
var a: A<string, number, Array<boolean>> = c;
"
`;
@ -72,20 +62,19 @@ class D extends C<O> {
foo(new D, { f_: 0 });
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1172:16)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
class C<X> {
x: X;
}
function foo<X>(c: C<X>, x: X) {
}
type O = { f: number };
foo((new C(): C<O>), { f_: [object Number] });
class D extends C<O> {
bar() {
this.x;
}
}
foo(new D(), { f_: [object Number] });
"
`;

View File

@ -11,21 +11,20 @@ function bar(x: Class<B>): B {
return new x(); // error (too few args)
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// OK
// error (too few args)
class A {}
function foo(x: Class<A>): A {
return new x();
}
class B {
constructor(_: any) {
}
}
function bar(x: Class<B>): B {
return new x();
}
"
`;
@ -45,20 +44,17 @@ check(C, new A);
check(C, new B);
check(B, new C);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// A function to typecheck values against their types. Covariance of Class<.>
// makes it useless in such a function (when limited to classes and instances),
// since everything can be trivially satisfied by going to \`mixed\`.
declare function check(cls: $Type<X>, inst: X): void;
class A {}
class B extends A {}
class C {}
check(B, new A());
check(A, new B());
check(C, new A());
check(C, new B());
check(B, new C());
"
`;

View File

@ -11,12 +11,11 @@ class A {
}
}
module.exports = A;
"
`;
exports[`test B.js 1`] = `
"var A = require(\'./A\');
"var A = require('./A');
class B extends A { }
@ -25,17 +24,17 @@ let b = new B();
module.exports = B;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var A = require(\"./A\");
// error, number !~> function
var A = require("./A");
class B extends A {}
let b = new B();
(b.foo: number);// error, number !~> function
(b.foo: number);
module.exports = B;
"
`;
exports[`test C.js 1`] = `
"var B = require(\'./B\');
"var B = require('./B');
class C extends B {
foo(x:string):void { }
@ -46,16 +45,16 @@ let c = new C();
module.exports = C;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var B = require(\"./B\");
// error, number !~> function
var B = require("./B");
class C extends B {
foo(x: string): void {
}
}
let c = new C();
(c.foo: number);// error, number !~> function
(c.foo: number);
module.exports = C;
"
`;
@ -67,7 +66,6 @@ new E().x
class D {}
class E {}
new E().x;
"
`;
@ -76,9 +74,9 @@ exports[`test class_shapes.js 1`] = `
type Foo = {
a: string; // exists in TestClass
b: string; // doesn\'t exist
b: string; // doesn't exist
c?: ?string; // exists in TestClass, optional
d?: number; // doesn\'t exist
d?: number; // doesn't exist
}
class TestClass {
@ -94,8 +92,8 @@ x.c; // ok
x.d; // error, TestClass has no d
var y : Foo = x;
y.b; // error, doesn\'t exist in TestClass
y.d; // ok, it\'s optional
y.b; // error, doesn't exist in TestClass
y.d; // ok, it's optional
class Test2Superclass {
a: number; // conflicts with cast to Foo
@ -109,34 +107,41 @@ var z = new Test2Class();
var w : Foo = z;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
type Foo = {
// exists in TestClass a: string,
// doesn\'t exist b: string,
// exists in TestClass, optional c?: ?string,
// doesn\'t exist d?: number
};
// exists in TestClass
// doesn't exist
// exists in TestClass, optional
/* doesn't exist*/
// ok
// error, TestClass has no b
// ok
// error, TestClass has no d
// error, doesn't exist in TestClass
// ok, it's optional
// conflicts with cast to Foo
// conflicts with cast to Foo
// conflicts with cast to Foo
type Foo = { a: string, b: string, c?: ?string, d?: number };
class TestClass {
a: string;
c: ?string;
}
var x = new TestClass();
x.a;// ok
x.b;// error, TestClass has no b
x.c;// ok
x.d;// error, TestClass has no d
x.a;
x.b;
x.c;
x.d;
var y: Foo = x;
y.b;// error, doesn\'t exist in TestClass
y.d;// ok, it\'s optional
y.b;
y.d;
class Test2Superclass {
a: number;// conflicts with cast to Foo
c: ?number;// conflicts with cast to Foo
a: number;
c: ?number;
}
class Test2Class extends Test2Superclass {
b: number;// conflicts with cast to Foo
b: number;
}
var z = new Test2Class();
var w: Foo = z;
"
`;
@ -150,7 +155,7 @@ exports[`test expr.js 1`] = `
var bar1: Bar = new Bar() // OK
var bar2: Bar = Bar.factory() // OK
// NB: Don\'t write expected errors using Foo to avoid error collapse hiding an
// NB: Don't write expected errors using Foo to avoid error collapse hiding an
// unexpected failure in the above code.
var B = class Baz { }
@ -172,32 +177,38 @@ var _Alias = class Alias {
var alias1: Alias = new _Alias(); // error: bad pun
var alias2: Alias = _Alias.factory(); // error: bad pun
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// OK: Foo is a type in this scope
// OK: Foo is a runtime binding in this scope
// OK
// OK
// NB: Don't write expected errors using Foo to avoid error collapse hiding an
// unexpected failure in the above code.
// error: Baz is not a runtime binding in this scope
// error: Qux is not a type in this scope
// OK: anon classes create no binding, but can be bound manually
// error: bad pun
// error: bad pun
var Bar = class Foo {
factory(): Foo {
// OK: Foo is a type in this scope
return new Foo();// OK: Foo is a runtime binding in this scope
static factory(): Foo {
return new Foo();
}
};
var bar1: Bar = new Bar();// OK
var bar2: Bar = Bar.factory();// OK
// NB: Don\'t write expected errors using Foo to avoid error collapse hiding an
// unexpected failure in the above code.
var bar1: Bar = new Bar();
var bar2: Bar = Bar.factory();
var B = class Baz {};
var b = new Baz();// error: Baz is not a runtime binding in this scope
var b = new Baz();
var C = class Qux {};
var c: Qux = new C();// error: Qux is not a type in this scope
// OK: anon classes create no binding, but can be bound manually
var c: Qux = new C();
var Anon = class {};
var anon: Anon = new Anon();
class Alias {}
var _Alias = class Alias {
factory(): Alias {
static factory(): Alias {
return new Alias();
}
};
var alias1: Alias = new _Alias();// error: bad pun
var alias2: Alias = _Alias.factory();// error: bad pun
var alias1: Alias = new _Alias();
var alias2: Alias = _Alias.factory();
"
`;
@ -209,9 +220,9 @@ type Foo = number
class Foo {} // error, shadows type Foo
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
// error, shadows type Foo
type Foo = number;
class Foo {}// error, shadows type Foo
class Foo {}
"
`;
@ -221,7 +232,7 @@ exports[`test statics.js 1`] = `
class C {
static p: string;
}
C.p = \"hi\";
C.p = "hi";
// Class static fields are compatible with object types
(C: {p:string}); // ok
@ -230,20 +241,18 @@ C.p = \"hi\";
declare var o: {p:number};
(o: Class<C>); // error, object type incompatible with class type
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
/* @flow */
// Class static fields are compatible with object types
// ok
// errors, string ~> number & vice versa (unify)
// error, object type incompatible with class type
class C {
static p: string;
}
C.p = "hi";
(C: { p: string });
(C: { p: number });
declare var o: { p: number };
(o: Class<C>);
"
`;

View File

@ -9,7 +9,7 @@ function takes_string(_:string) { }
// global write from function
//
var global_x = \"hello\";
var global_x = "hello";
function global_f() { }
function global_g() { global_x = 42; }
@ -20,14 +20,14 @@ takes_string(global_x); // ok
global_g();
takes_string(global_x); // error
global_x = 42; // shouldn\'t pollute linear refinement
global_x = 42; // shouldn't pollute linear refinement
// local write from function
//
function local_func() {
var local_x = \"hello\";
var local_x = "hello";
function local_f() { }
function local_g() { local_x = 42; }
@ -38,13 +38,13 @@ function local_func() {
local_g();
takes_string(local_x); // error
local_x = 42; // shouldn\'t pollute linear refinement
local_x = 42; // shouldn't pollute linear refinement
}
// global write from method
//
var global_y = \"hello\";
var global_y = "hello";
var global_o = {
f: function() { },
@ -57,14 +57,14 @@ takes_string(global_y); // ok
global_o.g();
takes_string(global_y); // error
global_y = 42; // shouldn\'t pollute linear refinement
global_y = 42; // shouldn't pollute linear refinement
// local write from method
//
function local_meth() {
var local_y = \"hello\";
var local_y = "hello";
var local_o = {
f: function() { },
@ -77,81 +77,92 @@ function local_meth() {
local_o.g();
takes_string(local_y); // error
local_y = 42; // shouldn\'t pollute linear refinement
local_y = 42; // shouldn't pollute linear refinement
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/***
* Test tracking of variable types across closure calls.
* @flow
*/
// global write from function
//
// ok
// error
// shouldn't pollute linear refinement
// local write from function
//
// ok
// error
// shouldn't pollute linear refinement
// global write from method
//
// ok
// error
// shouldn't pollute linear refinement
// local write from method
//
// ok
// error
// shouldn't pollute linear refinement
function takes_string(_: string) {
}
// global write from function
//
var global_x = \"hello\";
var global_x = "hello";
function global_f() {
}
function global_g() {
global_x = 42;
global_x = [object Number];
}
global_f();
takes_string(global_x);// ok
takes_string(global_x);
global_g();
takes_string(global_x);// error
global_x = 42;// shouldn\'t pollute linear refinement
// local write from function
//
takes_string(global_x);
global_x = [object Number];
function local_func() {
var local_x = \"hello\";
var local_x = "hello";
function local_f() {
}
function local_g() {
local_x = 42;
local_x = [object Number];
}
local_f();
takes_string(local_x);// ok
takes_string(local_x);
local_g();
takes_string(local_x);// error
local_x = 42;// shouldn\'t pollute linear refinement
takes_string(local_x);
local_x = [object Number];
}
// global write from method
//
var global_y = \"hello\";
var global_y = "hello";
var global_o = {
f: function() {
},
g: function() {
global_y = 42;
global_y = [object Number];
}
};
global_o.f();
takes_string(global_y);// ok
takes_string(global_y);
global_o.g();
takes_string(global_y);// error
global_y = 42;// shouldn\'t pollute linear refinement
// local write from method
//
takes_string(global_y);
global_y = [object Number];
function local_meth() {
var local_y = \"hello\";
var local_y = "hello";
var local_o = {
f: function() {
},
g: function() {
local_y = 42;
local_y = [object Number];
}
};
local_o.f();
takes_string(local_y);// ok
takes_string(local_y);
local_o.g();
takes_string(local_y);// error
local_y = 42;// shouldn\'t pollute linear refinement
takes_string(local_y);
local_y = [object Number];
}
"
`;
@ -163,7 +174,7 @@ exports[`test cond_havoc.js 1`] = `
//
function example(b: bool): number {
var x = 0;
function f() { x = \"\" }
function f() { x = "" }
if (b) {
f();
}
@ -174,17 +185,17 @@ function example(b: bool): number {
// from sam, https://github.com/facebook/flow/issues/780
// call to f() within if should properly havoc x.
//
// error, string ~/~> number (return type anno) TODO
function example(b: boolean): number {
var x = 0;
var x = [object Number];
function f() {
x = \"\";
x = "";
}
if (b) {
f();
}
return x;// error, string ~/~> number (return type anno) TODO
return x;
}
"
`;
@ -201,7 +212,7 @@ function g(x: ?number) {
const const_x = x;
if (const_x) {
// ok: if const_x is truthy here, it\'s truthy everywhere
// ok: if const_x is truthy here, it's truthy everywhere
call_me = () => { var y:number = const_x; };
}
@ -216,20 +227,20 @@ function g(x: ?number) {
function h(x: number | string | boolean) {
const const_x = x;
if (typeof(const_x) == \"number\") {
if (typeof(const_x) == "number") {
call_me = () => { var y:number = const_x; }; // ok
} else if (typeof(const_x) == \"string\") {
} else if (typeof(const_x) == "string") {
call_me = () => { var y:string = const_x; }; // ok
} else if (typeof(const_x) == \"boolean\") {
} else if (typeof(const_x) == "boolean") {
call_me = () => { var y:boolean = const_x; }; // ok
}
var var_x = x;
if (typeof(var_x) == \"number\") {
if (typeof(var_x) == "number") {
call_me = () => { var y:number = var_x; }; // error
} else if (typeof(var_x) == \"string\") {
} else if (typeof(var_x) == "string") {
call_me = () => { var y:string = var_x; }; // error
} else if (typeof(var_x) == \"boolean\") {
} else if (typeof(var_x) == "boolean") {
call_me = () => { var y:boolean = var_x; }; // error
}
}
@ -237,20 +248,73 @@ function h(x: number | string | boolean) {
// in a galaxy far far away
call_me();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1348
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1348:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1254:25)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
/***
* consts retain refinements
* @flow
*/
// global, anybody can call it at any time
// ok: if const_x is truthy here, it's truthy everywhere
// error: var_x might no longer be truthy when call_me is called
// error
// ok
// ok
// ok
// error
// error
// error
// in a galaxy far far away
var call_me: () => void = () => {
};
function g(x: ?number) {
const const_x = x;
if (const_x) {
call_me = () => {
var y: number = const_x;
};
}
var var_x = x;
if (var_x) {
call_me = () => {
var y: number = var_x;
};
}
var_x = [object Null];
}
function h(x: number | string | boolean) {
const const_x = x;
if (typeof const_x == "number") {
call_me = () => {
var y: number = const_x;
};
} else
if (typeof const_x == "string") {
call_me = () => {
var y: string = const_x;
};
} else
if (typeof const_x == "boolean") {
call_me = () => {
var y: boolean = const_x;
};
}
var var_x = x;
if (typeof var_x == "number") {
call_me = () => {
var y: number = var_x;
};
} else
if (typeof var_x == "string") {
call_me = () => {
var y: string = var_x;
};
} else
if (typeof var_x == "boolean") {
call_me = () => {
var y: boolean = var_x;
};
}
}
call_me();
"
`;

View File

@ -8,7 +8,6 @@ function f(x: string) {
}
module.exports = f;
"
`;
@ -19,7 +18,6 @@ var f = require('./Abs');
f(0);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var f = require("./Abs");
f(0);
f([object Number]);
"
`;

View File

@ -23,6 +23,8 @@ ColorIdToNumber.XXX; // oops
module.exports = { ColorId, ColorNumber };
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// oops
// oops
var ColorId = { RED: "R", GREEN: "G", BLUE: "B" };
var ColorNumber = { RED: "ff0000", GREEN: "00ff00", BLUE: "0000ff" };
var ColorIdToNumber = {
@ -30,10 +32,9 @@ var ColorIdToNumber = {
[ColorId.GREEN]: ColorNumber.GREEN,
[ColorId.BLUE]: ColorNumber.BLUE
};
(ColorIdToNumber[ColorId.RED]: "ffffff");// oops
ColorIdToNumber.XXX;// oops
(ColorIdToNumber[ColorId.RED]: "ffffff");
ColorIdToNumber.XXX;
module.exports = { ColorId, ColorNumber };
"
`;
@ -49,15 +50,15 @@ var ColorIdToNumber = {
module.exports = ColorIdToNumber;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// oops
var { ColorId, ColorNumber } = require("./test");
var ColorIdToNumber = {
[ColorId.RED]: ColorNumber.RED,
[ColorId.GREEN]: ColorNumber.GREEN,
[ColorId.BLUE]: ColorNumber.BLUE
};
(ColorIdToNumber[ColorId.GREEN]: "ffffff");// oops
(ColorIdToNumber[ColorId.GREEN]: "ffffff");
module.exports = ColorIdToNumber;
"
`;
@ -67,10 +68,10 @@ var ColorIdToNumber = require('./test2');
(ColorIdToNumber[ColorId.BLUE]: 'ffffff'); // oops
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// oops
var { ColorId } = require("./test");
var ColorIdToNumber = require("./test2");
(ColorIdToNumber[ColorId.BLUE]: "ffffff");// oops
(ColorIdToNumber[ColorId.BLUE]: "ffffff");
"
`;
@ -78,7 +79,6 @@ exports[`test test4.js 1`] = `
"module.exports = 'hello';
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
module.exports = "hello";
"
`;
@ -94,7 +94,6 @@ module.exports = {
var hello = require("./test4");
var dummy = require("./test");
module.exports = { ...dummy, [hello]: "world", ...dummy };
"
`;
@ -102,9 +101,9 @@ exports[`test test6.js 1`] = `
"var o = require('./test5');
(o.hello: 'nothing'); // oops
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// oops
var o = require("./test5");
(o.hello: "nothing");// oops
(o.hello: "nothing");
"
`;
@ -115,19 +114,20 @@ var x: string = obj['m'](); // error, number ~> string
var arr = [function() { return this.length }];
var y: string = arr[0](); // error: number ~> string
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// error, number ~> string
// error: number ~> string
var obj = {
x: 0,
x: [object Number],
m() {
return this.x;
}
};
var x: string = obj["m"]();// error, number ~> string
var x: string = obj["m"]();
var arr = [
function() {
return this.length;
}
];
var y: string = arr[0]();// error: number ~> string
var y: string = arr[[object Number]]();
"
`;

View File

@ -25,26 +25,25 @@ function d(): string { // expected \`: number | boolean\`
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
// equivalent to \`return (x && 1) || 0\`
// expected \`: number | boolean\`
// equivalent to \`return x != null && x\`
function a(): number {
var x: ?string = null;
return (x ? 1 : 0);
var x: ?string = [object Null];
return (x ? [object Number] : [object Number]);
}
function b(): number {
var x: ?number = null;
return (x != null ? x : 0);
var x: ?number = [object Null];
return (x != [object Null] ? x : [object Number]);
}
function c(): number {
// equivalent to \`return (x && 1) || 0\`
var x = false;
var temp = (x ? 1 : x);
return (temp ? temp : 0);
var x = [object Boolean];
var temp = (x ? [object Number] : x);
return (temp ? temp : [object Number]);
}
function d(): string {
// expected \`: number | boolean\`
// equivalent to \`return x != null && x\`
var x: ?number = null;
return (x != null ? x : x != null);
var x: ?number = [object Null];
return (x != [object Null] ? x : x != [object Null]);
}
"
`;

View File

@ -1,7 +1,7 @@
exports[`test no_at_flow.js 1`] = `
"var x: number = "not a number"; // Error: string ~> number
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var x: number = "not a number";// Error: string ~> number
// Error: string ~> number
var x: number = "not a number";
"
`;

View File

@ -1,7 +1,7 @@
exports[`test no_at_flow.js 1`] = `
"var x: number = "not a number"; // No error
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var x: number = "not a number";// No error
// No error
var x: number = "not a number";
"
`;

View File

@ -5,6 +5,5 @@ x.length;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var x;
x.length;
"
`;

View File

@ -14,12 +14,11 @@ foo('Hello, world!');
/*
* @flow
*/
// This file should be ignored, so this should not result in an error
function foo(x) {
var a: number = "asdf";
return x * 10;
return x * [object Number];
}
// This file should be ignored, so this should not result in an error
foo("Hello, world!");
"
`;

View File

@ -7,6 +7,5 @@ var x: number = "string";
/* @flow */
// No error, this file is ignored
var x: number = "string";
"
`;

View File

@ -4,7 +4,7 @@ exports[`test foo.js 1`] = `
var x: number = "string"; // Error string ~> number
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
var x: number = "string";// Error string ~> number
// Error string ~> number
var x: number = "string";
"
`;

View File

@ -7,9 +7,9 @@ var a: number = test;
var b: string = test; // Error: number ~> string
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
// Error: number ~> string
import { test } from "testmodule";
var a: number = test;
var b: string = test;// Error: number ~> string
var b: string = test;
"
`;

View File

@ -4,7 +4,6 @@ exports[`test testmodule.js 1`] = `
export let test = 42;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
export let test = 42;
export let test = [object Number];
"
`;

View File

@ -5,8 +5,8 @@ import {className} from "./SomeCSSFile.css";
import {doesntExist} from "./SomeCSSFile.css"; // Error: \`doestExist\` isn't an export
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
// Error: \`doestExist\` isn't an export
import { className } from "./SomeCSSFile.css";
import { doesntExist } from "./SomeCSSFile.css";// Error: \`doestExist\` isn't an export
import { doesntExist } from "./SomeCSSFile.css";
"
`;

View File

@ -14,17 +14,18 @@ var m2 = require('2DoesntExist'); // Error
import {numVal as numVal2} from '3DoesntExist'; // Error
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
var m1 = require("1DoesntExist");
import { numVal as numVal1 } from "1DoesntExist";
var a_1: number = m1.numVal;
var a_2: number = numVal1;
// Error: 'Exists2' is not a valid module name
//
// This tests that, for haste, the first name_mapper regexp that happens to
// match the given module name string is picked.
var m2 = require("2DoesntExist");// Error
import { numVal as numVal2 } from "3DoesntExist";// Error
// Error
// Error
var m1 = require("1DoesntExist");
import { numVal as numVal1 } from "1DoesntExist";
var a_1: number = m1.numVal;
var a_2: number = numVal1;
var m2 = require("2DoesntExist");
import { numVal as numVal2 } from "3DoesntExist";
"
`;
@ -42,7 +43,6 @@ module.exports = {
* @providesModule Exists
* @flow
*/
module.exports = { numVal: 42 };
module.exports = { numVal: [object Number] };
"
`;

View File

@ -26,28 +26,33 @@ var c_3: number = numVal3;
var c_4: string = numVal3; // Error: number ~> string
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
var m1 = require("./1DoesntExist");
var a_1: number = m1.numVal;
var a_2: string = m1.numVal;// Error: number ~> string
import { numVal } from "./1DoesntExist";
var a_3: number = numVal;
var a_4: string = numVal;// Error: number ~> string
// Error: number ~> string
// Error: number ~> string
// This tests that, for node, the first name mapping that both matches *and*
// results in a valid module filename is picked.
// Error: number ~> string
// Error: number ~> string
// node_modules/Exists/index.js
// Error: number ~> string
// Error: number ~> string
var m1 = require("./1DoesntExist");
var a_1: number = m1.numVal;
var a_2: string = m1.numVal;
import { numVal } from "./1DoesntExist";
var a_3: number = numVal;
var a_4: string = numVal;
var m2 = require("./2DoesntExist");
var b_1: number = m2.numVal;
var b_2: string = m2.numVal;// Error: number ~> string
var b_2: string = m2.numVal;
import { numVal as numVal2 } from "./3DoesntExist";
var b_3: number = numVal2;
var b_4: string = numVal2;// Error: number ~> string
// node_modules/Exists/index.js
var b_4: string = numVal2;
var m3 = require("4DoesntExist");
var c_1: number = m3.numVal;
var c_2: string = m3.numVal;// Error: number ~> string
var c_2: string = m3.numVal;
import { numVal as numVal3 } from "5DoesntExist";
var c_3: number = numVal3;
var c_4: string = numVal3;// Error: number ~> string
var c_4: string = numVal3;
"
`;
@ -59,7 +64,6 @@ module.exports = {
};
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
module.exports = { numVal: 42 };
module.exports = { numVal: [object Number] };
"
`;

View File

@ -7,9 +7,9 @@ import {name} from "testproj";
(name: "custom_resolve_dir/testproj"); // Error: Resolve from node_modules first!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
// Error: Resolve from node_modules first!
import { name } from "testproj";
(name: "node_modules/testproj");
(name: "custom_resolve_dir/testproj");// Error: Resolve from node_modules first!
(name: "custom_resolve_dir/testproj");
"
`;

View File

@ -5,6 +5,5 @@ export var name: "otherdir/testproj" = "otherdir/testproj";
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
export var name: "otherdir/testproj" = "otherdir/testproj";
"
`;

View File

@ -5,6 +5,5 @@ export var name: "otherdir/testproj2" = "otherdir/testproj2";
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
export var name: "otherdir/testproj2" = "otherdir/testproj2";
"
`;

View File

@ -7,9 +7,9 @@ import {name} from "testproj2";
(name: "subdir/custom_resolve_dir/testproj2");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
// Error: Resolve from sibling 'custom_resolve_dir' first!
import { name } from "testproj2";
(name: "node_modules/testproj2");// Error: Resolve from sibling 'custom_resolve_dir' first!
(name: "node_modules/testproj2");
(name: "subdir/custom_resolve_dir/testproj2");
"
`;

View File

@ -5,6 +5,5 @@ export var name: "subdir/custom_resolve_dir/testproj2" = "subdir/custom_resolve_
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
export var name: "subdir/custom_resolve_dir/testproj2" = "subdir/custom_resolve_dir/testproj2";
"
`;

View File

@ -39,16 +39,16 @@ class A {
_property1: number;
static _sProperty: number;
constructor() {
this._property1 = 5;
this._property1 = [object Number];
}
_method1(): number {
return 1;
return [object Number];
}
_sMethod(): string {
static _sMethod(): string {
return "some string";
}
}
A._sProperty = 48;
A._sProperty = [object Number];
class B extends A {
_property1: string;
static _sProperty: string;
@ -59,12 +59,11 @@ class B extends A {
_method1(): string {
return "yet another string";
}
_sMethod(): number {
return 23;
static _sMethod(): number {
return [object Number];
}
}
B._sProperty = "B._sProperty string";
"
`;
@ -82,7 +81,6 @@ class C {
_p: string;
}
module.exports = new C();
"
`;
@ -93,6 +91,5 @@ import {_p} from "./commonjs_export";
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
import { _p } from "./commonjs_export";
"
`;

View File

@ -39,16 +39,16 @@ class A {
_property1: number;
static _sProperty: number;
constructor() {
this._property1 = 5;
this._property1 = [object Number];
}
_method1(): number {
return 1;
return [object Number];
}
_sMethod(): string {
static _sMethod(): string {
return "some string";
}
}
A._sProperty = 48;
A._sProperty = [object Number];
class B extends A {
_property1: string;
static _sProperty: string;
@ -59,11 +59,10 @@ class B extends A {
_method1(): string {
return "yet another string";
}
_sMethod(): number {
return 23;
static _sMethod(): number {
return [object Number];
}
}
B._sProperty = "B._sProperty string";
"
`;

View File

@ -43,21 +43,21 @@ function durable_refi(x: ?number) {
*
* @flow
*/
function cannot_reassign(x: string) {
x = "hey";// error, const param cannot be reassigned
}
// error, const param cannot be reassigned
// Note: const params use the same machinery as explicit
// const bindings, which are tested more extensively elsewhere.
// Here we're just making sure the machinery is hooked up.
//
// ok: if x is truthy here, it's truthy everywhere
function cannot_reassign(x: string) {
x = "hey";
}
function durable_refi(x: ?number) {
if (x) {
// ok: if x is truthy here, it's truthy everywhere
return () => {
var y: number = x;
};
}
}
"
`;

View File

@ -20,6 +20,5 @@ class D {
}
}
module.exports = C;
"
`;

View File

@ -6,8 +6,8 @@ function Foo() {
Foo.y = 0; // has static property y
Foo.prototype = { m() { return 0; } };
// exporting Foo directly doesn\'t work
// Foo\'s instance and static props are not picked up
// exporting Foo directly doesn't work
// Foo's instance and static props are not picked up
exports.Foo = Foo;
// so you want to type Foo, by declaring it as a class
@ -21,43 +21,52 @@ interface IFoo extends IFooPrototype {
}
exports.Foo2 = (Foo: Class<IFoo>);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Unexpected token, expected : (19:9)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp.unexpected (/node_modules/babylon/lib/index.js:1633:8)
at Parser.pp.expect (/node_modules/babylon/lib/index.js:1621:33)
at Parser.pp$7.flowParseTypeInitialiser (/node_modules/babylon/lib/index.js:4424:8)
at Parser.pp$7.flowParseObjectType (/node_modules/babylon/lib/index.js:4809:27)
at Parser.pp$7.flowParseInterfaceish (/node_modules/babylon/lib/index.js:4575:20)
at Parser.pp$7.flowParseInterface (/node_modules/babylon/lib/index.js:4592:8)
at Parser.parseStatement (/node_modules/babylon/lib/index.js:5222:21)
at Parser.pp$1.parseBlockBody (/node_modules/babylon/lib/index.js:2139:21)
at Parser.pp$1.parseTopLevel (/node_modules/babylon/lib/index.js:1651:8)
// Foo is a class-like function
// constructs objects with property x
// has static property y
// exporting Foo directly doesn't work
// Foo's instance and static props are not picked up
// so you want to type Foo, by declaring it as a class
/* error, should have declared x: number instead*/
/* error, should have declared static y: number instead*/
function Foo() {
this.x = [object Number];
}
Foo.y = [object Number];
Foo.prototype = {
m() {
return [object Number];
}
};
exports.Foo = Foo;
interface IFooPrototype extends { m: : () => number }
interface IFoo extends IFooPrototype { (): void, x: boolean, y: boolean }
exports.Foo2 = (Foo: Class<IFoo>);
"
`;
exports[`test test.js 1`] = `
"var Foo = require(\'./constructors\').Foo;
"var Foo = require('./constructors').Foo;
var x: string = new Foo().x; // error, found number instead of string
var y: string = Foo.y; // error, found number instead of string
var z: string = new Foo().m();
var Foo2 = require(\'./constructors\').Foo2;
var Foo2 = require('./constructors').Foo2;
var x2: string = new Foo2().x; // error, found boolean instead of string
var y2: string = Foo2.y; // error, found boolean instead of string
var z2: string = new Foo2().m();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var Foo = require(\"./constructors\").Foo;
var x: string = new Foo().x;// error, found number instead of string
var y: string = Foo.y;// error, found number instead of string
// error, found number instead of string
// error, found number instead of string
// error, found boolean instead of string
// error, found boolean instead of string
var Foo = require("./constructors").Foo;
var x: string = new Foo().x;
var y: string = Foo.y;
var z: string = new Foo().m();
var Foo2 = require(\"./constructors\").Foo2;
var x2: string = new Foo2().x;// error, found boolean instead of string
var y2: string = Foo2.y;// error, found boolean instead of string
var Foo2 = require("./constructors").Foo2;
var x2: string = new Foo2().x;
var y2: string = Foo2.y;
var z2: string = new Foo2().m();
"
`;

View File

@ -1,7 +1,6 @@
exports[`test dummy.js 1`] = `
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"
`;
@ -11,8 +10,7 @@ var xxx = 0;
xxx
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
require("./dummy");
var xxx = 0;
var xxx = [object Number];
xxx;
"
`;

View File

@ -1,7 +1,6 @@
exports[`test dummy.js 1`] = `
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"
`;
@ -11,8 +10,7 @@ var xxx = 0;
xxx
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
require("./dummy");
var xxx = 0;
var xxx = [object Number];
xxx;
"
`;

View File

@ -13,7 +13,7 @@ let tests = [
new Boolean(false);
new Boolean(NaN);
new Boolean(undefined);
new Boolean(\"\");
new Boolean("");
},
// toString
@ -38,48 +38,47 @@ let tests = [
Boolean(false);
Boolean(NaN);
Boolean(undefined);
Boolean(\"\");
Boolean("");
},
];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
// Boolean (the class) tests. booleans (the literals) are not part of core.js
// constructor
// toString
// valueOf
// casting
let tests = [
// constructor
function() {
new Boolean();
new Boolean(0);
new Boolean(-0);
new Boolean(null);
new Boolean(false);
new Boolean([object Number]);
new Boolean(-[object Number]);
new Boolean([object Null]);
new Boolean([object Boolean]);
new Boolean(NaN);
new Boolean(undefined);
new Boolean(\"\");
new Boolean("");
},
// toString
function() {
true.toString();
let x: boolean = false;
[object Boolean].toString();
let x: boolean = [object Boolean];
x.toString();
new Boolean(true).toString();
new Boolean([object Boolean]).toString();
},
// valueOf
function() {
(new Boolean(0).valueOf(): boolean);
(new Boolean([object Number]).valueOf(): boolean);
},
// casting
function() {
Boolean();
Boolean(0);
Boolean(-0);
Boolean(null);
Boolean(false);
Boolean([object Number]);
Boolean(-[object Number]);
Boolean([object Null]);
Boolean([object Boolean]);
Boolean(NaN);
Boolean(undefined);
Boolean(\"\");
Boolean("");
}
];
"
`;
@ -88,7 +87,7 @@ exports[`test map.js 1`] = `
function* generator(): Iterable<[string, number]> {
while (true) {
yield [\'foo\', 123];
yield ['foo', 123];
}
}
@ -97,41 +96,58 @@ let tests = [
function() {
let w = new Map();
let x = new Map(null);
let y = new Map([[\'foo\', 123]]);
let y = new Map([['foo', 123]]);
let z = new Map(generator());
let a: Map<string, number> = new Map();
let b: Map<string, number> = new Map([[\'foo\', 123]]);
let b: Map<string, number> = new Map([['foo', 123]]);
let c: Map<string, number> = new Map(generator());
},
// bad constructors
function() {
let x = new Map([\'foo\', 123]); // error
let y: Map<number, string> = new Map([[\'foo\', 123]]); // error
let x = new Map(['foo', 123]); // error
let y: Map<number, string> = new Map([['foo', 123]]); // error
},
// get()
function(x: Map<string, number>) {
(x.get(\'foo\'): boolean); // error, string | void
(x.get('foo'): boolean); // error, string | void
x.get(123); // error, wrong key type
},
];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1237
throw new Error(\"unprintable type: \" + JSON.stringify(n.type));
^
Error: unprintable type: \"TupleTypeAnnotation\"
at genericPrintNoParens (/src/printer.js:1237:13)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.map (/src/fast-path.js:167:19)
at genericPrintNoParens (/src/printer.js:1497:36)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// @flow
// good constructors
// bad constructors
// error
// error
// get()
// error, string | void
// error, wrong key type
function* generator(): Iterable<[]> {
while ([object Boolean]) {
yield [ "foo", [object Number] ];
}
}
let tests = [
function() {
let w = new Map();
let x = new Map([object Null]);
let y = new Map([ [ "foo", [object Number] ] ]);
let z = new Map(generator());
let a: Map<string, number> = new Map();
let b: Map<string, number> = new Map([ [ "foo", [object Number] ] ]);
let c: Map<string, number> = new Map(generator());
},
function() {
let x = new Map([ "foo", [object Number] ]);
let y: Map<number, string> = new Map([ [ "foo", [object Number] ] ]);
},
function(x: Map<string, number>) {
(x.get("foo"): boolean);
x.get([object Number]);
}
];
"
`;
@ -141,58 +157,63 @@ exports[`test regexp.js 1`] = `
let tests = [
// constructor
function() {
new RegExp(\'foo\');
new RegExp('foo');
new RegExp(/foo/);
new RegExp(\'foo\', \'i\');
new RegExp(\'foo\', \'ig\');
new RegExp(/foo/, \'i\'); // invalid in ES5, valid in ES6
new RegExp(/foo/g, \'i\'); // invalid in ES5, valid in ES6
new RegExp('foo', 'i');
new RegExp('foo', 'ig');
new RegExp(/foo/, 'i'); // invalid in ES5, valid in ES6
new RegExp(/foo/g, 'i'); // invalid in ES5, valid in ES6
},
// called as a function (equivalent to the constructor per ES6 21.2.3)
function() {
RegExp(\'foo\');
RegExp('foo');
RegExp(/foo/);
RegExp(\'foo\', \'i\');
RegExp(\'foo\', \'ig\');
RegExp(/foo/, \'i\'); // invalid in ES5, valid in ES6
RegExp(/foo/g, \'i\'); // invalid in ES5, valid in ES6
RegExp('foo', 'i');
RegExp('foo', 'ig');
RegExp(/foo/, 'i'); // invalid in ES5, valid in ES6
RegExp(/foo/g, 'i'); // invalid in ES5, valid in ES6
},
// invalid flags
function() {
RegExp(\'foo\', \'z\'); // error
new RegExp(\'foo\', \'z\'); // error
RegExp('foo', 'z'); // error
new RegExp('foo', 'z'); // error
}
];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
// constructor
// invalid in ES5, valid in ES6
// invalid in ES5, valid in ES6
// called as a function (equivalent to the constructor per ES6 21.2.3)
// invalid in ES5, valid in ES6
// invalid in ES5, valid in ES6
// invalid flags
// error
// error
let tests = [
// constructor
function() {
new RegExp(\"foo\");
new RegExp(/foo/);
new RegExp(\"foo\", \"i\");
new RegExp(\"foo\", \"ig\");
new RegExp(/foo/, \"i\");// invalid in ES5, valid in ES6
new RegExp(/foo/g, \"i\");// invalid in ES5, valid in ES6
new RegExp("foo");
new RegExp([object RegExp]);
new RegExp("foo", "i");
new RegExp("foo", "ig");
new RegExp([object RegExp], "i");
new RegExp([object RegExp], "i");
},
// called as a function (equivalent to the constructor per ES6 21.2.3)
function() {
RegExp(\"foo\");
RegExp(/foo/);
RegExp(\"foo\", \"i\");
RegExp(\"foo\", \"ig\");
RegExp(/foo/, \"i\");// invalid in ES5, valid in ES6
RegExp(/foo/g, \"i\");// invalid in ES5, valid in ES6
RegExp("foo");
RegExp([object RegExp]);
RegExp("foo", "i");
RegExp("foo", "ig");
RegExp([object RegExp], "i");
RegExp([object RegExp], "i");
},
// invalid flags
function() {
RegExp(\"foo\", \"z\");// error
new RegExp(\"foo\", \"z\");// error
RegExp("foo", "z");
new RegExp("foo", "z");
}
];
"
`;
@ -201,7 +222,7 @@ exports[`test weakset.js 1`] = `
let ws = new WeakSet();
let obj: Object = {};
let dict: {foo: string} = {foo: \'bar\'};
let dict: {foo: string} = {foo: 'bar'};
ws.add(window);
ws.add(obj);
@ -219,7 +240,7 @@ let ws3 = new WeakSet([1, 2, 3]); // error, must be objects
function* generator(): Iterable<{foo: string}> {
while (true) {
yield {foo: \'bar\'};
yield {foo: 'bar'};
}
}
@ -234,20 +255,35 @@ function* numbers(): Iterable<number> {
let ws5 = new WeakSet(numbers()); // error, must be objects
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// @flow
// error, must be objects
// error, must be objects
let ws = new WeakSet();
let obj: Object = {};
let dict: { foo: string } = { foo: "bar" };
ws.add(window);
ws.add(obj);
ws.add(dict);
ws.has(window);
ws.has(obj);
ws.has(dict);
ws.delete(window);
ws.delete(obj);
ws.delete(dict);
let ws2 = new WeakSet([ obj, dict ]);
let ws3 = new WeakSet([ [object Number], [object Number], [object Number] ]);
function* generator(): Iterable<{ foo: string }> {
while ([object Boolean]) {
yield { foo: "bar" };
}
}
let ws4 = new WeakSet(generator());
function* numbers(): Iterable<number> {
let i = [object Number];
while ([object Boolean]) {
yield i++;
}
}
let ws5 = new WeakSet(numbers());
"
`;

View File

@ -2,7 +2,7 @@ exports[`test test.js 1`] = `
"type CovArrayVerbose<X,Y:X> = Array<Y>;
var b: CovArrayVerbose<number,*> = [];
var y: CovArrayVerbose<mixed,*> = b;
y[0] = \"\"; // error
y[0] = ""; // error
class NVerbose<E,I:E> {
x: CovArrayVerbose<E,I>;
@ -22,12 +22,12 @@ var z: CovArray<string> = c; // error
var d: CovArray<number> = [];
var w: CovArray<mixed> = d;
w[0] = \"\"; // error
w[0] = ""; // error
type P<X> = CovArray<X>;
var p: P<mixed> = [];
(p[0]: number); // not an error!
p[0] = \"\"; // error
p[0] = ""; // error
class M {
x: CovArray<number>;
@ -49,20 +49,56 @@ n.x = [0];
*/
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
// error
// error
// error
/* TODO: use existentials for non-verbose covariance?
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1479:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
type CovArray<X> = Array<*:X>;
var c: CovArray<number> = [0];
var z: CovArray<string> = c; // error
var d: CovArray<number> = [];
var w: CovArray<mixed> = d;
w[0] = ""; // error
type P<X> = CovArray<X>;
var p: P<mixed> = [];
(p[0]: number); // not an error!
p[0] = ""; // error
class M {
x: CovArray<number>;
foo(): CovArray<mixed> { return this.x; }
bar(x: string) { this.foo()[0] = x; } // error
}
class N<E> {
x: CovArray<E>;
foo(): CovArray<mixed> { return this.x; }
bar(e: string) { this.foo()[0] = e; } // error
qux(e: E) { this.foo()[0] = e; }
}
var n: N<number> = new N;
n.x = [0];
(n.x[0]: string); // error
(n.foo()[0]: string); // not an error!
*/
type CovArrayVerbose<X, Y: X> = Array<Y>;
var b: CovArrayVerbose<number, *> = [ ];
var y: CovArrayVerbose<mixed, *> = b;
y[[object Number]] = "";
class NVerbose<E, I: E> {
x: CovArrayVerbose<E, I>;
foo(): CovArrayVerbose<mixed, I> {
return this.x;
}
}
var nv: NVerbose<number, *> = new NVerbose();
nv.x = [ [object Number] ];
(nv.x[[object Number]]: string);
(nv.foo()[[object Number]]: string);
"
`;

View File

@ -14,13 +14,13 @@ declare module bar {
// This file triggers a violation of the "disjoint-or-nested ranges invariant"
// that we implicitly assume in type-at-pos and coverage implementations. In
// particular, when unchecked it causes a crash with coverage --color.
// TODO
declare module foo {
}
declare module bar {
}// TODO
}
"
`;
@ -34,7 +34,6 @@ declare module foo {
declare module foo {
}
"
`;
@ -42,9 +41,8 @@ exports[`test no_pragma.js 1`] = `
"let x = 0;
(x: string);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
let x = 0;
let x = [object Number];
(x: string);
"
`;
@ -67,14 +65,13 @@ declare class qux {
// This file triggers a violation of the "disjoint-or-nested ranges invariant"
// that we implicitly assume in type-at-pos and coverage implementations. In
// particular, when unchecked it causes non-termination with coverage --color.
// TODO
declare module foo {
}
declare module bar {
}
// TODO
declare class qux {}
"
`;

View File

@ -8,7 +8,6 @@ module.exports = A;
var B = require("./B");
class A extends B {}
module.exports = A;
"
`;
@ -19,9 +18,8 @@ exports[`test B.js 1`] = `
module.exports = B;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var A = require("./A");
//class B extends A { }
var A = require("./A");
module.exports = B;
"
`;

View File

@ -28,30 +28,80 @@ new Date(2015, 6, 18, 11, 55, 42, '999');
new Date('2015', 6);
new Date(2015, 6, 18, 11, 55, 42, 999, 'hahaha');
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var d = new Date(0);
// valid constructors
// invalid constructors
// invalid constructors that we incorrectly consider valid
var d = new Date([object Number]);
var x: string = d.getTime();
var y: number = d;
// valid constructors
new Date();
new Date(1234567890);
new Date([object Number]);
new Date("2015/06/18");
new Date(2015, 6);
new Date(2015, 6, 18);
new Date(2015, 6, 18, 11);
new Date(2015, 6, 18, 11, 55);
new Date(2015, 6, 18, 11, 55, 42);
new Date(2015, 6, 18, 11, 55, 42, 999);
// invalid constructors
new Date([object Number], [object Number]);
new Date([object Number], [object Number], [object Number]);
new Date([object Number], [object Number], [object Number], [object Number]);
new Date(
[object Number],
[object Number],
[object Number],
[object Number],
[object Number]
);
new Date(
[object Number],
[object Number],
[object Number],
[object Number],
[object Number],
[object Number]
);
new Date(
[object Number],
[object Number],
[object Number],
[object Number],
[object Number],
[object Number],
[object Number]
);
new Date({});
new Date(2015, "6");
new Date(2015, 6, "18");
new Date(2015, 6, 18, "11");
new Date(2015, 6, 18, 11, "55");
new Date(2015, 6, 18, 11, 55, "42");
new Date(2015, 6, 18, 11, 55, 42, "999");
// invalid constructors that we incorrectly consider valid
new Date("2015", 6);
new Date(2015, 6, 18, 11, 55, 42, 999, "hahaha");
new Date([object Number], "6");
new Date([object Number], [object Number], "18");
new Date([object Number], [object Number], [object Number], "11");
new Date(
[object Number],
[object Number],
[object Number],
[object Number],
"55"
);
new Date(
[object Number],
[object Number],
[object Number],
[object Number],
[object Number],
"42"
);
new Date(
[object Number],
[object Number],
[object Number],
[object Number],
[object Number],
[object Number],
"999"
);
new Date("2015", [object Number]);
new Date(
[object Number],
[object Number],
[object Number],
[object Number],
[object Number],
[object Number],
[object Number],
"hahaha"
);
"
`;

View File

@ -11,7 +11,6 @@ module.exports.fun = (): string => "hello there";
* @flow
*/
module.exports.fun = (): string => "hello there";
"
`;
@ -28,7 +27,6 @@ module.exports.fun = (): string => "hello there";
* @flow
*/
module.exports.fun = (): string => "hello there";
"
`;
@ -45,14 +43,13 @@ module.exports.fun = (): string => "hello there";
* @flow
*/
module.exports.fun = (): string => "hello there";
"
`;
exports[`test md5.js 1`] = `
"/* @providesModule md5 */
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @providesModule md5 */
"
`;
@ -76,6 +73,5 @@ var ExplicitSameName = require("ExplicitProvidesModuleSameName");
(ExplicitSameName.fun(): string);
var ExplicitDifferentName = require("ExplicitProvidesModuleDifferentName");
(ExplicitDifferentName.fun(): string);
"
`;

View File

@ -2,6 +2,5 @@ exports[`test min.js 1`] = `
"module.exports.fun = (): string => "hello there";
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
module.exports.fun = (): string => "hello there";
"
`;

View File

@ -14,15 +14,14 @@ var unreachable = require('annotation');
(corge.fun(): string);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
// make sure we don't pick up non-header @providesModule
// annotations - see node_modules/qux/docblock.js
var docblock = require("qux/docblock");
var min = require("d3/min.js");
var corge = require("qux/corge");
// make sure we don't pick up non-header @providesModule
// annotations - see node_modules/qux/docblock.js
var unreachable = require("annotation");
(docblock.fun(): string);
(min.fun(): string);
(corge.fun(): string);
"
`;

View File

@ -1,6 +1,5 @@
exports[`test index.js 1`] = `
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"
`;

View File

@ -2,6 +2,5 @@ exports[`test client.js 1`] = `
"var ws = require('../');
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var ws = require("../");
"
`;

View File

@ -8,7 +8,6 @@ class Implementation {}
export function foo(): Implementation {
return new Implementation();
}
"
`;
@ -27,7 +26,6 @@ module.exports.fun = (): Implementation => new Implementation;
*/
class Implementation {}
module.exports.fun = (): Implementation => new Implementation();
"
`;
@ -46,7 +44,6 @@ module.exports.fun = (): Implementation => new Implementation;
*/
class Implementation {}
module.exports.fun = (): Implementation => new Implementation();
"
`;
@ -65,14 +62,13 @@ module.exports.fun = (): Implementation => new Implementation;
*/
class Implementation {}
module.exports.fun = (): Implementation => new Implementation();
"
`;
exports[`test md5.js 1`] = `
"/* @providesModule md5 */
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @providesModule md5 */
"
`;
@ -90,12 +86,14 @@ var ExplicitDifferentName = require('ExplicitProvidesModuleDifferentName');
(ExplicitDifferentName.fun(): boolean); // Error: Either Implementation ~> boolean or Declaration ~> boolean
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
// Error: Either Implementation ~> boolean or Declaration ~> boolean
// Error: Either Implementation ~> boolean or Declaration ~> boolean
// Error: Either Implementation ~> boolean or Declaration ~> boolean
var Implicit = require("ImplicitProvidesModule");
(Implicit.fun(): boolean);// Error: Either Implementation ~> boolean or Declaration ~> boolean
(Implicit.fun(): boolean);
var ExplicitSameName = require("ExplicitProvidesModuleSameName");
(ExplicitSameName.fun(): boolean);// Error: Either Implementation ~> boolean or Declaration ~> boolean
(ExplicitSameName.fun(): boolean);
var ExplicitDifferentName = require("ExplicitProvidesModuleDifferentName");
(ExplicitDifferentName.fun(): boolean);// Error: Either Implementation ~> boolean or Declaration ~> boolean
(ExplicitDifferentName.fun(): boolean);
"
`;

View File

@ -4,6 +4,5 @@ module.exports.fun = (): Implementation => new Implementation;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class Implementation {}
module.exports.fun = (): Implementation => new Implementation();
"
`;

View File

@ -10,12 +10,14 @@ var corge = require('qux/corge');
(corge.fun(): boolean); // Error: Either Implementation ~> boolean or Declaration ~> boolean
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
// Error: Either Implementation ~> boolean or Declaration ~> boolean
// Error: Either Implementation ~> boolean or Declaration ~> boolean
// Error: Either Implementation ~> boolean or Declaration ~> boolean
var docblock = require("qux/docblock");
var min = require("d3/min.js");
var corge = require("qux/corge");
(docblock.fun(): boolean);// Error: Either Implementation ~> boolean or Declaration ~> boolean
(min.fun(): boolean);// Error: Either Implementation ~> boolean or Declaration ~> boolean
(corge.fun(): boolean);// Error: Either Implementation ~> boolean or Declaration ~> boolean
(docblock.fun(): boolean);
(min.fun(): boolean);
(corge.fun(): boolean);
"
`;

View File

@ -1,6 +1,5 @@
exports[`test index.js 1`] = `
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"
`;

View File

@ -2,6 +2,5 @@ exports[`test client.js 1`] = `
"var ws = require('../');
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var ws = require("../");
"
`;

View File

@ -6,7 +6,6 @@ class Implementation {}
export function foo(): Implementation {
return new Implementation();
}
"
`;
@ -55,34 +54,45 @@ var F = require('package_with_dir_main');
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
// This will require ./node_modules/B.js.flow
// Error either Implementation ~> boolean or Declaration ~> boolean
// This will require ./node_modules/B.js.flow
// Error either Implementation ~> boolean or Declaration ~> boolean
// Error either Implementation ~> boolean or Declaration ~> boolean
// Error either Implementation ~> boolean or Declaration ~> boolean
// Error either Implementation ~> boolean or Declaration ~> boolean
// Error either Implementation ~> boolean or Declaration ~> boolean
// This will require ./node_modules/B.js.flow
// Error either Implementation ~> boolean or Declaration ~> boolean
// This will require ./node_modules/B.js.flow
// Error either Implementation ~> boolean or Declaration ~> boolean
// Error either Implementation ~> boolean or Declaration ~> boolean
// Error either Implementation ~> boolean or Declaration ~> boolean
// Error either Implementation ~> boolean or Declaration ~> boolean
// Error either Implementation ~> boolean or Declaration ~> boolean
var B1 = require("B");
(B1.fun(): boolean);// Error either Implementation ~> boolean or Declaration ~> boolean
// This will require ./node_modules/B.js.flow
(B1.fun(): boolean);
var B2 = require("B.js");
(B2.fun(): boolean);// Error either Implementation ~> boolean or Declaration ~> boolean
(B2.fun(): boolean);
var C = require("package_with_full_main");
(C.fun(): boolean);// Error either Implementation ~> boolean or Declaration ~> boolean
(C.fun(): boolean);
var D = require("package_with_partial_main");
(D.fun(): boolean);// Error either Implementation ~> boolean or Declaration ~> boolean
(D.fun(): boolean);
var E = require("package_with_no_package_json");
(E.fun(): boolean);// Error either Implementation ~> boolean or Declaration ~> boolean
(E.fun(): boolean);
var F = require("package_with_dir_main");
(F.fun(): boolean);// Error either Implementation ~> boolean or Declaration ~> boolean
// This will require ./node_modules/B.js.flow
(F.fun(): boolean);
var B1 = require("B");
(B1.fun(): boolean);// Error either Implementation ~> boolean or Declaration ~> boolean
// This will require ./node_modules/B.js.flow
(B1.fun(): boolean);
var B2 = require("B.js");
(B2.fun(): boolean);// Error either Implementation ~> boolean or Declaration ~> boolean
(B2.fun(): boolean);
var C = require("package_with_full_main");
(C.fun(): boolean);// Error either Implementation ~> boolean or Declaration ~> boolean
(C.fun(): boolean);
var D = require("package_with_partial_main");
(D.fun(): boolean);// Error either Implementation ~> boolean or Declaration ~> boolean
(D.fun(): boolean);
var E = require("package_with_no_package_json");
(E.fun(): boolean);// Error either Implementation ~> boolean or Declaration ~> boolean
(E.fun(): boolean);
var F = require("package_with_dir_main");
(F.fun(): boolean);// Error either Implementation ~> boolean or Declaration ~> boolean
(F.fun(): boolean);
"
`;
@ -91,8 +101,8 @@ exports[`test test_relative.js 1`] = `
(foo(): boolean); // Error: either Implementation ~> boolean or Definition ~> boolean
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Error: either Implementation ~> boolean or Definition ~> boolean
import { foo } from "./A";
(foo(): boolean);// Error: either Implementation ~> boolean or Definition ~> boolean
(foo(): boolean);
"
`;

View File

@ -5,7 +5,6 @@ module.exports.fun = (): string => 'hello there!';
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
module.exports.fun = (): string => "hello there!";
"
`;
@ -14,8 +13,7 @@ exports[`test CJS.js 1`] = `
module.exports = 42;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
module.exports = 42;
module.exports = [object Number];
"
`;
@ -44,20 +42,25 @@ var F = require('package_with_dir_main');
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
// This will require ./node_modules/B.js.flow
var B1 = require("B");
(B1.fun(): string);// Error number ~> string
// Error number ~> string
// This will require ./node_modules/B.js.flow
// Error number ~> string
// Error number ~> string
// Error number ~> string
// Error number ~> string
// Error number ~> string
var B1 = require("B");
(B1.fun(): string);
var B2 = require("B.js");
(B2.fun(): string);// Error number ~> string
(B2.fun(): string);
var C = require("package_with_full_main");
(C.fun(): string);// Error number ~> string
(C.fun(): string);
var D = require("package_with_partial_main");
(D.fun(): string);// Error number ~> string
(D.fun(): string);
var E = require("package_with_no_package_json");
(E.fun(): string);// Error number ~> string
(E.fun(): string);
var F = require("package_with_dir_main");
(F.fun(): string);// Error number ~> string
(F.fun(): string);
"
`;
@ -78,14 +81,16 @@ var CJS = require('./CJS.js');
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
// This will require ./A.js.flow
var A1 = require("./A");
(A1.fun(): string);// Error number ~> string
// Error number ~> string
// This will require ./A.js.flow
// Error number ~> string
// Error: string ~> number
var A1 = require("./A");
(A1.fun(): string);
var A2 = require("./A.js");
(A2.fun(): string);// Error number ~> string
(A2.fun(): string);
var CJS = require("./CJS.js");
(CJS: string);
(CJS: number);// Error: string ~> number
(CJS: number);
"
`;

View File

@ -4,26 +4,17 @@ exports[`test declare_class.js 1`] = `
static foo(x: number): void;
}
C.x = \"\";
C.foo(\"\");
C.x = "";
C.foo("");
(C.name: string);
(C.name: number); // error, it\'s a string
(C.name: number); // error, it's a string
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1348
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1348:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1452:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// error, it's a string
declare class C { x: number, foo: : (x: number) => void }
C.x = "";
C.foo("");
(C.name: string);
(C.name: number);
"
`;

View File

@ -9,20 +9,8 @@ declare class D extends _module.C {
foo(): string;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1348
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1348:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1452:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
declare class _C { foo: : () => number }
declare var _module: { C: Class<_C> };
declare class D { foo: : () => string }
"
`;

File diff suppressed because it is too large Load Diff

View File

@ -4,23 +4,17 @@ declare function foo(x: string): number;
declare function foo<X>(x: X): X;
(foo(0): string); // OK
(foo(\"hello\"): number); // OK
(foo("hello"): number); // OK
(foo(false): void); // error, boolean ~/~ undefined
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1348
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1348:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1254:25)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// OK
// OK
// error, boolean ~/~ undefined
declare function foo(x: number): string;
declare function foo(x: string): number;
declare function foo(x: X): X;
(foo([object Number]): string);
(foo("hello"): number);
(foo([object Boolean]): void);
"
`;

View File

@ -26,24 +26,27 @@ import declare_m_e_with_declare_var_e from "declare_m_e_with_declare_var_e";
(declare_m_e_with_declare_var_e: string); // Error: number ~> string
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
import declare_module_exports from "declare_module_exports";
(declare_module_exports: number);
(declare_module_exports: string);// Error: number ~> string
// Error: number ~> string
// Error: Has no named export "str"!
import { str } from "declare_m_e_with_other_value_declares";
import type { str2 } from "declare_m_e_with_other_type_declares";
("asdf": str2);
(42: str2);// Error: number ~> string
// Error: number ~> string
/**
* \`declare var exports\` is deprecated, so we have a grace period where both
* syntaxes will work.
*/
// Error: number ~> string
// Error: number ~> string
import declare_module_exports from "declare_module_exports";
(declare_module_exports: number);
(declare_module_exports: string);
import { str } from "declare_m_e_with_other_value_declares";
import type { str2 } from "declare_m_e_with_other_type_declares";
("asdf": str2);
([object Number]: str2);
import DEPRECATED__declare_var_exports from "DEPRECATED__declare_var_exports";
(DEPRECATED__declare_var_exports: number);
(DEPRECATED__declare_var_exports: string);// Error: number ~> string
(DEPRECATED__declare_var_exports: string);
import declare_m_e_with_declare_var_e from "declare_m_e_with_declare_var_e";
(declare_m_e_with_declare_var_e: number);
(declare_m_e_with_declare_var_e: string);// Error: number ~> string
(declare_m_e_with_declare_var_e: string);
"
`;

View File

@ -30,6 +30,13 @@ declare module "declare_m_e_with_declare_var_e" {
declare var exports: string;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* \`declare var exports\` is deprecated, so we have a grace period where both
* syntaxes will work.
*/
/**
* Ensure that, if both are present, \`declare module.exports\` wins
*/
declare module "declare_module_exports" {
declare module.exports: number
}
@ -41,20 +48,12 @@ declare module "declare_m_e_with_other_type_declares" {
declare module.exports: number
type str2 = string;
}
/**
* \`declare var exports\` is deprecated, so we have a grace period where both
* syntaxes will work.
*/
declare module "DEPRECATED__declare_var_exports" {
declare var exports: number;
}
/**
* Ensure that, if both are present, \`declare module.exports\` wins
*/
declare module "declare_m_e_with_declare_var_e" {
declare module.exports: number
declare var exports: string;
}
"
`;

View File

@ -6,21 +6,21 @@ exports[`test import_declare_type.js 1`] = `
////////////////////////////////////////////////////////////
// == Import Declared Type Alias From Declared Module == //
//////////////////////////////////////////////////////////
import type {baz} from \"ModuleAliasFoo\";
import {foo} from \"ModuleAliasFoo\";
import type {baz} from "ModuleAliasFoo";
import {foo} from "ModuleAliasFoo";
var k1: baz = 42;
var k2: baz = \"shab\"; // Error: string to int
var k2: baz = "shab"; // Error: string to int
var k3: toz = foo(k1); // works
import type {toz} from \"ModuleAliasFoo\";
import type {toz} from "ModuleAliasFoo";
var k4: toz = foo(k1); // works
//////////////////////////////////////////////////////////
// == Declared Module with exports prop (issue 880) == //
////////////////////////////////////////////////////////
import blah from \'foo\';
import type { Foo, Bar, Id } from \'foo\';
import blah from 'foo';
import type { Foo, Bar, Id } from 'foo';
blah(0, 0);
@ -28,22 +28,35 @@ blah(0, 0);
(3 : Bar); // error : number ~> A
(\"lol\" : Id<number>); // error : string ~> number
("lol" : Id<number>); // error : string ~> number
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
/**
* @flow
*/
////////////////////////////////////////////////////////////
// == Import Declared Type Alias From Declared Module == //
//////////////////////////////////////////////////////////
// Error: string to int
// works
// works
//////////////////////////////////////////////////////////
// == Declared Module with exports prop (issue 880) == //
////////////////////////////////////////////////////////
// error : {toz : number} ~> string
// error : number ~> A
// error : string ~> number
import type { baz } from "ModuleAliasFoo";
import { foo } from "ModuleAliasFoo";
var k1: baz = [object Number];
var k2: baz = "shab";
var k3: toz = foo(k1);
import type { toz } from "ModuleAliasFoo";
var k4: toz = foo(k1);
import blah from "foo";
import type { Foo, Bar, Id } from "foo";
blah([object Number], [object Number]);
({ toz: [object Number] }: Foo);
([object Number]: Bar);
("lol": Id<number>);
"
`;

View File

@ -9,28 +9,21 @@ declare module ModuleAliasFoo {
declare function foo(bar : baz) : toz;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1348
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1348:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1254:25)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
/**
* @flow
*/
declare module ModuleAliasFoo {
type baz = number;
type toz = string;
declare function foo(bar: baz): toz;
}
"
`;
exports[`test declare_type_exports.js 1`] = `
"/* @flow */
declare module \'foo\' {
declare module 'foo' {
declare class A {
toz : number
}
@ -46,20 +39,14 @@ declare module \'foo\' {
};
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1479:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
/* @flow */
declare module "foo" {
declare class A { toz: number }
declare var n: string;
type Foo = typeof n;
type Bar = A;
type Id<T> = T;
declare var exports: { (a: number, b: number): number };
}
"
`;

View File

@ -31,20 +31,47 @@ class PropVariance<+Out,-In> {
con_dict2: {-[k:string]: In}; // ok
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1172:16)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// error on both targs (A ~/~> B)
// OK for both targs (B ~> A)
// error
// error
// error
// ok
// ok
// error
// error
// error
// ok
// error
// error
// ok
class Variance<+Out, -In> {
foo(x: Out): Out {
return x;
}
bar(y: In): In {
return y;
}
}
class A {}
class B extends A {}
function subtyping(v1: Variance<A, B>, v2: Variance<B, A>) {
(v1: Variance<B, A>);
(v2: Variance<A, B>);
}
class PropVariance<+Out, -In> {
inv1: Out;
inv2: In;
-co1: Out;
-co2: In;
+con1: Out;
+con2: In;
inv_dict1: { [k: string]: Out };
inv_dict2: { [k: string]: In };
co_dict1: { +[k: string]: Out };
co_dict2: { +[k: string]: In };
con_dict1: { -[k: string]: Out };
con_dict2: { -[k: string]: In };
}
"
`;

View File

@ -9,12 +9,11 @@ var x = null;
f(x);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* demo */
function f(x) {
return 42 / x;
}
var x = null;
//...
function f(x) {
return [object Number] / x;
}
var x = [object Null];
f(x);
"
`;

View File

@ -20,8 +20,9 @@ a.onLoad(callback);
module.exports = A;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @providesModule Demo */
// instance field declaration
class A {
x: number;// instance field declaration
x: number;
constructor(x) {
this.x = x;
}
@ -35,10 +36,9 @@ class A {
function callback(x: string) {
return x.length;
}
var a = new A(42);
var a = new A([object Number]);
a.onLoad(callback);
module.exports = A;
"
`;
@ -49,6 +49,5 @@ var z = new A("42").getX();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var A = require("Demo");
var z = new A("42").getX();
"
`;

View File

@ -2,7 +2,6 @@ exports[`test A.js 1`] = `
"require('./C');
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
require("./C");
"
`;
@ -10,7 +9,6 @@ exports[`test B.js 1`] = `
"require('./C');
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
require("./C");
"
`;
@ -24,7 +22,6 @@ require("./D");
require("./E");
require("./F");
require("./G");
"
`;
@ -32,7 +29,6 @@ exports[`test D.js 1`] = `
"require('./I');
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
require("./I");
"
`;
@ -40,14 +36,13 @@ exports[`test E.js 1`] = `
"require('./I');
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
require("./I");
"
`;
exports[`test F.js 1`] = `
"// empty
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// empty
"
`;
@ -56,14 +51,13 @@ exports[`test G.js 1`] = `
"require('./H');
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
require("./H");
"
`;
exports[`test H.js 1`] = `
"// empty
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// empty
"
`;
@ -72,6 +66,5 @@ exports[`test I.js 1`] = `
"require('./A');
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
require("./A");
"
`;

View File

@ -1,5 +1,5 @@
exports[`test array_rest.js 1`] = `
"let xs = [0, \"\", true];
"let xs = [0, "", true];
let [a, ...ys] = xs;
let [b, ...zs] = ys;
let c = zs[0]; // retain tuple info
@ -12,46 +12,53 @@ let d = zs[1]; // run off the end
let [...e] = 0;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
let xs = [ 0, \"\", true ];
// retain tuple info
// run off the end
// error: number ~> void
// error: string ~> void
// error: boolean ~> void
// error: number|string|boolean ~> void
let xs = [ [object Number], "", [object Boolean] ];
let [ a, ...ys ] = xs;
let [ b, ...zs ] = ys;
let c = zs[0];// retain tuple info
let d = zs[1];// run off the end
(a: void);// error: number ~> void
(b: void);// error: string ~> void
(c: void);// error: boolean ~> void
(d: void);// error: number|string|boolean ~> void
let [ ...e ] = 0;
let c = zs[[object Number]];
let d = zs[[object Number]];
(a: void);
(b: void);
(c: void);
(d: void);
let [ ...e ] = [object Number];
"
`;
exports[`test computed.js 1`] = `
"var { [\"key\"]: val1 } = { key: \"val\" };
"var { ["key"]: val1 } = { key: "val" };
(val1: void); // error: string ~> void
var key: string = \"key\";
var { [key]: val2 } = { key: \"val\" };
var key: string = "key";
var { [key]: val2 } = { key: "val" };
(val2: void); // ok (gasp!) by existing StrT -> ElemT rule
var { [\"key\"]: val3, ...spread } = { key: \"val\" };
(spread.key: void); // error (gasp!) in general we don\'t know if a computed prop should be excluded from spread
var { ["key"]: val3, ...spread } = { key: "val" };
(spread.key: void); // error (gasp!) in general we don't know if a computed prop should be excluded from spread
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var { [\"key\"]: val1 } = { key: \"val\" };
(val1: void);// error: string ~> void
var key: string = \"key\";
var { [key]: val2 } = { key: \"val\" };
(val2: void);// ok (gasp!) by existing StrT -> ElemT rule
var { [\"key\"]: val3, ...spread } = { key: \"val\" };
(spread.key: void);// error (gasp!) in general we don\'t know if a computed prop should be excluded from spread
// error: string ~> void
// ok (gasp!) by existing StrT -> ElemT rule
// error (gasp!) in general we don't know if a computed prop should be excluded from spread
var { ["key"]: val1 } = { key: "val" };
(val1: void);
var key: string = "key";
var { [key]: val2 } = { key: "val" };
(val2: void);
var { ["key"]: val3, ...spread } = { key: "val" };
(spread.key: void);
"
`;
exports[`test defaults.js 1`] = `
"/* @flow */
function obj_prop_fun({p:{q=0}={q:true}}={p:{q:\"\"}}) {
function obj_prop_fun({p:{q=0}={q:true}}={p:{q:""}}) {
// errors:
// * number ~> void, from default on _.p.q
// * boolean ~> void, from default on _.p
@ -62,9 +69,9 @@ function obj_prop_fun({p:{q=0}={q:true}}={p:{q:\"\"}}) {
obj_prop_fun(); // ok
obj_prop_fun({}); // ok
obj_prop_fun({p:{}}); // ok
obj_prop_fun({p:{q:null}}); // ok, provides add\'l lower bound
obj_prop_fun({p:{q:null}}); // ok, provides add'l lower bound
function obj_prop_var(o={p:{q:\"\"}}) {
function obj_prop_var(o={p:{q:""}}) {
var {p:{q=0}={q:true}} = o;
// errors:
// * number ~> void, from default on o.p.q
@ -76,9 +83,9 @@ function obj_prop_var(o={p:{q:\"\"}}) {
obj_prop_var(); // ok
obj_prop_var({}); // ok
obj_prop_var({p:{}}); // ok
obj_prop_var({p:{q:null}}); // ok, provides add\'l lower bound
obj_prop_var({p:{q:null}}); // ok, provides add'l lower bound
function obj_rest({p:{q,...o}={q:0,r:0}}={p:{q:0,r:\"\"}}) {
function obj_rest({p:{q,...o}={q:0,r:0}}={p:{q:0,r:""}}) {
// errors:
// * number ~> void, from default on _.p
// * string ~> void, from default on _
@ -132,21 +139,112 @@ function obj_prop_union2({p}:{p:number}|{p:string}={p:true}) {}
function default_expr_scope({a, b = a}) {}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:340:16)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
/* @flow */
// errors:
// * number ~> void, from default on _.p.q
// * boolean ~> void, from default on _.p
// * string ~> void, from default on _
// * null ~> void, from call below
// ok
// ok
// ok
// ok, provides add'l lower bound
// errors:
// * number ~> void, from default on o.p.q
// * boolean ~> void, from default on o.p
// * string ~> void, from default on o
// * null ~> void, from call below
// ok
// ok
// ok
// ok, provides add'l lower bound
// errors:
// * number ~> void, from default on _.p
// * string ~> void, from default on _
// * null ~> void, from call below
// ok
// ok
// ok
// error: boolean ~> string
// error: number ~> string
// error: string ~> void
// error: boolean ~> string
// error: number ~> string
// error: string ~> void
// error: property \`x\` cannot be accessed on null
// error: expected object instead of number
// error: element 0 cannot be accessed on null
// error: expected array instead of null
// Default values in destructuring unwrap optional types
// ok
// ok
// union-like upper bounds preserved through destructuring
// TODO: union-of-objects upper bounds preserved through destructuring
function obj_prop_fun(
{ p: { q } = { q: [object Boolean] } } = { p: { q: "" } }
) {
(q: void);
}
obj_prop_fun();
obj_prop_fun({});
obj_prop_fun({ p: {} });
obj_prop_fun({ p: { q: [object Null] } });
function obj_prop_var(o = { p: { q: "" } }) {
var { p: { q } = { q: [object Boolean] } } = o;
(q: void);
}
obj_prop_var();
obj_prop_var({});
obj_prop_var({ p: {} });
obj_prop_var({ p: { q: [object Null] } });
function obj_rest(
{ p: { q, ...o } = { q: [object Number], r: [object Number] } } = {
p: { q: [object Number], r: "" }
}
) {
(o.r: void);
}
obj_rest();
obj_rest({});
obj_rest({ p: {} });
obj_rest({ p: { q: [object Number], r: [object Null] } });
function obj_prop_annot({ p } = { p: [object Number] }) {
(p: void);
}
var { p } = { p: [object Number] };
(p: void);
function obj_prop_err({ x: { y } } = [object Null]) {
}
function obj_rest_err({ ...o } = [object Number]) {
}
function arr_elem_err([ x ] = [object Null]) {
}
function arr_rest_err([ ...a ] = [object Null]) {
}
function gen<T>(x: T, { p }): T {
return p;
}
obj_prop_fun(({}: { p?: { q?: null } }));
obj_prop_var(({}: { p?: { q?: null } }));
function obj_prop_opt({ p } = { p: [object Number] }) {
}
function obj_prop_maybe({ p } = { p: [object Number] }) {
}
function obj_prop_union({ p } = { p: [object Boolean] }) {
}
function obj_prop_union2({ p } = { p: [object Boolean] }) {
}
function default_expr_scope({ a, b }) {
}
"
`;
@ -161,7 +259,7 @@ var {m} = {m:0};
var obj;
({n: obj.x} = {n:3});
[obj.x] = [\'foo\'];
[obj.x] = ['foo'];
function foo({p, z:[r]}) {
a = p;
@ -175,17 +273,17 @@ foo({p:0, z:[1,2]});
function bar({x, ...z}) {
var o:{x: string; y: number;} = z;
}
bar({x:\"\",y:0});
bar({x:"",y:0});
var spread = {y:\"\"};
var spread = {y:""};
var extend: {x:number; y:string; z: boolean} = {x:0, ...spread};
function qux(_: {a:number}) { }
qux({a:\"\"});
qux({a:""});
function corge({b}: {b:string}) { }
corge({b:0});
var {n}:{n: number} = {n: \"\"}
var {n}:{n: number} = {n: ""}
function test() {
var {foo} = {bar: 123}; // error on foo
@ -193,9 +291,9 @@ function test() {
}
function test() {
var x = {foo: \'abc\', bar: 123};
var x = {foo: 'abc', bar: 123};
var {foo, ...rest} = x;
(x.baz: string); // error, baz doesn\'t exist
(x.baz: string); // error, baz doesn't exist
(rest.baz: string); // no error, rest is unsealed
}
@ -223,46 +321,65 @@ var cp1_err: string = childprop1; // Error: number ~> string
var cp2: number = others.childprop1;
var cp2_err: string = others.childprop2; // Error: number ~> string
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// error on foo
// error on baz
// error, baz doesn't exist
// no error, rest is unsealed
// Error: number ~> string
// Error: number ~> string
// Error: number ~> string
// Error: number ~> string
declare var a: string;
declare var b: string;
declare var c: string;
[ { a1: a, b }, c ] = [ { a1: 0, b: 1 }, 2 ];
var { m } = { m: 0 };
[ { a1: a, b }, c ] = [
{ a1: [object Number], b: [object Number] },
[object Number]
];
var { m } = { m: [object Number] };
{ m } = { m: m };
var obj;
{ n: obj.x } = { n: 3 };
[ obj.x ] = [ \"foo\" ];
{ n: obj.x } = { n: [object Number] };
[ obj.x ] = [ "foo" ];
function foo({ p, z: [ r ] }) {
a = p;
b = z;
c = r;
}
foo({ p: 0, z: [ 1, 2 ] });
[ a, , b, ...c ] = [ 0, 1, true, 3 ];
foo({ p: [object Number], z: [ [object Number], [object Number] ] });
[ a, , b, ...c ] = [
[object Number],
[object Number],
[object Boolean],
[object Number]
];
function bar({ x, ...z }) {
var o: { x: string, y: number } = z;
}
bar({ x: \"\", y: 0 });
var spread = { y: \"\" };
var extend: { x: number, y: string, z: boolean } = { x: 0, ...spread };
bar({ x: "", y: [object Number] });
var spread = { y: "" };
var extend: { x: number, y: string, z: boolean } = {
x: [object Number],
...spread
};
function qux(_: { a: number }) {
}
qux({ a: \"\" });
qux({ a: "" });
function corge({ b }) {
}
corge({ b: 0 });
var { n } = { n: \"\" };
corge({ b: [object Number] });
var { n } = { n: "" };
function test() {
var { foo } = { bar: 123 };// error on foo
var { bar, baz } = { bar: 123 };// error on baz
var { foo } = { bar: [object Number] };
var { bar, baz } = { bar: [object Number] };
}
function test() {
var x = { foo: \"abc\", bar: 123 };
var x = { foo: "abc", bar: [object Number] };
var { foo, ...rest } = x;
(x.baz: string);// error, baz doesn\'t exist
(rest.baz: string);// no error, rest is unsealed
(x.baz: string);
(rest.baz: string);
}
module.exports = corge;
class Base {
@ -275,14 +392,13 @@ class Child extends Base {
}
var { baseprop1, childprop1, ...others } = new Child();
var bp1: number = baseprop1;
var bp1_err: string = baseprop1;// Error: number ~> string
var bp1_err: string = baseprop1;
var bp2: number = others.baseprop2;
var bp2_err: string = others.baseprop2;// Error: number ~> string
var bp2_err: string = others.baseprop2;
var cp1: number = childprop1;
var cp1_err: string = childprop1;// Error: number ~> string
var cp1_err: string = childprop1;
var cp2: number = others.childprop1;
var cp2_err: string = others.childprop2;// Error: number ~> string
var cp2_err: string = others.childprop2;
"
`;
@ -293,21 +409,11 @@ var [];
var {};
var [], {toz};
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Complex binding patterns require an initialization value (1:9)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp$1.parseVar (/node_modules/babylon/lib/index.js:2215:12)
at Parser.pp$1.parseVarStatement (/node_modules/babylon/lib/index.js:2042:8)
at Parser.pp$1.parseStatement (/node_modules/babylon/lib/index.js:1735:19)
at Parser.parseStatement (/node_modules/babylon/lib/index.js:5224:22)
at Parser.pp$1.parseBlockBody (/node_modules/babylon/lib/index.js:2139:21)
at Parser.pp$1.parseTopLevel (/node_modules/babylon/lib/index.js:1651:8)
at Parser.parse (/node_modules/babylon/lib/index.js:1543:17)
at Object.parse$1 [as parse] (/node_modules/babylon/lib/index.js:6472:37)
at Object.parse (/index.js:34:26)
var { foo };
var [ bar ];
var [ ];
var {};
var [ ]{ toz };
"
`;
@ -324,21 +430,15 @@ function h({ a, { b } }, { c }, { { d } }) {
return a + b + c + d;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/node_modules/babylon/lib/index.js:4255
throw err;
^
SyntaxError: Argument name clash in strict mode (5:16)
at Parser.pp$5.raise (/node_modules/babylon/lib/index.js:4252:13)
at Parser.pp$2.checkLVal (/node_modules/babylon/lib/index.js:3007:16)
at Parser.checkLVal (/node_modules/babylon/lib/index.js:5446:22)
at Parser.pp$2.checkLVal (/node_modules/babylon/lib/index.js:3034:14)
at Parser.checkLVal (/node_modules/babylon/lib/index.js:5446:22)
at Parser.pp$3.parseFunctionBody (/node_modules/babylon/lib/index.js:4072:12)
at Parser.parseFunctionBody (/node_modules/babylon/lib/index.js:5211:20)
at Parser.pp$1.parseFunction (/node_modules/babylon/lib/index.js:2257:8)
at Parser.pp$1.parseFunctionStatement (/node_modules/babylon/lib/index.js:1926:15)
at Parser.pp$1.parseStatement (/node_modules/babylon/lib/index.js:1712:19)
function f(a, { b }) {
return a + b;
}
function g(a, { a }) {
return a;
}
function h({ a, { }, ,, c, ,, { d }) {
return a + b + c + d;
}
"
`;
@ -346,9 +446,9 @@ exports[`test eager.js 1`] = `
"var x;
({x} = null); // error, property \`x\` can not be accessed on \`null\`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// error, property \`x\` can not be accessed on \`null\`
var x;
{ x } = null;// error, property \`x\` can not be accessed on \`null\`
{ x } = [object Null];
"
`;
@ -386,28 +486,67 @@ function arr_rest_pattern<X>([ _, ...a ] : ArrRest<X>) { // a: [X]
a[0];
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:340:16)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// @flow
// prop: X
// prop: X
// elem: X
// elem: X
// proj: X
// proj: X
// nonsense
// r: X[]
// o: { x: X }
// o: { x: X }
// a: [X]
// a: [X]
function obj_pattern<X>({ prop }) {
}
type Prop<X> = { prop: X };
function obj_pattern2<X>({ prop }) {
}
function arr_pattern<X>([ elem ]) {
}
type Elem<X> = X[];
function arr_pattern2<X>([ elem ]) {
}
function tup_pattern<X>([ proj ]) {
}
type Proj<X> = [];
function tup_pattern2<X>([ proj ]) {
}
function rest_antipattern<T>(...t: T) {
}
function rest_pattern<X>(...r: X[]) {
}
function obj_rest_pattern<X>({ _, ...o }) {
o.x;
}
type ObjRest<X> = { _: any, x: X };
function obj_rest_pattern<X>({ _, ...o }) {
o.x;
}
function arr_rest_pattern<X>([ _, ...a ]) {
a[[object Number]];
}
type ArrRest<X> = [];
function arr_rest_pattern<X>([ _, ...a ]) {
a[[object Number]];
}
"
`;
exports[`test rec.js 1`] = `
"// @flow
// Make sure that destructuring doesn\'t cause infinite loops when combined with
// Make sure that destructuring doesn't cause infinite loops when combined with
// funny doses of repositioning
let foo = (i: number) => [i];
@ -421,14 +560,15 @@ foo = (i: number) => {
return bar(i);
};
// Also make sure that the following doesn\'t loop
// Also make sure that the following doesn't loop
declare var o;
var { x: o } = o;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
// Make sure that destructuring doesn\'t cause infinite loops when combined with
// Make sure that destructuring doesn't cause infinite loops when combined with
// funny doses of repositioning
// Also make sure that the following doesn't loop
let foo = (i: number) => [ i ];
const bar = (i: number) => {
[ i ] = foo(i);
@ -437,25 +577,24 @@ const bar = (i: number) => {
foo = (i: number) => {
return bar(i);
};
// Also make sure that the following doesn\'t loop
declare var o;
var { x: o } = o;
"
`;
exports[`test string_lit.js 1`] = `
"var { \"key\": val } = { key: \"val\" };
"var { "key": val } = { key: "val" };
(val: void); // error: string ~> void
var { \"with-dash\": with_dash } = { \"with-dash\": \"motivating example\" };
(with_dash: \"motivating example\"); // ok
var { "with-dash": with_dash } = { "with-dash": "motivating example" };
(with_dash: "motivating example"); // ok
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var { \"key\": val } = { key: \"val\" };
(val: void);// error: string ~> void
var { \"with-dash\": with_dash } = { \"with-dash\": \"motivating example\" };
(with_dash: \"motivating example\");// ok
// error: string ~> void
// ok
var { "key": val } = { key: "val" };
(val: void);
var { "with-dash": with_dash } = { "with-dash": "motivating example" };
(with_dash: "motivating example");
"
`;
@ -463,7 +602,7 @@ exports[`test unannotated.js 1`] = `
"// @flow
var { x } = {
x: { foo: \"foo\" }
x: { foo: "foo" }
};
function bar() {
@ -471,10 +610,9 @@ function bar() {
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
var { x } = { x: { foo: \"foo\" } };
var { x } = { x: { foo: "foo" } };
function bar() {
x.bar;
}
"
`;

View File

@ -2,14 +2,14 @@ exports[`test any.js 1`] = `
"/* @flow */
const dict: {[key: string]: number} = {}
const k: any = \'foo\'
const k: any = 'foo'
const val: string = dict[k] // error: number incompatible with string
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
// error: number incompatible with string
const dict: { [key: string]: number } = {};
const k: any = \"foo\";
const val: string = dict[k];// error: number incompatible with string
const k: any = "foo";
const val: string = dict[k];
"
`;
@ -19,32 +19,33 @@ exports[`test compatible.js 1`] = `
function foo0(x: Array<{[key: string]: mixed}>): Array<{[key: string]: mixed}> {
// this adds a fooBar property to the param type, which should NOT cause
// an error in the return type because it is a dictionary.
x[0].fooBar = \'foobar\';
x[0].fooBar = 'foobar';
return x;
}
function foo2(
x: {[key: string]: number}
): {[key: string]: number, +toString: () => string} {
// x\'s prototype has a toString method
// x's prototype has a toString method
return x;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
/* @flow */
// this adds a fooBar property to the param type, which should NOT cause
// an error in the return type because it is a dictionary.
// x's prototype has a toString method
function foo0(x: Array<{ [key: string]: mixed }>): Array<{
[key: string]: mixed
}> {
x[[object Number]].fooBar = "foobar";
return x;
}
function foo2(x: { [key: string]: number }): {
[key: string]: number,
+toString: : () => string
} {
return x;
}
"
`;
@ -58,7 +59,7 @@ exports[`test dictionary.js 1`] = `
* maps. They can also be used to represent array-like objects, e.g., NodeList
* from the DOM API.
*
* A dictionary is assumed to have every property described by it\'s key type.
* A dictionary is assumed to have every property described by it's key type.
* This behavior is similar to the behavior of arrays, which are assumed to have
* a value at every index.
*
@ -78,17 +79,17 @@ class Y {}
function set_prop_to_string_key(
o: {[k:string]:any},
) {
o.prop = \"ok\";
o.prop = "ok";
}
// **UNSOUND**
// This is allowed by design. We don\'t track get/set and we don\'t wrap the
// This is allowed by design. We don't track get/set and we don't wrap the
// return type in a maybe.
function unsound_dict_has_every_key(
o: {[k:string]:X},
) {
(o.p: X); // ok
(o[\"p\"]: X); // ok
(o["p"]: X); // ok
}
// As with any object type, we can assign subtypes to properties.
@ -100,7 +101,7 @@ function set_prop_covariant(
o.p = new C; // ok
}
// This isn\'t specific behavior to dictionaries, but for completeness...
// This isn't specific behavior to dictionaries, but for completeness...
function get_prop_contravariant(
o: {[k:string]:B},
) {
@ -114,7 +115,7 @@ function get_prop_contravariant(
function add_prop_to_nonstring_key_dot(
o: {[k:number]:any},
) {
o.prop = \"err\"; // error: string ~> number
o.prop = "err"; // error: string ~> number
}
// Bracket notation can be used to add properties to dictionaries with
@ -123,7 +124,7 @@ function add_prop_to_nonstring_key_dot(
function add_prop_to_nonstring_key_bracket(
o: {[k:number]:any},
) {
o[0] = \"ok\";
o[0] = "ok";
}
// Objects can be part dict, part not by mixing an indexer with declared props.
@ -147,12 +148,12 @@ function object_prototype(
}
// **UNSOUND**
// Because we support non-string props w/ bracket notation, it\'s possible to
// Because we support non-string props w/ bracket notation, it's possible to
// write into a declared prop unsoundly.
function unsound_string_conversion_alias_declared_prop(
o: {[k:number]:any, \"0\":X},
o: {[k:number]:any, "0":X},
) {
o[0] = \"not-x\"; // a[\"0\"] no longer X
o[0] = "not-x"; // a["0"] no longer X
}
function unification_dict_values_invariant(
@ -200,7 +201,7 @@ function subtype_dict_values_fresh_exception() {
}
// Actually, unsound_string_conversion_alias_declared_prop behavior makes an
// argument that we shouldn\'t really care about this, since we ignore the fact
// argument that we shouldn't really care about this, since we ignore the fact
// that coercing values to string keys can cause unintended aliasing in general.
// Barring some compelling use case for that in this context, though, we choose
// to be strict.
@ -370,21 +371,303 @@ function subtype_optional_c_to_dict(
return x;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1348
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1348:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1452:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
/* Dictionary types are object types that include an indexer, which specifies a
* key type and a value type. The presence of an indexer makes the object type
* unsealed, but all added properties must be consistent with the indexer
* signature.
*
* Dictionaries can be used to represent the common idiom of objects used as
* maps. They can also be used to represent array-like objects, e.g., NodeList
* from the DOM API.
*
* A dictionary is assumed to have every property described by it's key type.
* This behavior is similar to the behavior of arrays, which are assumed to have
* a value at every index.
*
* @flow
*/
// Some logic is variance-sensitive.
// Just a couple of short type names. Compare to string/number.
// Any property can be set on a dict with string keys.
// **UNSOUND**
// This is allowed by design. We don't track get/set and we don't wrap the
// return type in a maybe.
// ok
// ok
// As with any object type, we can assign subtypes to properties.
// error, A ~> B
// ok
// ok
// This isn't specific behavior to dictionaries, but for completeness...
// ok
// ok
// error, C ~> B
// Dot-notation can not be used to add properties to dictionaries with
// non-string keys, because keys are strings.
// error: string ~> number
// Bracket notation can be used to add properties to dictionaries with
// non-string keys, even though all keys are strings. This is a convenient
// affordance.
// Objects can be part dict, part not by mixing an indexer with declared props.
// ok
// ok
// ok
// ok
// Indeed, dict types are still Objects and have Object.prototype stuff
// error: string ~> boolean
// ok
// **UNSOUND**
// Because we support non-string props w/ bracket notation, it's possible to
// write into a declared prop unsoundly.
// a["0"] no longer X
// error
// in[0].p no longer B
// ok
// error
// not true
// error
// x[0].p no longer B
// ok
// error
// not true
// ok, A == A
// ok, B <: A
// ok, C <: A
// error, A not <: B
// ok, B == B
// ok, C <: A
// error, A not <: C
// error, A not <: C
// ok, C == C
// Actually, unsound_string_conversion_alias_declared_prop behavior makes an
// argument that we shouldn't really care about this, since we ignore the fact
// that coercing values to string keys can cause unintended aliasing in general.
// Barring some compelling use case for that in this context, though, we choose
// to be strict.
// error
// ok
// error
// error
// ok
// error
// error: A ~> B
// x[0].p no longer B
// ok
// error
// not true
// error
// xa[0].p no longer B
// ok
// error
// not true
// error: A ~> B
// x.p no longer B
// ok
// error
// not true
// error
// xa.p no longer B
// ok
// error
// not true
// error: if allowed, could write {p:X,q:Y} into \`x\`
// error: if allowed, could write {p:X,q:Y} into returned array
// error
// x.p no longer B
// ok
// error
// not true
// error
// x.p no longer B
// error
// not true
// Only props in l which are not in u must match indexer, but must do so
// exactly.
// error (as above), but exclusive of x
// ok,
// error (as above), but exclusive of x
// error
// ok
// error
// error
// ok
// error
// error
// ok
// error
// error: A ~> B
// ok
// error: C ~> B
class A {}
class B extends A {}
class C extends B {}
class X {}
class Y {}
function set_prop_to_string_key(o: { [k: string]: any }) {
o.prop = "ok";
}
function unsound_dict_has_every_key(o: { [k: string]: X }) {
(o.p: X);
(o["p"]: X);
}
function set_prop_covariant(o: { [k: string]: B }) {
o.p = new A();
o.p = new B();
o.p = new C();
}
function get_prop_contravariant(o: { [k: string]: B }) {
(o.p: A);
(o.p: B);
(o.p: C);
}
function add_prop_to_nonstring_key_dot(o: { [k: number]: any }) {
o.prop = "err";
}
function add_prop_to_nonstring_key_bracket(o: { [k: number]: any }) {
o[[object Number]] = "ok";
}
function mix_with_declared_props(o: { [k: number]: X, p: Y }, x: X, y: Y) {
(o[[object Number]]: X);
(o.p: Y);
o[[object Number]] = x;
o.p = y;
}
function object_prototype(o: { [k: string]: number }): {
[k: string]: number,
+toString: : () => string
} {
(o.toString(): boolean);
return o;
}
function unsound_string_conversion_alias_declared_prop(
o: { [k: number]: any, "0": X }
) {
o[[object Number]] = "not-x";
}
function unification_dict_values_invariant(x: Array<{ [k: string]: B }>) {
let a: Array<{ [k: string]: A }> = x;
a[[object Number]].p = new A();
let b: Array<{ [k: string]: B }> = x;
let c: Array<{ [k: string]: C }> = x;
(x[[object Number]].p: C);
}
function subtype_dict_values_invariant(x: { [k: string]: B }) {
let a: { [k: string]: A } = x;
a.p = new A();
let b: { [k: string]: B } = x;
let c: { [k: string]: C } = x;
(x.p: C);
}
function subtype_dict_values_fresh_exception() {
let a: { [k: string]: A } = { a: new A(), b: new B(), c: new C() };
let b: { [k: string]: B } = { a: new A(), b: new B(), c: new C() };
let c: { [k: string]: C } = { a: new A(), b: new B(), c: new C() };
}
function unification_dict_keys_invariant(x: Array<{ [k: B]: any }>) {
let a: Array<{ [k: A]: any }> = x;
let b: Array<{ [k: B]: any }> = x;
let c: Array<{ [k: C]: any }> = x;
}
function subtype_dict_keys_invariant(x: { [k: B]: any }) {
let a: { [k: A]: any } = x;
let b: { [k: B]: any } = x;
let c: { [k: C]: any } = x;
}
function unification_mix_with_declared_props_invariant_l(
x: Array<{ [k: string]: B }>
) {
let a: Array<{ [k: string]: B, p: A }> = x;
a[[object Number]].p = new A();
let b: Array<{ [k: string]: B, p: B }> = x;
let c: Array<{ [k: string]: B, p: C }> = x;
(x[[object Number]].p: C);
}
function unification_mix_with_declared_props_invariant_r(
xa: Array<{ [k: string]: A, p: B }>,
xb: Array<{ [k: string]: B, p: B }>,
xc: Array<{ [k: string]: C, p: B }>
) {
let a: Array<{ [k: string]: A }> = xa;
a[[object Number]].p = new A();
let b: Array<{ [k: string]: B }> = xb;
let c: Array<{ [k: string]: C }> = xc;
(xc[[object Number]].p: C);
}
function subtype_mix_with_declared_props_invariant_l(x: { [k: string]: B }) {
let a: { [k: string]: B, p: A } = x;
a.p = new A();
let b: { [k: string]: B, p: B } = x;
let c: { [k: string]: B, p: C } = x;
(x.p: C);
}
function subtype_mix_with_declared_props_invariant_r(
xa: { [k: string]: A, p: B },
xb: { [k: string]: B, p: B },
xc: { [k: string]: C, p: B }
) {
let a: { [k: string]: A } = xa;
a.p = new A();
let b: { [k: string]: B } = xb;
let c: { [k: string]: C } = xc;
(xc.p: C);
}
function unification_dict_to_obj(x: Array<{ [k: string]: X }>): Array<{
p: X
}> {
return x;
}
function unification_obj_to_dict(x: Array<{ p: X }>): Array<{
[k: string]: X
}> {
return x;
}
function subtype_dict_to_obj(x: { [k: string]: B }) {
let a: { p: A } = x;
a.p = new A();
let b: { p: B } = x;
let c: { p: C } = x;
(x.p: C);
}
function subtype_obj_to_dict(x: { p: B }) {
let a: { [k: string]: A } = x;
a.p = new A();
let b: { [k: string]: B } = x;
let c: { [k: string]: C } = x;
(x.p: C);
}
function subtype_obj_to_mixed(x: { p: B, x: X }) {
let a: { [k: string]: A, x: X } = x;
let b: { [k: string]: B, x: X } = x;
let c: { [k: string]: C, x: X } = x;
}
function unification_dict_to_mixed(x: Array<{ [k: string]: B }>) {
let a: Array<{ [k: string]: B, p: A }> = x;
let b: Array<{ [k: string]: B, p: B }> = x;
let c: Array<{ [k: string]: B, p: C }> = x;
}
function subtype_dict_to_mixed(x: { [k: string]: B }) {
let a: { [k: string]: B, p: A } = x;
let b: { [k: string]: B, p: B } = x;
let c: { [k: string]: B, p: C } = x;
}
function subtype_dict_to_optional_a(x: { [k: string]: B }) {
let a: { p?: A } = x;
}
function subtype_dict_to_optional_b(x: { [k: string]: B }) {
let b: { p?: B } = x;
}
function subtype_dict_to_optional_c(x: { [k: string]: B }) {
let c: { p?: C } = x;
}
function subtype_optional_a_to_dict(x: { p?: A }): { [k: string]: B } {
return x;
}
function subtype_optional_b_to_dict(x: { p?: B }): { [k: string]: B } {
return x;
}
function subtype_optional_c_to_dict(x: { p?: C }): { [k: string]: B } {
return x;
}
"
`;
@ -397,14 +680,14 @@ var z : {[key: number]: string} = x; // 2 errors, string !~> number & vice versa
var a : {[key: string]: ?string} = {};
var b : {[key: string]: string} = a; // 2 errors (null & undefined)
var c : {[key: string]: ?string} = b; // 2 errors, since c[\'x\'] = null updates b
var c : {[key: string]: ?string} = b; // 2 errors, since c['x'] = null updates b
// 2 errors (number !~> string, string !~> number)
function foo0(x: Array<{[key: string]: number}>): Array<{[key: string]: string}> {
return x;
}
// error, fooBar:string !~> number (x\'s dictionary)
// error, fooBar:string !~> number (x's dictionary)
function foo1(
x: Array<{[key: string]: number}>
): Array<{[key: string]: number, fooBar: string}> {
@ -414,7 +697,7 @@ function foo1(
function foo2(
x: Array<{[key: string]: mixed}>
): Array<{[key: string]: mixed, fooBar: string}> {
x[0].fooBar = 123; // OK, since number ~> mixed (x elem\'s dictionary)
x[0].fooBar = 123; // OK, since number ~> mixed (x elem's dictionary)
return x; // error: mixed ~> string
}
@ -423,7 +706,7 @@ function foo3(x: {[key: string]: number}): {foo: number} {
return x;
}
// error: foo can\'t exist in x
// error: foo can't exist in x
function foo4(x: {[key: string]: number}): {[key: string]: number, foo: string} {
return x;
}
@ -447,21 +730,66 @@ function foo8(x: {[key: string]: number}) {
(x.foo: number);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
/* @flow */
// 2 errors, number !~> string & vice versa
// 2 errors, string !~> number & vice versa
// 2 errors (null & undefined)
// 2 errors, since c['x'] = null updates b
// 2 errors (number !~> string, string !~> number)
// error, fooBar:string !~> number (x's dictionary)
// OK, since number ~> mixed (x elem's dictionary)
// error: mixed ~> string
// OK, since we assume dictionaries have every key
// error: foo can't exist in x
// error, some prop in x could be incompatible (covariance)
// error, some prop in return could be incompatible
// error
var x: { [key: string]: string } = {};
var y: { [key: string]: number } = x;
var z: { [key: number]: string } = x;
var a: { [key: string]: ?string } = {};
var b: { [key: string]: string } = a;
var c: { [key: string]: ?string } = b;
function foo0(x: Array<{ [key: string]: number }>): Array<{
[key: string]: string
}> {
return x;
}
function foo1(x: Array<{ [key: string]: number }>): Array<{
[key: string]: number,
fooBar: string
}> {
return x;
}
function foo2(x: Array<{ [key: string]: mixed }>): Array<{
[key: string]: mixed,
fooBar: string
}> {
x[[object Number]].fooBar = [object Number];
return x;
}
function foo3(x: { [key: string]: number }): { foo: number } {
return x;
}
function foo4(x: { [key: string]: number }): {
[key: string]: number,
foo: string
} {
return x;
}
function foo5(x: Array<{ [key: string]: number }>): Array<{ foo: number }> {
return x;
}
function foo6(x: Array<{ foo: number }>): Array<{ [key: string]: number }> {
return x;
}
function foo7(x: { [key: string]: number, bar: string }) {
(x.bar: string);
}
function foo8(x: { [key: string]: number }) {
(x.foo: string);
(x.foo: number);
}
"
`;
@ -493,25 +821,28 @@ class B {
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
// no error
// no error
// no error
// no error
class A {
x: { [k: string]: number };
m1() {
this.x = { bar: 0 };// no error
this.x = { bar: [object Number] };
}
m2() {
this.x.foo = 0;// no error
this.x.foo = [object Number];
}
}
class B {
x: { [k: string]: number };
m2() {
this.x.foo = 0;// no error
this.x.foo = [object Number];
}
m1() {
this.x = { bar: 0 };// no error
this.x = { bar: [object Number] };
}
}
"
`;
@ -527,35 +858,29 @@ var o: { foo: QueryFunction } = {
module.exports = o;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1348
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1348:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1481:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// error, number ~/~ string
type Params = { [name: string]: string, count: number };
type QueryFunction = : (params: Params) => string;
var o: { foo: QueryFunction } = {
foo(params) {
return params.count;
}
};
module.exports = o;
"
`;
exports[`test test_client.js 1`] = `
"var o = require(\'./test\');
"var o = require('./test');
o.foo = function (params) {
return params.count; // error, number ~/~ string
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
var o = require(\"./test\");
// error, number ~/~ string
var o = require("./test");
o.foo = function(params) {
return params.count;// error, number ~/~ string
return params.count;
};
"
`;

File diff suppressed because it is too large Load Diff

View File

@ -6,8 +6,8 @@ exports[`test license_with_flow.js 1`] = `
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* Copyright example */
/* @flow */
("": void);// error
// error
("": void);
"
`;
@ -21,7 +21,14 @@ exports[`test max_header_tokens.js 1`] = `
* @flow
*/
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
/* second token */
/* third token */
/**
* After max_header_tokens (in .flowconfig), we no longer care:
*
* @flow
*/
"
`;
@ -30,7 +37,8 @@ exports[`test multiple_flows_1.js 1`] = `
"/* @flow */
/* @flow */
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
/* @flow */
"
`;
@ -41,7 +49,10 @@ exports[`test multiple_flows_2.js 1`] = `
* @noflow
*/
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* @flow
* @noflow
*/
"
`;
@ -53,7 +64,11 @@ exports[`test multiple_providesModule_1.js 1`] = `
* @flow
*/
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* @providesModule Foo
* @providesModule Bar
* @flow
*/
"
`;
@ -67,7 +82,13 @@ exports[`test multiple_providesModule_2.js 1`] = `
* @providesModule Bar
*/
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* @providesModule Foo
* @flow
*/
/**
* @providesModule Bar
*/
"
`;
@ -78,10 +99,10 @@ exports[`test use_strict_with_flow.js 1`] = `
("": void); // error
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"use strict";
/* @flow */
("": void);// error
// error
"use strict";
("": void);
"
`;
@ -91,8 +112,8 @@ exports[`test with_flow.js 1`] = `
("": void); // error
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
("": void);// error
// error
("": void);
"
`;
@ -102,7 +123,7 @@ exports[`test without_flow.js 1`] = `
("": void); // no error
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* some other comment */
("": void);// no error
// no error
("": void);
"
`;

View File

@ -9,22 +9,27 @@ let tests = [
// moveTo
function(ctx: CanvasRenderingContext2D) {
ctx.moveTo(\'0\', \'1\'); // error: should be numbers
ctx.moveTo('0', '1'); // error: should be numbers
},
];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
// fillRect
// moveTo
// error: should be numbers
let tests = [
// fillRect
function(ctx: CanvasRenderingContext2D) {
ctx.fillRect(0, 0, 200, 100);
ctx.fillRect(
[object Number],
[object Number],
[object Number],
[object Number]
);
},
// moveTo
function(ctx: CanvasRenderingContext2D) {
ctx.moveTo(\"0\", \"1\");// error: should be numbers
ctx.moveTo("0", "1");
}
];
"
`;
@ -34,20 +39,24 @@ exports[`test CustomEvent.js 1`] = `
let tests = [
// CustomEvent
function(document: Document) {
const event = document.createEvent(\'CustomEvent\');
event.initCustomEvent(\'butts\', true, false, { nice: 42 });
const event = document.createEvent('CustomEvent');
event.initCustomEvent('butts', true, false, { nice: 42 });
}
];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
// CustomEvent
let tests = [
// CustomEvent
function(document: Document) {
const event = document.createEvent(\"CustomEvent\");
event.initCustomEvent(\"butts\", true, false, { nice: 42 });
const event = document.createEvent("CustomEvent");
event.initCustomEvent(
"butts",
[object Boolean],
[object Boolean],
{ nice: [object Number] }
);
}
];
"
`;
@ -57,24 +66,23 @@ exports[`test Document.js 1`] = `
let tests = [
// createElement
function(document: Document) {
(document.createElement(\'canvas\'): HTMLCanvasElement);
(document.createElement(\'link\'): HTMLLinkElement);
(document.createElement(\'option\'): HTMLOptionElement);
(document.createElement(\'select\'): HTMLSelectElement);
(document.createElement('canvas'): HTMLCanvasElement);
(document.createElement('link'): HTMLLinkElement);
(document.createElement('option'): HTMLOptionElement);
(document.createElement('select'): HTMLSelectElement);
}
];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
// createElement
let tests = [
// createElement
function(document: Document) {
(document.createElement(\"canvas\"): HTMLCanvasElement);
(document.createElement(\"link\"): HTMLLinkElement);
(document.createElement(\"option\"): HTMLOptionElement);
(document.createElement(\"select\"): HTMLSelectElement);
(document.createElement("canvas"): HTMLCanvasElement);
(document.createElement("link"): HTMLLinkElement);
(document.createElement("option"): HTMLOptionElement);
(document.createElement("select"): HTMLSelectElement);
}
];
"
`;
@ -87,34 +95,33 @@ let tests = [
element.scrollIntoView();
element.scrollIntoView(false);
element.scrollIntoView({});
element.scrollIntoView({ behavior: \'smooth\', block: \'end\' });
element.scrollIntoView({ block: \'end\' });
element.scrollIntoView({ behavior: \'smooth\' });
element.scrollIntoView({ behavior: 'smooth', block: 'end' });
element.scrollIntoView({ block: 'end' });
element.scrollIntoView({ behavior: 'smooth' });
// fails
element.scrollIntoView({ behavior: \'invalid\' });
element.scrollIntoView({ block: \'invalid\' });
element.scrollIntoView({ behavior: 'invalid' });
element.scrollIntoView({ block: 'invalid' });
element.scrollIntoView(1);
}
];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
// scrollIntoView
// fails
let tests = [
// scrollIntoView
function(element: Element) {
element.scrollIntoView();
element.scrollIntoView(false);
element.scrollIntoView([object Boolean]);
element.scrollIntoView({});
element.scrollIntoView({ behavior: \"smooth\", block: \"end\" });
element.scrollIntoView({ block: \"end\" });
element.scrollIntoView({ behavior: \"smooth\" });
// fails
element.scrollIntoView({ behavior: \"invalid\" });
element.scrollIntoView({ block: \"invalid\" });
element.scrollIntoView(1);
element.scrollIntoView({ behavior: "smooth", block: "end" });
element.scrollIntoView({ block: "end" });
element.scrollIntoView({ behavior: "smooth" });
element.scrollIntoView({ behavior: "invalid" });
element.scrollIntoView({ block: "invalid" });
element.scrollIntoView([object Number]);
}
];
"
`;
@ -124,18 +131,17 @@ exports[`test HTMLCanvasElement.js 1`] = `
let tests = [
// getContext
function(el: HTMLCanvasElement) {
(el.getContext(\'2d\'): ?CanvasRenderingContext2D);
(el.getContext('2d'): ?CanvasRenderingContext2D);
}
];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
// getContext
let tests = [
// getContext
function(el: HTMLCanvasElement) {
(el.getContext(\"2d\"): ?CanvasRenderingContext2D);
(el.getContext("2d"): ?CanvasRenderingContext2D);
}
];
"
`;
@ -148,34 +154,33 @@ let tests = [
element.scrollIntoView();
element.scrollIntoView(false);
element.scrollIntoView({});
element.scrollIntoView({ behavior: \'smooth\', block: \'end\' });
element.scrollIntoView({ block: \'end\' });
element.scrollIntoView({ behavior: \'smooth\' });
element.scrollIntoView({ behavior: 'smooth', block: 'end' });
element.scrollIntoView({ block: 'end' });
element.scrollIntoView({ behavior: 'smooth' });
// fails
element.scrollIntoView({ behavior: \'invalid\' });
element.scrollIntoView({ block: \'invalid\' });
element.scrollIntoView({ behavior: 'invalid' });
element.scrollIntoView({ block: 'invalid' });
element.scrollIntoView(1);
}
];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
// scrollIntoView
// fails
let tests = [
// scrollIntoView
function(element: HTMLElement) {
element.scrollIntoView();
element.scrollIntoView(false);
element.scrollIntoView([object Boolean]);
element.scrollIntoView({});
element.scrollIntoView({ behavior: \"smooth\", block: \"end\" });
element.scrollIntoView({ block: \"end\" });
element.scrollIntoView({ behavior: \"smooth\" });
// fails
element.scrollIntoView({ behavior: \"invalid\" });
element.scrollIntoView({ block: \"invalid\" });
element.scrollIntoView(1);
element.scrollIntoView({ behavior: "smooth", block: "end" });
element.scrollIntoView({ block: "end" });
element.scrollIntoView({ behavior: "smooth" });
element.scrollIntoView({ behavior: "invalid" });
element.scrollIntoView({ block: "invalid" });
element.scrollIntoView([object Number]);
}
];
"
`;
@ -185,35 +190,36 @@ exports[`test HTMLInputElement.js 1`] = `
let tests = [
// setRangeText
function(el: HTMLInputElement) {
el.setRangeText(\'foo\');
el.setRangeText(\'foo\', 123); // end is required
el.setRangeText(\'foo\', 123, 234);
el.setRangeText(\'foo\', 123, 234, \'select\');
el.setRangeText(\'foo\', 123, 234, \'bogus\'); // invalid value
el.setRangeText('foo');
el.setRangeText('foo', 123); // end is required
el.setRangeText('foo', 123, 234);
el.setRangeText('foo', 123, 234, 'select');
el.setRangeText('foo', 123, 234, 'bogus'); // invalid value
}
];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
// setRangeText
// end is required
// invalid value
let tests = [
// setRangeText
function(el: HTMLInputElement) {
el.setRangeText(\"foo\");
el.setRangeText(\"foo\", 123);// end is required
el.setRangeText(\"foo\", 123, 234);
el.setRangeText(\"foo\", 123, 234, \"select\");
el.setRangeText(\"foo\", 123, 234, \"bogus\");// invalid value
el.setRangeText("foo");
el.setRangeText("foo", [object Number]);
el.setRangeText("foo", [object Number], [object Number]);
el.setRangeText("foo", [object Number], [object Number], "select");
el.setRangeText("foo", [object Number], [object Number], "bogus");
}
];
"
`;
exports[`test URL.js 1`] = `
"/* @flow */
const a = new URL(\'http://flowtype.org/\'); // correct
const b = new URL(\'/docs\', a); // correct
const c = new URL(\'/docs\', \'http://flowtype.org/\'); // correct
const a = new URL('http://flowtype.org/'); // correct
const b = new URL('/docs', a); // correct
const c = new URL('/docs', 'http://flowtype.org/'); // correct
const d: URLSearchParams = c.searchParams; // correct
const e: string = c.path; // not correct
@ -231,24 +237,40 @@ const q: string = c.search; // correct
const r: string = c.username; // correct
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow */
const a = new URL(\"http://flowtype.org/\");// correct
const b = new URL(\"/docs\", a);// correct
const c = new URL(\"/docs\", \"http://flowtype.org/\");// correct
const d: URLSearchParams = c.searchParams;// correct
const e: string = c.path;// not correct
const f: string = c.pathname;// correct
const g: string = c.hash;// correct
const h: string = c.host;// correct
const i: string = c.hostname;// correct
const j: string = c.href;// correct
const l: string = c.origin;// correct
const m: string = c.password;// correct
const n: string = c.pathname;// correct
const o: string = c.port;// correct
const p: string = c.protocol;// correct
const q: string = c.search;// correct
const r: string = c.username;// correct
// correct
// correct
// correct
// correct
// not correct
// correct
// correct
// correct
// correct
// correct
// correct
// correct
// correct
// correct
// correct
// correct
// correct
const a = new URL("http://flowtype.org/");
const b = new URL("/docs", a);
const c = new URL("/docs", "http://flowtype.org/");
const d: URLSearchParams = c.searchParams;
const e: string = c.path;
const f: string = c.pathname;
const g: string = c.hash;
const h: string = c.host;
const i: string = c.hostname;
const j: string = c.href;
const l: string = c.origin;
const m: string = c.password;
const n: string = c.pathname;
const o: string = c.port;
const p: string = c.protocol;
const q: string = c.search;
const r: string = c.username;
"
`;
@ -261,15 +283,15 @@ let tests = [
// attachEvent
function() {
let target = new EventTarget();
(target.attachEvent(\'foo\', listener): void); // invalid, may be undefined
(target.attachEvent && target.attachEvent(\'foo\', listener): void); // valid
(target.attachEvent('foo', listener): void); // invalid, may be undefined
(target.attachEvent && target.attachEvent('foo', listener): void); // valid
},
// detachEvent
function() {
let target = new EventTarget();
(target.detachEvent(\'foo\', listener): void); // invalid, may be undefined
(target.detachEvent && target.detachEvent(\'foo\', listener): void); // valid
(target.detachEvent('foo', listener): void); // invalid, may be undefined
(target.detachEvent && target.detachEvent('foo', listener): void); // valid
},
function() {
@ -280,21 +302,25 @@ let tests = [
];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
// attachEvent
// invalid, may be undefined
// valid
// detachEvent
// invalid, may be undefined
// valid
let listener: EventListener = function(event: Event): void {
};
let tests = [
// attachEvent
function() {
let target = new EventTarget();
(target.attachEvent(\"foo\", listener): void);// invalid, may be undefined
(target.attachEvent && target.attachEvent(\"foo\", listener): void);// valid
(target.attachEvent("foo", listener): void);
(target.attachEvent && target.attachEvent("foo", listener): void);
},
// detachEvent
function() {
let target = new EventTarget();
(target.detachEvent(\"foo\", listener): void);// invalid, may be undefined
(target.detachEvent && target.detachEvent(\"foo\", listener): void);// valid
(target.detachEvent("foo", listener): void);
(target.detachEvent && target.detachEvent("foo", listener): void);
},
function() {
window.onmessage = (event: MessageEvent) => {
@ -302,7 +328,6 @@ let tests = [
};
}
];
"
`;
@ -315,21 +340,45 @@ let tests = [
let path = new Path2D();
(path.arcTo(0, 0, 0, 0, 10): void); // valid
(path.arcTo(0, 0, 0, 0, 10, 20, 5): void); // valid
(path.arcTo(0, 0, 0, 0, 10, \'20\', 5): void); // invalid
(path.arcTo(0, 0, 0, 0, 10, '20', 5): void); // invalid
},
];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
// arcTo
// valid
// valid
// invalid
let tests = [
// arcTo
function() {
let path = new Path2D();
(path.arcTo(0, 0, 0, 0, 10): void);// valid
(path.arcTo(0, 0, 0, 0, 10, 20, 5): void);// valid
(path.arcTo(0, 0, 0, 0, 10, \"20\", 5): void);// invalid
(path.arcTo(
[object Number],
[object Number],
[object Number],
[object Number],
[object Number]
): void);
(path.arcTo(
[object Number],
[object Number],
[object Number],
[object Number],
[object Number],
[object Number],
[object Number]
): void);
(path.arcTo(
[object Number],
[object Number],
[object Number],
[object Number],
[object Number],
"20",
[object Number]
): void);
}
];
"
`;
@ -339,7 +388,7 @@ exports[`test registerElement.js 1`] = `
let tests = [
// should work with Object.create()
function() {
document.registerElement(\'custom-element\', {
document.registerElement('custom-element', {
prototype: Object.create(HTMLElement.prototype, {
createdCallback: { value: function createdCallback () {
}},
@ -361,7 +410,7 @@ let tests = [
},
// or with Object.assign()
function() {
document.registerElement(\'custom-element\', {
document.registerElement('custom-element', {
prototype: Object.assign(Object.create(HTMLElement.prototype), {
createdCallback () {
},
@ -381,7 +430,7 @@ let tests = [
},
// should complain about invalid callback parameters
function() {
document.registerElement(\'custom-element\', {
document.registerElement('custom-element', {
prototype: {
attributeChangedCallback(
localName: string,
@ -394,11 +443,15 @@ let tests = [
];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
// should work with Object.create()
// or with Object.assign()
// should complain about invalid callback parameters
// Error: This might be null
// Error: This might be null
let tests = [
// should work with Object.create()
function() {
document.registerElement(
\"custom-element\",
"custom-element",
{
prototype: Object.create(
HTMLElement.prototype,
@ -433,10 +486,9 @@ let tests = [
}
);
},
// or with Object.assign()
function() {
document.registerElement(
\"custom-element\",
"custom-element",
{
prototype: Object.assign(
Object.create(HTMLElement.prototype),
@ -461,16 +513,13 @@ let tests = [
}
);
},
// should complain about invalid callback parameters
function() {
document.registerElement(
\"custom-element\",
"custom-element",
{
prototype: {
attributeChangedCallback(localName: string,
// Error: This might be null
oldVal: string,
// Error: This might be null
newVal: string,
namespace: string) {
@ -480,7 +529,6 @@ let tests = [
);
}
];
"
`;
@ -667,34 +715,260 @@ let tests = [
// NodeFilterInterface
function() {
document.createNodeIterator(document.body, -1, node => NodeFilter.FILTER_ACCEPT); // valid
document.createNodeIterator(document.body, -1, node => \'accept\'); // invalid
document.createNodeIterator(document.body, -1, node => 'accept'); // invalid
document.createNodeIterator(document.body, -1, { accept: node => NodeFilter.FILTER_ACCEPT }); // valid
document.createNodeIterator(document.body, -1, { accept: node => \'accept\' }); // invalid
document.createNodeIterator(document.body, -1, { accept: node => 'accept' }); // invalid
document.createNodeIterator(document.body, -1, {}); // invalid
},
function() {
document.createTreeWalker(document.body, -1, node => NodeFilter.FILTER_ACCEPT); // valid
document.createTreeWalker(document.body, -1, node => \'accept\'); // invalid
document.createTreeWalker(document.body, -1, node => 'accept'); // invalid
document.createTreeWalker(document.body, -1, { accept: node => NodeFilter.FILTER_ACCEPT }); // valid
document.createTreeWalker(document.body, -1, { accept: node => \'accept\' }); // invalid
document.createTreeWalker(document.body, -1, { accept: node => 'accept' }); // invalid
document.createTreeWalker(document.body, -1, {}); // invalid
},
];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1497
fromString(\", \").join(path.map(print, \"params\")),
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1497:26)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1374:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// @flow
// basic functionality
// rootNode must be a Node
// valid
// invalid
// invalid
// Type Parameters
// NodeFilterInterface
// valid
// invalid
// valid
// invalid
// invalid
// valid
// invalid
// valid
// invalid
// invalid
let tests = [
function() {
const i: NodeIterator<*, *> = document.createNodeIterator(document.body);
const filter: NodeFilter = i.filter;
const response: typeof NodeFilter.FILTER_ACCEPT | typeof NodeFilter.FILTER_REJECT | typeof NodeFilter.FILTER_SKIP = filter.acceptNode(
document.body
);
},
function() {
const w: TreeWalker<*, *> = document.createTreeWalker(document.body);
const filter: NodeFilter = w.filter;
const response: typeof NodeFilter.FILTER_ACCEPT | typeof NodeFilter.FILTER_REJECT | typeof NodeFilter.FILTER_SKIP = filter.acceptNode(
document.body
);
},
function() {
document.createNodeIterator(document.body);
document.createNodeIterator({});
},
function() {
document.createTreeWalker(document.body);
document.createTreeWalker({});
},
function() {
const _root = document.body;
const i = document.createNodeIterator(_root, NodeFilter.SHOW_ELEMENT);
const root: typeof _root = i.root;
const referenceNode: typeof _root | Element = i.referenceNode;
const previousNode: Element | null = i.previousNode();
const nextNode: Element | null = i.nextNode();
},
function() {
const _root = document.body.attributes[[object Number]];
const i = document.createNodeIterator(_root, NodeFilter.SHOW_ATTRIBUTE);
const root: typeof _root = i.root;
const referenceNode: typeof _root | Attr = i.referenceNode;
const previousNode: Attr | null = i.previousNode();
const nextNode: Attr | null = i.nextNode();
},
function() {
const _root = document.body;
const i = document.createNodeIterator(_root, NodeFilter.SHOW_TEXT);
const root: typeof _root = i.root;
const referenceNode: typeof _root | Text = i.referenceNode;
const previousNode: Text | null = i.previousNode();
const nextNode: Text | null = i.nextNode();
},
function() {
const _root = document;
const i = document.createNodeIterator(_root, NodeFilter.SHOW_DOCUMENT);
const root: typeof _root = i.root;
const referenceNode: typeof _root | Document = i.referenceNode;
const previousNode: Document | null = i.previousNode();
const nextNode: Document | null = i.nextNode();
},
function() {
const _root = document;
const i = document.createNodeIterator(_root, NodeFilter.SHOW_DOCUMENT_TYPE);
const root: typeof _root = i.root;
const referenceNode: typeof _root | DocumentType = i.referenceNode;
const previousNode: DocumentType | null = i.previousNode();
const nextNode: DocumentType | null = i.nextNode();
},
function() {
const _root = document.createDocumentFragment();
const i = document.createNodeIterator(
_root,
NodeFilter.SHOW_DOCUMENT_FRAGMENT
);
const root: typeof _root = i.root;
const referenceNode: typeof _root | DocumentFragment = i.referenceNode;
const previousNode: DocumentFragment | null = i.previousNode();
const nextNode: DocumentFragment | null = i.nextNode();
},
function() {
const _root = document.body;
const i = document.createNodeIterator(_root, NodeFilter.SHOW_ALL);
const root: typeof _root = i.root;
const referenceNode: typeof _root | Node = i.referenceNode;
const previousNode: Node | null = i.previousNode();
const nextNode: Node | null = i.nextNode();
},
function() {
const _root = document.body;
const w = document.createTreeWalker(_root, NodeFilter.SHOW_ELEMENT);
const root: typeof _root = w.root;
const currentNode: typeof _root | Element = w.currentNode;
const parentNode: Element | null = w.parentNode();
const firstChild: Element | null = w.firstChild();
const lastChild: Element | null = w.lastChild();
const previousSibling: Element | null = w.previousSibling();
const nextSibling: Element | null = w.nextSibling();
const previousNode: Element | null = w.previousNode();
const nextNode: Element | null = w.nextNode();
},
function() {
const _root = document.body.attributes[[object Number]];
const w = document.createTreeWalker(_root, NodeFilter.SHOW_ATTRIBUTE);
const root: typeof _root = w.root;
const currentNode: typeof _root | Attr = w.currentNode;
const parentNode: Attr | null = w.parentNode();
const firstChild: Attr | null = w.firstChild();
const lastChild: Attr | null = w.lastChild();
const previousSibling: Attr | null = w.previousSibling();
const nextSibling: Attr | null = w.nextSibling();
const previousNode: Attr | null = w.previousNode();
const nextNode: Attr | null = w.nextNode();
},
function() {
const _root = document.body;
const w = document.createTreeWalker(_root, NodeFilter.SHOW_TEXT);
const root: typeof _root = w.root;
const currentNode: typeof _root | Text = w.currentNode;
const parentNode: Text | null = w.parentNode();
const firstChild: Text | null = w.firstChild();
const lastChild: Text | null = w.lastChild();
const previousSibling: Text | null = w.previousSibling();
const nextSibling: Text | null = w.nextSibling();
const previousNode: Text | null = w.previousNode();
const nextNode: Text | null = w.nextNode();
},
function() {
const _root = document;
const w = document.createTreeWalker(_root, NodeFilter.SHOW_DOCUMENT);
const root: typeof _root = w.root;
const currentNode: typeof _root | Document = w.currentNode;
const parentNode: Document | null = w.parentNode();
const firstChild: Document | null = w.firstChild();
const lastChild: Document | null = w.lastChild();
const previousSibling: Document | null = w.previousSibling();
const nextSibling: Document | null = w.nextSibling();
const previousNode: Document | null = w.previousNode();
const nextNode: Document | null = w.nextNode();
},
function() {
const _root = document;
const w = document.createTreeWalker(_root, NodeFilter.SHOW_DOCUMENT_TYPE);
const root: typeof _root = w.root;
const currentNode: typeof _root | DocumentType = w.currentNode;
const parentNode: DocumentType | null = w.parentNode();
const firstChild: DocumentType | null = w.firstChild();
const lastChild: DocumentType | null = w.lastChild();
const previousSibling: DocumentType | null = w.previousSibling();
const nextSibling: DocumentType | null = w.nextSibling();
const previousNode: DocumentType | null = w.previousNode();
const nextNode: DocumentType | null = w.nextNode();
},
function() {
const _root = document.createDocumentFragment();
const w = document.createTreeWalker(
_root,
NodeFilter.SHOW_DOCUMENT_FRAGMENT
);
const root: typeof _root = w.root;
const currentNode: typeof _root | DocumentFragment = w.currentNode;
const parentNode: DocumentFragment | null = w.parentNode();
const firstChild: DocumentFragment | null = w.firstChild();
const lastChild: DocumentFragment | null = w.lastChild();
const previousSibling: DocumentFragment | null = w.previousSibling();
const nextSibling: DocumentFragment | null = w.nextSibling();
const previousNode: DocumentFragment | null = w.previousNode();
const nextNode: DocumentFragment | null = w.nextNode();
},
function() {
const _root = document.body;
const w = document.createTreeWalker(_root, NodeFilter.SHOW_ALL);
const root: typeof _root = w.root;
const currentNode: typeof _root | Node = w.currentNode;
const parentNode: Node | null = w.parentNode();
const firstChild: Node | null = w.firstChild();
const lastChild: Node | null = w.lastChild();
const previousSibling: Node | null = w.previousSibling();
const nextSibling: Node | null = w.nextSibling();
const previousNode: Node | null = w.previousNode();
const nextNode: Node | null = w.nextNode();
},
function() {
document.createNodeIterator(
document.body,
-[object Number],
node => NodeFilter.FILTER_ACCEPT
);
document.createNodeIterator(
document.body,
-[object Number],
node => "accept"
);
document.createNodeIterator(
document.body,
-[object Number],
{ accept: node => NodeFilter.FILTER_ACCEPT }
);
document.createNodeIterator(
document.body,
-[object Number],
{ accept: node => "accept" }
);
document.createNodeIterator(document.body, -[object Number], {});
},
function() {
document.createTreeWalker(
document.body,
-[object Number],
node => NodeFilter.FILTER_ACCEPT
);
document.createTreeWalker(
document.body,
-[object Number],
node => "accept"
);
document.createTreeWalker(
document.body,
-[object Number],
{ accept: node => NodeFilter.FILTER_ACCEPT }
);
document.createTreeWalker(
document.body,
-[object Number],
{ accept: node => "accept" }
);
document.createTreeWalker(document.body, -[object Number], {});
}
];
"
`;

View File

@ -6,19 +6,18 @@ bar();
module.exports = num;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// @flow
var num = 42;
var num = [object Number];
function bar() {
}
bar();
module.exports = num;
"
`;
exports[`test test.js 1`] = `
"// @flow
var num = require(\'./import\');
var num = require('./import');
function foo(x) { }
foo(0);
var a:string = num;
@ -39,20 +38,32 @@ declare var idx: $Facebookism$Idx;
declare var obj: {a?: {b: ?{c: null | {d: number}}}};
const idxResult = idx(obj, obj => obj.a.b.c.d);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/src/printer.js:1530
return fromString(\" | \").join(path.map(print, \"types\"));
^
TypeError: fromString(...).join is not a function
at genericPrintNoParens (/src/printer.js:1530:32)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
at printGenerically (/src/printer.js:111:12)
at FastPath.call (/src/fast-path.js:113:16)
at genericPrintNoParens (/src/printer.js:1452:14)
at genericPrint (/src/printer.js:166:7)
at p (/src/printer.js:111:37)
at exports.printComments (/src/comments.js:327:20)
// @flow
// test deduping of inferred types
var num = require("./import");
function foo(x) {
}
foo([object Number]);
var a: string = num;
function unannotated(x) {
return x;
}
const nullToUndefined = val => (val === [object Null] ? undefined : val);
function f0(x: ?Object) {
return nullToUndefined(x);
}
function f1(x: ?Object) {
return nullToUndefined(x);
}
function f2(x: ?string) {
return nullToUndefined(x);
}
function f3(x: ?string) {
return nullToUndefined(x);
}
declare var idx: $Facebookism$Idx;
declare var obj: { a?: { b: ?{ c: null | { d: number } } } };
const idxResult = idx(obj, obj => obj.a.b.c.d);
"
`;

View File

@ -46,7 +46,7 @@ class C1 {
new C1().m();
class C2 {
get m() {
return 42;
return [object Number];
}
m() {
@ -64,25 +64,24 @@ class C3 {
new C3().m();
class C4 {
get m() {
return 42;
return [object Number];
}
set m(x: number) {
}
}
new C4().m = new C4().m - 42;
new C4().m = new C4().m - [object Number];
class C5 {
m() {
}
get m() {
return 42;
return [object Number];
}
set m(x: number) {
}
}
new C5().m = new C5().m - 42;
new C5().m = new C5().m - [object Number];
"
`;

Some files were not shown because too many files have changed in this diff Show More