update snapshots
parent
599e5821c1
commit
9acd34d67d
|
@ -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
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
// @flow
|
||||
|
||||
break; // error, illegal
|
|
@ -1,3 +0,0 @@
|
|||
// @flow
|
||||
|
||||
continue; // error, illegal
|
|
@ -1,3 +0,0 @@
|
|||
// @flow
|
||||
|
||||
return; // error, illegal
|
|
@ -1,3 +0,0 @@
|
|||
// @flow
|
||||
|
||||
throw new Error('foo'); // no error
|
|
@ -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);
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
];
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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);
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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 ];
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
);
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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);
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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]];
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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;
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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 };
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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: \"\" } };
|
||||
|
||||
"
|
||||
`;
|
|
@ -2,6 +2,5 @@ exports[`test client.js 1`] = `
|
|||
"var y:number = x;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
var y: number = x;
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -2,6 +2,5 @@ exports[`test lib.js 1`] = `
|
|||
"declare var x: string;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
declare var x: string;
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
];
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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);
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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();
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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]);
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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);
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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;
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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";
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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]);
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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];
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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 };
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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] });
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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());
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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>);
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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();
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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]);
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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]]();
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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";
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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";
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -5,6 +5,5 @@ x.length;
|
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
var x;
|
||||
x.length;
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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!");
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -7,6 +7,5 @@ var x: number = "string";
|
|||
/* @flow */
|
||||
// No error, this file is ignored
|
||||
var x: number = "string";
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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";
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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;
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -4,7 +4,6 @@ exports[`test testmodule.js 1`] = `
|
|||
export let test = 42;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// @flow
|
||||
export let test = 42;
|
||||
|
||||
export let test = [object Number];
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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";
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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] };
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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] };
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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");
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -5,6 +5,5 @@ export var name: "otherdir/testproj" = "otherdir/testproj";
|
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// @flow
|
||||
export var name: "otherdir/testproj" = "otherdir/testproj";
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -5,6 +5,5 @@ export var name: "otherdir/testproj2" = "otherdir/testproj2";
|
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// @flow
|
||||
export var name: "otherdir/testproj2" = "otherdir/testproj2";
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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");
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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";
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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";
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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";
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -20,6 +20,5 @@ class D {
|
|||
}
|
||||
}
|
||||
module.exports = C;
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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();
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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;
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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;
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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());
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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);
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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 {}
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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;
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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"
|
||||
);
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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);
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -2,6 +2,5 @@ exports[`test min.js 1`] = `
|
|||
"module.exports.fun = (): string => "hello there";
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
module.exports.fun = (): string => "hello there";
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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);
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
exports[`test index.js 1`] = `
|
||||
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -2,6 +2,5 @@ exports[`test client.js 1`] = `
|
|||
"var ws = require('../');
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
var ws = require("../");
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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);
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -4,6 +4,5 @@ module.exports.fun = (): Implementation => new Implementation;
|
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class Implementation {}
|
||||
module.exports.fun = (): Implementation => new Implementation();
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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);
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
exports[`test index.js 1`] = `
|
||||
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -2,6 +2,5 @@ exports[`test client.js 1`] = `
|
|||
"var ws = require('../');
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
var ws = require("../");
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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);
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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);
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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);
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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);
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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>);
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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 };
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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 };
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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);
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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();
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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");
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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], {});
|
||||
}
|
||||
];
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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);
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue