Add special case for comment at top of file; regenerate snapshots
parent
74fc539e1a
commit
a4643f1bae
|
@ -79,7 +79,8 @@ function decorateComment(node, comment, text) {
|
||||||
if (locStart(child) - locStart(comment) <= 0 &&
|
if (locStart(child) - locStart(comment) <= 0 &&
|
||||||
locEnd(comment) - locEnd(child) <= 0) {
|
locEnd(comment) - locEnd(child) <= 0) {
|
||||||
// The comment is completely contained by this child node.
|
// The comment is completely contained by this child node.
|
||||||
decorateComment(comment.enclosingNode = child, comment, text);
|
comment.enclosingNode = child;
|
||||||
|
decorateComment(child, comment, text);
|
||||||
return; // Abandon the binary search at this level.
|
return; // Abandon the binary search at this level.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,7 +164,7 @@ exports.attach = function(comments, ast, text) {
|
||||||
addDanglingComment(en, comment);
|
addDanglingComment(en, comment);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error("AST contains no nodes at all?");
|
// throw new Error("AST contains no nodes at all?");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -271,9 +272,12 @@ function printTrailingComment(commentPath, print, options) {
|
||||||
|
|
||||||
exports.printComments = function(path, print, options) {
|
exports.printComments = function(path, print, options) {
|
||||||
var value = path.getValue();
|
var value = path.getValue();
|
||||||
|
var parent = path.getParentNode();
|
||||||
var printed = print(path);
|
var printed = print(path);
|
||||||
var comments = n.Node.check(value) &&
|
var comments = n.Node.check(value) &&
|
||||||
types.getFieldValue(value, "comments");
|
types.getFieldValue(value, "comments");
|
||||||
|
var isFirstInProgram = n.Program.check(parent) &&
|
||||||
|
parent.body[0] === value;
|
||||||
|
|
||||||
if (!comments || comments.length === 0) {
|
if (!comments || comments.length === 0) {
|
||||||
return printed;
|
return printed;
|
||||||
|
@ -291,6 +295,15 @@ exports.printComments = function(path, print, options) {
|
||||||
comment.type === "Block" ||
|
comment.type === "Block" ||
|
||||||
comment.type === "CommentBlock"))) {
|
comment.type === "CommentBlock"))) {
|
||||||
leadingParts.push(printLeadingComment(commentPath, print));
|
leadingParts.push(printLeadingComment(commentPath, print));
|
||||||
|
|
||||||
|
|
||||||
|
// Support a special case where a comment exists at the very top
|
||||||
|
// of the file. Allow the user to add spacing between that file
|
||||||
|
// and any code beneath it.
|
||||||
|
if(isFirstInProgram &&
|
||||||
|
util.newlineExistsAfter(options.originalText, util.locEnd(comment))) {
|
||||||
|
leadingParts.push(hardline);
|
||||||
|
}
|
||||||
} else if (trailing) {
|
} else if (trailing) {
|
||||||
trailingParts.push(printTrailingComment(commentPath, print, options));
|
trailingParts.push(printTrailingComment(commentPath, print, options));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1551,8 +1551,6 @@ function genericPrintNoParens(path, options, print) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function printStatementSequence(path, options, print) {
|
function printStatementSequence(path, options, print) {
|
||||||
let inClassBody = namedTypes.ClassBody &&
|
|
||||||
namedTypes.ClassBody.check(path.getParentNode());
|
|
||||||
let printed = [];
|
let printed = [];
|
||||||
|
|
||||||
path.map(function(stmtPath, i) {
|
path.map(function(stmtPath, i) {
|
||||||
|
@ -1571,11 +1569,13 @@ function printStatementSequence(path, options, print) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const stmtPrinted = print(stmtPath);
|
const stmtPrinted = print(stmtPath);
|
||||||
|
const text = options.originalText;
|
||||||
const parts = [];
|
const parts = [];
|
||||||
|
|
||||||
parts.push(stmtPrinted);
|
parts.push(stmtPrinted);
|
||||||
|
|
||||||
if (shouldAddSpacing(stmt, options) && !isLastStatement(stmtPath)) {
|
if (util.newlineExistsAfter(text, util.locEnd(stmt)) &&
|
||||||
|
!isLastStatement(stmtPath)) {
|
||||||
parts.push(hardline);
|
parts.push(hardline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2008,11 +2008,6 @@ function nodeStr(str, options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function shouldAddSpacing(node, options) {
|
|
||||||
const text = options.originalText;
|
|
||||||
return util.newlineExistsAfter(text, util.locEnd(node));
|
|
||||||
}
|
|
||||||
|
|
||||||
function isFirstStatement(path) {
|
function isFirstStatement(path) {
|
||||||
const parent = path.getParentNode();
|
const parent = path.getParentNode();
|
||||||
const node = path.getValue();
|
const node = path.getValue();
|
||||||
|
|
|
@ -12,13 +12,13 @@ function foo() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function bar() {
|
function bar() {
|
||||||
L:
|
L:
|
||||||
do {
|
do {
|
||||||
continue L;
|
continue L;
|
||||||
} while (false);
|
} while (false);
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test return.js 1`] = `
|
exports[`test return.js 1`] = `
|
||||||
|
@ -35,6 +35,5 @@ function foo() {
|
||||||
if (x == null)
|
if (x == null)
|
||||||
return;
|
return;
|
||||||
bar(x);
|
bar(x);
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -60,45 +60,54 @@ var zer : null = null;
|
||||||
function foobar(n : ?number) : number | null | void { return n; }
|
function foobar(n : ?number) : number | null | void { return n; }
|
||||||
function barfoo(n : number | null | void) : ?number { return n; }
|
function barfoo(n : number | null | void) : ?number { return n; }
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// 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 {
|
function foo(str: string, i: number): string {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
var bar: (str: number, i: number) => string = foo;
|
var bar: (str: number, i: number) => string = foo;
|
||||||
|
|
||||||
var qux = function(str: string, i: number): number {
|
var qux = function(str: string, i: number): number {
|
||||||
return foo(str, i);
|
return foo(str, i);
|
||||||
};
|
};
|
||||||
|
|
||||||
var obj: { str: string, i: number, j: boolean } = {
|
var obj: { str: string, i: number, j: boolean } = {
|
||||||
str: \"...\",
|
str: \"...\",
|
||||||
i: \"...\",
|
i: \"...\",
|
||||||
k: false
|
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: number[][] = [ [ 1, 2 ], [ 3, 4 ] ];
|
||||||
var matrix_parens: number[][] = matrix;
|
var matrix_parens: number[][] = matrix;
|
||||||
|
|
||||||
var nullable_array: ?(number[]) = null;
|
var nullable_array: ?(number[]) = null;
|
||||||
var nullable_array_parens: ?(number[]) = nullable_array;
|
var nullable_array_parens: ?(number[]) = nullable_array;
|
||||||
|
|
||||||
var array_of_nullable: (?number)[] = [ null, 3 ];
|
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;
|
var array_of_tuple_parens: [number, string][] = array_of_tuple;
|
||||||
|
|
||||||
type ObjType = { \"bar-foo\": string, \"foo-bar\": number };
|
type ObjType = { \"bar-foo\": string, \"foo-bar\": number };
|
||||||
var test_obj: ObjType = { \"bar-foo\": \"23\" };
|
var test_obj: ObjType = { \"bar-foo\": \"23\" };
|
||||||
|
|
||||||
|
// param type annos are strict UBs like var type annos
|
||||||
function param_anno(n: number): void {
|
function param_anno(n: number): void {
|
||||||
n = \"hey\";
|
n = \"hey\"; // error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// another error on param UB, more typical of www (mis)use-cases
|
||||||
|
// this one cribbed from API.atlas.js
|
||||||
function param_anno2(
|
function param_anno2(
|
||||||
batchRequests: Array<{ method: string, path: string, params: ?Object }>
|
batchRequests: Array<{ method: string, path: string, params: ?Object }>
|
||||||
): void {
|
): void {
|
||||||
|
// 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.
|
||||||
batchRequests = batchRequests.map(request => {
|
batchRequests = batchRequests.map(request => {
|
||||||
return {
|
return {
|
||||||
method: request.method,
|
method: request.method,
|
||||||
|
@ -106,16 +115,19 @@ function param_anno2(
|
||||||
relative_url: request.path
|
relative_url: request.path
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
var toz: null = 3;
|
var toz: null = 3;
|
||||||
|
|
||||||
var zer: null = null;
|
var zer: null = null;
|
||||||
|
|
||||||
function foobar(n: ?number): number | null | void {
|
function foobar(n: ?number): number | null | void {
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
function barfoo(n: number | null | void): ?number {
|
function barfoo(n: number | null | void): ?number {
|
||||||
return n;
|
return n;
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test forward_ref.js 1`] = `
|
exports[`test forward_ref.js 1`] = `
|
||||||
|
@ -134,24 +146,23 @@ function foo() {
|
||||||
class MyClass { } // looked up above
|
class MyClass { } // looked up above
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// 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 = null;
|
let myClassInstance: MyClass = null;
|
||||||
|
// forward ref ok, null ~> class error
|
||||||
function bar(): MyClass {
|
function bar(): MyClass {
|
||||||
return null;
|
return null; // forward ref ok, null ~> class error
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyClass {}
|
class MyClass {}
|
||||||
|
// looked up above
|
||||||
function foo() {
|
function foo() {
|
||||||
let myClassInstance: MyClass = mk();
|
let myClassInstance: MyClass = mk();
|
||||||
|
// ok (no confusion across scopes)
|
||||||
function mk() {
|
function mk() {
|
||||||
return new MyClass();
|
return new MyClass();
|
||||||
}
|
}
|
||||||
class MyClass {}
|
|
||||||
}
|
class MyClass {} // looked up above
|
||||||
"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test issue-530.js 1`] = `
|
exports[`test issue-530.js 1`] = `
|
||||||
|
@ -160,8 +171,8 @@ exports[`test issue-530.js 1`] = `
|
||||||
module.exports = foo;
|
module.exports = foo;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
function foo(...args: any) {}
|
function foo(...args: any) {}
|
||||||
module.exports = foo;
|
|
||||||
"
|
module.exports = foo;"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test leak.js 1`] = `
|
exports[`test leak.js 1`] = `
|
||||||
|
@ -189,6 +200,7 @@ function bar(y: MyObj): string {
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/** @flow */
|
/** @flow */
|
||||||
|
|
||||||
/* This test documents an example we ran into of a type annotation leaking.
|
/* This test documents an example we ran into of a type annotation leaking.
|
||||||
*
|
*
|
||||||
* When foo() calls bar(), we should make sure the type of x matches the type
|
* When foo() calls bar(), we should make sure the type of x matches the type
|
||||||
|
@ -199,14 +211,16 @@ function bar(y: MyObj): string {
|
||||||
* and type checking the body of bar() using the stricter dictionary type,
|
* and type checking the body of bar() using the stricter dictionary type,
|
||||||
* leading to an error.
|
* leading to an error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
type MyObj = Object;
|
type MyObj = Object;
|
||||||
|
|
||||||
function foo(x: { [key: string]: mixed }) {
|
function foo(x: { [key: string]: mixed }) {
|
||||||
bar(x);
|
bar(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
function bar(y: MyObj): string {
|
function bar(y: MyObj): string {
|
||||||
return y.foo;
|
return y.foo;
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test other.js 1`] = `
|
exports[`test other.js 1`] = `
|
||||||
|
@ -214,8 +228,7 @@ exports[`test other.js 1`] = `
|
||||||
module.exports = (C: any);
|
module.exports = (C: any);
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
class C {}
|
class C {}
|
||||||
module.exports = (C: any);
|
module.exports = (C: any);"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test scope.js 1`] = `
|
exports[`test scope.js 1`] = `
|
||||||
|
@ -244,13 +257,16 @@ class Foo<A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// hypothetical immutable map
|
|
||||||
type Merge<T> = (a: T, b: T) => T;
|
type Merge<T> = (a: T, b: T) => T;
|
||||||
|
|
||||||
|
// hypothetical immutable map
|
||||||
declare class Map<K, V> {
|
declare class Map<K, V> {
|
||||||
(): Map<K, V>,
|
(): Map<K, V>,
|
||||||
insertWith(fn: Merge<V>, k: K, v: V): Map<K, V>
|
insertWith(fn: Merge<V>, k: K, v: V): Map<K, V>
|
||||||
}
|
}
|
||||||
|
|
||||||
declare function foldr<A, B>(fn: (a: A, b: B) => B, b: B, as: A[]): B;
|
declare function foldr<A, B>(fn: (a: A, b: B) => B, b: B, as: A[]): B;
|
||||||
|
|
||||||
function insertMany<K, V>(
|
function insertMany<K, V>(
|
||||||
merge: Merge<V>,
|
merge: Merge<V>,
|
||||||
vs: [K, V][],
|
vs: [K, V][],
|
||||||
|
@ -261,14 +277,14 @@ function insertMany<K, V>(
|
||||||
}
|
}
|
||||||
return foldr(f, m, vs);
|
return foldr(f, m, vs);
|
||||||
}
|
}
|
||||||
|
|
||||||
class Foo<A> {
|
class Foo<A> {
|
||||||
bar<B>() {
|
bar<B>() {
|
||||||
return function<C>(a: A, b: B, c: C): void {
|
return function<C>(a: A, b: B, c: C): void {
|
||||||
([ a, b, c ]: [A, B, C]);
|
([ a, b, c ]: [A, B, C]);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test test.js 1`] = `
|
exports[`test test.js 1`] = `
|
||||||
|
@ -276,6 +292,5 @@ exports[`test test.js 1`] = `
|
||||||
((0: C): string);
|
((0: C): string);
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
var C = require(\"./other\");
|
var C = require(\"./other\");
|
||||||
((0: C): string);
|
((0: C): string);"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -10,13 +10,14 @@ export default class {
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
type T = any;
|
type T = any;
|
||||||
|
|
||||||
export default class {
|
export default class {
|
||||||
p: T;
|
p: T;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.p = 0;
|
this.p = 0;
|
||||||
}
|
}
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test B.js 1`] = `
|
exports[`test B.js 1`] = `
|
||||||
|
@ -26,10 +27,9 @@ class B extends A {
|
||||||
p: string; // OK, string ~> any
|
p: string; // OK, string ~> any
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// OK, string ~> any
|
|
||||||
import A from \"./A\";
|
import A from \"./A\";
|
||||||
|
|
||||||
class B extends A {
|
class B extends A {
|
||||||
p: string;
|
p: string; // OK, string ~> any
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -18,14 +18,16 @@ export default class {
|
||||||
* @providesModule A
|
* @providesModule A
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type T from \"T\";
|
import type T from \"T\";
|
||||||
|
|
||||||
export default class {
|
export default class {
|
||||||
p: T;
|
p: T;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.p = 0;
|
this.p = 0;
|
||||||
}
|
}
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test B.js 1`] = `
|
exports[`test B.js 1`] = `
|
||||||
|
@ -42,12 +44,12 @@ class B extends A {
|
||||||
/**
|
/**
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
// OK, string ~> any
|
|
||||||
import A from \"A\";
|
import A from \"A\";
|
||||||
|
|
||||||
class B extends A {
|
class B extends A {
|
||||||
p: string;
|
p: string; // OK, string ~> any
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test T.js 1`] = `
|
exports[`test T.js 1`] = `
|
||||||
|
@ -55,9 +57,5 @@ exports[`test T.js 1`] = `
|
||||||
* @providesModule T
|
* @providesModule T
|
||||||
*/
|
*/
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/**
|
|
||||||
* @providesModule T
|
|
||||||
*/
|
|
||||||
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -10,6 +10,7 @@ var y:string = bar(0);
|
||||||
var z:string = qux(0);
|
var z:string = qux(0);
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
function foo(x: any): any {
|
function foo(x: any): any {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
@ -19,10 +20,10 @@ function bar(x: any): mixed {
|
||||||
function qux(x: mixed): any {
|
function qux(x: mixed): any {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
var x: string = foo(0);
|
var x: string = foo(0);
|
||||||
var y: string = bar(0);
|
var y: string = bar(0);
|
||||||
var z: string = qux(0);
|
var z: string = qux(0);"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test anyexportflowfile.js 1`] = `
|
exports[`test anyexportflowfile.js 1`] = `
|
||||||
|
@ -31,8 +32,8 @@ exports[`test anyexportflowfile.js 1`] = `
|
||||||
module.exports = ((x: any) => x: any);
|
module.exports = ((x: any) => x: any);
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
module.exports = ((x: any) => x: any);
|
|
||||||
"
|
module.exports = ((x: any) => x: any);"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test flowfixme.js 1`] = `
|
exports[`test flowfixme.js 1`] = `
|
||||||
|
@ -62,26 +63,27 @@ var w:string = baz(0);
|
||||||
|
|
||||||
@flow
|
@flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// no param
|
// no param
|
||||||
// param (info only)
|
|
||||||
// ...params are still checked. unknown type
|
|
||||||
function foo(x: $FlowFixMe): $FlowFixMe {
|
function foo(x: $FlowFixMe): $FlowFixMe {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
function bar(x: $FlowFixMe): mixed {
|
function bar(x: $FlowFixMe): mixed {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
// param (info only)
|
||||||
function qux(x: $FlowFixMe<number>): $FlowFixMe<number> {
|
function qux(x: $FlowFixMe<number>): $FlowFixMe<number> {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
// ...params are still checked. unknown type
|
||||||
function baz(x: $FlowFixMe<nnumber>): $FlowFixMe<number> {
|
function baz(x: $FlowFixMe<nnumber>): $FlowFixMe<number> {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
var x: string = foo(0);
|
var x: string = foo(0);
|
||||||
var y: string = bar(0);
|
var y: string = bar(0);
|
||||||
var z: string = qux(0);
|
var z: string = qux(0);
|
||||||
var w: string = baz(0);
|
var w: string = baz(0);"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test flowissue.js 1`] = `
|
exports[`test flowissue.js 1`] = `
|
||||||
|
@ -111,26 +113,27 @@ var w:string = baz(0);
|
||||||
|
|
||||||
@flow
|
@flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// no param
|
// no param
|
||||||
// param (info only)
|
|
||||||
// ...params are still checked. unknown type
|
|
||||||
function foo(x: $FlowIssue): $FlowIssue {
|
function foo(x: $FlowIssue): $FlowIssue {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
function bar(x: $FlowIssue): mixed {
|
function bar(x: $FlowIssue): mixed {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
// param (info only)
|
||||||
function qux(x: $FlowIssue<number>): $FlowIssue<number> {
|
function qux(x: $FlowIssue<number>): $FlowIssue<number> {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
// ...params are still checked. unknown type
|
||||||
function baz(x: $FlowIssue<nnumber>): $FlowIssue<number> {
|
function baz(x: $FlowIssue<nnumber>): $FlowIssue<number> {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
var x: string = foo(0);
|
var x: string = foo(0);
|
||||||
var y: string = bar(0);
|
var y: string = bar(0);
|
||||||
var z: string = qux(0);
|
var z: string = qux(0);
|
||||||
var w: string = baz(0);
|
var w: string = baz(0);"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test nonflowfile.js 1`] = `
|
exports[`test nonflowfile.js 1`] = `
|
||||||
|
@ -139,8 +142,8 @@ exports[`test nonflowfile.js 1`] = `
|
||||||
module.exports = (x) => x;
|
module.exports = (x) => x;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @noflow
|
// @noflow
|
||||||
module.exports = x => x;
|
|
||||||
"
|
module.exports = x => x;"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test propagate.js 1`] = `
|
exports[`test propagate.js 1`] = `
|
||||||
|
@ -171,28 +174,30 @@ function bar2(x: mixed) {
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
// should be able to select first case and error
|
|
||||||
declare class C {
|
declare class C {
|
||||||
bar(n1: number, n2: number): number,
|
bar(n1: number, n2: number): number,
|
||||||
bar(s1: string, s2: string): string
|
bar(s1: string, s2: string): string
|
||||||
}
|
}
|
||||||
|
|
||||||
function foo(c: C, x: any): string {
|
function foo(c: C, x: any): string {
|
||||||
let y = x.y;
|
let y = x.y;
|
||||||
return c.bar(0, y);
|
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) {
|
function bar1(x: mixed) {
|
||||||
if (any_fun1(x)) {
|
if (any_fun1(x)) {
|
||||||
(x: boolean);
|
(x: boolean);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var any_fun2 = require(\"./anyexportflowfile\");
|
var any_fun2 = require(\"./anyexportflowfile\");
|
||||||
function bar2(x: mixed) {
|
function bar2(x: mixed) {
|
||||||
if (any_fun2(x)) {
|
if (any_fun2(x)) {
|
||||||
(x: boolean);
|
(x: boolean);
|
||||||
}
|
}
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test reach.js 1`] = `
|
exports[`test reach.js 1`] = `
|
||||||
|
@ -215,11 +220,12 @@ function foo(o: ?AsyncRequest) {
|
||||||
* type annotations. Here we test propagation of any through the
|
* type annotations. Here we test propagation of any through the
|
||||||
* annotation - without it, the body of the if will be unreachable
|
* annotation - without it, the body of the if will be unreachable
|
||||||
*/
|
*/
|
||||||
|
|
||||||
type AsyncRequest = any;
|
type AsyncRequest = any;
|
||||||
|
|
||||||
function foo(o: ?AsyncRequest) {
|
function foo(o: ?AsyncRequest) {
|
||||||
if (o) {
|
if (o) {
|
||||||
var n: number = o;
|
var n: number = o;
|
||||||
}
|
}
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -92,116 +92,118 @@ let tests = [
|
||||||
];
|
];
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @providesModule Arith */
|
/* @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) {}
|
function num(x: number) {}
|
||||||
|
|
||||||
function str(x: string) {}
|
function str(x: string) {}
|
||||||
|
|
||||||
function foo() {
|
function foo() {
|
||||||
var x = 0;
|
var x = 0;
|
||||||
var y = \"...\";
|
var y = \"...\";
|
||||||
var z = {};
|
var z = {};
|
||||||
num(x + x);
|
num(x + x);
|
||||||
num(x + y);
|
num(x + y);
|
||||||
|
// error
|
||||||
str(x + y);
|
str(x + y);
|
||||||
str(x + x);
|
str(x + x);
|
||||||
str(z + y);
|
// error
|
||||||
|
str(z + y); // error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test MaybeT(NumT)
|
||||||
function bar0(x: ?number, y: number) {
|
function bar0(x: ?number, y: number) {
|
||||||
num(x + y);
|
num(x + y);
|
||||||
}
|
}
|
||||||
function bar1(x: number, y: ?number) {
|
function bar1(x: number, y: ?number) {
|
||||||
num(x + y);
|
num(x + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test OptionalT(NumT)
|
||||||
function bar2(x?: number, y: number) {
|
function bar2(x?: number, y: number) {
|
||||||
num(x + y);
|
num(x + y);
|
||||||
}
|
}
|
||||||
function bar3(x: number, y?: number) {
|
function bar3(x: number, y?: number) {
|
||||||
num(x + y);
|
num(x + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test OptionalT(MaybeT(NumT))
|
||||||
function bar4(x?: ?number, y: number) {
|
function bar4(x?: ?number, y: number) {
|
||||||
num(x + y);
|
num(x + y);
|
||||||
}
|
}
|
||||||
function bar5(x: number, y?: ?number) {
|
function bar5(x: number, y?: ?number) {
|
||||||
num(x + y);
|
num(x + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
num(null + null);
|
num(null + null);
|
||||||
|
// === 0
|
||||||
num(undefined + undefined);
|
num(undefined + undefined);
|
||||||
|
// === NaN
|
||||||
num(null + 1);
|
num(null + 1);
|
||||||
|
// === 1
|
||||||
num(1 + null);
|
num(1 + null);
|
||||||
|
// === 1
|
||||||
num(undefined + 1);
|
num(undefined + 1);
|
||||||
|
// === NaN
|
||||||
num(1 + undefined);
|
num(1 + undefined);
|
||||||
|
// === NaN
|
||||||
num(null + true);
|
num(null + true);
|
||||||
|
// === 1
|
||||||
num(true + null);
|
num(true + null);
|
||||||
|
// === 1
|
||||||
num(undefined + true);
|
num(undefined + true);
|
||||||
|
// === NaN
|
||||||
num(true + undefined);
|
num(true + undefined);
|
||||||
|
// === NaN
|
||||||
str(\"foo\" + true);
|
str(\"foo\" + true);
|
||||||
|
// error
|
||||||
str(true + \"foo\");
|
str(true + \"foo\");
|
||||||
|
// error
|
||||||
str(\"foo\" + null);
|
str(\"foo\" + null);
|
||||||
|
// error
|
||||||
str(null + \"foo\");
|
str(null + \"foo\");
|
||||||
|
// error
|
||||||
str(\"foo\" + undefined);
|
str(\"foo\" + undefined);
|
||||||
|
// error
|
||||||
str(undefined + \"foo\");
|
str(undefined + \"foo\");
|
||||||
|
// error
|
||||||
let tests = [
|
let tests = [
|
||||||
function(x: mixed, y: mixed) {
|
function(x: mixed, y: mixed) {
|
||||||
x + y;
|
x + y;
|
||||||
|
// error
|
||||||
x + 0;
|
x + 0;
|
||||||
|
// error
|
||||||
0 + x;
|
0 + x;
|
||||||
|
// error
|
||||||
x + \"\";
|
x + \"\";
|
||||||
|
// error
|
||||||
\"\" + x;
|
\"\" + x;
|
||||||
|
// error
|
||||||
x + {};
|
x + {};
|
||||||
({}) + x;
|
// error
|
||||||
|
({}) + x; // 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.
|
||||||
function() {
|
function() {
|
||||||
(1 + {}: number);
|
(1 + {}: number);
|
||||||
|
// error: object !~> number
|
||||||
({} + 1: number);
|
({} + 1: number);
|
||||||
|
// error: object !~> number
|
||||||
(\"1\" + {}: string);
|
(\"1\" + {}: string);
|
||||||
({} + \"1\": string);
|
// error: object !~> string
|
||||||
|
({} + \"1\": string); // error: object !~> string
|
||||||
},
|
},
|
||||||
function(x: any, y: number, z: string) {
|
function(x: any, y: number, z: string) {
|
||||||
(x + y: string);
|
(x + y: string);
|
||||||
|
// ok
|
||||||
(y + x: string);
|
(y + x: string);
|
||||||
|
// ok
|
||||||
(x + z: empty);
|
(x + z: empty);
|
||||||
(z + x: empty);
|
// error, string ~> empty
|
||||||
|
(z + x: empty); // error, string ~> empty
|
||||||
}
|
}
|
||||||
];
|
];"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test exponent.js 1`] = `
|
exports[`test exponent.js 1`] = `
|
||||||
|
@ -218,15 +220,16 @@ y **= 2; // error
|
||||||
(-2) ** 2;
|
(-2) ** 2;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
// error
|
|
||||||
let x: number = 2 ** 3;
|
let x: number = 2 ** 3;
|
||||||
x **= 4;
|
x **= 4;
|
||||||
|
|
||||||
let y: string = \"123\";
|
let y: string = \"123\";
|
||||||
y **= 2;
|
y **= 2;
|
||||||
|
// error
|
||||||
1 + 2 ** 3 + 4;
|
1 + 2 ** 3 + 4;
|
||||||
2 ** 2;
|
2 ** 2;
|
||||||
(-2) ** 2;
|
(-2) ** 2;"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test generic.js 1`] = `
|
exports[`test generic.js 1`] = `
|
||||||
|
@ -239,27 +242,26 @@ 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
|
function f<A,B>(a: A, b: B): B {return b + a; } // error
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
// error
|
|
||||||
// error
|
|
||||||
// error
|
|
||||||
// error
|
|
||||||
// error
|
|
||||||
function f<A>(a: A): A {
|
function f<A>(a: A): A {
|
||||||
return a + a;
|
return a + a;
|
||||||
}
|
}
|
||||||
|
// error
|
||||||
function f<A, B>(a: A, b: B): A {
|
function f<A, B>(a: A, b: B): A {
|
||||||
return a + b;
|
return a + b;
|
||||||
}
|
}
|
||||||
|
// error
|
||||||
function f<A, B>(a: A, b: B): A {
|
function f<A, B>(a: A, b: B): A {
|
||||||
return b + a;
|
return b + a;
|
||||||
}
|
}
|
||||||
|
// error
|
||||||
function f<A, B>(a: A, b: B): B {
|
function f<A, B>(a: A, b: B): B {
|
||||||
return a + b;
|
return a + b;
|
||||||
}
|
}
|
||||||
|
// error
|
||||||
function f<A, B>(a: A, b: B): B {
|
function f<A, B>(a: A, b: B): B {
|
||||||
return b + a;
|
return b + a;
|
||||||
}
|
} // error"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test mult.js 1`] = `
|
exports[`test mult.js 1`] = `
|
||||||
|
@ -277,15 +279,17 @@ let y: string = \"123\";
|
||||||
y *= 2; // error
|
y *= 2; // error
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
// error
|
|
||||||
function num(x: number) {}
|
function num(x: number) {}
|
||||||
|
|
||||||
num(null * 1);
|
num(null * 1);
|
||||||
num(1 * null);
|
num(1 * null);
|
||||||
|
|
||||||
let x: number = 2 * 3;
|
let x: number = 2 * 3;
|
||||||
x *= 4;
|
x *= 4;
|
||||||
|
|
||||||
let y: string = \"123\";
|
let y: string = \"123\";
|
||||||
y *= 2;
|
y *= 2; // error"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test relational.js 1`] = `
|
exports[`test relational.js 1`] = `
|
||||||
|
@ -321,43 +325,44 @@ let tests = [
|
||||||
];
|
];
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
// error
|
|
||||||
// error
|
|
||||||
// error
|
|
||||||
// error
|
|
||||||
// error
|
|
||||||
// error
|
|
||||||
// error
|
|
||||||
// 2 errors: null !~> number; undefined !~> number
|
|
||||||
// 2 errors: null !~> number; undefined !~> number
|
|
||||||
// error
|
|
||||||
// error
|
|
||||||
// error
|
|
||||||
// error
|
|
||||||
1 < 2;
|
1 < 2;
|
||||||
1 < \"foo\";
|
1 < \"foo\";
|
||||||
|
// error
|
||||||
\"foo\" < 1;
|
\"foo\" < 1;
|
||||||
|
// error
|
||||||
\"foo\" < \"bar\";
|
\"foo\" < \"bar\";
|
||||||
1 < { foo: 1 };
|
1 < { foo: 1 };
|
||||||
|
// error
|
||||||
({ foo: 1 }) < 1;
|
({ foo: 1 }) < 1;
|
||||||
|
// error
|
||||||
({ foo: 1 }) < { foo: 1 };
|
({ foo: 1 }) < { foo: 1 };
|
||||||
|
// error
|
||||||
\"foo\" < { foo: 1 };
|
\"foo\" < { foo: 1 };
|
||||||
|
// error
|
||||||
({ foo: 1 }) < \"foo\";
|
({ foo: 1 }) < \"foo\";
|
||||||
|
// error
|
||||||
var x = (null: ?number);
|
var x = (null: ?number);
|
||||||
1 < x;
|
1 < x;
|
||||||
|
// 2 errors: null !~> number; undefined !~> number
|
||||||
x < 1;
|
x < 1;
|
||||||
|
// 2 errors: null !~> number; undefined !~> number
|
||||||
null < null;
|
null < null;
|
||||||
|
// error
|
||||||
undefined < null;
|
undefined < null;
|
||||||
|
// error
|
||||||
null < undefined;
|
null < undefined;
|
||||||
|
// error
|
||||||
undefined < undefined;
|
undefined < undefined;
|
||||||
|
// error
|
||||||
NaN < 1;
|
NaN < 1;
|
||||||
1 < NaN;
|
1 < NaN;
|
||||||
NaN < NaN;
|
NaN < NaN;
|
||||||
|
|
||||||
let tests = [
|
let tests = [
|
||||||
function(x: any, y: number, z: string) {
|
function(x: any, y: number, z: string) {
|
||||||
x > y;
|
x > y;
|
||||||
x > z;
|
x > z;
|
||||||
}
|
}
|
||||||
];
|
];"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -10,13 +10,14 @@ function filterOutSmall (arr: Array<?number>): Array<?number> {
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
function filterOutVoids<T>(arr: Array<?T>): Array<T> {
|
function filterOutVoids<T>(arr: Array<?T>): Array<T> {
|
||||||
return arr.filter(Boolean);
|
return arr.filter(Boolean);
|
||||||
}
|
}
|
||||||
|
|
||||||
function filterOutSmall(arr: Array<?number>): Array<?number> {
|
function filterOutSmall(arr: Array<?number>): Array<?number> {
|
||||||
return arr.filter(num => num && num > 10);
|
return arr.filter(num => num && num > 10);
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test test2.js 1`] = `
|
exports[`test test2.js 1`] = `
|
||||||
|
@ -37,6 +38,7 @@ const filteredItems = filterItems([\'foo\', \'b\', 1, 2]);
|
||||||
console.log(filteredItems);
|
console.log(filteredItems);
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
function filterItems(items: Array<string | number>): Array<string | number> {
|
function filterItems(items: Array<string | number>): Array<string | number> {
|
||||||
return items.map(item => {
|
return items.map(item => {
|
||||||
if (typeof item === \"string\") {
|
if (typeof item === \"string\") {
|
||||||
|
@ -46,7 +48,8 @@ function filterItems(items: Array<string | number>): Array<string | number> {
|
||||||
}
|
}
|
||||||
}).filter(Boolean);
|
}).filter(Boolean);
|
||||||
}
|
}
|
||||||
|
|
||||||
const filteredItems = filterItems([ \"foo\", \"b\", 1, 2 ]);
|
const filteredItems = filterItems([ \"foo\", \"b\", 1, 2 ]);
|
||||||
console.log(filteredItems);
|
|
||||||
"
|
console.log(filteredItems);"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -13,7 +13,7 @@ var B = [ ...A ];
|
||||||
var C = [ 1, 2, 3 ];
|
var C = [ 1, 2, 3 ];
|
||||||
B.sort((a, b) => a - b);
|
B.sort((a, b) => a - b);
|
||||||
C.sort((a, b) => a - b);
|
C.sort((a, b) => a - b);
|
||||||
|
|
||||||
var x: Array<string> = [ \"1\", \"2\" ];
|
var x: Array<string> = [ \"1\", \"2\" ];
|
||||||
var y: Array<string> = [ \"3\", ...x ];
|
var y: Array<string> = [ \"3\", ...x ];"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -58,27 +58,24 @@ function from_test() {
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @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) {}
|
function foo(x: string) {}
|
||||||
|
|
||||||
var a = [ 0 ];
|
var a = [ 0 ];
|
||||||
var b = a.map(function(x) {
|
var b = a.map(function(x) {
|
||||||
foo(x);
|
foo(x);
|
||||||
return \"\" + x;
|
return \"\" + x;
|
||||||
});
|
});
|
||||||
|
|
||||||
var c: number = a[0];
|
var c: number = a[0];
|
||||||
var d: number = b[0];
|
var d: number = b[0];
|
||||||
|
|
||||||
var e: Array<string> = a.reverse();
|
var e: Array<string> = a.reverse();
|
||||||
|
|
||||||
var f = [ \"\" ];
|
var f = [ \"\" ];
|
||||||
var g: number = f.map(function() {
|
var g: number = f.map(function() {
|
||||||
return 0;
|
return 0;
|
||||||
})[0];
|
})[0];
|
||||||
|
|
||||||
var h: Array<number> = [ 1, 2, 3 ];
|
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 j: Array<number | string> = h.concat(i);
|
||||||
|
@ -86,25 +83,37 @@ var k: Array<number> = h.concat(h);
|
||||||
var l: Array<number> = h.concat(1, 2, 3);
|
var l: Array<number> = h.concat(1, 2, 3);
|
||||||
var m: Array<number | string> = h.concat(\"a\", \"b\", \"c\");
|
var m: Array<number | string> = h.concat(\"a\", \"b\", \"c\");
|
||||||
var n: Array<number> = h.concat(\"a\", \"b\", \"c\");
|
var n: Array<number> = h.concat(\"a\", \"b\", \"c\");
|
||||||
|
// Error
|
||||||
function reduce_test() {
|
function reduce_test() {
|
||||||
|
/* Adapted from the following source:
|
||||||
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
|
||||||
|
*/
|
||||||
[ 0, 1, 2, 3, 4 ].reduce(function(previousValue, currentValue, index, array) {
|
[ 0, 1, 2, 3, 4 ].reduce(function(previousValue, currentValue, index, array) {
|
||||||
return previousValue + currentValue + array[index];
|
return previousValue + currentValue + array[index];
|
||||||
});
|
});
|
||||||
|
|
||||||
[ 0, 1, 2, 3, 4 ].reduce(
|
[ 0, 1, 2, 3, 4 ].reduce(
|
||||||
function(previousValue, currentValue, index, array) {
|
function(previousValue, currentValue, index, array) {
|
||||||
return previousValue + currentValue + array[index];
|
return previousValue + currentValue + array[index];
|
||||||
},
|
},
|
||||||
10
|
10
|
||||||
);
|
);
|
||||||
|
|
||||||
var total = [ 0, 1, 2, 3 ].reduce(function(a, b) {
|
var total = [ 0, 1, 2, 3 ].reduce(function(a, b) {
|
||||||
return a + b;
|
return a + b;
|
||||||
});
|
});
|
||||||
|
|
||||||
var flattened = [ [ 0, 1 ], [ 2, 3 ], [ 4, 5 ] ].reduce(function(a, b) {
|
var flattened = [ [ 0, 1 ], [ 2, 3 ], [ 4, 5 ] ].reduce(function(a, b) {
|
||||||
return a.concat(b);
|
return a.concat(b);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* Added later, because the above is insufficient */
|
||||||
|
// acc is element type of array when no init is provided
|
||||||
[ \"\" ].reduce((acc, str) => acc * str.length);
|
[ \"\" ].reduce((acc, str) => acc * str.length);
|
||||||
[ \"\" ].reduceRight((acc, str) => acc * str.length);
|
// error, string ~> number
|
||||||
|
[ \"\" ].reduceRight((acc, str) => acc * str.length); // error, string ~> number
|
||||||
}
|
}
|
||||||
|
|
||||||
function from_test() {
|
function from_test() {
|
||||||
var a: Array<string> = Array.from([ 1, 2, 3 ], function(val, index) {
|
var a: Array<string> = Array.from([ 1, 2, 3 ], function(val, index) {
|
||||||
return index % 2 ? \"foo\" : String(val);
|
return index % 2 ? \"foo\" : String(val);
|
||||||
|
@ -112,6 +121,5 @@ function from_test() {
|
||||||
var b: Array<string> = Array.from([ 1, 2, 3 ], function(val) {
|
var b: Array<string> = Array.from([ 1, 2, 3 ], function(val) {
|
||||||
return String(val);
|
return String(val);
|
||||||
});
|
});
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -40,17 +40,22 @@ var abig2: Array<{x:number; y:number}> = [
|
||||||
module.exports = \"arrays\";
|
module.exports = \"arrays\";
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @providesModule Arrays */
|
/* @providesModule Arrays */
|
||||||
// for literals, composite element type is union of individuals
|
|
||||||
// note: test both tuple and non-tuple inferred literals
|
|
||||||
function foo(x: string) {}
|
function foo(x: string) {}
|
||||||
|
|
||||||
var a = [];
|
var a = [];
|
||||||
a[0] = 1;
|
a[0] = 1;
|
||||||
a[1] = \"...\";
|
a[1] = \"...\";
|
||||||
|
|
||||||
foo(a[1]);
|
foo(a[1]);
|
||||||
var y;
|
var y;
|
||||||
a.forEach(x => y = x);
|
a.forEach(x => y = x);
|
||||||
|
|
||||||
|
// for literals, composite element type is union of individuals
|
||||||
|
// note: test both tuple and non-tuple inferred literals
|
||||||
var alittle: Array<?number> = [ 0, 1, 2, 3, null ];
|
var alittle: Array<?number> = [ 0, 1, 2, 3, null ];
|
||||||
var abig: Array<?number> = [ 0, 1, 2, 3, 4, 5, 6, 8, null ];
|
var abig: Array<?number> = [ 0, 1, 2, 3, 4, 5, 6, 8, null ];
|
||||||
|
|
||||||
var abig2: Array<{ x: number, y: number }> = [
|
var abig2: Array<{ x: number, y: number }> = [
|
||||||
{ x: 0, y: 0 },
|
{ x: 0, y: 0 },
|
||||||
{ x: 0, y: 0 },
|
{ x: 0, y: 0 },
|
||||||
|
@ -70,8 +75,8 @@ var abig2: Array<{ x: number, y: number }> = [
|
||||||
{ x: 0, y: 0, c: 1 },
|
{ x: 0, y: 0, c: 1 },
|
||||||
{ x: 0, y: 0, c: \"hey\" }
|
{ x: 0, y: 0, c: \"hey\" }
|
||||||
];
|
];
|
||||||
module.exports = \"arrays\";
|
|
||||||
"
|
module.exports = \"arrays\";"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test numeric_elem.js 1`] = `
|
exports[`test numeric_elem.js 1`] = `
|
||||||
|
@ -83,12 +88,11 @@ var day = new Date;
|
||||||
arr[day] = 0;
|
arr[day] = 0;
|
||||||
(arr[day]: string); // error: number ~> string
|
(arr[day]: string); // error: number ~> string
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// Date instances are numeric (see Flow_js.numeric) and thus can index into
|
|
||||||
// arrays.
|
|
||||||
// error: number ~> string
|
|
||||||
var arr = [];
|
var arr = [];
|
||||||
var day = new Date();
|
var day = new Date();
|
||||||
|
|
||||||
|
// Date instances are numeric (see Flow_js.numeric) and thus can index into
|
||||||
|
// arrays.
|
||||||
arr[day] = 0;
|
arr[day] = 0;
|
||||||
(arr[day]: string);
|
(arr[day]: string); // error: number ~> string"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -14,14 +14,14 @@ var ident = <T>(x: T): T => x;
|
||||||
/**
|
/**
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
// Error!
|
|
||||||
// Error
|
|
||||||
var add = (x: number, y: number): number => x + y;
|
var add = (x: number, y: number): number => x + y;
|
||||||
|
|
||||||
var bad = (x: number): string => x;
|
var bad = (x: number): string => x;
|
||||||
|
// Error!
|
||||||
var ident = <T>(x: T): T => x;
|
var ident = <T>(x: T): T => x;
|
||||||
(ident(1): number);
|
(ident(1): number);
|
||||||
(ident(\"hi\"): number);
|
(ident(\"hi\"): number); // Error"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test arrows.js 1`] = `
|
exports[`test arrows.js 1`] = `
|
||||||
|
@ -36,15 +36,14 @@ exports[`test arrows.js 1`] = `
|
||||||
images[images.length - 1];
|
images[images.length - 1];
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//images = images.sort(function (a, b) { return a.width - b.width });
|
|
||||||
function selectBestEffortImageForWidth(
|
function selectBestEffortImageForWidth(
|
||||||
maxWidth: number,
|
maxWidth: number,
|
||||||
images: Array<Image>
|
images: Array<Image>
|
||||||
): Image {
|
): Image {
|
||||||
var maxPixelWidth = maxWidth;
|
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) ||
|
return images.find(image => image.width >= maxPixelWidth) ||
|
||||||
images[images.length - 1];
|
images[images.length - 1];
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -53,39 +53,43 @@ var obj = { f: async () => await 1 };
|
||||||
var objf : () => Promise<number> = obj.f;
|
var objf : () => Promise<number> = obj.f;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
// \"For async functions, a Promise<T> is returned,
|
// \"For async functions, a Promise<T> is returned,
|
||||||
// and the type of return expressions must be T.\"
|
// 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> {
|
async function f0(): Promise<number> {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function f1(): Promise<boolean> {
|
async function f1(): Promise<boolean> {
|
||||||
return 1;
|
return 1; // error, number != bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// await: (p: Promise<T> | T) => T
|
||||||
|
//
|
||||||
async function f2(p: Promise<number>): Promise<number> {
|
async function f2(p: Promise<number>): Promise<number> {
|
||||||
var x: number = await p;
|
var x: number = await p;
|
||||||
var y: number = await 1;
|
var y: number = await 1;
|
||||||
return x + y;
|
return x + y;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function f3(p: Promise<number>): Promise<number> {
|
async function f3(p: Promise<number>): Promise<number> {
|
||||||
return await p;
|
return await p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: this is one of those bad generic errors, currently:
|
||||||
|
// \"inconsistent use of library definitions\" with two core.js locs
|
||||||
async function f4(p: Promise<number>): Promise<boolean> {
|
async function f4(p: Promise<number>): Promise<boolean> {
|
||||||
return await p;
|
return await p; // error, number != bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// async arrow functions
|
||||||
|
//
|
||||||
var f5: () => Promise<number> = async () => await 1;
|
var f5: () => Promise<number> = async () => await 1;
|
||||||
|
|
||||||
|
// async methods
|
||||||
|
//
|
||||||
class C {
|
class C {
|
||||||
async m() {
|
async m() {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -96,13 +100,15 @@ class C {
|
||||||
static async m(a): void {
|
static async m(a): void {
|
||||||
await a;
|
await a;
|
||||||
}
|
}
|
||||||
|
// error, void != Promise<void>
|
||||||
static async mt<T>(a: T): Promise<T> {
|
static async mt<T>(a: T): Promise<T> {
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// async function props
|
||||||
var obj = { f: async () => await 1 };
|
var obj = { f: async () => await 1 };
|
||||||
var objf: () => Promise<number> = obj.f;
|
var objf: () => Promise<number> = obj.f;"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test async_base_class.js 1`] = `
|
exports[`test async_base_class.js 1`] = `
|
||||||
|
@ -126,14 +132,15 @@ async function foo() {
|
||||||
// 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.
|
// that is probably not important to support.
|
||||||
class C {}
|
class C {}
|
||||||
|
|
||||||
var P: Promise<Class<C>> = new Promise(function(resolve, reject) {
|
var P: Promise<Class<C>> = new Promise(function(resolve, reject) {
|
||||||
resolve(C);
|
resolve(C);
|
||||||
});
|
});
|
||||||
|
|
||||||
async function foo() {
|
async function foo() {
|
||||||
class Bar extends (await P) {}
|
class Bar extends (await P) {}
|
||||||
return Bar;
|
return Bar;
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test async_parse.js 1`] = `
|
exports[`test async_parse.js 1`] = `
|
||||||
|
@ -164,23 +171,28 @@ var y = { async };
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
async function f() {}
|
async function f() {}
|
||||||
async function ft<T>(a: T) {}
|
async function ft<T>(a: T) {}
|
||||||
|
|
||||||
class C {
|
class C {
|
||||||
async m() {}
|
async m() {}
|
||||||
async mt<T>(a: T) {}
|
async mt<T>(a: T) {}
|
||||||
static async m(a) {}
|
static async m(a) {}
|
||||||
static async mt<T>(a: T) {}
|
static async mt<T>(a: T) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
var e = async function() {};
|
var e = async function() {};
|
||||||
var et = async function<T>(a: T) {};
|
var et = async function<T>(a: T) {};
|
||||||
|
|
||||||
var n = new async function() {}();
|
var n = new async function() {}();
|
||||||
|
|
||||||
var o = { async m() {} };
|
var o = { async m() {} };
|
||||||
var ot = { async m<T>(a: T) {} };
|
var ot = { async m<T>(a: T) {} };
|
||||||
var oz = { async async() {} };
|
var oz = { async async() {} };
|
||||||
|
|
||||||
var x = { async: 5 };
|
var x = { async: 5 };
|
||||||
console.log(x.async);
|
console.log(x.async);
|
||||||
|
|
||||||
var async = 3;
|
var async = 3;
|
||||||
var y = { async };
|
var y = { async };"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test async_promise.js 1`] = `
|
exports[`test async_promise.js 1`] = `
|
||||||
|
@ -190,8 +202,7 @@ exports[`test async_promise.js 1`] = `
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
async function f(): Promise<number> {
|
async function f(): Promise<number> {
|
||||||
return Promise.resolve(1);
|
return Promise.resolve(1);
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test async_return_void.js 1`] = `
|
exports[`test async_return_void.js 1`] = `
|
||||||
|
@ -211,17 +222,19 @@ async function foo3(): Promise<string> {
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
async function foo1(): Promise<string> {
|
async function foo1(): Promise<string> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function foo2(): Promise<string> {
|
async function foo2(): Promise<string> {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function foo3(): Promise<string> {
|
async function foo3(): Promise<string> {
|
||||||
function bar() {}
|
function bar() {}
|
||||||
return bar();
|
return bar();
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test async2.js 1`] = `
|
exports[`test async2.js 1`] = `
|
||||||
|
@ -287,59 +300,64 @@ function test5() {
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
// misc basic
|
// misc basic
|
||||||
|
|
||||||
|
function test1() {
|
||||||
|
async function foo() {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function bar() {
|
||||||
|
var a = await foo();
|
||||||
|
var b: number = a;
|
||||||
// valid
|
// valid
|
||||||
// Error: number ~> string
|
var c: string = a; // Error: number ~> string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// void returns:
|
// void returns:
|
||||||
//
|
//
|
||||||
// inference should produce return type Promise<void>
|
// inference should produce return type Promise<void>
|
||||||
// in the absence of an explicit return
|
// 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 42;
|
|
||||||
}
|
|
||||||
async function bar() {
|
|
||||||
var a = await foo();
|
|
||||||
var b: number = a;
|
|
||||||
var c: string = a;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function test2() {
|
function test2() {
|
||||||
async function voidoid1() {
|
async function voidoid1() {
|
||||||
console.log(\"HEY\");
|
console.log(\"HEY\");
|
||||||
}
|
}
|
||||||
|
|
||||||
var voidoid2: () => Promise<void> = voidoid1;
|
var voidoid2: () => Promise<void> = voidoid1;
|
||||||
var voidoid3: () => void = voidoid1;
|
// ok
|
||||||
|
var voidoid3: () => void = voidoid1; // error, void != Promise<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// annotated return type of Promise<void> should work
|
||||||
|
//
|
||||||
function test3() {
|
function test3() {
|
||||||
async function voidoid4(): Promise<void> {
|
async function voidoid4(): Promise<void> {
|
||||||
|
// ok
|
||||||
console.log(\"HEY\");
|
console.log(\"HEY\");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// other annotated return types should fail
|
||||||
|
// (note: misannotated return types with explicit
|
||||||
|
// return statements are covered in async.js)
|
||||||
|
//
|
||||||
function test4() {
|
function test4() {
|
||||||
async function voidoid5(): void {
|
async function voidoid5(): void {
|
||||||
|
// error, void != Promise<void>
|
||||||
console.log(\"HEY\");
|
console.log(\"HEY\");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function test5() {
|
function test5() {
|
||||||
async function voidoid6(): Promise<number> {
|
async function voidoid6(): Promise<number> {
|
||||||
|
// error, number != void
|
||||||
console.log(\"HEY\");
|
console.log(\"HEY\");
|
||||||
}
|
}
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test async3.js 1`] = `
|
exports[`test async3.js 1`] = `
|
||||||
|
@ -377,6 +395,7 @@ async function baz() {
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* test nested-promise unwrapping.
|
* 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
|
||||||
|
@ -384,24 +403,28 @@ async function baz() {
|
||||||
* 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.
|
* 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() {
|
async function foo() {
|
||||||
return 42;
|
return 42;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function bar() {
|
async function bar() {
|
||||||
return foo();
|
return foo();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function baz() {
|
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();
|
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;
|
var b: number = a;
|
||||||
|
|
||||||
|
// should be number ~> string error, but currently gives
|
||||||
|
// Promise ~> string error for the same reason
|
||||||
var c: string = a;
|
var c: string = a;
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test await_parse.js 1`] = `
|
exports[`test await_parse.js 1`] = `
|
||||||
|
@ -436,6 +459,7 @@ async function f() {
|
||||||
async function ft<T>(a: T) {
|
async function ft<T>(a: T) {
|
||||||
await 1;
|
await 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
class C {
|
class C {
|
||||||
async m() {
|
async m() {
|
||||||
await 1;
|
await 1;
|
||||||
|
@ -450,15 +474,18 @@ class C {
|
||||||
await 1;
|
await 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var e = async function() {
|
var e = async function() {
|
||||||
await 1;
|
await 1;
|
||||||
};
|
};
|
||||||
var et = async function<T>(a: T) {
|
var et = async function<T>(a: T) {
|
||||||
await 1;
|
await 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
var n = new async function() {
|
var n = new async function() {
|
||||||
await 1;
|
await 1;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
var o = {
|
var o = {
|
||||||
async m() {
|
async m() {
|
||||||
await 1;
|
await 1;
|
||||||
|
@ -474,9 +501,10 @@ var oz = {
|
||||||
await async;
|
await async;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var x = { await: 5 };
|
var x = { await: 5 };
|
||||||
console.log(x.await);
|
console.log(x.await);
|
||||||
|
|
||||||
var await = 3;
|
var await = 3;
|
||||||
var y = { await };
|
var y = { await };"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -26,16 +26,14 @@ async function *delegate_return() {
|
||||||
var x: void = yield *inner(); // error: number ~> void
|
var x: void = yield *inner(); // error: number ~> void
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// error: number ~> void
|
|
||||||
// error: number ~> void
|
|
||||||
// error: number ~> void
|
|
||||||
async function* delegate_next() {
|
async function* delegate_next() {
|
||||||
async function* inner() {
|
async function* inner() {
|
||||||
var x: void = yield;
|
var x: void = yield; // error: number ~> void
|
||||||
}
|
}
|
||||||
yield* inner();
|
yield* inner();
|
||||||
}
|
}
|
||||||
delegate_next().next(0);
|
delegate_next().next(0);
|
||||||
|
|
||||||
async function* delegate_yield() {
|
async function* delegate_yield() {
|
||||||
async function* inner() {
|
async function* inner() {
|
||||||
yield 0;
|
yield 0;
|
||||||
|
@ -44,16 +42,16 @@ async function* delegate_yield() {
|
||||||
}
|
}
|
||||||
async () => {
|
async () => {
|
||||||
for await (const x of delegate_yield()) {
|
for await (const x of delegate_yield()) {
|
||||||
(x: void);
|
(x: void); // error: number ~> void
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
async function* delegate_return() {
|
async function* delegate_return() {
|
||||||
async function* inner() {
|
async function* inner() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
var x: void = yield* inner();
|
var x: void = yield* inner(); // error: number ~> void
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test generator.js 1`] = `
|
exports[`test generator.js 1`] = `
|
||||||
|
@ -83,11 +81,13 @@ async function f() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// error: string ~> void
|
|
||||||
interface File { readLine(): Promise<string>, close(): void, EOF: boolean }
|
interface File { readLine(): Promise<string>, close(): void, EOF: boolean }
|
||||||
|
|
||||||
declare function fileOpen(path: string): Promise<File>;
|
declare function fileOpen(path: string): Promise<File>;
|
||||||
|
|
||||||
async function* readLines(path) {
|
async function* readLines(path) {
|
||||||
let file: File = await fileOpen(path);
|
let file: File = await fileOpen(path);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while (!file.EOF) {
|
while (!file.EOF) {
|
||||||
yield await file.readLine();
|
yield await file.readLine();
|
||||||
|
@ -96,12 +96,12 @@ async function* readLines(path) {
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function f() {
|
async function f() {
|
||||||
for await (const line of readLines(\"/path/to/file\")) {
|
for await (const line of readLines(\"/path/to/file\")) {
|
||||||
(line: void);
|
(line: void); // error: string ~> void
|
||||||
}
|
}
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test return.js 1`] = `
|
exports[`test return.js 1`] = `
|
||||||
|
@ -128,16 +128,16 @@ refuse_return().return(\"string\").then(result => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
declare var gen: AsyncGenerator<void, string, void>;
|
||||||
|
|
||||||
// You can pass whatever you like to return, it doesn\'t need to be related to
|
// You can pass whatever you like to return, it doesn\'t need to be related to
|
||||||
// the AsyncGenerator\'s return type
|
// the AsyncGenerator\'s return type
|
||||||
// error: string | number ~> void
|
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.
|
// yielding or returning internally.
|
||||||
// error: number | void ~> string
|
|
||||||
declare var gen: AsyncGenerator<void, string, void>;
|
|
||||||
gen.return(0).then(result => {
|
|
||||||
(result.value: void);
|
|
||||||
});
|
|
||||||
async function* refuse_return() {
|
async function* refuse_return() {
|
||||||
try {
|
try {
|
||||||
yield 1;
|
yield 1;
|
||||||
|
@ -147,10 +147,9 @@ async function* refuse_return() {
|
||||||
}
|
}
|
||||||
refuse_return().return(\"string\").then(result => {
|
refuse_return().return(\"string\").then(result => {
|
||||||
if (result.done) {
|
if (result.done) {
|
||||||
(result.value: string);
|
(result.value: string); // error: number | void ~> string
|
||||||
}
|
}
|
||||||
});
|
});"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test throw.js 1`] = `
|
exports[`test throw.js 1`] = `
|
||||||
|
@ -187,8 +186,6 @@ async function *yield_return() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// error: number ~> void
|
|
||||||
// error: number ~> void
|
|
||||||
async function* catch_return() {
|
async function* catch_return() {
|
||||||
try {
|
try {
|
||||||
yield 0;
|
yield 0;
|
||||||
|
@ -196,13 +193,15 @@ async function* catch_return() {
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async () => {
|
async () => {
|
||||||
catch_return().throw(\"\").then(({ value }) => {
|
catch_return().throw(\"\").then(({ value }) => {
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
(value: void);
|
(value: void); // error: number ~> void
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
async function* yield_return() {
|
async function* yield_return() {
|
||||||
try {
|
try {
|
||||||
yield 0;
|
yield 0;
|
||||||
|
@ -211,12 +210,12 @@ async function* yield_return() {
|
||||||
yield e;
|
yield e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async () => {
|
async () => {
|
||||||
yield_return().throw(\"\").then(({ value }) => {
|
yield_return().throw(\"\").then(({ value }) => {
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
(value: void);
|
(value: void); // error: number ~> void
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -12,6 +12,7 @@ declare var objectAssign: Object$Assign
|
||||||
m
|
m
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
declare var idx: $Facebookism$Idx;
|
declare var idx: $Facebookism$Idx;
|
||||||
declare var merge: $Facebookism$Merge;
|
declare var merge: $Facebookism$Merge;
|
||||||
declare var mergeDeepInto: $Facebookism$MergeDeepInto;
|
declare var mergeDeepInto: $Facebookism$MergeDeepInto;
|
||||||
|
@ -19,8 +20,8 @@ declare var mergeInto: $Facebookism$MergeInto;
|
||||||
declare var mixin: $Facebookism$Mixin;
|
declare var mixin: $Facebookism$Mixin;
|
||||||
declare var objectGetPrototypeOf: Object$GetPrototypeOf;
|
declare var objectGetPrototypeOf: Object$GetPrototypeOf;
|
||||||
declare var objectAssign: Object$Assign;
|
declare var objectAssign: Object$Assign;
|
||||||
m;
|
|
||||||
"
|
m;"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test unknown.js 1`] = `
|
exports[`test unknown.js 1`] = `
|
||||||
|
@ -28,6 +29,5 @@ exports[`test unknown.js 1`] = `
|
||||||
module.exports = { x: { y: \"\" } };
|
module.exports = { x: { y: \"\" } };
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @noflow
|
// @noflow
|
||||||
module.exports = { x: { y: \"\" } };
|
module.exports = { x: { y: \"\" } };"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
exports[`test client.js 1`] = `
|
exports[`test client.js 1`] = `
|
||||||
"var y:number = x;
|
"var y:number = x;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
var y: number = x;
|
var y: number = x;"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
exports[`test lib.js 1`] = `
|
exports[`test lib.js 1`] = `
|
||||||
"declare var x: string;
|
"declare var x: string;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
declare var x: string;
|
declare var x: string;"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -55,64 +55,61 @@ let tests = [
|
||||||
]
|
]
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @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 = [
|
let tests = [
|
||||||
|
// objects on RHS
|
||||||
function() {
|
function() {
|
||||||
\"foo\" in {};
|
\"foo\" in {};
|
||||||
\"foo\" in { foo: null };
|
\"foo\" in { foo: null };
|
||||||
0 in {};
|
0 in {};
|
||||||
0 in { \"0\": null };
|
0 in { \"0\": null };
|
||||||
},
|
},
|
||||||
|
// arrays on RHS
|
||||||
function() {
|
function() {
|
||||||
\"foo\" in [];
|
\"foo\" in [];
|
||||||
0 in [];
|
0 in [];
|
||||||
\"length\" in [];
|
\"length\" in [];
|
||||||
},
|
},
|
||||||
|
// primitive classes on RHS
|
||||||
function() {
|
function() {
|
||||||
\"foo\" in new String(\"bar\");
|
\"foo\" in new String(\"bar\");
|
||||||
\"foo\" in new Number(123);
|
\"foo\" in new Number(123);
|
||||||
},
|
},
|
||||||
|
// primitives on RHS
|
||||||
function() {
|
function() {
|
||||||
\"foo\" in 123;
|
\"foo\" in 123;
|
||||||
|
// error
|
||||||
\"foo\" in \"bar\";
|
\"foo\" in \"bar\";
|
||||||
|
// error
|
||||||
\"foo\" in void 0;
|
\"foo\" in void 0;
|
||||||
\"foo\" in null;
|
// error
|
||||||
|
\"foo\" in null; // error
|
||||||
},
|
},
|
||||||
|
// bogus stuff on LHS
|
||||||
function() {
|
function() {
|
||||||
null in {};
|
null in {};
|
||||||
|
// error
|
||||||
void 0 in {};
|
void 0 in {};
|
||||||
|
// error
|
||||||
({}) in {};
|
({}) in {};
|
||||||
|
// error
|
||||||
[] in {};
|
[] in {};
|
||||||
false in [];
|
// error
|
||||||
|
false in []; // error
|
||||||
},
|
},
|
||||||
|
// in predicates
|
||||||
function() {
|
function() {
|
||||||
if (\"foo\" in 123) {}
|
if (\"foo\" in 123) {}
|
||||||
|
// error
|
||||||
if (!\"foo\" in {}) {}
|
if (!\"foo\" in {}) {}
|
||||||
|
// error, !\'foo\' is a boolean
|
||||||
if (!(\"foo\" in {})) {}
|
if (!(\"foo\" in {})) {}
|
||||||
},
|
},
|
||||||
|
// annotations on RHS
|
||||||
function(x: Object, y: mixed) {
|
function(x: Object, y: mixed) {
|
||||||
\"foo\" in x;
|
\"foo\" in x;
|
||||||
\"foo\" in y;
|
// ok
|
||||||
|
\"foo\" in y; // error
|
||||||
}
|
}
|
||||||
];
|
];"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -27,12 +27,9 @@ for (const { baz } of bazzes) {
|
||||||
(baz: number); // error: string ~> number
|
(baz: number); // error: string ~> number
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// errors: const cannot be reassigned
|
|
||||||
// regression tests -- OK to assign consts like this:
|
|
||||||
// error: string ~> number
|
|
||||||
// error: string ~> number
|
|
||||||
// error: string ~> number
|
|
||||||
const x = 0;
|
const x = 0;
|
||||||
|
|
||||||
|
// errors: const cannot be reassigned
|
||||||
x++;
|
x++;
|
||||||
x--;
|
x--;
|
||||||
x += 0;
|
x += 0;
|
||||||
|
@ -45,15 +42,18 @@ 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 { foo } = { foo: \"foo\" };
|
||||||
const [ bar ] = [ \"bar\" ];
|
const [ bar ] = [ \"bar\" ];
|
||||||
(foo: number);
|
(foo: number);
|
||||||
|
// error: string ~> number
|
||||||
(bar: number);
|
(bar: number);
|
||||||
|
// error: string ~> number
|
||||||
declare var bazzes: { baz: string }[];
|
declare var bazzes: { baz: string }[];
|
||||||
for (const { baz } of bazzes) {
|
for (const { baz } of bazzes) {
|
||||||
(baz: number);
|
(baz: number); // error: string ~> number
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test rebinding.js 1`] = `
|
exports[`test rebinding.js 1`] = `
|
||||||
|
@ -265,188 +265,189 @@ function fn_params_clash_fn_binding(x,y) {
|
||||||
* const x x x x x x
|
* const x x x x x x
|
||||||
* var x x x x
|
* var x x x x
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// type 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() {
|
function type_type() {
|
||||||
type A = number;
|
type A = number;
|
||||||
type A = number;
|
type A = number; // error: name already bound
|
||||||
}
|
}
|
||||||
|
|
||||||
function type_class() {
|
function type_class() {
|
||||||
type A = number;
|
type A = number;
|
||||||
class A {}
|
class A {} // error: name already bound
|
||||||
}
|
}
|
||||||
|
|
||||||
function type_let() {
|
function type_let() {
|
||||||
type A = number;
|
type A = number;
|
||||||
let A = 0;
|
let A = 0; // error: name already bound
|
||||||
}
|
}
|
||||||
|
|
||||||
function type_const() {
|
function type_const() {
|
||||||
type A = number;
|
type A = number;
|
||||||
const A = 0;
|
const A = 0; // error: name already bound
|
||||||
}
|
}
|
||||||
|
|
||||||
function type_var() {
|
function type_var() {
|
||||||
type A = number;
|
type A = number;
|
||||||
var A = 0;
|
var A = 0; // error: name already bound
|
||||||
}
|
}
|
||||||
|
|
||||||
function type_reassign() {
|
function type_reassign() {
|
||||||
type A = number;
|
type A = number;
|
||||||
A = 42;
|
A = 42; // error: type alias ref\'d from value pos
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// class x *
|
||||||
function class_type() {
|
function class_type() {
|
||||||
class A {}
|
class A {}
|
||||||
type A = number;
|
type A = number; // error: name already bound
|
||||||
}
|
}
|
||||||
|
|
||||||
function class_class() {
|
function class_class() {
|
||||||
class A {}
|
class A {}
|
||||||
class A {}
|
class A {} // error: name already bound
|
||||||
}
|
}
|
||||||
|
|
||||||
function class_let() {
|
function class_let() {
|
||||||
class A {}
|
class A {}
|
||||||
let A = 0;
|
let A = 0; // error: name already bound
|
||||||
}
|
}
|
||||||
|
|
||||||
function class_const() {
|
function class_const() {
|
||||||
class A {}
|
class A {}
|
||||||
const A = 0;
|
const A = 0; // error: name already bound
|
||||||
}
|
}
|
||||||
|
|
||||||
function class_var() {
|
function class_var() {
|
||||||
class A {}
|
class A {}
|
||||||
var A = 0;
|
var A = 0; // error: name already bound
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// let x *
|
||||||
function let_type() {
|
function let_type() {
|
||||||
let A = 0;
|
let A = 0;
|
||||||
type A = number;
|
type A = number; // error: name already bound
|
||||||
}
|
}
|
||||||
|
|
||||||
function let_class() {
|
function let_class() {
|
||||||
let A = 0;
|
let A = 0;
|
||||||
class A {}
|
class A {} // error: name already bound
|
||||||
}
|
}
|
||||||
|
|
||||||
function let_let() {
|
function let_let() {
|
||||||
let A = 0;
|
let A = 0;
|
||||||
let A = 0;
|
let A = 0; // error: name already bound
|
||||||
}
|
}
|
||||||
|
|
||||||
function let_const() {
|
function let_const() {
|
||||||
let A = 0;
|
let A = 0;
|
||||||
const A = 0;
|
const A = 0; // error: name already bound
|
||||||
}
|
}
|
||||||
|
|
||||||
function let_var() {
|
function let_var() {
|
||||||
let A = 0;
|
let A = 0;
|
||||||
var A = 0;
|
var A = 0; // error: name already bound
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// const x *
|
||||||
function const_type() {
|
function const_type() {
|
||||||
const A = 0;
|
const A = 0;
|
||||||
type A = number;
|
type A = number; // error: name already bound
|
||||||
}
|
}
|
||||||
|
|
||||||
function const_class() {
|
function const_class() {
|
||||||
const A = 0;
|
const A = 0;
|
||||||
class A {}
|
class A {} // error: name already bound
|
||||||
}
|
}
|
||||||
|
|
||||||
function const_let() {
|
function const_let() {
|
||||||
const A = 0;
|
const A = 0;
|
||||||
let A = 0;
|
let A = 0; // error: name already bound
|
||||||
}
|
}
|
||||||
|
|
||||||
function const_const() {
|
function const_const() {
|
||||||
const A = 0;
|
const A = 0;
|
||||||
const A = 0;
|
const A = 0; // error: name already bound
|
||||||
}
|
}
|
||||||
|
|
||||||
function const_var() {
|
function const_var() {
|
||||||
const A = 0;
|
const A = 0;
|
||||||
var A = 0;
|
var A = 0; // error: name already bound
|
||||||
}
|
}
|
||||||
|
|
||||||
function const_reassign() {
|
function const_reassign() {
|
||||||
const A = 0;
|
const A = 0;
|
||||||
A = 42;
|
A = 42; // error: cannot be reassigned
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// var x *
|
||||||
function var_type() {
|
function var_type() {
|
||||||
var A = 0;
|
var A = 0;
|
||||||
type A = number;
|
type A = number; // error: name already bound
|
||||||
}
|
}
|
||||||
|
|
||||||
function var_class() {
|
function var_class() {
|
||||||
var A = 0;
|
var A = 0;
|
||||||
class A {}
|
class A {} // error: name already bound
|
||||||
}
|
}
|
||||||
|
|
||||||
function var_let() {
|
function var_let() {
|
||||||
var A = 0;
|
var A = 0;
|
||||||
let A = 0;
|
let A = 0; // error: name already bound
|
||||||
}
|
}
|
||||||
|
|
||||||
function var_const() {
|
function var_const() {
|
||||||
var A = 0;
|
var A = 0;
|
||||||
const A = 0;
|
const A = 0; // error: name already bound
|
||||||
}
|
}
|
||||||
|
|
||||||
function var_var() {
|
function var_var() {
|
||||||
var A = 0;
|
var A = 0;
|
||||||
var A = 0;
|
var A = 0; // OK
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// function x *
|
||||||
function function_toplevel() {
|
function function_toplevel() {
|
||||||
function a() {}
|
function a() {}
|
||||||
|
|
||||||
function a() {}
|
function a() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
function function_block() {
|
function function_block() {
|
||||||
{
|
{
|
||||||
function a() {}
|
function a() {}
|
||||||
|
|
||||||
function a() {}
|
function a() {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// corner cases
|
||||||
function var_shadow_nested_scope() {
|
function var_shadow_nested_scope() {
|
||||||
{
|
{
|
||||||
let x = 0;
|
let x = 0;
|
||||||
{
|
{
|
||||||
var x = 0;
|
var x = 0; // error: name already bound
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function type_shadow_nested_scope() {
|
function type_shadow_nested_scope() {
|
||||||
{
|
{
|
||||||
let x = 0;
|
let x = 0;
|
||||||
{
|
{
|
||||||
type x = string;
|
type x = string; // error: name already bound
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function fn_params_name_clash(x, x) {}
|
|
||||||
|
// fn params name clash
|
||||||
|
function fn_params_name_clash(x, x /* error: x already bound */) {}
|
||||||
function fn_params_clash_fn_binding(x, y) {
|
function fn_params_clash_fn_binding(x, y) {
|
||||||
let x = 0;
|
let x = 0;
|
||||||
var y = 0;
|
// error: x already bound
|
||||||
}
|
var y = 0; // OK
|
||||||
"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test scope.js 1`] = `
|
exports[`test scope.js 1`] = `
|
||||||
|
@ -560,125 +561,124 @@ function default_param_2() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// 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() {
|
function block_scope() {
|
||||||
let a: number = 0;
|
let a: number = 0;
|
||||||
var b: number = 0;
|
var b: number = 0;
|
||||||
{
|
{
|
||||||
let a = \"\";
|
let a = \"\";
|
||||||
var b = \"\";
|
// ok: local to block
|
||||||
|
var b = \"\"; // error: string ~> number
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function switch_scope(x: string) {
|
function switch_scope(x: string) {
|
||||||
let a: number = 0;
|
let a: number = 0;
|
||||||
var b: number = 0;
|
var b: number = 0;
|
||||||
switch (x) {
|
switch (x) {
|
||||||
case \"foo\":
|
case \"foo\":
|
||||||
let a = \"\";
|
let a = \"\";
|
||||||
|
// ok: local to switch
|
||||||
var b = \"\";
|
var b = \"\";
|
||||||
|
// error: string ~> number
|
||||||
break;
|
break;
|
||||||
case \"bar\":
|
case \"bar\":
|
||||||
let a = \"\";
|
let a = \"\";
|
||||||
|
// error: a already bound in switch
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
function switch_scope2(x: number) {
|
function switch_scope2(x: number) {
|
||||||
switch (x) {
|
switch (x) {
|
||||||
case 0:
|
case 0:
|
||||||
a = \"\";
|
a = \"\";
|
||||||
|
// error: assign before declaration
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
var b = a;
|
var b = a;
|
||||||
|
// error: use before declaration
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
let a = \"\";
|
let a = \"\";
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
a = \"\";
|
a = \"\";
|
||||||
|
// error: skipped initializer
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
var c: string = a;
|
var c: string = a;
|
||||||
|
// error: skipped initializer
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
a = \"\";
|
a = \"\"; // error: a no longer in scope
|
||||||
}
|
}
|
||||||
|
|
||||||
function try_scope() {
|
function try_scope() {
|
||||||
let a: number = 0;
|
let a: number = 0;
|
||||||
try {
|
try {
|
||||||
let a = \"\";
|
let a = \"\"; // ok
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
let a = \"\";
|
let a = \"\"; // ok
|
||||||
} finally {
|
} finally {
|
||||||
let a = \"\";
|
let a = \"\"; // ok
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function for_scope_let() {
|
function for_scope_let() {
|
||||||
let a: number = 0;
|
let a: number = 0;
|
||||||
for (let a = \"\"; ; ) {}
|
for (let a = \"\" /* ok: local to init */; ; ) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
function for_scope_var() {
|
function for_scope_var() {
|
||||||
var a: number = 0;
|
var a: number = 0;
|
||||||
for (var a = \"\"; ; ) {}
|
for (var a = \"\" /* error: string ~> number */; ; ) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
function for_in_scope_let(o: Object) {
|
function for_in_scope_let(o: Object) {
|
||||||
let a: number = 0;
|
let a: number = 0;
|
||||||
for (let a in o) {}
|
for (let a /* ok: local to init */ in o) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
function for_in_scope_var(o: Object) {
|
function for_in_scope_var(o: Object) {
|
||||||
var a: number = 0;
|
var a: number = 0;
|
||||||
for (var a in o) {}
|
for (var a /* error: string ~> number */ in o) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
function for_of_scope_let(xs: string[]) {
|
function for_of_scope_let(xs: string[]) {
|
||||||
let a: number = 0;
|
let a: number = 0;
|
||||||
for (let a of xs) {}
|
for (let a /* ok: local to init */ of xs) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
function for_of_scope_var(xs: string[]) {
|
function for_of_scope_var(xs: string[]) {
|
||||||
var a: number = 0;
|
var a: number = 0;
|
||||||
for (var a of xs) {}
|
for (var a /* error: string ~> number */ of xs) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
function default_param_1() {
|
function default_param_1() {
|
||||||
function f(x: () => string = f): number {
|
// function binding in scope in default expr
|
||||||
|
function f(
|
||||||
|
// error: number ~> string
|
||||||
|
x: () => string = f
|
||||||
|
): number {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function default_param_2() {
|
function default_param_2() {
|
||||||
|
// fn body bindings not visible from param scope
|
||||||
let a = \"\";
|
let a = \"\";
|
||||||
function f0(x = () => a): number {
|
function f0(x = () => a): number {
|
||||||
let a = 0;
|
let a = 0;
|
||||||
return x();
|
return x(); // error: string ~> number
|
||||||
}
|
}
|
||||||
function f1(x = b): number {
|
function f1(x = b /* error: cannot resolve b */): number {
|
||||||
let b = 0;
|
let b = 0;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test tdz.js 1`] = `
|
exports[`test tdz.js 1`] = `
|
||||||
|
@ -784,9 +784,15 @@ a = 10;
|
||||||
f(a); // ok, a: number (not ?number)
|
f(a); // ok, a: number (not ?number)
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/** @flow */
|
/** @flow */
|
||||||
|
|
||||||
// -- types ---
|
// -- types ---
|
||||||
|
|
||||||
// type aliases are hoisted and always available
|
// type aliases are hoisted and always available
|
||||||
|
|
||||||
|
type T1 = T2;
|
||||||
// ok
|
// ok
|
||||||
|
type T2 = number;
|
||||||
|
|
||||||
// --- lets ---
|
// --- lets ---
|
||||||
// to be correct, we would
|
// to be correct, we would
|
||||||
// - not allow forward refs to lets from value positions,
|
// - not allow forward refs to lets from value positions,
|
||||||
|
@ -799,92 +805,96 @@ f(a); // ok, a: number (not ?number)
|
||||||
// a lambda runs. But a simple conservative approach would prohibit
|
// a lambda runs. But a simple conservative approach would prohibit
|
||||||
// forward references to let/consts from within lambdas entirely,
|
// forward references to let/consts from within lambdas entirely,
|
||||||
// which would be annoying. TODO
|
// which would be annoying. TODO
|
||||||
// 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
|
|
||||||
// ok, finds hoisted outer
|
|
||||||
// ok, finds hoisted inner
|
|
||||||
// ok, hoisted outer not clobbered
|
|
||||||
// out-of-scope TDZ not enforced. sometimes right...
|
|
||||||
// ok, g doesn\'t run in TDZ
|
|
||||||
// ...sometimes wrong
|
|
||||||
// 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.
|
|
||||||
//
|
|
||||||
// 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
|
|
||||||
// initialized before use)
|
|
||||||
// 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() {
|
function f0() {
|
||||||
var v = x * c;
|
var v = x * c;
|
||||||
|
// errors, let + const referenced before decl
|
||||||
let x = 0;
|
let x = 0;
|
||||||
const c = 0;
|
const c = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function f1(b) {
|
function f1(b) {
|
||||||
x = 10;
|
x = 10;
|
||||||
|
// error, attempt to write to let before decl
|
||||||
let x = 0;
|
let x = 0;
|
||||||
if (b) {
|
if (b) {
|
||||||
y = 10;
|
y = 10;
|
||||||
|
// error, attempt to write to let before decl
|
||||||
let y = 0;
|
let y = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function f2() {
|
function f2() {
|
||||||
{
|
{
|
||||||
var v = x * c;
|
var v = x * c; // errors, let + const referenced before decl
|
||||||
}
|
}
|
||||||
let x = 0;
|
let x = 0;
|
||||||
const c = 0;
|
const c = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// functions are let-scoped and hoisted
|
||||||
function f3() {
|
function f3() {
|
||||||
var s: string = foo();
|
var s: string = foo();
|
||||||
|
// ok, finds hoisted outer
|
||||||
{
|
{
|
||||||
var n: number = foo();
|
var n: number = foo();
|
||||||
|
// ok, finds hoisted inner
|
||||||
function foo() {
|
function foo() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var s2: string = foo();
|
var s2: string = foo();
|
||||||
|
// ok, hoisted outer not clobbered
|
||||||
function foo() {
|
function foo() {
|
||||||
return \"\";
|
return \"\";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// out-of-scope TDZ not enforced. sometimes right...
|
||||||
function f4() {
|
function f4() {
|
||||||
function g() {
|
function g() {
|
||||||
return x + c;
|
return x + c;
|
||||||
}
|
}
|
||||||
|
// ok, g doesn\'t run in TDZ
|
||||||
let x = 0;
|
let x = 0;
|
||||||
const c = 0;
|
const c = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ...sometimes wrong
|
||||||
function f5() {
|
function f5() {
|
||||||
function g() {
|
function g() {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
g();
|
g();
|
||||||
|
// should error, but doesn\'t currently
|
||||||
let x = 0;
|
let x = 0;
|
||||||
const c = 0;
|
const c = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - 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;
|
var x: C;
|
||||||
|
// ok
|
||||||
var y = new C();
|
var y = new C();
|
||||||
|
// error: let ref before decl from value position
|
||||||
class C {}
|
class C {}
|
||||||
|
|
||||||
var z: C = new C();
|
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
|
||||||
|
// initialized before use)
|
||||||
var a: number;
|
var a: number;
|
||||||
|
// not an error per se - only if used before init
|
||||||
function f(n: number) {
|
function f(n: number) {
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
f(a);
|
f(a);
|
||||||
|
// error: undefined ~/> number
|
||||||
a = 10;
|
a = 10;
|
||||||
f(a);
|
|
||||||
"
|
f(a); // ok, a: number (not ?number)"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -68,109 +68,108 @@ for (let [x, y]: [string, number] of a.entries()) {} // incorrect
|
||||||
for (let [x, y]: [number, number] of a.entries()) {} // incorrect
|
for (let [x, y]: [number, number] of a.entries()) {} // incorrect
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
|
const a: FormData = new FormData();
|
||||||
// correct
|
// correct
|
||||||
|
new FormData(\"\");
|
||||||
// incorrect
|
// incorrect
|
||||||
|
new FormData(document.createElement(\"input\"));
|
||||||
// incorrect
|
// incorrect
|
||||||
|
new FormData(document.createElement(\"form\"));
|
||||||
// correct
|
// correct
|
||||||
// has
|
// has
|
||||||
|
const b: boolean = a.has(\"foo\");
|
||||||
// correct
|
// correct
|
||||||
// get
|
// get
|
||||||
|
const c: ?(string | File) = a.get(\"foo\");
|
||||||
// correct
|
// correct
|
||||||
|
const d: string = a.get(\"foo\");
|
||||||
// incorrect
|
// incorrect
|
||||||
|
const e: Blob = a.get(\"foo\");
|
||||||
// incorrect
|
// incorrect
|
||||||
|
const f: ?(string | File | Blob) = a.get(\"foo\");
|
||||||
// incorrect
|
// incorrect
|
||||||
|
a.get(2);
|
||||||
// incorrect
|
// incorrect
|
||||||
// getAll
|
// getAll
|
||||||
|
const a1: Array<string | File> = a.getAll(\"foo\");
|
||||||
// correct
|
// correct
|
||||||
|
const a2: Array<string | File | number> = a.getAll(\"foo\");
|
||||||
// incorrect
|
// incorrect
|
||||||
|
const a3: Array<string | Blob | File> = a.getAll(\"foo\");
|
||||||
// incorrect
|
// incorrect
|
||||||
|
a.getAll(23);
|
||||||
// incorrect
|
// incorrect
|
||||||
// set
|
// set
|
||||||
|
a.set(\"foo\", \"bar\");
|
||||||
// correct
|
// correct
|
||||||
|
a.set(\"foo\", {});
|
||||||
// incorrect
|
// incorrect
|
||||||
|
a.set(2, \"bar\");
|
||||||
// incorrect
|
// incorrect
|
||||||
|
a.set(\"foo\", \"bar\", \"baz\");
|
||||||
// incorrect
|
// incorrect
|
||||||
|
a.set(\"bar\", new File([], \"q\"));
|
||||||
// correct
|
// correct
|
||||||
|
a.set(\"bar\", new File([], \"q\"), \"x\");
|
||||||
// correct
|
// correct
|
||||||
|
a.set(\"bar\", new File([], \"q\"), 2);
|
||||||
// incorrect
|
// incorrect
|
||||||
|
a.set(\"bar\", new Blob());
|
||||||
// correct
|
// correct
|
||||||
|
a.set(\"bar\", new Blob(), \"x\");
|
||||||
// correct
|
// correct
|
||||||
|
a.set(\"bar\", new Blob(), 2);
|
||||||
// incorrect
|
// incorrect
|
||||||
// append
|
// append
|
||||||
|
a.append(\"foo\", \"bar\");
|
||||||
// correct
|
// correct
|
||||||
|
a.append(\"foo\", {});
|
||||||
// incorrect
|
// incorrect
|
||||||
|
a.append(2, \"bar\");
|
||||||
// incorrect
|
// incorrect
|
||||||
|
a.append(\"foo\", \"bar\", \"baz\");
|
||||||
// incorrect
|
// incorrect
|
||||||
|
a.append(\"foo\", \"bar\");
|
||||||
// incorrect
|
// incorrect
|
||||||
|
a.append(\"bar\", new File([], \"q\"));
|
||||||
// correct
|
// correct
|
||||||
|
a.append(\"bar\", new File([], \"q\"), \"x\");
|
||||||
// correct
|
// correct
|
||||||
|
a.append(\"bar\", new File([], \"q\"), 2);
|
||||||
// incorrect
|
// incorrect
|
||||||
|
a.append(\"bar\", new Blob());
|
||||||
// correct
|
// correct
|
||||||
|
a.append(\"bar\", new Blob(), \"x\");
|
||||||
// correct
|
// correct
|
||||||
|
a.append(\"bar\", new Blob(), 2);
|
||||||
// incorrect
|
// incorrect
|
||||||
// delete
|
// delete
|
||||||
|
a.delete(\"xx\");
|
||||||
// correct
|
// correct
|
||||||
|
a.delete(3);
|
||||||
// incorrect
|
// incorrect
|
||||||
// keys
|
// keys
|
||||||
|
for (let x: string of a.keys()) {}
|
||||||
// correct
|
// correct
|
||||||
|
for (let x: number of a.keys()) {}
|
||||||
// incorrect
|
// incorrect
|
||||||
// values
|
// values
|
||||||
|
for (let x: string | File of a.values()) {}
|
||||||
// correct
|
// correct
|
||||||
|
for (let x: string | File | Blob of a.values()) {}
|
||||||
// incorrect
|
// incorrect
|
||||||
// entries
|
// 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(2);
|
|
||||||
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(23);
|
|
||||||
a.set(\"foo\", \"bar\");
|
|
||||||
a.set(\"foo\", {});
|
|
||||||
a.set(2, \"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\"), 2);
|
|
||||||
a.set(\"bar\", new Blob());
|
|
||||||
a.set(\"bar\", new Blob(), \"x\");
|
|
||||||
a.set(\"bar\", new Blob(), 2);
|
|
||||||
a.append(\"foo\", \"bar\");
|
|
||||||
a.append(\"foo\", {});
|
|
||||||
a.append(2, \"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\"), 2);
|
|
||||||
a.append(\"bar\", new Blob());
|
|
||||||
a.append(\"bar\", new Blob(), \"x\");
|
|
||||||
a.append(\"bar\", new Blob(), 2);
|
|
||||||
a.delete(\"xx\");
|
|
||||||
a.delete(3);
|
|
||||||
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 ]: [string, string | File] of a.entries()) {}
|
for (let [ x, y ]: [string, string | File] of a.entries()) {}
|
||||||
|
// correct
|
||||||
for (let [ x, y ]: [string, string | File | Blob] of a.entries()) {}
|
for (let [ x, y ]: [string, string | File | Blob] of a.entries()) {}
|
||||||
|
// incorrect
|
||||||
for (let [ x, y ]: [number, string] of a.entries()) {}
|
for (let [ x, y ]: [number, string] of a.entries()) {}
|
||||||
|
// incorrect
|
||||||
for (let [ x, y ]: [string, number] of a.entries()) {}
|
for (let [ x, y ]: [string, number] of a.entries()) {}
|
||||||
for (let [ x, y ]: [number, number] of a.entries()) {}
|
// incorrect
|
||||||
"
|
for (let [ x, y ]: [number, number] of a.entries()) {} // incorrect"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test MutationObserver.js 1`] = `
|
exports[`test MutationObserver.js 1`] = `
|
||||||
|
@ -205,26 +204,8 @@ o.takeRecords(); // correct
|
||||||
o.disconnect(); // correct
|
o.disconnect(); // correct
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
// correct
|
|
||||||
// correct
|
|
||||||
// correct
|
|
||||||
// incorrect
|
|
||||||
// incorrect
|
|
||||||
// incorrect
|
|
||||||
// observe
|
|
||||||
// correct
|
|
||||||
// correct
|
|
||||||
// incorrect
|
|
||||||
// incorrect
|
|
||||||
// incorrect
|
|
||||||
// incorrect
|
|
||||||
// incorrect
|
|
||||||
// incorrect
|
|
||||||
// takeRecords
|
|
||||||
// correct
|
|
||||||
// disconnect
|
|
||||||
// correct
|
|
||||||
function callback(
|
function callback(
|
||||||
arr: Array<MutationRecord>,
|
arr: Array<MutationRecord>,
|
||||||
observer: MutationObserver
|
observer: MutationObserver
|
||||||
|
@ -232,21 +213,38 @@ function callback(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const o: MutationObserver = new MutationObserver(callback);
|
const o: MutationObserver = new MutationObserver(callback);
|
||||||
|
// correct
|
||||||
new MutationObserver((arr: Array<MutationRecord>) => true);
|
new MutationObserver((arr: Array<MutationRecord>) => true);
|
||||||
|
// correct
|
||||||
new MutationObserver(() => {});
|
new MutationObserver(() => {});
|
||||||
|
// correct
|
||||||
new MutationObserver();
|
new MutationObserver();
|
||||||
|
// incorrect
|
||||||
new MutationObserver(42);
|
new MutationObserver(42);
|
||||||
|
// incorrect
|
||||||
new MutationObserver((n: number) => {});
|
new MutationObserver((n: number) => {});
|
||||||
|
// incorrect
|
||||||
|
// observe
|
||||||
const div = document.createElement(\"div\");
|
const div = document.createElement(\"div\");
|
||||||
o.observe(div, { attributes: true, attributeFilter: [ \"style\" ] });
|
o.observe(div, { attributes: true, attributeFilter: [ \"style\" ] });
|
||||||
|
// correct
|
||||||
o.observe(div, { characterData: true, invalid: true });
|
o.observe(div, { characterData: true, invalid: true });
|
||||||
|
// correct
|
||||||
o.observe();
|
o.observe();
|
||||||
|
// incorrect
|
||||||
o.observe(\"invalid\");
|
o.observe(\"invalid\");
|
||||||
|
// incorrect
|
||||||
o.observe(div);
|
o.observe(div);
|
||||||
|
// incorrect
|
||||||
o.observe(div, {});
|
o.observe(div, {});
|
||||||
|
// incorrect
|
||||||
o.observe(div, { subtree: true });
|
o.observe(div, { subtree: true });
|
||||||
|
// incorrect
|
||||||
o.observe(div, { attributes: true, attributeFilter: true });
|
o.observe(div, { attributes: true, attributeFilter: true });
|
||||||
|
// incorrect
|
||||||
|
// takeRecords
|
||||||
o.takeRecords();
|
o.takeRecords();
|
||||||
o.disconnect();
|
// correct
|
||||||
"
|
// disconnect
|
||||||
|
o.disconnect(); // correct"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -6,10 +6,10 @@ function bar<X:number, Y:X>(x:X, y:Y): number { return y*0; }
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
function foo<X, Y: X>(x: X, y: Y): void {}
|
function foo<X, Y: X>(x: X, y: Y): void {}
|
||||||
foo(0, \"\");
|
foo(0, \"\");
|
||||||
|
|
||||||
function bar<X: number, Y: X>(x: X, y: Y): number {
|
function bar<X: number, Y: X>(x: X, y: Y): number {
|
||||||
return y * 0;
|
return y * 0;
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test test.js 1`] = `
|
exports[`test test.js 1`] = `
|
||||||
|
@ -39,38 +39,37 @@ var q: number = c.qux(0);
|
||||||
/* 2 more errors, since argument U = number is incompatible with T = string, and
|
/* 2 more errors, since argument U = number is incompatible with T = string, and
|
||||||
* result T = string is incompatible with number */
|
* result T = string is incompatible with number */
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// 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 {
|
function foo<T: number>(x: T): T {
|
||||||
var _ = x * 1;
|
var _ = x * 1;
|
||||||
|
// OK
|
||||||
var y: string = x;
|
var y: string = x;
|
||||||
return x;
|
// error
|
||||||
|
return x; // OK
|
||||||
}
|
}
|
||||||
|
|
||||||
class C<T: number> {
|
class C<T: number> {
|
||||||
bar<U: number>(x: U): T {
|
bar<U: number>(x: U): T {
|
||||||
return x;
|
return x; // error, since T: number and U: number does not imply U: T
|
||||||
}
|
}
|
||||||
qux<U: T>(x: U): T {
|
qux<U: T>(x: U): T {
|
||||||
var _ = x * 1;
|
var _ = x * 1;
|
||||||
|
// OK, since T: number and U: T implies U: number
|
||||||
var y: string = x;
|
var y: string = x;
|
||||||
return x;
|
// error
|
||||||
|
return x; // OK, since U: T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function example<T: { x: number }>(o: T): T {
|
function example<T: { x: number }>(o: T): T {
|
||||||
o.x = 0;
|
o.x = 0;
|
||||||
return o;
|
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 obj2: { x: number } = example({ x: 0 });
|
||||||
|
|
||||||
var c: C<string> = new C();
|
var c: C<string> = new C();
|
||||||
|
// error, since T = string is incompatible with number
|
||||||
var q: number = c.qux(0);
|
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 */"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -68,19 +68,6 @@ function test_const() {
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// 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) {
|
function foo(b) {
|
||||||
var x = b ? null : false;
|
var x = b ? null : false;
|
||||||
var z;
|
var z;
|
||||||
|
@ -89,10 +76,11 @@ function foo(b) {
|
||||||
z = \"\";
|
z = \"\";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
var y: number = x;
|
var y: number = x; // error: boolean !~> number
|
||||||
}
|
}
|
||||||
var w: number = z;
|
var w: number = z; // 2 errors: ?string !~> number
|
||||||
}
|
}
|
||||||
|
|
||||||
function bar(b) {
|
function bar(b) {
|
||||||
var x = b ? null : false;
|
var x = b ? null : false;
|
||||||
if (x == null)
|
if (x == null)
|
||||||
|
@ -100,14 +88,17 @@ function bar(b) {
|
||||||
switch (\"\") {
|
switch (\"\") {
|
||||||
case 0:
|
case 0:
|
||||||
var y: number = x;
|
var y: number = x;
|
||||||
|
// error: boolean !~> number
|
||||||
x = \"\";
|
x = \"\";
|
||||||
case 1:
|
case 1:
|
||||||
var z: number = x;
|
var z: number = x;
|
||||||
|
// 2 errors: (boolean | string) !~> number
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
}
|
}
|
||||||
var w: number = x;
|
var w: number = x; // 2 errors: (boolean | string) !~> number
|
||||||
}
|
}
|
||||||
|
|
||||||
function bar2(b) {
|
function bar2(b) {
|
||||||
var x = b ? null : false;
|
var x = b ? null : false;
|
||||||
if (x == null)
|
if (x == null)
|
||||||
|
@ -115,16 +106,19 @@ function bar2(b) {
|
||||||
switch (\"\") {
|
switch (\"\") {
|
||||||
case 0: {
|
case 0: {
|
||||||
let y: number = x;
|
let y: number = x;
|
||||||
|
// error: boolean !~> number
|
||||||
x = \"\";
|
x = \"\";
|
||||||
}
|
}
|
||||||
case 1: {
|
case 1: {
|
||||||
let z: number = x;
|
let z: number = x;
|
||||||
|
// 2 errors: (boolean | string) !~> number
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
}
|
}
|
||||||
var w: number = x;
|
var w: number = x; // 2 errors: (boolean | string) !~> number
|
||||||
}
|
}
|
||||||
|
|
||||||
function qux(b) {
|
function qux(b) {
|
||||||
var z = 0;
|
var z = 0;
|
||||||
while (b) {
|
while (b) {
|
||||||
|
@ -133,20 +127,26 @@ function qux(b) {
|
||||||
z = \"\";
|
z = \"\";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// error: string !~> number
|
||||||
z = 0;
|
z = 0;
|
||||||
}
|
}
|
||||||
var w: number = z;
|
var w: number = z; // error: string !~> number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// same basic test as foo(), but with const. probes the
|
||||||
|
// logic that still uses havoc to do env resets.
|
||||||
function test_const() {
|
function test_const() {
|
||||||
let st: string = \"abc\";
|
let st: string = \"abc\";
|
||||||
|
|
||||||
for (let i = 1; i < 100; i++) {
|
for (let i = 1; i < 100; i++) {
|
||||||
const fooRes: ?string = \"HEY\";
|
const fooRes: ?string = \"HEY\";
|
||||||
if (!fooRes) {
|
if (!fooRes) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
st = fooRes;
|
|
||||||
|
st = fooRes; // no error
|
||||||
}
|
}
|
||||||
|
|
||||||
return st;
|
return st;
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -5,8 +5,7 @@ module.exports = o;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
var o = Object.freeze({ foo: 0 });
|
var o = Object.freeze({ foo: 0 });
|
||||||
(o.foo: string);
|
(o.foo: string);
|
||||||
module.exports = o;
|
module.exports = o;"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test test2.js 1`] = `
|
exports[`test test2.js 1`] = `
|
||||||
|
@ -14,6 +13,5 @@ exports[`test test2.js 1`] = `
|
||||||
(o.foo: string);
|
(o.foo: string);
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
var o = require(\"./test\");
|
var o = require(\"./test\");
|
||||||
(o.foo: string);
|
(o.foo: string);"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -17,21 +17,20 @@ function g() {
|
||||||
foo = foo1;
|
foo = foo1;
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// error: number !~> string
|
|
||||||
// error: string !~> number
|
|
||||||
// error: string !~> number
|
|
||||||
var a = [ \"...\" ];
|
var a = [ \"...\" ];
|
||||||
var b = a.map(function(x) {
|
var b = a.map(function(x) {
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
var c: string = b[0];
|
var c: string = b[0];
|
||||||
|
// error: number !~> string
|
||||||
var array = [];
|
var array = [];
|
||||||
function f() {
|
function f() {
|
||||||
array = array.map(function() {
|
array = array.map(function() {
|
||||||
return \"...\";
|
return \"...\";
|
||||||
});
|
});
|
||||||
var x: number = array[0];
|
var x: number = array[0]; // error: string !~> number
|
||||||
}
|
}
|
||||||
|
|
||||||
var Foo = require(\"./genericfoo\");
|
var Foo = require(\"./genericfoo\");
|
||||||
var foo = new Foo();
|
var foo = new Foo();
|
||||||
function g() {
|
function g() {
|
||||||
|
@ -39,9 +38,9 @@ function g() {
|
||||||
return \"...\";
|
return \"...\";
|
||||||
});
|
});
|
||||||
var x: number = foo1.get();
|
var x: number = foo1.get();
|
||||||
|
// error: string !~> number
|
||||||
foo = foo1;
|
foo = foo1;
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test genericfoo.js 1`] = `
|
exports[`test genericfoo.js 1`] = `
|
||||||
|
@ -68,6 +67,6 @@ class Foo<T> {
|
||||||
return this.x;
|
return this.x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
module.exports = Foo;
|
|
||||||
"
|
module.exports = Foo;"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -31,31 +31,35 @@ function f(): number {
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// You should be able to call objects with call properties
|
// 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 {
|
function a(f: { (): string }, g: { (x: number): string }): string {
|
||||||
return f() + g(123);
|
return f() + g(123);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ...and get an error if the return type is wrong
|
||||||
function b(f: { (): string }): number {
|
function b(f: { (): string }): number {
|
||||||
return f();
|
return f();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ...or if the param type is wrong
|
||||||
function c(f: { (x: number): number }): number {
|
function c(f: { (x: number): number }): number {
|
||||||
return f(\"hello\");
|
return f(\"hello\");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ...or if the arity is wrong
|
||||||
function d(f: { (x: number): number }): number {
|
function d(f: { (x: number): number }): number {
|
||||||
return f();
|
return f();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ...or if there is no call property
|
||||||
function e(f: {}): number {
|
function e(f: {}): number {
|
||||||
return f();
|
return f();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure we complain even if the object literal is unsealed.
|
||||||
function f(): number {
|
function f(): number {
|
||||||
var x = {};
|
var x = {};
|
||||||
return x();
|
return x();
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test B.js 1`] = `
|
exports[`test B.js 1`] = `
|
||||||
|
@ -81,38 +85,41 @@ var y : {} = function (x: number): string { return \"hi\"; };
|
||||||
var z : Object = function (x: number): string { return \"hi\"; };
|
var z : Object = function (x: number): string { return \"hi\"; };
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// You should be able to use a function as an object with a call property
|
// 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 {
|
var a: { (x: number): string } = function(x: number): string {
|
||||||
return \"hi\";
|
return \"hi\";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ...and it should notice when the return type is wrong
|
||||||
var b: { (x: number): number } = function(x: number): string {
|
var b: { (x: number): number } = function(x: number): string {
|
||||||
return \"hi\";
|
return \"hi\";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ...or if the param type is wrong
|
||||||
var c: { (x: string): string } = function(x: number): string {
|
var c: { (x: string): string } = function(x: number): string {
|
||||||
return \"hi\";
|
return \"hi\";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ...or if the arity is wrong
|
||||||
var d: { (): string } = function(x: number): string {
|
var d: { (): string } = function(x: number): string {
|
||||||
return \"hi\";
|
return \"hi\";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ...but subtyping rules still apply
|
||||||
var e: { (x: any): void } = function() {};
|
var e: { (x: any): void } = function() {};
|
||||||
|
// arity
|
||||||
var f: { (): mixed } = function(): string {
|
var f: { (): mixed } = function(): string {
|
||||||
return \"hi\";
|
return \"hi\";
|
||||||
};
|
};
|
||||||
|
// return type
|
||||||
var g: { (x: string): void } = function(x: mixed) {};
|
var g: { (x: string): void } = function(x: mixed) {};
|
||||||
|
// param type
|
||||||
|
// A function can be an object
|
||||||
var y: {} = function(x: number): string {
|
var y: {} = function(x: number): string {
|
||||||
return \"hi\";
|
return \"hi\";
|
||||||
};
|
};
|
||||||
var z: Object = function(x: number): string {
|
var z: Object = function(x: number): string {
|
||||||
return \"hi\";
|
return \"hi\";
|
||||||
};
|
};"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test C.js 1`] = `
|
exports[`test C.js 1`] = `
|
||||||
|
@ -152,35 +159,39 @@ function g(x: {}): Function {
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// You should be able to use an object as a function
|
// 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 {
|
function a(x: { (z: number): string }): (z: number) => string {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ...and it should notice when the return type is wrong
|
||||||
function b(x: { (z: number): string }): (z: number) => number {
|
function b(x: { (z: number): string }): (z: number) => number {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ...or if the param type is wrong
|
||||||
function c(x: { (z: number): string }): (z: string) => string {
|
function c(x: { (z: number): string }): (z: string) => string {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ...or if the arity is wrong
|
||||||
function d(x: { (z: number): string }): () => string {
|
function d(x: { (z: number): string }): () => string {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ...or if it doesn\'t have a call property
|
||||||
function e(x: {}): () => string {
|
function e(x: {}): () => string {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AnyFunT should also be allowed
|
||||||
function f(x: { (z: number): string }): Function {
|
function f(x: { (z: number): string }): Function {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ... but only if the object is callable
|
||||||
function g(x: {}): Function {
|
function g(x: {}): Function {
|
||||||
return x;
|
return x; // error
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test D.js 1`] = `
|
exports[`test D.js 1`] = `
|
||||||
|
@ -208,26 +219,29 @@ function e(x: { (): string; (x: number): string }): () => number {
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// Multiple call properties should also be supported
|
// 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 {
|
function a(f: { (): string, (x: number): string }): string {
|
||||||
return f() + f(123);
|
return f() + f(123);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// It should be fine when a function satisfies them all
|
||||||
var b: { (): string, (x: number): string } = function(x?: number): string {
|
var b: { (): string, (x: number): string } = function(x?: number): string {
|
||||||
return \"hi\";
|
return \"hi\";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ...but should notice when a function doesn\'t satisfy them all
|
||||||
var c: { (): string, (x: number): string } = function(x: number): string {
|
var c: { (): string, (x: number): string } = function(x: number): string {
|
||||||
return \"hi\";
|
return \"hi\";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Only one call property needs to match the function
|
||||||
function d(x: { (): string, (x: number): string }): () => string {
|
function d(x: { (): string, (x: number): string }): () => string {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ...but you need at least one
|
||||||
function e(x: { (): string, (x: number): string }): () => number {
|
function e(x: { (): string, (x: number): string }): () => number {
|
||||||
return x;
|
return x;
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test E.js 1`] = `
|
exports[`test E.js 1`] = `
|
||||||
|
@ -243,14 +257,15 @@ f.myProp = 123;
|
||||||
var c : { myProp: number } = f;
|
var c : { myProp: number } = f;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// Expecting properties that don\'t exist should be an error
|
// Expecting properties that don\'t exist should be an error
|
||||||
// Expecting properties that do exist should be fine
|
|
||||||
// Expecting properties in the functions statics should be fine
|
|
||||||
var a: { someProp: number } = function() {};
|
var a: { someProp: number } = function() {};
|
||||||
|
|
||||||
|
// Expecting properties that do exist should be fine
|
||||||
var b: { apply: Function } = function() {};
|
var b: { apply: Function } = function() {};
|
||||||
|
|
||||||
|
// Expecting properties in the functions statics should be fine
|
||||||
var f = function() {};
|
var f = function() {};
|
||||||
f.myProp = 123;
|
f.myProp = 123;
|
||||||
var c: { myProp: number } = f;
|
var c: { myProp: number } = f;"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test F.js 1`] = `
|
exports[`test F.js 1`] = `
|
||||||
|
@ -277,24 +292,28 @@ var y : {} = (x) => \"hi\"
|
||||||
var z : Object = (x) => \"hi\"
|
var z : Object = (x) => \"hi\"
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// You should be able to use an arrow function as an object with a call property
|
// 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 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();
|
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 } = () => {};
|
var e: { (x: any): void } = () => {};
|
||||||
|
// arity
|
||||||
var f: { (): mixed } = () => \"hi\";
|
var f: { (): mixed } = () => \"hi\";
|
||||||
|
// return type
|
||||||
var g: { (x: Date): void } = x => {
|
var g: { (x: Date): void } = x => {
|
||||||
x * 2;
|
x * 2;
|
||||||
};
|
};
|
||||||
|
// param type (date < number)
|
||||||
|
// A function can be an object
|
||||||
var y: {} = x => \"hi\";
|
var y: {} = x => \"hi\";
|
||||||
var z: Object = x => \"hi\";
|
var z: Object = x => \"hi\";"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -11,11 +11,12 @@ function f(x) {
|
||||||
(f: F);
|
(f: F);
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
type F = { (x: string): number, p?: string };
|
type F = { (x: string): number, p?: string };
|
||||||
|
|
||||||
function f(x) {
|
function f(x) {
|
||||||
return x.length;
|
return x.length;
|
||||||
}
|
}
|
||||||
(f: F);
|
|
||||||
"
|
(f: F);"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test primitives.js 1`] = `
|
exports[`test primitives.js 1`] = `
|
||||||
|
@ -41,23 +42,23 @@ declare var callable: Callable;
|
||||||
callable(0); // error, number ~> string
|
callable(0); // error, number ~> string
|
||||||
callable.call(null, 0); // error, number ~> string
|
callable.call(null, 0); // error, number ~> string
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// error, callable signature not found
|
|
||||||
// error, number ~> string
|
|
||||||
// error, number ~> string
|
|
||||||
// error, number ~> string
|
|
||||||
// error, number ~> string
|
|
||||||
var x = Boolean(4);
|
var x = Boolean(4);
|
||||||
function foo(fn: (value: any) => boolean) {}
|
function foo(fn: (value: any) => boolean) {}
|
||||||
foo(Boolean);
|
foo(Boolean);
|
||||||
|
|
||||||
var dict: { [k: string]: any } = {};
|
var dict: { [k: string]: any } = {};
|
||||||
dict();
|
dict();
|
||||||
|
// error, callable signature not found
|
||||||
interface ICall { (x: string): void }
|
interface ICall { (x: string): void }
|
||||||
declare var icall: ICall;
|
declare var icall: ICall;
|
||||||
icall(0);
|
icall(0);
|
||||||
|
// error, number ~> string
|
||||||
icall.call(null, 0);
|
icall.call(null, 0);
|
||||||
|
// error, number ~> string
|
||||||
type Callable = { (x: string): void };
|
type Callable = { (x: string): void };
|
||||||
|
|
||||||
declare var callable: Callable;
|
declare var callable: Callable;
|
||||||
callable(0);
|
callable(0);
|
||||||
callable.call(null, 0);
|
// error, number ~> string
|
||||||
"
|
callable.call(null, 0); // error, number ~> string"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
exports[`test not_flow.js 1`] = `
|
exports[`test not_flow.js 1`] = `
|
||||||
"1 * \'foo\';
|
"1 * \'foo\';
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
1 * \"foo\";
|
1 * \"foo\";"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -18,18 +18,18 @@ class Bar extends Foo {
|
||||||
/**
|
/**
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
// error
|
|
||||||
class Foo {
|
class Foo {
|
||||||
_method(): string {
|
_method(): string {
|
||||||
return \"this is private\";
|
return \"this is private\";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Bar extends Foo {
|
class Bar extends Foo {
|
||||||
test() {
|
test() {
|
||||||
(this._method(): string);
|
(this._method(): string); // error
|
||||||
}
|
}
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test without_munging.js 1`] = `
|
exports[`test without_munging.js 1`] = `
|
||||||
|
@ -54,16 +54,16 @@ class Bar extends Foo {
|
||||||
* @flow
|
* @flow
|
||||||
* @preventMunge
|
* @preventMunge
|
||||||
*/
|
*/
|
||||||
// ok
|
|
||||||
class Foo {
|
class Foo {
|
||||||
_method(): string {
|
_method(): string {
|
||||||
return \"this is not private\";
|
return \"this is not private\";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Bar extends Foo {
|
class Bar extends Foo {
|
||||||
test() {
|
test() {
|
||||||
(this._method(): string);
|
(this._method(): string); // ok
|
||||||
}
|
}
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -61,19 +61,6 @@ module.exports = {
|
||||||
A: A, B: B, C: C, D: D, E: E
|
A: A, B: B, C: C, D: D, E: E
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// error?
|
|
||||||
// error?
|
|
||||||
// error?
|
|
||||||
// error
|
|
||||||
// error
|
|
||||||
// error
|
|
||||||
// error
|
|
||||||
// error
|
|
||||||
// error B ~> number
|
|
||||||
// error?
|
|
||||||
// error
|
|
||||||
// error
|
|
||||||
// note: above classdefs are sufficiently annotated to export
|
|
||||||
class A {
|
class A {
|
||||||
static x: number;
|
static x: number;
|
||||||
static y: string;
|
static y: string;
|
||||||
|
@ -81,25 +68,34 @@ class A {
|
||||||
static bar(y: string) {}
|
static bar(y: string) {}
|
||||||
}
|
}
|
||||||
A.qux = function(x: string) {};
|
A.qux = function(x: string) {};
|
||||||
|
// error?
|
||||||
class B extends A {
|
class B extends A {
|
||||||
static x: string;
|
static x: string;
|
||||||
|
// error?
|
||||||
static foo(x: string) {}
|
static foo(x: string) {}
|
||||||
|
// error?
|
||||||
static main() {
|
static main() {
|
||||||
B.x = 0;
|
B.x = 0;
|
||||||
|
// error
|
||||||
B.x = \"\";
|
B.x = \"\";
|
||||||
B.foo(0);
|
B.foo(0);
|
||||||
|
// error
|
||||||
B.foo(\"\");
|
B.foo(\"\");
|
||||||
B.y = 0;
|
B.y = 0;
|
||||||
|
// error
|
||||||
B.bar(0);
|
B.bar(0);
|
||||||
B.qux(0);
|
// error
|
||||||
|
B.qux(0); // error
|
||||||
}
|
}
|
||||||
static create(): A {
|
static create(): A {
|
||||||
return new this();
|
return new this();
|
||||||
}
|
}
|
||||||
|
|
||||||
static badCreate(): number {
|
static badCreate(): number {
|
||||||
return new this();
|
return new this(); // error B ~> number
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class C<X> {
|
class C<X> {
|
||||||
static x: X;
|
static x: X;
|
||||||
static bar(x: X) {}
|
static bar(x: X) {}
|
||||||
|
@ -107,22 +103,28 @@ class C<X> {
|
||||||
return new this();
|
return new this();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class D extends C<string> {
|
class D extends C<string> {
|
||||||
static main() {
|
static main() {
|
||||||
D.foo(0);
|
D.foo(0);
|
||||||
|
// error?
|
||||||
D.bar(0);
|
D.bar(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var d: C<*> = D.create();
|
var d: C<*> = D.create();
|
||||||
(new A(): typeof A);
|
(new A(): typeof A);
|
||||||
(B: typeof A);
|
(B: typeof A);
|
||||||
|
|
||||||
class E {
|
class E {
|
||||||
static x: number;
|
static x: number;
|
||||||
static foo(): string {
|
static foo(): string {
|
||||||
this.bar();
|
this.bar();
|
||||||
return this.x;
|
// error
|
||||||
|
return this.x; // error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
module.exports = { A: A, B: B, C: C, D: D, E: E };
|
|
||||||
"
|
// note: above classdefs are sufficiently annotated to export
|
||||||
|
module.exports = { A: A, B: B, C: C, D: D, E: E };"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -8,8 +8,8 @@ module.exports = { A, B };
|
||||||
/* @flow */
|
/* @flow */
|
||||||
class A {}
|
class A {}
|
||||||
class B {}
|
class B {}
|
||||||
module.exports = { A, B };
|
|
||||||
"
|
module.exports = { A, B };"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test test2.js 1`] = `
|
exports[`test test2.js 1`] = `
|
||||||
|
@ -23,10 +23,11 @@ var y: I.B = new C();
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
var I = require(\"./test.js\");
|
var I = require(\"./test.js\");
|
||||||
|
|
||||||
class C extends I.A {}
|
class C extends I.A {}
|
||||||
|
|
||||||
var x: I.A = new C();
|
var x: I.A = new C();
|
||||||
var y: I.B = new C();
|
var y: I.B = new C();"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test test3.js 1`] = `
|
exports[`test test3.js 1`] = `
|
||||||
|
@ -37,14 +38,13 @@ class C<X, Y, Z> extends B {}
|
||||||
var c: C<number, string, Array<bool>> = new C; // none of the type args matter
|
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
|
var a: A<string, number, Array<bool>> = c; // the third type arg is incorrect
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// none of the type args matter
|
|
||||||
// the third type arg is incorrect
|
|
||||||
class A<X, Y, Z> {}
|
class A<X, Y, Z> {}
|
||||||
class B extends A<string, number, boolean> {}
|
class B extends A<string, number, boolean> {}
|
||||||
class C<X, Y, Z> extends B {}
|
class C<X, Y, Z> extends B {}
|
||||||
|
|
||||||
var c: C<number, string, Array<boolean>> = new C();
|
var c: C<number, string, Array<boolean>> = new C();
|
||||||
var a: A<string, number, Array<boolean>> = c;
|
// none of the type args matter
|
||||||
"
|
var a: A<string, number, Array<boolean>> = c; // the third type arg is incorrect"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test test4.js 1`] = `
|
exports[`test test4.js 1`] = `
|
||||||
|
@ -65,14 +65,18 @@ foo(new D, { f_: 0 });
|
||||||
class C<X> {
|
class C<X> {
|
||||||
x: X;
|
x: X;
|
||||||
}
|
}
|
||||||
|
|
||||||
function foo<X>(c: C<X>, x: X) {}
|
function foo<X>(c: C<X>, x: X) {}
|
||||||
|
|
||||||
type O = { f: number };
|
type O = { f: number };
|
||||||
|
|
||||||
foo((new C(): C<O>), { f_: 0 });
|
foo((new C(): C<O>), { f_: 0 });
|
||||||
|
|
||||||
class D extends C<O> {
|
class D extends C<O> {
|
||||||
bar() {
|
bar() {
|
||||||
this.x;
|
this.x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foo(new D(), { f_: 0 });
|
|
||||||
"
|
foo(new D(), { f_: 0 });"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -11,19 +11,17 @@ function bar(x: Class<B>): B {
|
||||||
return new x(); // error (too few args)
|
return new x(); // error (too few args)
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// OK
|
|
||||||
// error (too few args)
|
|
||||||
class A {}
|
class A {}
|
||||||
function foo(x: Class<A>): A {
|
function foo(x: Class<A>): A {
|
||||||
return new x();
|
return new x(); // OK
|
||||||
}
|
}
|
||||||
|
|
||||||
class B {
|
class B {
|
||||||
constructor(_: any) {}
|
constructor(_: any) {}
|
||||||
}
|
}
|
||||||
function bar(x: Class<B>): B {
|
function bar(x: Class<B>): B {
|
||||||
return new x();
|
return new x(); // error (too few args)
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test test2.js 1`] = `
|
exports[`test test2.js 1`] = `
|
||||||
|
@ -46,13 +44,14 @@ check(B, new C);
|
||||||
// makes it useless in such a function (when limited to classes and instances),
|
// makes it useless in such a function (when limited to classes and instances),
|
||||||
// since everything can be trivially satisfied by going to \`mixed\`.
|
// since everything can be trivially satisfied by going to \`mixed\`.
|
||||||
declare function check<X>(cls: $Type<X>, inst: X): void;
|
declare function check<X>(cls: $Type<X>, inst: X): void;
|
||||||
|
|
||||||
class A {}
|
class A {}
|
||||||
class B extends A {}
|
class B extends A {}
|
||||||
class C {}
|
class C {}
|
||||||
|
|
||||||
check(B, new A());
|
check(B, new A());
|
||||||
check(A, new B());
|
check(A, new B());
|
||||||
check(C, new A());
|
check(C, new A());
|
||||||
check(C, new B());
|
check(C, new B());
|
||||||
check(B, new C());
|
check(B, new C());"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -8,8 +8,8 @@ module.exports = A;
|
||||||
class A {
|
class A {
|
||||||
foo(x: number): void {}
|
foo(x: number): void {}
|
||||||
}
|
}
|
||||||
module.exports = A;
|
|
||||||
"
|
module.exports = A;"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test B.js 1`] = `
|
exports[`test B.js 1`] = `
|
||||||
|
@ -22,13 +22,14 @@ let b = new B();
|
||||||
|
|
||||||
module.exports = B;
|
module.exports = B;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// error, number !~> function
|
|
||||||
var A = require(\"./A\");
|
var A = require(\"./A\");
|
||||||
|
|
||||||
class B extends A {}
|
class B extends A {}
|
||||||
|
|
||||||
let b = new B();
|
let b = new B();
|
||||||
(b.foo: number);
|
(b.foo: number);
|
||||||
module.exports = B;
|
// error, number !~> function
|
||||||
"
|
module.exports = B;"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test C.js 1`] = `
|
exports[`test C.js 1`] = `
|
||||||
|
@ -43,15 +44,16 @@ let c = new C();
|
||||||
|
|
||||||
module.exports = C;
|
module.exports = C;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// error, number !~> function
|
|
||||||
var B = require(\"./B\");
|
var B = require(\"./B\");
|
||||||
|
|
||||||
class C extends B {
|
class C extends B {
|
||||||
foo(x: string): void {}
|
foo(x: string): void {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let c = new C();
|
let c = new C();
|
||||||
(c.foo: number);
|
(c.foo: number);
|
||||||
module.exports = C;
|
// error, number !~> function
|
||||||
"
|
module.exports = C;"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test D.js 1`] = `
|
exports[`test D.js 1`] = `
|
||||||
|
@ -61,8 +63,7 @@ new E().x
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
class D {}
|
class D {}
|
||||||
class E {}
|
class E {}
|
||||||
new E().x;
|
new E().x;"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test class_shapes.js 1`] = `
|
exports[`test class_shapes.js 1`] = `
|
||||||
|
@ -103,42 +104,48 @@ var z = new Test2Class();
|
||||||
var w : Foo = z;
|
var w : Foo = z;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
|
type Foo = {
|
||||||
|
a: string,
|
||||||
// exists in TestClass
|
// exists in TestClass
|
||||||
|
b: string,
|
||||||
// doesn\'t exist
|
// doesn\'t exist
|
||||||
|
c?: ?string,
|
||||||
// exists in TestClass, optional
|
// exists in TestClass, optional
|
||||||
/* doesn\'t exist*/
|
d?: number /* 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 {
|
class TestClass {
|
||||||
a: string;
|
a: string;
|
||||||
c: ?string;
|
c: ?string;
|
||||||
}
|
}
|
||||||
|
|
||||||
var x = new TestClass();
|
var x = new TestClass();
|
||||||
|
|
||||||
x.a;
|
x.a;
|
||||||
|
// ok
|
||||||
x.b;
|
x.b;
|
||||||
|
// error, TestClass has no b
|
||||||
x.c;
|
x.c;
|
||||||
|
// ok
|
||||||
x.d;
|
x.d;
|
||||||
|
// error, TestClass has no d
|
||||||
var y: Foo = x;
|
var y: Foo = x;
|
||||||
y.b;
|
y.b;
|
||||||
|
// error, doesn\'t exist in TestClass
|
||||||
y.d;
|
y.d;
|
||||||
|
// ok, it\'s optional
|
||||||
class Test2Superclass {
|
class Test2Superclass {
|
||||||
a: number;
|
a: number;
|
||||||
c: ?number;
|
// conflicts with cast to Foo
|
||||||
|
c: ?number; // conflicts with cast to Foo
|
||||||
}
|
}
|
||||||
class Test2Class extends Test2Superclass {
|
class Test2Class extends Test2Superclass {
|
||||||
b: number;
|
b: number; // conflicts with cast to Foo
|
||||||
}
|
}
|
||||||
|
|
||||||
var z = new Test2Class();
|
var z = new Test2Class();
|
||||||
var w: Foo = z;
|
var w: Foo = z;"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test expr.js 1`] = `
|
exports[`test expr.js 1`] = `
|
||||||
|
@ -173,30 +180,29 @@ var _Alias = class Alias {
|
||||||
var alias1: Alias = new _Alias(); // error: bad pun
|
var alias1: Alias = new _Alias(); // error: bad pun
|
||||||
var alias2: Alias = _Alias.factory(); // error: bad pun
|
var alias2: Alias = _Alias.factory(); // error: bad pun
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
var Bar = class Foo {
|
||||||
|
static factory(): Foo {
|
||||||
// OK: Foo is a type in this scope
|
// OK: Foo is a type in this scope
|
||||||
// OK: Foo is a runtime binding in this scope
|
return new Foo(); // OK: Foo is a runtime binding in this scope
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var bar1: Bar = new Bar();
|
||||||
// OK
|
// OK
|
||||||
|
var bar2: Bar = Bar.factory();
|
||||||
// OK
|
// 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.
|
// 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 {
|
|
||||||
static factory(): Foo {
|
|
||||||
return new Foo();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var bar1: Bar = new Bar();
|
|
||||||
var bar2: Bar = Bar.factory();
|
|
||||||
var B = class Baz {};
|
var B = class Baz {};
|
||||||
var b = new Baz();
|
var b = new Baz();
|
||||||
|
// error: Baz is not a runtime binding in this scope
|
||||||
var C = class Qux {};
|
var C = class Qux {};
|
||||||
var c: Qux = new C();
|
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 Anon = class {};
|
var Anon = class {};
|
||||||
var anon: Anon = new Anon();
|
var anon: Anon = new Anon();
|
||||||
|
|
||||||
class Alias {}
|
class Alias {}
|
||||||
var _Alias = class Alias {
|
var _Alias = class Alias {
|
||||||
static factory(): Alias {
|
static factory(): Alias {
|
||||||
|
@ -204,8 +210,8 @@ var _Alias = class Alias {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var alias1: Alias = new _Alias();
|
var alias1: Alias = new _Alias();
|
||||||
var alias2: Alias = _Alias.factory();
|
// error: bad pun
|
||||||
"
|
var alias2: Alias = _Alias.factory(); // error: bad pun"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test loc.js 1`] = `
|
exports[`test loc.js 1`] = `
|
||||||
|
@ -216,10 +222,10 @@ type Foo = number
|
||||||
class Foo {} // error, shadows type Foo
|
class Foo {} // error, shadows type Foo
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
// error, shadows type Foo
|
|
||||||
type Foo = number;
|
type Foo = number;
|
||||||
class Foo {}
|
|
||||||
"
|
class Foo {} // error, shadows type Foo"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test statics.js 1`] = `
|
exports[`test statics.js 1`] = `
|
||||||
|
@ -238,17 +244,17 @@ declare var o: {p:number};
|
||||||
(o: Class<C>); // error, object type incompatible with class type
|
(o: Class<C>); // error, object type incompatible with class type
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @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 {
|
class C {
|
||||||
static p: string;
|
static p: string;
|
||||||
}
|
}
|
||||||
C.p = \"hi\";
|
C.p = \"hi\";
|
||||||
|
|
||||||
|
// Class static fields are compatible with object types
|
||||||
(C: { p: string });
|
(C: { p: string });
|
||||||
|
// ok
|
||||||
(C: { p: number });
|
(C: { p: number });
|
||||||
|
// errors, string ~> number & vice versa (unify)
|
||||||
declare var o: { p: number };
|
declare var o: { p: number };
|
||||||
(o: Class<C>);
|
(o: Class<C>); // error, object type incompatible with class type"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -84,76 +84,84 @@ function local_meth() {
|
||||||
* Test tracking of variable types across closure calls.
|
* Test tracking of variable types across closure calls.
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
function takes_string(_: string) {}
|
||||||
|
|
||||||
// global write from function
|
// 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) {}
|
|
||||||
var global_x = \"hello\";
|
var global_x = \"hello\";
|
||||||
|
|
||||||
function global_f() {}
|
function global_f() {}
|
||||||
function global_g() {
|
function global_g() {
|
||||||
global_x = 42;
|
global_x = 42;
|
||||||
}
|
}
|
||||||
|
|
||||||
global_f();
|
global_f();
|
||||||
takes_string(global_x);
|
takes_string(global_x);
|
||||||
|
// ok
|
||||||
global_g();
|
global_g();
|
||||||
takes_string(global_x);
|
takes_string(global_x);
|
||||||
|
// error
|
||||||
global_x = 42;
|
global_x = 42;
|
||||||
|
// shouldn\'t pollute linear refinement
|
||||||
|
// local write from function
|
||||||
|
//
|
||||||
function local_func() {
|
function local_func() {
|
||||||
var local_x = \"hello\";
|
var local_x = \"hello\";
|
||||||
|
|
||||||
function local_f() {}
|
function local_f() {}
|
||||||
function local_g() {
|
function local_g() {
|
||||||
local_x = 42;
|
local_x = 42;
|
||||||
}
|
}
|
||||||
|
|
||||||
local_f();
|
local_f();
|
||||||
takes_string(local_x);
|
takes_string(local_x);
|
||||||
|
// ok
|
||||||
local_g();
|
local_g();
|
||||||
takes_string(local_x);
|
takes_string(local_x);
|
||||||
local_x = 42;
|
// error
|
||||||
|
local_x = 42; // shouldn\'t pollute linear refinement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// global write from method
|
||||||
|
//
|
||||||
var global_y = \"hello\";
|
var global_y = \"hello\";
|
||||||
|
|
||||||
var global_o = {
|
var global_o = {
|
||||||
f: function() {},
|
f: function() {},
|
||||||
g: function() {
|
g: function() {
|
||||||
global_y = 42;
|
global_y = 42;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
global_o.f();
|
global_o.f();
|
||||||
takes_string(global_y);
|
takes_string(global_y);
|
||||||
|
// ok
|
||||||
global_o.g();
|
global_o.g();
|
||||||
takes_string(global_y);
|
takes_string(global_y);
|
||||||
|
// error
|
||||||
global_y = 42;
|
global_y = 42;
|
||||||
|
// shouldn\'t pollute linear refinement
|
||||||
|
// local write from method
|
||||||
|
//
|
||||||
function local_meth() {
|
function local_meth() {
|
||||||
var local_y = \"hello\";
|
var local_y = \"hello\";
|
||||||
|
|
||||||
var local_o = {
|
var local_o = {
|
||||||
f: function() {},
|
f: function() {},
|
||||||
g: function() {
|
g: function() {
|
||||||
local_y = 42;
|
local_y = 42;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
local_o.f();
|
local_o.f();
|
||||||
takes_string(local_y);
|
takes_string(local_y);
|
||||||
|
// ok
|
||||||
local_o.g();
|
local_o.g();
|
||||||
takes_string(local_y);
|
takes_string(local_y);
|
||||||
local_y = 42;
|
// error
|
||||||
}
|
local_y = 42; // shouldn\'t pollute linear refinement
|
||||||
"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test cond_havoc.js 1`] = `
|
exports[`test cond_havoc.js 1`] = `
|
||||||
|
@ -172,10 +180,10 @@ function example(b: bool): number {
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
// from sam, https://github.com/facebook/flow/issues/780
|
// from sam, https://github.com/facebook/flow/issues/780
|
||||||
// call to f() within if should properly havoc x.
|
// call to f() within if should properly havoc x.
|
||||||
//
|
//
|
||||||
// error, string ~/~> number (return type anno) TODO
|
|
||||||
function example(b: boolean): number {
|
function example(b: boolean): number {
|
||||||
var x = 0;
|
var x = 0;
|
||||||
function f() {
|
function f() {
|
||||||
|
@ -184,9 +192,8 @@ function example(b: boolean): number {
|
||||||
if (b) {
|
if (b) {
|
||||||
f();
|
f();
|
||||||
}
|
}
|
||||||
return x;
|
return x; // error, string ~/~> number (return type anno) TODO
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test const.js 1`] = `
|
exports[`test const.js 1`] = `
|
||||||
|
@ -242,63 +249,61 @@ call_me();
|
||||||
* consts retain refinements
|
* consts retain refinements
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// global, anybody can call it at any time
|
// 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 = () => {};
|
var call_me: () => void = () => {};
|
||||||
|
|
||||||
function g(x: ?number) {
|
function g(x: ?number) {
|
||||||
const const_x = x;
|
const const_x = x;
|
||||||
if (const_x) {
|
if (const_x) {
|
||||||
|
// ok: if const_x is truthy here, it\'s truthy everywhere
|
||||||
call_me = () => {
|
call_me = () => {
|
||||||
var y: number = const_x;
|
var y: number = const_x;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var var_x = x;
|
var var_x = x;
|
||||||
if (var_x) {
|
if (var_x) {
|
||||||
|
// error: var_x might no longer be truthy when call_me is called
|
||||||
call_me = () => {
|
call_me = () => {
|
||||||
var y: number = var_x;
|
var y: number = var_x;
|
||||||
};
|
}; // error
|
||||||
}
|
}
|
||||||
var_x = null;
|
var_x = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function h(x: number | string | boolean) {
|
function h(x: number | string | boolean) {
|
||||||
const const_x = x;
|
const const_x = x;
|
||||||
if (typeof const_x == \"number\") {
|
if (typeof const_x == \"number\") {
|
||||||
call_me = () => {
|
call_me = () => {
|
||||||
var y: number = const_x;
|
var y: number = const_x;
|
||||||
};
|
}; // ok
|
||||||
} else if (typeof const_x == \"string\") {
|
} else if (typeof const_x == \"string\") {
|
||||||
call_me = () => {
|
call_me = () => {
|
||||||
var y: string = const_x;
|
var y: string = const_x;
|
||||||
};
|
}; // ok
|
||||||
} else if (typeof const_x == \"boolean\") {
|
} else if (typeof const_x == \"boolean\") {
|
||||||
call_me = () => {
|
call_me = () => {
|
||||||
var y: boolean = const_x;
|
var y: boolean = const_x;
|
||||||
};
|
}; // ok
|
||||||
}
|
}
|
||||||
|
|
||||||
var var_x = x;
|
var var_x = x;
|
||||||
if (typeof var_x == \"number\") {
|
if (typeof var_x == \"number\") {
|
||||||
call_me = () => {
|
call_me = () => {
|
||||||
var y: number = var_x;
|
var y: number = var_x;
|
||||||
};
|
}; // error
|
||||||
} else if (typeof var_x == \"string\") {
|
} else if (typeof var_x == \"string\") {
|
||||||
call_me = () => {
|
call_me = () => {
|
||||||
var y: string = var_x;
|
var y: string = var_x;
|
||||||
};
|
}; // error
|
||||||
} else if (typeof var_x == \"boolean\") {
|
} else if (typeof var_x == \"boolean\") {
|
||||||
call_me = () => {
|
call_me = () => {
|
||||||
var y: boolean = var_x;
|
var y: boolean = var_x;
|
||||||
};
|
}; // error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
call_me();
|
|
||||||
"
|
// in a galaxy far far away
|
||||||
|
call_me();"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -5,8 +5,8 @@ function f(x:string) { }
|
||||||
module.exports = f;
|
module.exports = f;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
function f(x: string) {}
|
function f(x: string) {}
|
||||||
module.exports = f;
|
|
||||||
"
|
module.exports = f;"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test Rel.js 1`] = `
|
exports[`test Rel.js 1`] = `
|
||||||
|
@ -16,6 +16,6 @@ var f = require(\'./Abs\');
|
||||||
f(0);
|
f(0);
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
var f = require(\"./Abs\");
|
var f = require(\"./Abs\");
|
||||||
f(0);
|
|
||||||
"
|
f(0);"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -23,19 +23,21 @@ ColorIdToNumber.XXX; // oops
|
||||||
|
|
||||||
module.exports = { ColorId, ColorNumber };
|
module.exports = { ColorId, ColorNumber };
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// oops
|
|
||||||
// oops
|
|
||||||
var ColorId = { RED: \"R\", GREEN: \"G\", BLUE: \"B\" };
|
var ColorId = { RED: \"R\", GREEN: \"G\", BLUE: \"B\" };
|
||||||
|
|
||||||
var ColorNumber = { RED: \"ff0000\", GREEN: \"00ff00\", BLUE: \"0000ff\" };
|
var ColorNumber = { RED: \"ff0000\", GREEN: \"00ff00\", BLUE: \"0000ff\" };
|
||||||
|
|
||||||
var ColorIdToNumber = {
|
var ColorIdToNumber = {
|
||||||
[ColorId.RED]: ColorNumber.RED,
|
[ColorId.RED]: ColorNumber.RED,
|
||||||
[ColorId.GREEN]: ColorNumber.GREEN,
|
[ColorId.GREEN]: ColorNumber.GREEN,
|
||||||
[ColorId.BLUE]: ColorNumber.BLUE
|
[ColorId.BLUE]: ColorNumber.BLUE
|
||||||
};
|
};
|
||||||
|
|
||||||
(ColorIdToNumber[ColorId.RED]: \"ffffff\");
|
(ColorIdToNumber[ColorId.RED]: \"ffffff\");
|
||||||
|
// oops
|
||||||
ColorIdToNumber.XXX;
|
ColorIdToNumber.XXX;
|
||||||
module.exports = { ColorId, ColorNumber };
|
// oops
|
||||||
"
|
module.exports = { ColorId, ColorNumber };"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test test2.js 1`] = `
|
exports[`test test2.js 1`] = `
|
||||||
|
@ -50,16 +52,16 @@ var ColorIdToNumber = {
|
||||||
|
|
||||||
module.exports = ColorIdToNumber;
|
module.exports = ColorIdToNumber;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// oops
|
|
||||||
var { ColorId, ColorNumber } = require(\"./test\");
|
var { ColorId, ColorNumber } = require(\"./test\");
|
||||||
var ColorIdToNumber = {
|
var ColorIdToNumber = {
|
||||||
[ColorId.RED]: ColorNumber.RED,
|
[ColorId.RED]: ColorNumber.RED,
|
||||||
[ColorId.GREEN]: ColorNumber.GREEN,
|
[ColorId.GREEN]: ColorNumber.GREEN,
|
||||||
[ColorId.BLUE]: ColorNumber.BLUE
|
[ColorId.BLUE]: ColorNumber.BLUE
|
||||||
};
|
};
|
||||||
|
|
||||||
(ColorIdToNumber[ColorId.GREEN]: \"ffffff\");
|
(ColorIdToNumber[ColorId.GREEN]: \"ffffff\");
|
||||||
module.exports = ColorIdToNumber;
|
// oops
|
||||||
"
|
module.exports = ColorIdToNumber;"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test test3.js 1`] = `
|
exports[`test test3.js 1`] = `
|
||||||
|
@ -68,18 +70,16 @@ var ColorIdToNumber = require(\'./test2\');
|
||||||
|
|
||||||
(ColorIdToNumber[ColorId.BLUE]: \'ffffff\'); // oops
|
(ColorIdToNumber[ColorId.BLUE]: \'ffffff\'); // oops
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// oops
|
|
||||||
var { ColorId } = require(\"./test\");
|
var { ColorId } = require(\"./test\");
|
||||||
var ColorIdToNumber = require(\"./test2\");
|
var ColorIdToNumber = require(\"./test2\");
|
||||||
(ColorIdToNumber[ColorId.BLUE]: \"ffffff\");
|
|
||||||
"
|
(ColorIdToNumber[ColorId.BLUE]: \"ffffff\"); // oops"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test test4.js 1`] = `
|
exports[`test test4.js 1`] = `
|
||||||
"module.exports = \'hello\';
|
"module.exports = \'hello\';
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
module.exports = \"hello\";
|
module.exports = \"hello\";"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test test5.js 1`] = `
|
exports[`test test5.js 1`] = `
|
||||||
|
@ -93,18 +93,15 @@ module.exports = {
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
var hello = require(\"./test4\");
|
var hello = require(\"./test4\");
|
||||||
var dummy = require(\"./test\");
|
var dummy = require(\"./test\");
|
||||||
module.exports = { ...dummy, [hello]: \"world\", ...dummy };
|
module.exports = { ...dummy, [hello]: \"world\", ...dummy };"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test test6.js 1`] = `
|
exports[`test test6.js 1`] = `
|
||||||
"var o = require(\'./test5\');
|
"var o = require(\'./test5\');
|
||||||
(o.hello: \'nothing\'); // oops
|
(o.hello: \'nothing\'); // oops
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// oops
|
|
||||||
var o = require(\"./test5\");
|
var o = require(\"./test5\");
|
||||||
(o.hello: \"nothing\");
|
(o.hello: \"nothing\"); // oops"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test test7.js 1`] = `
|
exports[`test test7.js 1`] = `
|
||||||
|
@ -114,8 +111,6 @@ var x: string = obj[\'m\'](); // error, number ~> string
|
||||||
var arr = [function() { return this.length }];
|
var arr = [function() { return this.length }];
|
||||||
var y: string = arr[0](); // error: number ~> string
|
var y: string = arr[0](); // error: number ~> string
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// error, number ~> string
|
|
||||||
// error: number ~> string
|
|
||||||
var obj = {
|
var obj = {
|
||||||
x: 0,
|
x: 0,
|
||||||
m() {
|
m() {
|
||||||
|
@ -123,11 +118,11 @@ var obj = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var x: string = obj[\"m\"]();
|
var x: string = obj[\"m\"]();
|
||||||
|
// error, number ~> string
|
||||||
var arr = [
|
var arr = [
|
||||||
function() {
|
function() {
|
||||||
return this.length;
|
return this.length;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
var y: string = arr[0]();
|
var y: string = arr[0](); // error: number ~> string"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -25,25 +25,28 @@ function d(): string { // expected \`: number | boolean\`
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
// equivalent to \`return (x && 1) || 0\`
|
|
||||||
// expected \`: number | boolean\`
|
|
||||||
// equivalent to \`return x != null && x\`
|
|
||||||
function a(): number {
|
function a(): number {
|
||||||
var x: ?string = null;
|
var x: ?string = null;
|
||||||
return x ? 1 : 0;
|
return x ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function b(): number {
|
function b(): number {
|
||||||
var x: ?number = null;
|
var x: ?number = null;
|
||||||
return x != null ? x : 0;
|
return x != null ? x : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function c(): number {
|
function c(): number {
|
||||||
|
// equivalent to \`return (x && 1) || 0\`
|
||||||
var x = false;
|
var x = false;
|
||||||
var temp = x ? 1 : x;
|
var temp = x ? 1 : x;
|
||||||
return temp ? temp : 0;
|
return temp ? temp : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function d(): string {
|
function d(): string {
|
||||||
|
// expected \`: number | boolean\`
|
||||||
|
// equivalent to \`return x != null && x\`
|
||||||
var x: ?number = null;
|
var x: ?number = null;
|
||||||
return x != null ? x : x != null;
|
return x != null ? x : x != null;
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
exports[`test no_at_flow.js 1`] = `
|
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\"; // Error: string ~> number"
|
||||||
var x: number = \"not a number\";
|
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
exports[`test no_at_flow.js 1`] = `
|
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\"; // No error"
|
||||||
var x: number = \"not a number\";
|
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -4,6 +4,6 @@ exports[`test no_at_flow.js 1`] = `
|
||||||
x.length;
|
x.length;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
var x;
|
var x;
|
||||||
x.length;
|
|
||||||
"
|
x.length;"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -14,11 +14,12 @@ foo(\'Hello, world!\');
|
||||||
/*
|
/*
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
// This file should be ignored, so this should not result in an error
|
|
||||||
function foo(x) {
|
function foo(x) {
|
||||||
var a: number = \"asdf\";
|
var a: number = \"asdf\";
|
||||||
return x * 10;
|
return x * 10;
|
||||||
}
|
}
|
||||||
foo(\"Hello, world!\");
|
|
||||||
"
|
// This file should be ignored, so this should not result in an error
|
||||||
|
foo(\"Hello, world!\");"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -5,7 +5,7 @@ exports[`test foo.js 1`] = `
|
||||||
var x: number = \"string\";
|
var x: number = \"string\";
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
// No error, this file is ignored
|
// No error, this file is ignored
|
||||||
var x: number = \"string\";
|
var x: number = \"string\";"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -4,7 +4,6 @@ exports[`test foo.js 1`] = `
|
||||||
var x: number = \"string\"; // Error string ~> number
|
var x: number = \"string\"; // Error string ~> number
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
// Error string ~> number
|
|
||||||
var x: number = \"string\";
|
var x: number = \"string\"; // Error string ~> number"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -7,9 +7,9 @@ var a: number = test;
|
||||||
var b: string = test; // Error: number ~> string
|
var b: string = test; // Error: number ~> string
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
// Error: number ~> string
|
|
||||||
import {test} from \"testmodule\";
|
import {test} from \"testmodule\";
|
||||||
|
|
||||||
var a: number = test;
|
var a: number = test;
|
||||||
var b: string = test;
|
var b: string = test; // Error: number ~> string"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -4,6 +4,6 @@ exports[`test testmodule.js 1`] = `
|
||||||
export let test = 42;
|
export let test = 42;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
export let test = 42;
|
|
||||||
"
|
export let test = 42;"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -5,8 +5,7 @@ import {className} from \"./SomeCSSFile.css\";
|
||||||
import {doesntExist} from \"./SomeCSSFile.css\"; // Error: \`doestExist\` isn\'t an export
|
import {doesntExist} from \"./SomeCSSFile.css\"; // Error: \`doestExist\` isn\'t an export
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
// Error: \`doestExist\` isn\'t an export
|
|
||||||
import {className} from \"./SomeCSSFile.css\";
|
import {className} from \"./SomeCSSFile.css\";
|
||||||
import {doesntExist} from \"./SomeCSSFile.css\";
|
import {doesntExist} from \"./SomeCSSFile.css\"; // Error: \`doestExist\` isn\'t an export"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -14,19 +14,19 @@ var m2 = require(\'2DoesntExist\'); // Error
|
||||||
import {numVal as numVal2} from \'3DoesntExist\'; // Error
|
import {numVal as numVal2} from \'3DoesntExist\'; // Error
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
// 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.
|
|
||||||
// Error
|
|
||||||
// Error
|
|
||||||
var m1 = require(\"1DoesntExist\");
|
var m1 = require(\"1DoesntExist\");
|
||||||
import {numVal as numVal1} from \"1DoesntExist\";
|
import {numVal as numVal1} from \"1DoesntExist\";
|
||||||
var a_1: number = m1.numVal;
|
var a_1: number = m1.numVal;
|
||||||
var a_2: number = numVal1;
|
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\");
|
var m2 = require(\"2DoesntExist\");
|
||||||
import {numVal as numVal2} from \"3DoesntExist\";
|
// Error
|
||||||
"
|
import {numVal as numVal2} from \"3DoesntExist\"; // Error"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test Exists.js 1`] = `
|
exports[`test Exists.js 1`] = `
|
||||||
|
@ -43,6 +43,6 @@ module.exports = {
|
||||||
* @providesModule Exists
|
* @providesModule Exists
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
module.exports = { numVal: 42 };
|
|
||||||
"
|
module.exports = { numVal: 42 };"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -26,34 +26,33 @@ var c_3: number = numVal3;
|
||||||
var c_4: string = numVal3; // Error: number ~> string
|
var c_4: string = numVal3; // Error: number ~> string
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
// 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 m1 = require(\"./1DoesntExist\");
|
||||||
var a_1: number = m1.numVal;
|
var a_1: number = m1.numVal;
|
||||||
var a_2: string = m1.numVal;
|
var a_2: string = m1.numVal;
|
||||||
|
// Error: number ~> string
|
||||||
import {numVal} from \"./1DoesntExist\";
|
import {numVal} from \"./1DoesntExist\";
|
||||||
var a_3: number = numVal;
|
var a_3: number = numVal;
|
||||||
var a_4: string = numVal;
|
var a_4: string = numVal;
|
||||||
|
// Error: number ~> string
|
||||||
|
// This tests that, for node, the first name mapping that both matches *and*
|
||||||
|
// results in a valid module filename is picked.
|
||||||
var m2 = require(\"./2DoesntExist\");
|
var m2 = require(\"./2DoesntExist\");
|
||||||
var b_1: number = m2.numVal;
|
var b_1: number = m2.numVal;
|
||||||
var b_2: string = m2.numVal;
|
var b_2: string = m2.numVal;
|
||||||
|
// Error: number ~> string
|
||||||
import {numVal as numVal2} from \"./3DoesntExist\";
|
import {numVal as numVal2} from \"./3DoesntExist\";
|
||||||
var b_3: number = numVal2;
|
var b_3: number = numVal2;
|
||||||
var b_4: string = numVal2;
|
var b_4: string = numVal2;
|
||||||
|
// Error: number ~> string
|
||||||
|
// node_modules/Exists/index.js
|
||||||
var m3 = require(\"4DoesntExist\");
|
var m3 = require(\"4DoesntExist\");
|
||||||
var c_1: number = m3.numVal;
|
var c_1: number = m3.numVal;
|
||||||
var c_2: string = m3.numVal;
|
var c_2: string = m3.numVal;
|
||||||
|
// Error: number ~> string
|
||||||
import {numVal as numVal3} from \"5DoesntExist\";
|
import {numVal as numVal3} from \"5DoesntExist\";
|
||||||
var c_3: number = numVal3;
|
var c_3: number = numVal3;
|
||||||
var c_4: string = numVal3;
|
var c_4: string = numVal3; // Error: number ~> string"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test Exists.js 1`] = `
|
exports[`test Exists.js 1`] = `
|
||||||
|
@ -64,6 +63,6 @@ module.exports = {
|
||||||
};
|
};
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
module.exports = { numVal: 42 };
|
|
||||||
"
|
module.exports = { numVal: 42 };"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -7,9 +7,9 @@ import {name} from \"testproj\";
|
||||||
(name: \"custom_resolve_dir/testproj\"); // Error: Resolve from node_modules first!
|
(name: \"custom_resolve_dir/testproj\"); // Error: Resolve from node_modules first!
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
// Error: Resolve from node_modules first!
|
|
||||||
import {name} from \"testproj\";
|
import {name} from \"testproj\";
|
||||||
|
|
||||||
(name: \"node_modules/testproj\");
|
(name: \"node_modules/testproj\");
|
||||||
(name: \"custom_resolve_dir/testproj\");
|
(name: \"custom_resolve_dir/testproj\"); // Error: Resolve from node_modules first!"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -4,6 +4,6 @@ exports[`test index.js 1`] = `
|
||||||
export var name: \"otherdir/testproj\" = \"otherdir/testproj\";
|
export var name: \"otherdir/testproj\" = \"otherdir/testproj\";
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
export var name: \"otherdir/testproj\" = \"otherdir/testproj\";
|
|
||||||
"
|
export var name: \"otherdir/testproj\" = \"otherdir/testproj\";"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -4,6 +4,6 @@ exports[`test index.js 1`] = `
|
||||||
export var name: \"otherdir/testproj2\" = \"otherdir/testproj2\";
|
export var name: \"otherdir/testproj2\" = \"otherdir/testproj2\";
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
export var name: \"otherdir/testproj2\" = \"otherdir/testproj2\";
|
|
||||||
"
|
export var name: \"otherdir/testproj2\" = \"otherdir/testproj2\";"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -7,9 +7,10 @@ import {name} from \"testproj2\";
|
||||||
(name: \"subdir/custom_resolve_dir/testproj2\");
|
(name: \"subdir/custom_resolve_dir/testproj2\");
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
// Error: Resolve from sibling \'custom_resolve_dir\' first!
|
|
||||||
import {name} from \"testproj2\";
|
import {name} from \"testproj2\";
|
||||||
|
|
||||||
(name: \"node_modules/testproj2\");
|
(name: \"node_modules/testproj2\");
|
||||||
(name: \"subdir/custom_resolve_dir/testproj2\");
|
// Error: Resolve from sibling \'custom_resolve_dir\' first!
|
||||||
"
|
(name: \"subdir/custom_resolve_dir/testproj2\");"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -4,6 +4,6 @@ exports[`test index.js 1`] = `
|
||||||
export var name: \"subdir/custom_resolve_dir/testproj2\" = \"subdir/custom_resolve_dir/testproj2\";
|
export var name: \"subdir/custom_resolve_dir/testproj2\" = \"subdir/custom_resolve_dir/testproj2\";
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
export var name: \"subdir/custom_resolve_dir/testproj2\" = \"subdir/custom_resolve_dir/testproj2\";
|
|
||||||
"
|
export var name: \"subdir/custom_resolve_dir/testproj2\" = \"subdir/custom_resolve_dir/testproj2\";"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -35,9 +35,11 @@ class B extends A {
|
||||||
B._sProperty = \"B._sProperty string\";
|
B._sProperty = \"B._sProperty string\";
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
class A {
|
class A {
|
||||||
_property1: number;
|
_property1: number;
|
||||||
static _sProperty: number;
|
static _sProperty: number;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this._property1 = 5;
|
this._property1 = 5;
|
||||||
}
|
}
|
||||||
|
@ -49,9 +51,11 @@ class A {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
A._sProperty = 48;
|
A._sProperty = 48;
|
||||||
|
|
||||||
class B extends A {
|
class B extends A {
|
||||||
_property1: string;
|
_property1: string;
|
||||||
static _sProperty: string;
|
static _sProperty: string;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this._property1 = \"another string\";
|
this._property1 = \"another string\";
|
||||||
|
@ -63,8 +67,7 @@ class B extends A {
|
||||||
return 23;
|
return 23;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
B._sProperty = \"B._sProperty string\";
|
B._sProperty = \"B._sProperty string\";"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test commonjs_export.js 1`] = `
|
exports[`test commonjs_export.js 1`] = `
|
||||||
|
@ -77,11 +80,12 @@ class C {
|
||||||
module.exports = new C;
|
module.exports = new C;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
class C {
|
class C {
|
||||||
_p: string;
|
_p: string;
|
||||||
}
|
}
|
||||||
module.exports = new C();
|
|
||||||
"
|
module.exports = new C();"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test commonjs_import.js 1`] = `
|
exports[`test commonjs_import.js 1`] = `
|
||||||
|
@ -90,6 +94,6 @@ exports[`test commonjs_import.js 1`] = `
|
||||||
import {_p} from \"./commonjs_export\";
|
import {_p} from \"./commonjs_export\";
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
import {_p} from \"./commonjs_export\";
|
|
||||||
"
|
import {_p} from \"./commonjs_export\";"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -35,9 +35,11 @@ class B extends A {
|
||||||
B._sProperty = \"B._sProperty string\";
|
B._sProperty = \"B._sProperty string\";
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
class A {
|
class A {
|
||||||
_property1: number;
|
_property1: number;
|
||||||
static _sProperty: number;
|
static _sProperty: number;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this._property1 = 5;
|
this._property1 = 5;
|
||||||
}
|
}
|
||||||
|
@ -49,9 +51,11 @@ class A {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
A._sProperty = 48;
|
A._sProperty = 48;
|
||||||
|
|
||||||
class B extends A {
|
class B extends A {
|
||||||
_property1: string;
|
_property1: string;
|
||||||
static _sProperty: string;
|
static _sProperty: string;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this._property1 = \"another string\";
|
this._property1 = \"another string\";
|
||||||
|
@ -63,6 +67,5 @@ class B extends A {
|
||||||
return 23;
|
return 23;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
B._sProperty = \"B._sProperty string\";
|
B._sProperty = \"B._sProperty string\";"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -43,21 +43,21 @@ function durable_refi(x: ?number) {
|
||||||
*
|
*
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
// error, const param cannot be reassigned
|
|
||||||
|
function cannot_reassign(x: string) {
|
||||||
|
x = \"hey\"; // error, const param cannot be reassigned
|
||||||
|
}
|
||||||
|
|
||||||
// Note: const params use the same machinery as explicit
|
// Note: const params use the same machinery as explicit
|
||||||
// const bindings, which are tested more extensively elsewhere.
|
// const bindings, which are tested more extensively elsewhere.
|
||||||
// Here we\'re just making sure the machinery is hooked up.
|
// 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) {
|
function durable_refi(x: ?number) {
|
||||||
if (x) {
|
if (x) {
|
||||||
|
// ok: if x is truthy here, it\'s truthy everywhere
|
||||||
return () => {
|
return () => {
|
||||||
var y: number = x;
|
var y: number = x;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -12,9 +12,10 @@ module.exports = C;
|
||||||
class C {
|
class C {
|
||||||
constructor() {}
|
constructor() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
class D {
|
class D {
|
||||||
constructor(): number {}
|
constructor(): number {}
|
||||||
}
|
}
|
||||||
module.exports = C;
|
|
||||||
"
|
module.exports = C;"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -22,31 +22,30 @@ interface IFoo extends IFooPrototype {
|
||||||
exports.Foo2 = (Foo: Class<IFoo>);
|
exports.Foo2 = (Foo: Class<IFoo>);
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// Foo is a class-like function
|
// 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() {
|
function Foo() {
|
||||||
this.x = 0;
|
this.x = 0; // constructs objects with property x
|
||||||
}
|
}
|
||||||
Foo.y = 0;
|
Foo.y = 0;
|
||||||
|
// has static property y
|
||||||
Foo.prototype = {
|
Foo.prototype = {
|
||||||
m() {
|
m() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// exporting Foo directly doesn\'t work
|
||||||
|
// Foo\'s instance and static props are not picked up
|
||||||
exports.Foo = Foo;
|
exports.Foo = Foo;
|
||||||
|
|
||||||
|
// so you want to type Foo, by declaring it as a class
|
||||||
interface IFooPrototype { m(): number }
|
interface IFooPrototype { m(): number }
|
||||||
interface IFoo extends IFooPrototype {
|
interface IFoo extends IFooPrototype {
|
||||||
|
/* error, should have declared x: number instead*/
|
||||||
static (): void,
|
static (): void,
|
||||||
x: boolean,
|
x: boolean,
|
||||||
static y: boolean
|
static y: boolean /* error, should have declared static y: number instead*/
|
||||||
}
|
}
|
||||||
exports.Foo2 = (Foo: Class<IFoo>);
|
exports.Foo2 = (Foo: Class<IFoo>);"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test test.js 1`] = `
|
exports[`test test.js 1`] = `
|
||||||
|
@ -60,17 +59,17 @@ var x2: string = new Foo2().x; // error, found boolean instead of string
|
||||||
var y2: string = Foo2.y; // error, found boolean instead of string
|
var y2: string = Foo2.y; // error, found boolean instead of string
|
||||||
var z2: string = new Foo2().m();
|
var z2: string = new Foo2().m();
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// 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 Foo = require(\"./constructors\").Foo;
|
||||||
var x: string = new Foo().x;
|
var x: string = new Foo().x;
|
||||||
|
// error, found number instead of string
|
||||||
var y: string = Foo.y;
|
var y: string = Foo.y;
|
||||||
|
// error, found number instead of string
|
||||||
var z: string = new Foo().m();
|
var z: string = new Foo().m();
|
||||||
|
|
||||||
var Foo2 = require(\"./constructors\").Foo2;
|
var Foo2 = require(\"./constructors\").Foo2;
|
||||||
var x2: string = new Foo2().x;
|
var x2: string = new Foo2().x;
|
||||||
|
// error, found boolean instead of string
|
||||||
var y2: string = Foo2.y;
|
var y2: string = Foo2.y;
|
||||||
var z2: string = new Foo2().m();
|
// error, found boolean instead of string
|
||||||
"
|
var z2: string = new Foo2().m();"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
exports[`test dummy.js 1`] = `
|
exports[`test dummy.js 1`] = `
|
||||||
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -11,6 +10,5 @@ xxx
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
require(\"./dummy\");
|
require(\"./dummy\");
|
||||||
var xxx = 0;
|
var xxx = 0;
|
||||||
xxx;
|
xxx;"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
exports[`test dummy.js 1`] = `
|
exports[`test dummy.js 1`] = `
|
||||||
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -11,6 +10,5 @@ xxx
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
require(\"./dummy\");
|
require(\"./dummy\");
|
||||||
var xxx = 0;
|
var xxx = 0;
|
||||||
xxx;
|
xxx;"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -43,12 +43,11 @@ let tests = [
|
||||||
];
|
];
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
// Boolean (the class) tests. booleans (the literals) are not part of core.js
|
// Boolean (the class) tests. booleans (the literals) are not part of core.js
|
||||||
// constructor
|
|
||||||
// toString
|
|
||||||
// valueOf
|
|
||||||
// casting
|
|
||||||
let tests = [
|
let tests = [
|
||||||
|
// constructor
|
||||||
function() {
|
function() {
|
||||||
new Boolean();
|
new Boolean();
|
||||||
new Boolean(0);
|
new Boolean(0);
|
||||||
|
@ -59,15 +58,18 @@ let tests = [
|
||||||
new Boolean(undefined);
|
new Boolean(undefined);
|
||||||
new Boolean(\"\");
|
new Boolean(\"\");
|
||||||
},
|
},
|
||||||
|
// toString
|
||||||
function() {
|
function() {
|
||||||
true.toString();
|
true.toString();
|
||||||
let x: boolean = false;
|
let x: boolean = false;
|
||||||
x.toString();
|
x.toString();
|
||||||
new Boolean(true).toString();
|
new Boolean(true).toString();
|
||||||
},
|
},
|
||||||
|
// valueOf
|
||||||
function() {
|
function() {
|
||||||
(new Boolean(0).valueOf(): boolean);
|
(new Boolean(0).valueOf(): boolean);
|
||||||
},
|
},
|
||||||
|
// casting
|
||||||
function() {
|
function() {
|
||||||
Boolean();
|
Boolean();
|
||||||
Boolean(0);
|
Boolean(0);
|
||||||
|
@ -78,8 +80,7 @@ let tests = [
|
||||||
Boolean(undefined);
|
Boolean(undefined);
|
||||||
Boolean(\"\");
|
Boolean(\"\");
|
||||||
}
|
}
|
||||||
];
|
];"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test map.js 1`] = `
|
exports[`test map.js 1`] = `
|
||||||
|
@ -117,19 +118,15 @@ let tests = [
|
||||||
];
|
];
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
// good constructors
|
|
||||||
// bad constructors
|
|
||||||
// error
|
|
||||||
// error
|
|
||||||
// get()
|
|
||||||
// error, string | void
|
|
||||||
// error, wrong key type
|
|
||||||
function* generator(): Iterable<[string, number]> {
|
function* generator(): Iterable<[string, number]> {
|
||||||
while (true) {
|
while (true) {
|
||||||
yield [ \"foo\", 123 ];
|
yield [ \"foo\", 123 ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let tests = [
|
let tests = [
|
||||||
|
// good constructors
|
||||||
function() {
|
function() {
|
||||||
let w = new Map();
|
let w = new Map();
|
||||||
let x = new Map(null);
|
let x = new Map(null);
|
||||||
|
@ -139,16 +136,19 @@ let tests = [
|
||||||
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());
|
let c: Map<string, number> = new Map(generator());
|
||||||
},
|
},
|
||||||
|
// bad constructors
|
||||||
function() {
|
function() {
|
||||||
let x = new Map([ \"foo\", 123 ]);
|
let x = new Map([ \"foo\", 123 ]);
|
||||||
let y: Map<number, string> = new Map([ [ \"foo\", 123 ] ]);
|
// error
|
||||||
|
let y: Map<number, string> = new Map([ [ \"foo\", 123 ] ]); // error
|
||||||
},
|
},
|
||||||
|
// get()
|
||||||
function(x: Map<string, number>) {
|
function(x: Map<string, number>) {
|
||||||
(x.get(\"foo\"): boolean);
|
(x.get(\"foo\"): boolean);
|
||||||
x.get(123);
|
// error, string | void
|
||||||
|
x.get(123); // error, wrong key type
|
||||||
}
|
}
|
||||||
];
|
];"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test regexp.js 1`] = `
|
exports[`test regexp.js 1`] = `
|
||||||
|
@ -183,38 +183,35 @@ let tests = [
|
||||||
];
|
];
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @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 = [
|
let tests = [
|
||||||
|
// constructor
|
||||||
function() {
|
function() {
|
||||||
new RegExp(\"foo\");
|
new RegExp(\"foo\");
|
||||||
new RegExp(/foo/);
|
new RegExp(/foo/);
|
||||||
new RegExp(\"foo\", \"i\");
|
new RegExp(\"foo\", \"i\");
|
||||||
new RegExp(\"foo\", \"ig\");
|
new RegExp(\"foo\", \"ig\");
|
||||||
new RegExp(/foo/, \"i\");
|
new RegExp(/foo/, \"i\");
|
||||||
new RegExp(/foo/g, \"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() {
|
function() {
|
||||||
RegExp(\"foo\");
|
RegExp(\"foo\");
|
||||||
RegExp(/foo/);
|
RegExp(/foo/);
|
||||||
RegExp(\"foo\", \"i\");
|
RegExp(\"foo\", \"i\");
|
||||||
RegExp(\"foo\", \"ig\");
|
RegExp(\"foo\", \"ig\");
|
||||||
RegExp(/foo/, \"i\");
|
RegExp(/foo/, \"i\");
|
||||||
RegExp(/foo/g, \"i\");
|
// invalid in ES5, valid in ES6
|
||||||
|
RegExp(/foo/g, \"i\"); // invalid in ES5, valid in ES6
|
||||||
},
|
},
|
||||||
|
// invalid flags
|
||||||
function() {
|
function() {
|
||||||
RegExp(\"foo\", \"z\");
|
RegExp(\"foo\", \"z\");
|
||||||
new RegExp(\"foo\", \"z\");
|
// error
|
||||||
|
new RegExp(\"foo\", \"z\"); // error
|
||||||
}
|
}
|
||||||
];
|
];"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test weakset.js 1`] = `
|
exports[`test weakset.js 1`] = `
|
||||||
|
@ -256,11 +253,11 @@ function* numbers(): Iterable<number> {
|
||||||
let ws5 = new WeakSet(numbers()); // error, must be objects
|
let ws5 = new WeakSet(numbers()); // error, must be objects
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
// error, must be objects
|
|
||||||
// error, must be objects
|
|
||||||
let ws = new WeakSet();
|
let ws = new WeakSet();
|
||||||
let obj: Object = {};
|
let obj: Object = {};
|
||||||
let dict: { foo: string } = { foo: \"bar\" };
|
let dict: { foo: string } = { foo: \"bar\" };
|
||||||
|
|
||||||
ws.add(window);
|
ws.add(window);
|
||||||
ws.add(obj);
|
ws.add(obj);
|
||||||
ws.add(dict);
|
ws.add(dict);
|
||||||
|
@ -270,20 +267,25 @@ ws.has(dict);
|
||||||
ws.delete(window);
|
ws.delete(window);
|
||||||
ws.delete(obj);
|
ws.delete(obj);
|
||||||
ws.delete(dict);
|
ws.delete(dict);
|
||||||
|
|
||||||
let ws2 = new WeakSet([ obj, dict ]);
|
let ws2 = new WeakSet([ obj, dict ]);
|
||||||
|
|
||||||
let ws3 = new WeakSet([ 1, 2, 3 ]);
|
let ws3 = new WeakSet([ 1, 2, 3 ]);
|
||||||
|
// error, must be objects
|
||||||
function* generator(): Iterable<{ foo: string }> {
|
function* generator(): Iterable<{ foo: string }> {
|
||||||
while (true) {
|
while (true) {
|
||||||
yield { foo: \"bar\" };
|
yield { foo: \"bar\" };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let ws4 = new WeakSet(generator());
|
let ws4 = new WeakSet(generator());
|
||||||
|
|
||||||
function* numbers(): Iterable<number> {
|
function* numbers(): Iterable<number> {
|
||||||
let i = 0;
|
let i = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
yield i++;
|
yield i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let ws5 = new WeakSet(numbers());
|
|
||||||
"
|
let ws5 = new WeakSet(numbers()); // error, must be objects"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -49,9 +49,23 @@ n.x = [0];
|
||||||
|
|
||||||
*/
|
*/
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
type CovArrayVerbose<X, Y: X> = Array<Y>;
|
||||||
|
var b: CovArrayVerbose<number, *> = [];
|
||||||
|
var y: CovArrayVerbose<mixed, *> = b;
|
||||||
|
y[0] = \"\";
|
||||||
// error
|
// error
|
||||||
|
class NVerbose<E, I: E> {
|
||||||
|
x: CovArrayVerbose<E, I>;
|
||||||
|
foo(): CovArrayVerbose<mixed, I> {
|
||||||
|
return this.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var nv: NVerbose<number, *> = new NVerbose();
|
||||||
|
nv.x = [ 0 ];
|
||||||
|
(nv.x[0]: string);
|
||||||
// error
|
// error
|
||||||
// error
|
(nv.foo()[0]: string); // error
|
||||||
/* TODO: use existentials for non-verbose covariance?
|
/* TODO: use existentials for non-verbose covariance?
|
||||||
|
|
||||||
type CovArray<X> = Array<*:X>;
|
type CovArray<X> = Array<*:X>;
|
||||||
|
@ -85,20 +99,5 @@ n.x = [0];
|
||||||
(n.x[0]: string); // error
|
(n.x[0]: string); // error
|
||||||
(n.foo()[0]: string); // not an 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[0] = \"\";
|
|
||||||
class NVerbose<E, I: E> {
|
|
||||||
x: CovArrayVerbose<E, I>;
|
|
||||||
foo(): CovArrayVerbose<mixed, I> {
|
|
||||||
return this.x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var nv: NVerbose<number, *> = new NVerbose();
|
|
||||||
nv.x = [ 0 ];
|
|
||||||
(nv.x[0]: string);
|
|
||||||
(nv.foo()[0]: string);
|
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -11,13 +11,12 @@ declare module bar {
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
declare module foo {}
|
||||||
|
// TODO
|
||||||
// This file triggers a violation of the \"disjoint-or-nested ranges invariant\"
|
// This file triggers a violation of the \"disjoint-or-nested ranges invariant\"
|
||||||
// that we implicitly assume in type-at-pos and coverage implementations. In
|
// that we implicitly assume in type-at-pos and coverage implementations. In
|
||||||
// particular, when unchecked it causes a crash with coverage --color.
|
// particular, when unchecked it causes a crash with coverage --color.
|
||||||
// TODO
|
declare module bar {}"
|
||||||
declare module foo {}
|
|
||||||
declare module bar {}
|
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test declare_module.js 1`] = `
|
exports[`test declare_module.js 1`] = `
|
||||||
|
@ -27,8 +26,8 @@ declare module foo {
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// check coverage of declare module
|
// check coverage of declare module
|
||||||
declare module foo {}
|
|
||||||
"
|
declare module foo {}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test no_pragma.js 1`] = `
|
exports[`test no_pragma.js 1`] = `
|
||||||
|
@ -36,8 +35,7 @@ exports[`test no_pragma.js 1`] = `
|
||||||
(x: string);
|
(x: string);
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
let x = 0;
|
let x = 0;
|
||||||
(x: string);
|
(x: string);"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test non-termination.js 1`] = `
|
exports[`test non-termination.js 1`] = `
|
||||||
|
@ -56,12 +54,11 @@ declare module bar {
|
||||||
declare class qux {
|
declare class qux {
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
declare module foo {}
|
||||||
// This file triggers a violation of the \"disjoint-or-nested ranges invariant\"
|
// This file triggers a violation of the \"disjoint-or-nested ranges invariant\"
|
||||||
// that we implicitly assume in type-at-pos and coverage implementations. In
|
// that we implicitly assume in type-at-pos and coverage implementations. In
|
||||||
// particular, when unchecked it causes non-termination with coverage --color.
|
// particular, when unchecked it causes non-termination with coverage --color.
|
||||||
// TODO
|
|
||||||
declare module foo {}
|
|
||||||
declare module bar {}
|
declare module bar {}
|
||||||
declare class qux {}
|
// TODO
|
||||||
"
|
declare class qux {}"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -6,9 +6,10 @@ class A extends B { }
|
||||||
module.exports = A;
|
module.exports = A;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
var B = require(\"./B\");
|
var B = require(\"./B\");
|
||||||
|
|
||||||
class A extends B {}
|
class A extends B {}
|
||||||
module.exports = A;
|
|
||||||
"
|
module.exports = A;"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test B.js 1`] = `
|
exports[`test B.js 1`] = `
|
||||||
|
@ -18,8 +19,8 @@ exports[`test B.js 1`] = `
|
||||||
|
|
||||||
module.exports = B;
|
module.exports = B;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
//class B extends A { }
|
|
||||||
var A = require(\"./A\");
|
var A = require(\"./A\");
|
||||||
module.exports = B;
|
|
||||||
"
|
//class B extends A { }
|
||||||
|
module.exports = B;"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -28,12 +28,12 @@ new Date(2015, 6, 18, 11, 55, 42, \'999\');
|
||||||
new Date(\'2015\', 6);
|
new Date(\'2015\', 6);
|
||||||
new Date(2015, 6, 18, 11, 55, 42, 999, \'hahaha\');
|
new Date(2015, 6, 18, 11, 55, 42, 999, \'hahaha\');
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// valid constructors
|
|
||||||
// invalid constructors
|
|
||||||
// invalid constructors that we incorrectly consider valid
|
|
||||||
var d = new Date(0);
|
var d = new Date(0);
|
||||||
var x: string = d.getTime();
|
var x: string = d.getTime();
|
||||||
|
|
||||||
var y: number = d;
|
var y: number = d;
|
||||||
|
|
||||||
|
// valid constructors
|
||||||
new Date();
|
new Date();
|
||||||
new Date(1234567890);
|
new Date(1234567890);
|
||||||
new Date(\"2015/06/18\");
|
new Date(\"2015/06/18\");
|
||||||
|
@ -43,6 +43,8 @@ new Date(2015, 6, 18, 11);
|
||||||
new Date(2015, 6, 18, 11, 55);
|
new Date(2015, 6, 18, 11, 55);
|
||||||
new Date(2015, 6, 18, 11, 55, 42);
|
new Date(2015, 6, 18, 11, 55, 42);
|
||||||
new Date(2015, 6, 18, 11, 55, 42, 999);
|
new Date(2015, 6, 18, 11, 55, 42, 999);
|
||||||
|
|
||||||
|
// invalid constructors
|
||||||
new Date({});
|
new Date({});
|
||||||
new Date(2015, \"6\");
|
new Date(2015, \"6\");
|
||||||
new Date(2015, 6, \"18\");
|
new Date(2015, 6, \"18\");
|
||||||
|
@ -50,7 +52,8 @@ new Date(2015, 6, 18, \"11\");
|
||||||
new Date(2015, 6, 18, 11, \"55\");
|
new Date(2015, 6, 18, 11, \"55\");
|
||||||
new Date(2015, 6, 18, 11, 55, \"42\");
|
new Date(2015, 6, 18, 11, 55, \"42\");
|
||||||
new Date(2015, 6, 18, 11, 55, 42, \"999\");
|
new Date(2015, 6, 18, 11, 55, 42, \"999\");
|
||||||
|
|
||||||
|
// invalid constructors that we incorrectly consider valid
|
||||||
new Date(\"2015\", 6);
|
new Date(\"2015\", 6);
|
||||||
new Date(2015, 6, 18, 11, 55, 42, 999, \"hahaha\");
|
new Date(2015, 6, 18, 11, 55, 42, 999, \"hahaha\");"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -10,8 +10,8 @@ module.exports.fun = (): string => \"hello there\";
|
||||||
* @providesModule ExplicitProvidesModuleDifferentName
|
* @providesModule ExplicitProvidesModuleDifferentName
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
module.exports.fun = (): string => \"hello there\";
|
|
||||||
"
|
module.exports.fun = (): string => \"hello there\";"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ExplicitProvidesModuleSameName.js 1`] = `
|
exports[`test ExplicitProvidesModuleSameName.js 1`] = `
|
||||||
|
@ -26,8 +26,8 @@ module.exports.fun = (): string => \"hello there\";
|
||||||
* @providesModule ExplicitProvidesModuleSameName
|
* @providesModule ExplicitProvidesModuleSameName
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
module.exports.fun = (): string => \"hello there\";
|
|
||||||
"
|
module.exports.fun = (): string => \"hello there\";"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ImplicitProvidesModule.js 1`] = `
|
exports[`test ImplicitProvidesModule.js 1`] = `
|
||||||
|
@ -42,15 +42,13 @@ module.exports.fun = (): string => \"hello there\";
|
||||||
* @providesModule ImplicitProvidesModule
|
* @providesModule ImplicitProvidesModule
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
module.exports.fun = (): string => \"hello there\";
|
|
||||||
"
|
module.exports.fun = (): string => \"hello there\";"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test md5.js 1`] = `
|
exports[`test md5.js 1`] = `
|
||||||
"/* @providesModule md5 */
|
"/* @providesModule md5 */
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @providesModule md5 */
|
|
||||||
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -67,11 +65,13 @@ var ExplicitDifferentName = require(\'ExplicitProvidesModuleDifferentName\');
|
||||||
(ExplicitDifferentName.fun(): string);
|
(ExplicitDifferentName.fun(): string);
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
var Implicit = require(\"ImplicitProvidesModule\");
|
var Implicit = require(\"ImplicitProvidesModule\");
|
||||||
(Implicit.fun(): string);
|
(Implicit.fun(): string);
|
||||||
|
|
||||||
var ExplicitSameName = require(\"ExplicitProvidesModuleSameName\");
|
var ExplicitSameName = require(\"ExplicitProvidesModuleSameName\");
|
||||||
(ExplicitSameName.fun(): string);
|
(ExplicitSameName.fun(): string);
|
||||||
|
|
||||||
var ExplicitDifferentName = require(\"ExplicitProvidesModuleDifferentName\");
|
var ExplicitDifferentName = require(\"ExplicitProvidesModuleDifferentName\");
|
||||||
(ExplicitDifferentName.fun(): string);
|
(ExplicitDifferentName.fun(): string);"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
exports[`test min.js 1`] = `
|
exports[`test min.js 1`] = `
|
||||||
"module.exports.fun = (): string => \"hello there\";
|
"module.exports.fun = (): string => \"hello there\";
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
module.exports.fun = (): string => \"hello there\";
|
module.exports.fun = (): string => \"hello there\";"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -14,14 +14,16 @@ var unreachable = require(\'annotation\');
|
||||||
(corge.fun(): string);
|
(corge.fun(): string);
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
// make sure we don\'t pick up non-header @providesModule
|
|
||||||
// annotations - see node_modules/qux/docblock.js
|
|
||||||
var docblock = require(\"qux/docblock\");
|
var docblock = require(\"qux/docblock\");
|
||||||
var min = require(\"d3/min.js\");
|
var min = require(\"d3/min.js\");
|
||||||
var corge = require(\"qux/corge\");
|
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\");
|
var unreachable = require(\"annotation\");
|
||||||
|
|
||||||
(docblock.fun(): string);
|
(docblock.fun(): string);
|
||||||
(min.fun(): string);
|
(min.fun(): string);
|
||||||
(corge.fun(): string);
|
(corge.fun(): string);"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
exports[`test index.js 1`] = `
|
exports[`test index.js 1`] = `
|
||||||
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
exports[`test client.js 1`] = `
|
exports[`test client.js 1`] = `
|
||||||
"var ws = require(\'../\');
|
"var ws = require(\'../\');
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
var ws = require(\"../\");
|
var ws = require(\"../\");"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -7,8 +7,7 @@ export function foo(): Implementation { return new Implementation; }
|
||||||
class Implementation {}
|
class Implementation {}
|
||||||
export function foo(): Implementation {
|
export function foo(): Implementation {
|
||||||
return new Implementation();
|
return new Implementation();
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ExplicitProvidesModuleDifferentName.js 1`] = `
|
exports[`test ExplicitProvidesModuleDifferentName.js 1`] = `
|
||||||
|
@ -24,9 +23,9 @@ module.exports.fun = (): Implementation => new Implementation;
|
||||||
* @providesModule ExplicitProvidesModuleDifferentName
|
* @providesModule ExplicitProvidesModuleDifferentName
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Implementation {}
|
class Implementation {}
|
||||||
module.exports.fun = (): Implementation => new Implementation();
|
module.exports.fun = (): Implementation => new Implementation();"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ExplicitProvidesModuleSameName.js 1`] = `
|
exports[`test ExplicitProvidesModuleSameName.js 1`] = `
|
||||||
|
@ -42,9 +41,9 @@ module.exports.fun = (): Implementation => new Implementation;
|
||||||
* @providesModule ExplicitProvidesModuleSameName
|
* @providesModule ExplicitProvidesModuleSameName
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Implementation {}
|
class Implementation {}
|
||||||
module.exports.fun = (): Implementation => new Implementation();
|
module.exports.fun = (): Implementation => new Implementation();"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ImplicitProvidesModule.js 1`] = `
|
exports[`test ImplicitProvidesModule.js 1`] = `
|
||||||
|
@ -60,16 +59,14 @@ module.exports.fun = (): Implementation => new Implementation;
|
||||||
* @providesModule ImplicitProvidesModule
|
* @providesModule ImplicitProvidesModule
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Implementation {}
|
class Implementation {}
|
||||||
module.exports.fun = (): Implementation => new Implementation();
|
module.exports.fun = (): Implementation => new Implementation();"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test md5.js 1`] = `
|
exports[`test md5.js 1`] = `
|
||||||
"/* @providesModule md5 */
|
"/* @providesModule md5 */
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @providesModule md5 */
|
|
||||||
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -86,14 +83,13 @@ var ExplicitDifferentName = require(\'ExplicitProvidesModuleDifferentName\');
|
||||||
(ExplicitDifferentName.fun(): boolean); // Error: Either Implementation ~> boolean or Declaration ~> boolean
|
(ExplicitDifferentName.fun(): boolean); // Error: Either Implementation ~> boolean or Declaration ~> boolean
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @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\");
|
var Implicit = require(\"ImplicitProvidesModule\");
|
||||||
(Implicit.fun(): boolean);
|
(Implicit.fun(): boolean);
|
||||||
|
// Error: Either Implementation ~> boolean or Declaration ~> boolean
|
||||||
var ExplicitSameName = require(\"ExplicitProvidesModuleSameName\");
|
var ExplicitSameName = require(\"ExplicitProvidesModuleSameName\");
|
||||||
(ExplicitSameName.fun(): boolean);
|
(ExplicitSameName.fun(): boolean);
|
||||||
|
// Error: Either Implementation ~> boolean or Declaration ~> boolean
|
||||||
var ExplicitDifferentName = require(\"ExplicitProvidesModuleDifferentName\");
|
var ExplicitDifferentName = require(\"ExplicitProvidesModuleDifferentName\");
|
||||||
(ExplicitDifferentName.fun(): boolean);
|
(ExplicitDifferentName.fun(): boolean); // Error: Either Implementation ~> boolean or Declaration ~> boolean"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -3,6 +3,5 @@ exports[`test min.js 1`] = `
|
||||||
module.exports.fun = (): Implementation => new Implementation;
|
module.exports.fun = (): Implementation => new Implementation;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
class Implementation {}
|
class Implementation {}
|
||||||
module.exports.fun = (): Implementation => new Implementation();
|
module.exports.fun = (): Implementation => new Implementation();"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -10,14 +10,14 @@ var corge = require(\'qux/corge\');
|
||||||
(corge.fun(): boolean); // Error: Either Implementation ~> boolean or Declaration ~> boolean
|
(corge.fun(): boolean); // Error: Either Implementation ~> boolean or Declaration ~> boolean
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @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 docblock = require(\"qux/docblock\");
|
||||||
var min = require(\"d3/min.js\");
|
var min = require(\"d3/min.js\");
|
||||||
var corge = require(\"qux/corge\");
|
var corge = require(\"qux/corge\");
|
||||||
|
|
||||||
(docblock.fun(): boolean);
|
(docblock.fun(): boolean);
|
||||||
|
// Error: Either Implementation ~> boolean or Declaration ~> boolean
|
||||||
(min.fun(): boolean);
|
(min.fun(): boolean);
|
||||||
(corge.fun(): boolean);
|
// Error: Either Implementation ~> boolean or Declaration ~> boolean
|
||||||
"
|
(corge.fun(): boolean); // Error: Either Implementation ~> boolean or Declaration ~> boolean"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
exports[`test index.js 1`] = `
|
exports[`test index.js 1`] = `
|
||||||
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
exports[`test client.js 1`] = `
|
exports[`test client.js 1`] = `
|
||||||
"var ws = require(\'../\');
|
"var ws = require(\'../\');
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
var ws = require(\"../\");
|
var ws = require(\"../\");"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -5,8 +5,7 @@ export function foo(): Implementation { return new Implementation; }
|
||||||
class Implementation {}
|
class Implementation {}
|
||||||
export function foo(): Implementation {
|
export function foo(): Implementation {
|
||||||
return new Implementation();
|
return new Implementation();
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test test_absolute.js 1`] = `
|
exports[`test test_absolute.js 1`] = `
|
||||||
|
@ -53,47 +52,46 @@ var F = require(\'package_with_dir_main\');
|
||||||
(F.fun(): boolean); // Error either Implementation ~> boolean or Declaration ~> boolean
|
(F.fun(): boolean); // Error either Implementation ~> boolean or Declaration ~> boolean
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
// This will require ./node_modules/B.js.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\");
|
var B1 = require(\"B\");
|
||||||
(B1.fun(): boolean);
|
(B1.fun(): boolean);
|
||||||
|
// Error either Implementation ~> boolean or Declaration ~> boolean
|
||||||
|
// This will require ./node_modules/B.js.flow
|
||||||
var B2 = require(\"B.js\");
|
var B2 = require(\"B.js\");
|
||||||
(B2.fun(): boolean);
|
(B2.fun(): boolean);
|
||||||
|
// Error either Implementation ~> boolean or Declaration ~> boolean
|
||||||
var C = require(\"package_with_full_main\");
|
var C = require(\"package_with_full_main\");
|
||||||
(C.fun(): boolean);
|
(C.fun(): boolean);
|
||||||
|
// Error either Implementation ~> boolean or Declaration ~> boolean
|
||||||
var D = require(\"package_with_partial_main\");
|
var D = require(\"package_with_partial_main\");
|
||||||
(D.fun(): boolean);
|
(D.fun(): boolean);
|
||||||
|
// Error either Implementation ~> boolean or Declaration ~> boolean
|
||||||
var E = require(\"package_with_no_package_json\");
|
var E = require(\"package_with_no_package_json\");
|
||||||
(E.fun(): boolean);
|
(E.fun(): boolean);
|
||||||
|
// Error either Implementation ~> boolean or Declaration ~> boolean
|
||||||
var F = require(\"package_with_dir_main\");
|
var F = require(\"package_with_dir_main\");
|
||||||
(F.fun(): boolean);
|
(F.fun(): boolean);
|
||||||
|
// Error either Implementation ~> boolean or Declaration ~> boolean
|
||||||
|
// This will require ./node_modules/B.js.flow
|
||||||
var B1 = require(\"B\");
|
var B1 = require(\"B\");
|
||||||
(B1.fun(): boolean);
|
(B1.fun(): boolean);
|
||||||
|
// Error either Implementation ~> boolean or Declaration ~> boolean
|
||||||
|
// This will require ./node_modules/B.js.flow
|
||||||
var B2 = require(\"B.js\");
|
var B2 = require(\"B.js\");
|
||||||
(B2.fun(): boolean);
|
(B2.fun(): boolean);
|
||||||
|
// Error either Implementation ~> boolean or Declaration ~> boolean
|
||||||
var C = require(\"package_with_full_main\");
|
var C = require(\"package_with_full_main\");
|
||||||
(C.fun(): boolean);
|
(C.fun(): boolean);
|
||||||
|
// Error either Implementation ~> boolean or Declaration ~> boolean
|
||||||
var D = require(\"package_with_partial_main\");
|
var D = require(\"package_with_partial_main\");
|
||||||
(D.fun(): boolean);
|
(D.fun(): boolean);
|
||||||
|
// Error either Implementation ~> boolean or Declaration ~> boolean
|
||||||
var E = require(\"package_with_no_package_json\");
|
var E = require(\"package_with_no_package_json\");
|
||||||
(E.fun(): boolean);
|
(E.fun(): boolean);
|
||||||
|
// Error either Implementation ~> boolean or Declaration ~> boolean
|
||||||
var F = require(\"package_with_dir_main\");
|
var F = require(\"package_with_dir_main\");
|
||||||
(F.fun(): boolean);
|
(F.fun(): boolean); // Error either Implementation ~> boolean or Declaration ~> boolean"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test test_relative.js 1`] = `
|
exports[`test test_relative.js 1`] = `
|
||||||
|
@ -101,8 +99,7 @@ exports[`test test_relative.js 1`] = `
|
||||||
|
|
||||||
(foo(): boolean); // Error: either Implementation ~> boolean or Definition ~> boolean
|
(foo(): boolean); // Error: either Implementation ~> boolean or Definition ~> boolean
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// Error: either Implementation ~> boolean or Definition ~> boolean
|
|
||||||
import {foo} from \"./A\";
|
import {foo} from \"./A\";
|
||||||
(foo(): boolean);
|
|
||||||
"
|
(foo(): boolean); // Error: either Implementation ~> boolean or Definition ~> boolean"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -4,8 +4,8 @@ exports[`test A.js 1`] = `
|
||||||
module.exports.fun = (): string => \'hello there!\';
|
module.exports.fun = (): string => \'hello there!\';
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
module.exports.fun = (): string => \"hello there!\";
|
|
||||||
"
|
module.exports.fun = (): string => \"hello there!\";"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test CJS.js 1`] = `
|
exports[`test CJS.js 1`] = `
|
||||||
|
@ -13,8 +13,7 @@ exports[`test CJS.js 1`] = `
|
||||||
module.exports = 42;
|
module.exports = 42;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
module.exports = 42;
|
module.exports = 42;"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test test_absolute.js 1`] = `
|
exports[`test test_absolute.js 1`] = `
|
||||||
|
@ -41,27 +40,26 @@ var F = require(\'package_with_dir_main\');
|
||||||
(F.fun(): string); // Error number ~> string
|
(F.fun(): string); // Error number ~> string
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
// This will require ./node_modules/B.js.flow
|
// This will require ./node_modules/B.js.flow
|
||||||
// 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\");
|
var B1 = require(\"B\");
|
||||||
(B1.fun(): string);
|
(B1.fun(): string);
|
||||||
|
// Error number ~> string
|
||||||
|
// This will require ./node_modules/B.js.flow
|
||||||
var B2 = require(\"B.js\");
|
var B2 = require(\"B.js\");
|
||||||
(B2.fun(): string);
|
(B2.fun(): string);
|
||||||
|
// Error number ~> string
|
||||||
var C = require(\"package_with_full_main\");
|
var C = require(\"package_with_full_main\");
|
||||||
(C.fun(): string);
|
(C.fun(): string);
|
||||||
|
// Error number ~> string
|
||||||
var D = require(\"package_with_partial_main\");
|
var D = require(\"package_with_partial_main\");
|
||||||
(D.fun(): string);
|
(D.fun(): string);
|
||||||
|
// Error number ~> string
|
||||||
var E = require(\"package_with_no_package_json\");
|
var E = require(\"package_with_no_package_json\");
|
||||||
(E.fun(): string);
|
(E.fun(): string);
|
||||||
|
// Error number ~> string
|
||||||
var F = require(\"package_with_dir_main\");
|
var F = require(\"package_with_dir_main\");
|
||||||
(F.fun(): string);
|
(F.fun(): string); // Error number ~> string"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test test_relative.js 1`] = `
|
exports[`test test_relative.js 1`] = `
|
||||||
|
@ -80,17 +78,16 @@ var CJS = require(\'./CJS.js\');
|
||||||
(CJS: number); // Error: string ~> number
|
(CJS: number); // Error: string ~> number
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
// This will require ./A.js.flow
|
// This will require ./A.js.flow
|
||||||
// Error number ~> string
|
|
||||||
// This will require ./A.js.flow
|
|
||||||
// Error number ~> string
|
|
||||||
// Error: string ~> number
|
|
||||||
var A1 = require(\"./A\");
|
var A1 = require(\"./A\");
|
||||||
(A1.fun(): string);
|
(A1.fun(): string);
|
||||||
|
// Error number ~> string
|
||||||
|
// This will require ./A.js.flow
|
||||||
var A2 = require(\"./A.js\");
|
var A2 = require(\"./A.js\");
|
||||||
(A2.fun(): string);
|
(A2.fun(): string);
|
||||||
|
// Error number ~> string
|
||||||
var CJS = require(\"./CJS.js\");
|
var CJS = require(\"./CJS.js\");
|
||||||
(CJS: string);
|
(CJS: string);
|
||||||
(CJS: number);
|
(CJS: number); // Error: string ~> number"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -10,11 +10,11 @@ C.foo(\"\");
|
||||||
(C.name: string);
|
(C.name: string);
|
||||||
(C.name: number); // error, it\'s a string
|
(C.name: number); // error, it\'s a string
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// error, it\'s a string
|
|
||||||
declare class C { static x: number, static foo(x: number): void }
|
declare class C { static x: number, static foo(x: number): void }
|
||||||
|
|
||||||
C.x = \"\";
|
C.x = \"\";
|
||||||
C.foo(\"\");
|
C.foo(\"\");
|
||||||
|
|
||||||
(C.name: string);
|
(C.name: string);
|
||||||
(C.name: number);
|
(C.name: number); // error, it\'s a string"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -11,6 +11,5 @@ declare class D extends _module.C {
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
declare class _C { foo(): number }
|
declare class _C { foo(): number }
|
||||||
declare var _module: { C: Class<_C> };
|
declare var _module: { C: Class<_C> };
|
||||||
declare class D extends _module.C { foo(): string }
|
declare class D extends _module.C { foo(): string }"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -4,15 +4,13 @@ exports[`test B.js 1`] = `
|
||||||
exports.numberValue = 42;
|
exports.numberValue = 42;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
exports.numberValue = 42;
|
|
||||||
"
|
exports.numberValue = 42;"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test C.js 1`] = `
|
exports[`test C.js 1`] = `
|
||||||
"/* @flow */
|
"/* @flow */
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
|
||||||
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -43,11 +41,14 @@ module.exports = Test;
|
||||||
* @providesModule CommonJS_Clobbering_Class
|
* @providesModule CommonJS_Clobbering_Class
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Base {
|
class Base {
|
||||||
static baseProp: number;
|
static baseProp: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Test extends Base {
|
class Test extends Base {
|
||||||
static childProp: number;
|
static childProp: number;
|
||||||
|
|
||||||
static staticNumber1(): number {
|
static staticNumber1(): number {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -57,6 +58,7 @@ class Test extends Base {
|
||||||
static staticNumber3(): number {
|
static staticNumber3(): number {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
instNumber1(): number {
|
instNumber1(): number {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -64,8 +66,8 @@ class Test extends Base {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
module.exports = Test;
|
|
||||||
"
|
module.exports = Test;"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test CommonJS_Clobbering_Lit.js 1`] = `
|
exports[`test CommonJS_Clobbering_Lit.js 1`] = `
|
||||||
|
@ -86,14 +88,14 @@ module.exports = {
|
||||||
* @providesModule CommonJS_Clobbering_Lit
|
* @providesModule CommonJS_Clobbering_Lit
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
numberValue1: 1,
|
numberValue1: 1,
|
||||||
numberValue2: 2,
|
numberValue2: 2,
|
||||||
numberValue3: 3,
|
numberValue3: 3,
|
||||||
numberValue4: 4,
|
numberValue4: 4,
|
||||||
numberValue5: 5
|
numberValue5: 5
|
||||||
};
|
};"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test CommonJS_Named.js 1`] = `
|
exports[`test CommonJS_Named.js 1`] = `
|
||||||
|
@ -112,12 +114,12 @@ exports.numberValue5 = 5;
|
||||||
* @providesModule CommonJS_Named
|
* @providesModule CommonJS_Named
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
exports.numberValue1 = 1;
|
exports.numberValue1 = 1;
|
||||||
exports.numberValue2 = 2;
|
exports.numberValue2 = 2;
|
||||||
exports.numberValue3 = 3;
|
exports.numberValue3 = 3;
|
||||||
exports.numberValue4 = 4;
|
exports.numberValue4 = 4;
|
||||||
exports.numberValue5 = 5;
|
exports.numberValue5 = 5;"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ES6_Default_AnonFunction1.js 1`] = `
|
exports[`test ES6_Default_AnonFunction1.js 1`] = `
|
||||||
|
@ -132,8 +134,8 @@ declare export default () => number;
|
||||||
* @providesModule ES6_Default_AnonFunction1
|
* @providesModule ES6_Default_AnonFunction1
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
declare export default () => number
|
|
||||||
"
|
declare export default () => number"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ES6_Default_AnonFunction2.js 1`] = `
|
exports[`test ES6_Default_AnonFunction2.js 1`] = `
|
||||||
|
@ -148,8 +150,8 @@ declare export default () =>number;
|
||||||
* @providesModule ES6_Default_AnonFunction2
|
* @providesModule ES6_Default_AnonFunction2
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
declare export default () => number
|
|
||||||
"
|
declare export default () => number"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ES6_Default_NamedClass1.js 1`] = `
|
exports[`test ES6_Default_NamedClass1.js 1`] = `
|
||||||
|
@ -170,13 +172,14 @@ declare export function getAFoo(): FooImpl;
|
||||||
* @providesModule ES6_Default_NamedClass1
|
* @providesModule ES6_Default_NamedClass1
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
declare export default class FooImpl { givesANum(): number }
|
||||||
|
|
||||||
// Regression test for https://github.com/facebook/flow/issues/511
|
// Regression test for https://github.com/facebook/flow/issues/511
|
||||||
//
|
//
|
||||||
// Default-exported class should also be available in local scope
|
// Default-exported class should also be available in local scope
|
||||||
declare export default class FooImpl { givesANum(): number }
|
|
||||||
declare export {FooImpl as Foo}
|
declare export {FooImpl as Foo}
|
||||||
declare export function getAFoo(): FooImpl;
|
declare export function getAFoo(): FooImpl;"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ES6_Default_NamedClass2.js 1`] = `
|
exports[`test ES6_Default_NamedClass2.js 1`] = `
|
||||||
|
@ -191,6 +194,7 @@ declare export default class Foo { givesANum(): number; };
|
||||||
* @providesModule ES6_Default_NamedClass2
|
* @providesModule ES6_Default_NamedClass2
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
declare export default class Foo { givesANum(): number }
|
declare export default class Foo { givesANum(): number }
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
@ -207,8 +211,8 @@ declare export default function foo():number;
|
||||||
* @providesModule ES6_Default_NamedFunction1
|
* @providesModule ES6_Default_NamedFunction1
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
declare export default function foo(): number;
|
|
||||||
"
|
declare export default function foo(): number;"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ES6_Default_NamedFunction2.js 1`] = `
|
exports[`test ES6_Default_NamedFunction2.js 1`] = `
|
||||||
|
@ -223,8 +227,8 @@ declare export default function foo():number;
|
||||||
* @providesModule ES6_Default_NamedFunction2
|
* @providesModule ES6_Default_NamedFunction2
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
declare export default function foo(): number;
|
|
||||||
"
|
declare export default function foo(): number;"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ES6_DefaultAndNamed.js 1`] = `
|
exports[`test ES6_DefaultAndNamed.js 1`] = `
|
||||||
|
@ -234,9 +238,9 @@ declare export default number;
|
||||||
declare export var str: string;
|
declare export var str: string;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
declare export default number
|
declare export default number
|
||||||
declare export var str: string;
|
declare export var str: string;"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ES6_ExportAllFrom_Intermediary1.js 1`] = `
|
exports[`test ES6_ExportAllFrom_Intermediary1.js 1`] = `
|
||||||
|
@ -251,8 +255,8 @@ declare export * from \"ES6_ExportAllFrom_Source1\";
|
||||||
* @providesModule ES6_ExportAllFrom_Intermediary1
|
* @providesModule ES6_ExportAllFrom_Intermediary1
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
declare export * from \"ES6_ExportAllFrom_Source1\"
|
|
||||||
"
|
declare export * from \"ES6_ExportAllFrom_Source1\""
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ES6_ExportAllFrom_Intermediary2.js 1`] = `
|
exports[`test ES6_ExportAllFrom_Intermediary2.js 1`] = `
|
||||||
|
@ -267,8 +271,8 @@ declare export * from \"ES6_ExportAllFrom_Source2\";
|
||||||
* @providesModule ES6_ExportAllFrom_Intermediary2
|
* @providesModule ES6_ExportAllFrom_Intermediary2
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
declare export * from \"ES6_ExportAllFrom_Source2\"
|
|
||||||
"
|
declare export * from \"ES6_ExportAllFrom_Source2\""
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ES6_ExportAllFrom_Source1.js 1`] = `
|
exports[`test ES6_ExportAllFrom_Source1.js 1`] = `
|
||||||
|
@ -283,8 +287,8 @@ declare export var numberValue1: number;
|
||||||
* @providesModule ES6_ExportAllFrom_Source1
|
* @providesModule ES6_ExportAllFrom_Source1
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
declare export var numberValue1: number;
|
|
||||||
"
|
declare export var numberValue1: number;"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ES6_ExportAllFrom_Source2.js 1`] = `
|
exports[`test ES6_ExportAllFrom_Source2.js 1`] = `
|
||||||
|
@ -299,8 +303,8 @@ declare export var numberValue2: number;
|
||||||
* @providesModule ES6_ExportAllFrom_Source2
|
* @providesModule ES6_ExportAllFrom_Source2
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
declare export var numberValue2: number;
|
|
||||||
"
|
declare export var numberValue2: number;"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ES6_ExportAllFromMulti.js 1`] = `
|
exports[`test ES6_ExportAllFromMulti.js 1`] = `
|
||||||
|
@ -310,9 +314,9 @@ declare export * from \"./ES6_ExportAllFrom_Source1\";
|
||||||
declare export * from \"./ES6_ExportAllFrom_Source2\";
|
declare export * from \"./ES6_ExportAllFrom_Source2\";
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
declare export * from \"./ES6_ExportAllFrom_Source1\"
|
declare export * from \"./ES6_ExportAllFrom_Source1\"
|
||||||
declare export * from \"./ES6_ExportAllFrom_Source2\"
|
declare export * from \"./ES6_ExportAllFrom_Source2\""
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ES6_ExportFrom_Intermediary1.js 1`] = `
|
exports[`test ES6_ExportFrom_Intermediary1.js 1`] = `
|
||||||
|
@ -330,8 +334,8 @@ declare export {
|
||||||
* @providesModule ES6_ExportFrom_Intermediary1
|
* @providesModule ES6_ExportFrom_Intermediary1
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
declare export {numberValue1, numberValue2 as numberValue2_renamed} from \"ES6_ExportFrom_Source1\"
|
|
||||||
"
|
declare export {numberValue1, numberValue2 as numberValue2_renamed} from \"ES6_ExportFrom_Source1\""
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ES6_ExportFrom_Intermediary2.js 1`] = `
|
exports[`test ES6_ExportFrom_Intermediary2.js 1`] = `
|
||||||
|
@ -349,8 +353,8 @@ declare export {
|
||||||
* @providesModule ES6_ExportFrom_Intermediary2
|
* @providesModule ES6_ExportFrom_Intermediary2
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
declare export {numberValue1, numberValue2 as numberValue2_renamed2} from \"ES6_ExportFrom_Source2\"
|
|
||||||
"
|
declare export {numberValue1, numberValue2 as numberValue2_renamed2} from \"ES6_ExportFrom_Source2\""
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ES6_ExportFrom_Source1.js 1`] = `
|
exports[`test ES6_ExportFrom_Source1.js 1`] = `
|
||||||
|
@ -366,9 +370,9 @@ declare export var numberValue2: number;
|
||||||
* @providesModule ES6_ExportFrom_Source1
|
* @providesModule ES6_ExportFrom_Source1
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
declare export var numberValue1: number;
|
declare export var numberValue1: number;
|
||||||
declare export var numberValue2: number;
|
declare export var numberValue2: number;"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ES6_ExportFrom_Source2.js 1`] = `
|
exports[`test ES6_ExportFrom_Source2.js 1`] = `
|
||||||
|
@ -384,9 +388,9 @@ declare export var numberValue2: number;
|
||||||
* @providesModule ES6_ExportFrom_Source2
|
* @providesModule ES6_ExportFrom_Source2
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
declare export var numberValue1: number;
|
declare export var numberValue1: number;
|
||||||
declare export var numberValue2: number;
|
declare export var numberValue2: number;"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ES6_Named1.js 1`] = `
|
exports[`test ES6_Named1.js 1`] = `
|
||||||
|
@ -416,20 +420,23 @@ declare export var varDeclNumber2: number;
|
||||||
* @providesModule ES6_Named1
|
* @providesModule ES6_Named1
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var specifierNumber1 = 1;
|
var specifierNumber1 = 1;
|
||||||
var specifierNumber2 = 2;
|
var specifierNumber2 = 2;
|
||||||
var specifierNumber3 = 3;
|
var specifierNumber3 = 3;
|
||||||
var groupedSpecifierNumber1 = 1;
|
var groupedSpecifierNumber1 = 1;
|
||||||
var groupedSpecifierNumber2 = 2;
|
var groupedSpecifierNumber2 = 2;
|
||||||
|
|
||||||
declare export {specifierNumber1}
|
declare export {specifierNumber1}
|
||||||
declare export {specifierNumber2 as specifierNumber2Renamed}
|
declare export {specifierNumber2 as specifierNumber2Renamed}
|
||||||
declare export {specifierNumber3}
|
declare export {specifierNumber3}
|
||||||
declare export {groupedSpecifierNumber1, groupedSpecifierNumber2}
|
declare export {groupedSpecifierNumber1, groupedSpecifierNumber2}
|
||||||
|
|
||||||
declare export function givesANumber(): number;
|
declare export function givesANumber(): number;
|
||||||
declare export class NumberGenerator { givesANumber(): number }
|
declare export class NumberGenerator { givesANumber(): number }
|
||||||
|
|
||||||
declare export var varDeclNumber1: number;
|
declare export var varDeclNumber1: number;
|
||||||
declare export var varDeclNumber2: number;
|
declare export var varDeclNumber2: number;"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ES6_Named2.js 1`] = `
|
exports[`test ES6_Named2.js 1`] = `
|
||||||
|
@ -457,18 +464,21 @@ declare export var varDeclNumber4: number;
|
||||||
* @providesModule ES6_Named2
|
* @providesModule ES6_Named2
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var specifierNumber4 = 1;
|
var specifierNumber4 = 1;
|
||||||
var specifierNumber5 = 2;
|
var specifierNumber5 = 2;
|
||||||
var groupedSpecifierNumber3 = 1;
|
var groupedSpecifierNumber3 = 1;
|
||||||
var groupedSpecifierNumber4 = 2;
|
var groupedSpecifierNumber4 = 2;
|
||||||
|
|
||||||
declare export {specifierNumber4}
|
declare export {specifierNumber4}
|
||||||
declare export {specifierNumber5 as specifierNumber5Renamed}
|
declare export {specifierNumber5 as specifierNumber5Renamed}
|
||||||
declare export {groupedSpecifierNumber3, groupedSpecifierNumber4}
|
declare export {groupedSpecifierNumber3, groupedSpecifierNumber4}
|
||||||
|
|
||||||
declare export function givesANumber2(): number;
|
declare export function givesANumber2(): number;
|
||||||
declare export class NumberGenerator2 { givesANumber(): number }
|
declare export class NumberGenerator2 { givesANumber(): number }
|
||||||
|
|
||||||
declare export var varDeclNumber3: number;
|
declare export var varDeclNumber3: number;
|
||||||
declare export var varDeclNumber4: number;
|
declare export var varDeclNumber4: number;"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ProvidesModuleA.js 1`] = `
|
exports[`test ProvidesModuleA.js 1`] = `
|
||||||
|
@ -487,12 +497,12 @@ exports.stringValue = \"str\";
|
||||||
* @providesModule A
|
* @providesModule A
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
exports.numberValue1 = 42;
|
exports.numberValue1 = 42;
|
||||||
exports.numberValue2 = 42;
|
exports.numberValue2 = 42;
|
||||||
exports.numberValue3 = 42;
|
exports.numberValue3 = 42;
|
||||||
exports.numberValue4 = 42;
|
exports.numberValue4 = 42;
|
||||||
exports.stringValue = \"str\";
|
exports.stringValue = \"str\";"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ProvidesModuleCJSDefault.js 1`] = `
|
exports[`test ProvidesModuleCJSDefault.js 1`] = `
|
||||||
|
@ -509,8 +519,8 @@ module.exports = {
|
||||||
* @providesModule CJSDefault
|
* @providesModule CJSDefault
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
module.exports = { numberValue: 42 };
|
|
||||||
"
|
module.exports = { numberValue: 42 };"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test ProvidesModuleD.js 1`] = `
|
exports[`test ProvidesModuleD.js 1`] = `
|
||||||
|
@ -519,11 +529,6 @@ exports[`test ProvidesModuleD.js 1`] = `
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/**
|
|
||||||
* @providesModule D
|
|
||||||
* @flow
|
|
||||||
*/
|
|
||||||
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -539,24 +544,12 @@ export default {
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/**
|
|
||||||
* @providesModule ES6Default
|
|
||||||
* @flow
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
export default {
|
|
||||||
numberValue: 42,
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test SideEffects.js 1`] = `
|
exports[`test SideEffects.js 1`] = `
|
||||||
"/* @flow */
|
"/* @flow */
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
|
||||||
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -854,271 +847,274 @@ var at3: number = numberValue9;
|
||||||
var at4: string = numberValue9; // Error: number ~> string
|
var at4: string = numberValue9; // Error: number ~> string
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
// ===================== //
|
// ===================== //
|
||||||
// == Path Resolution == //
|
// == Path Resolution == //
|
||||||
// ===================== //
|
// ===================== //
|
||||||
|
|
||||||
// @providesModule
|
// @providesModule
|
||||||
|
import * as DefaultA from \"A\";
|
||||||
|
var a1: number = DefaultA.numberValue1;
|
||||||
|
var a2: string = DefaultA.numberValue1;
|
||||||
// Error: number ~> string
|
// Error: number ~> string
|
||||||
// File path
|
// File path
|
||||||
|
import * as DefaultB from \"./B\";
|
||||||
|
var b1: number = DefaultB.numberValue;
|
||||||
|
var b2: string = DefaultB.numberValue;
|
||||||
// Error: number ~> string
|
// Error: number ~> string
|
||||||
// C.js exists, but not as a providesModule
|
// C.js exists, but not as a providesModule
|
||||||
|
import DefaultC from \"C\";
|
||||||
// Error: No such module
|
// Error: No such module
|
||||||
// @providesModule D exists, but not as a filename
|
// @providesModule D exists, but not as a filename
|
||||||
|
import DefaultD from \"./D\";
|
||||||
// Error: No such module
|
// Error: No such module
|
||||||
// ================================================ //
|
// ================================================ //
|
||||||
// == CommonJS Clobbering Literal Exports -> ES6 == //
|
// == CommonJS Clobbering Literal Exports -> ES6 == //
|
||||||
// ================================================ //
|
// ================================================ //
|
||||||
|
import {doesntExist1} from \"CommonJS_Clobbering_Lit\";
|
||||||
// Error: Not an exported binding
|
// Error: Not an exported binding
|
||||||
|
import {numberValue1} from \"CommonJS_Clobbering_Lit\";
|
||||||
|
var c1: number = numberValue1;
|
||||||
|
var c2: string = numberValue1;
|
||||||
// Error: number ~> string
|
// Error: number ~> string
|
||||||
|
import {numberValue2 as numVal1} from \"CommonJS_Clobbering_Lit\";
|
||||||
|
var d1: number = numVal1;
|
||||||
|
var d2: string = numVal1;
|
||||||
// Error: number ~> string
|
// Error: number ~> string
|
||||||
|
import CJS_Clobb_Lit from \"CommonJS_Clobbering_Lit\";
|
||||||
|
var e1: number = CJS_Clobb_Lit.numberValue3;
|
||||||
|
var e2: string = CJS_Clobb_Lit.numberValue3;
|
||||||
// Error: number ~> string
|
// Error: number ~> string
|
||||||
|
CJS_Clobb_Lit.doesntExist;
|
||||||
// Error: doesntExist isn\'t a property
|
// Error: doesntExist isn\'t a property
|
||||||
|
import * as CJS_Clobb_Lit_NS from \"CommonJS_Clobbering_Lit\";
|
||||||
|
var f1: number = CJS_Clobb_Lit_NS.numberValue4;
|
||||||
|
var f2: number = CJS_Clobb_Lit_NS.default.numberValue4;
|
||||||
|
CJS_Clobb_Lit_NS.default.default;
|
||||||
// Error: No \'default\' property on the exported obj
|
// Error: No \'default\' property on the exported obj
|
||||||
|
var f3: string = CJS_Clobb_Lit_NS.numberValue4;
|
||||||
// Error: number ~> string
|
// Error: number ~> string
|
||||||
|
var f4: string = CJS_Clobb_Lit_NS.default.numberValue5;
|
||||||
// Error: number ~> string
|
// Error: number ~> string
|
||||||
// ============================================== //
|
// ============================================== //
|
||||||
// == CommonJS Clobbering Class Exports -> ES6 == //
|
// == CommonJS Clobbering Class Exports -> ES6 == //
|
||||||
// ============================================== //
|
// ============================================== //
|
||||||
|
import {doesntExist2} from \"CommonJS_Clobbering_Class\";
|
||||||
// Error: Not an exported binding
|
// Error: Not an exported binding
|
||||||
// The following import should error because class statics are not turned into
|
// The following import should error because class statics are not turned into
|
||||||
// named exports for now. This avoids complexities with polymorphic static
|
// named exports for now. This avoids complexities with polymorphic static
|
||||||
// members (where the polymophism is defined on the class itself rather than the
|
// members (where the polymophism is defined on the class itself rather than the
|
||||||
// method).
|
// method).
|
||||||
|
import {staticNumber1, baseProp, childProp} from \"CommonJS_Clobbering_Class\";
|
||||||
// Error
|
// Error
|
||||||
|
import CJS_Clobb_Class from \"CommonJS_Clobbering_Class\";
|
||||||
|
new CJS_Clobb_Class();
|
||||||
|
new CJS_Clobb_Class().doesntExist;
|
||||||
// Error: Class has no \`doesntExist\` property
|
// Error: Class has no \`doesntExist\` property
|
||||||
|
var h1: number = CJS_Clobb_Class.staticNumber2();
|
||||||
|
var h2: string = CJS_Clobb_Class.staticNumber2();
|
||||||
// Error: number ~> string
|
// Error: number ~> string
|
||||||
|
var h3: number = new CJS_Clobb_Class().instNumber1();
|
||||||
|
var h4: string = new CJS_Clobb_Class().instNumber1();
|
||||||
// Error: number ~> string
|
// Error: number ~> string
|
||||||
|
import * as CJS_Clobb_Class_NS from \"CommonJS_Clobbering_Class\";
|
||||||
|
new CJS_Clobb_Class_NS();
|
||||||
// Error: Namespace object isn\'t constructable
|
// Error: Namespace object isn\'t constructable
|
||||||
|
var i1: number = CJS_Clobb_Class_NS.staticNumber3();
|
||||||
// Error: Class statics not copied to Namespace object
|
// Error: Class statics not copied to Namespace object
|
||||||
|
var i2: number = new CJS_Clobb_Class_NS.default().instNumber2();
|
||||||
|
var i3: string = new CJS_Clobb_Class_NS.default().instNumber2();
|
||||||
// Error: number ~> string
|
// Error: number ~> string
|
||||||
// =================================== //
|
// =================================== //
|
||||||
// == CommonJS Named Exports -> ES6 == //
|
// == CommonJS Named Exports -> ES6 == //
|
||||||
// =================================== //
|
// =================================== //
|
||||||
|
import {doesntExist3} from \"CommonJS_Named\";
|
||||||
// Error: Not an exported binding
|
// Error: Not an exported binding
|
||||||
|
import {numberValue2} from \"CommonJS_Named\";
|
||||||
|
var j1: number = numberValue2;
|
||||||
|
var j2: string = numberValue2;
|
||||||
// Error: number ~> string
|
// Error: number ~> string
|
||||||
|
import {numberValue3 as numVal3} from \"CommonJS_Named\";
|
||||||
|
var k1: number = numVal3;
|
||||||
|
var k2: string = numVal3;
|
||||||
// Error: number ~> string
|
// Error: number ~> string
|
||||||
|
import * as CJS_Named from \"CommonJS_Named\";
|
||||||
|
var l1: number = CJS_Named.numberValue1;
|
||||||
|
var l2: string = CJS_Named.numberValue1;
|
||||||
// Error: number ~> string
|
// Error: number ~> string
|
||||||
|
CJS_Named.doesntExist;
|
||||||
// Error: doesntExist isn\'t a property
|
// Error: doesntExist isn\'t a property
|
||||||
|
import * as CJS_Named_NS from \"CommonJS_Named\";
|
||||||
|
var m1: number = CJS_Named_NS.numberValue4;
|
||||||
|
var m2: string = CJS_Named_NS.default.numberValue4;
|
||||||
// Error: CommonJS_Named has no default export
|
// Error: CommonJS_Named has no default export
|
||||||
|
var m3: string = CJS_Named_NS.numberValue4;
|
||||||
// Error: number ~> string
|
// Error: number ~> string
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
// == ES6 Default -> ES6 == //
|
// == ES6 Default -> ES6 == //
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
|
import {doesntExist4} from \"ES6_Default_AnonFunction1\";
|
||||||
// Error: Not an exported binding
|
// Error: Not an exported binding
|
||||||
|
import ES6_Def_AnonFunc1 from \"ES6_Default_AnonFunction1\";
|
||||||
|
var n1: number = ES6_Def_AnonFunc1();
|
||||||
|
var n2: string = ES6_Def_AnonFunc1();
|
||||||
// Error: number ~> string
|
// Error: number ~> string
|
||||||
|
import ES6_Def_NamedFunc1 from \"ES6_Default_NamedFunction1\";
|
||||||
|
var o1: number = ES6_Def_NamedFunc1();
|
||||||
|
var o2: string = ES6_Def_NamedFunc1();
|
||||||
// Error: number ~> string
|
// Error: number ~> string
|
||||||
|
import ES6_Def_NamedClass1 from \"ES6_Default_NamedClass1\";
|
||||||
|
var q1: number = new ES6_Def_NamedClass1().givesANum();
|
||||||
|
var q2: string = new ES6_Def_NamedClass1().givesANum();
|
||||||
// Error: number ~> string
|
// Error: number ~> string
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
// == ES6 Named -> ES6 == //
|
// == ES6 Named -> ES6 == //
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
// Error: Not an exported binding
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: number ~> string
|
|
||||||
///////////////////////////////////
|
|
||||||
// == ES6 Default -> CommonJS == //
|
|
||||||
///////////////////////////////////
|
|
||||||
// Error: \'doesntExist\' isn\'t an export
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: number ~> string
|
|
||||||
/////////////////////////////////
|
|
||||||
// == ES6 Named -> CommonJS == //
|
|
||||||
/////////////////////////////////
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: number ~> string
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
// == ES6 Default+Named -> ES6 import Default+Named== //
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: string ~> number
|
|
||||||
////////////////////////////////////////
|
|
||||||
// == Side-effect only ES6 imports == //
|
|
||||||
////////////////////////////////////////
|
|
||||||
//////////////////////////////////////////////
|
|
||||||
// == Suggest export name on likely typo == //
|
|
||||||
//////////////////////////////////////////////
|
|
||||||
// Error: Did you mean \`import {specifierNumber1} from ...\`?
|
|
||||||
// Error: Did you mean \`specifierNumber1\`?
|
|
||||||
///////////////////////////////////////////////////
|
|
||||||
// == Multi \`export *\` should combine exports == //
|
|
||||||
///////////////////////////////////////////////////
|
|
||||||
// Error: number ~> string
|
|
||||||
// Error: number ~> string
|
|
||||||
import * as DefaultA from \"A\";
|
|
||||||
var a1: number = DefaultA.numberValue1;
|
|
||||||
var a2: string = DefaultA.numberValue1;
|
|
||||||
import * as DefaultB from \"./B\";
|
|
||||||
var b1: number = DefaultB.numberValue;
|
|
||||||
var b2: string = DefaultB.numberValue;
|
|
||||||
import DefaultC from \"C\";
|
|
||||||
import DefaultD from \"./D\";
|
|
||||||
import {doesntExist1} from \"CommonJS_Clobbering_Lit\";
|
|
||||||
import {numberValue1} from \"CommonJS_Clobbering_Lit\";
|
|
||||||
var c1: number = numberValue1;
|
|
||||||
var c2: string = numberValue1;
|
|
||||||
import {numberValue2 as numVal1} from \"CommonJS_Clobbering_Lit\";
|
|
||||||
var d1: number = numVal1;
|
|
||||||
var d2: string = numVal1;
|
|
||||||
import CJS_Clobb_Lit from \"CommonJS_Clobbering_Lit\";
|
|
||||||
var e1: number = CJS_Clobb_Lit.numberValue3;
|
|
||||||
var e2: string = CJS_Clobb_Lit.numberValue3;
|
|
||||||
CJS_Clobb_Lit.doesntExist;
|
|
||||||
import * as CJS_Clobb_Lit_NS from \"CommonJS_Clobbering_Lit\";
|
|
||||||
var f1: number = CJS_Clobb_Lit_NS.numberValue4;
|
|
||||||
var f2: number = CJS_Clobb_Lit_NS.default.numberValue4;
|
|
||||||
CJS_Clobb_Lit_NS.default.default;
|
|
||||||
var f3: string = CJS_Clobb_Lit_NS.numberValue4;
|
|
||||||
var f4: string = CJS_Clobb_Lit_NS.default.numberValue5;
|
|
||||||
import {doesntExist2} from \"CommonJS_Clobbering_Class\";
|
|
||||||
import {staticNumber1, baseProp, childProp} from \"CommonJS_Clobbering_Class\";
|
|
||||||
import CJS_Clobb_Class from \"CommonJS_Clobbering_Class\";
|
|
||||||
new CJS_Clobb_Class();
|
|
||||||
new CJS_Clobb_Class().doesntExist;
|
|
||||||
var h1: number = CJS_Clobb_Class.staticNumber2();
|
|
||||||
var h2: string = CJS_Clobb_Class.staticNumber2();
|
|
||||||
var h3: number = new CJS_Clobb_Class().instNumber1();
|
|
||||||
var h4: string = new CJS_Clobb_Class().instNumber1();
|
|
||||||
import * as CJS_Clobb_Class_NS from \"CommonJS_Clobbering_Class\";
|
|
||||||
new CJS_Clobb_Class_NS();
|
|
||||||
var i1: number = CJS_Clobb_Class_NS.staticNumber3();
|
|
||||||
var i2: number = new CJS_Clobb_Class_NS.default().instNumber2();
|
|
||||||
var i3: string = new CJS_Clobb_Class_NS.default().instNumber2();
|
|
||||||
import {doesntExist3} from \"CommonJS_Named\";
|
|
||||||
import {numberValue2} from \"CommonJS_Named\";
|
|
||||||
var j1: number = numberValue2;
|
|
||||||
var j2: string = numberValue2;
|
|
||||||
import {numberValue3 as numVal3} from \"CommonJS_Named\";
|
|
||||||
var k1: number = numVal3;
|
|
||||||
var k2: string = numVal3;
|
|
||||||
import * as CJS_Named from \"CommonJS_Named\";
|
|
||||||
var l1: number = CJS_Named.numberValue1;
|
|
||||||
var l2: string = CJS_Named.numberValue1;
|
|
||||||
CJS_Named.doesntExist;
|
|
||||||
import * as CJS_Named_NS from \"CommonJS_Named\";
|
|
||||||
var m1: number = CJS_Named_NS.numberValue4;
|
|
||||||
var m2: string = CJS_Named_NS.default.numberValue4;
|
|
||||||
var m3: string = CJS_Named_NS.numberValue4;
|
|
||||||
import {doesntExist4} from \"ES6_Default_AnonFunction1\";
|
|
||||||
import ES6_Def_AnonFunc1 from \"ES6_Default_AnonFunction1\";
|
|
||||||
var n1: number = ES6_Def_AnonFunc1();
|
|
||||||
var n2: string = ES6_Def_AnonFunc1();
|
|
||||||
import ES6_Def_NamedFunc1 from \"ES6_Default_NamedFunction1\";
|
|
||||||
var o1: number = ES6_Def_NamedFunc1();
|
|
||||||
var o2: string = ES6_Def_NamedFunc1();
|
|
||||||
import ES6_Def_NamedClass1 from \"ES6_Default_NamedClass1\";
|
|
||||||
var q1: number = new ES6_Def_NamedClass1().givesANum();
|
|
||||||
var q2: string = new ES6_Def_NamedClass1().givesANum();
|
|
||||||
import doesntExist5 from \"ES6_Named1\";
|
import doesntExist5 from \"ES6_Named1\";
|
||||||
|
// Error: Not an exported binding
|
||||||
import {specifierNumber1 as specifierNumber1_1} from \"ES6_Named1\";
|
import {specifierNumber1 as specifierNumber1_1} from \"ES6_Named1\";
|
||||||
var r1: number = specifierNumber1_1;
|
var r1: number = specifierNumber1_1;
|
||||||
var r2: string = specifierNumber1_1;
|
var r2: string = specifierNumber1_1;
|
||||||
|
// Error: number ~> string
|
||||||
import {specifierNumber2Renamed} from \"ES6_Named1\";
|
import {specifierNumber2Renamed} from \"ES6_Named1\";
|
||||||
var s1: number = specifierNumber2Renamed;
|
var s1: number = specifierNumber2Renamed;
|
||||||
var s2: string = specifierNumber2Renamed;
|
var s2: string = specifierNumber2Renamed;
|
||||||
|
// Error: number ~> string
|
||||||
import {specifierNumber3 as specifierNumber3Renamed} from \"ES6_Named1\";
|
import {specifierNumber3 as specifierNumber3Renamed} from \"ES6_Named1\";
|
||||||
var t1: number = specifierNumber3Renamed;
|
var t1: number = specifierNumber3Renamed;
|
||||||
var t2: string = specifierNumber3Renamed;
|
var t2: string = specifierNumber3Renamed;
|
||||||
|
// Error: number ~> string
|
||||||
import {groupedSpecifierNumber1, groupedSpecifierNumber2} from \"ES6_Named1\";
|
import {groupedSpecifierNumber1, groupedSpecifierNumber2} from \"ES6_Named1\";
|
||||||
var u1: number = groupedSpecifierNumber1;
|
var u1: number = groupedSpecifierNumber1;
|
||||||
var u2: number = groupedSpecifierNumber2;
|
var u2: number = groupedSpecifierNumber2;
|
||||||
var u3: string = groupedSpecifierNumber1;
|
var u3: string = groupedSpecifierNumber1;
|
||||||
|
// Error: number ~> string
|
||||||
var u4: string = groupedSpecifierNumber2;
|
var u4: string = groupedSpecifierNumber2;
|
||||||
|
// Error: number ~> string
|
||||||
import {givesANumber} from \"ES6_Named1\";
|
import {givesANumber} from \"ES6_Named1\";
|
||||||
var v1: number = givesANumber();
|
var v1: number = givesANumber();
|
||||||
var v2: string = givesANumber();
|
var v2: string = givesANumber();
|
||||||
|
// Error: number ~> string
|
||||||
import {NumberGenerator} from \"ES6_Named1\";
|
import {NumberGenerator} from \"ES6_Named1\";
|
||||||
var w1: number = new NumberGenerator().givesANumber();
|
var w1: number = new NumberGenerator().givesANumber();
|
||||||
var w2: string = new NumberGenerator().givesANumber();
|
var w2: string = new NumberGenerator().givesANumber();
|
||||||
|
// Error: number ~> string
|
||||||
import {varDeclNumber1, varDeclNumber2} from \"ES6_Named1\";
|
import {varDeclNumber1, varDeclNumber2} from \"ES6_Named1\";
|
||||||
var x1: number = varDeclNumber1;
|
var x1: number = varDeclNumber1;
|
||||||
var x2: number = varDeclNumber2;
|
var x2: number = varDeclNumber2;
|
||||||
var x3: string = varDeclNumber1;
|
var x3: string = varDeclNumber1;
|
||||||
|
// Error: number ~> string
|
||||||
var x4: string = varDeclNumber2;
|
var x4: string = varDeclNumber2;
|
||||||
|
// Error: number ~> string
|
||||||
import {numberValue1 as numberValue4} from \"ES6_ExportFrom_Intermediary1\";
|
import {numberValue1 as numberValue4} from \"ES6_ExportFrom_Intermediary1\";
|
||||||
var aa1: number = numberValue4;
|
var aa1: number = numberValue4;
|
||||||
var aa2: string = numberValue4;
|
var aa2: string = numberValue4;
|
||||||
|
// Error: number ~> string
|
||||||
import {numberValue2_renamed} from \"ES6_ExportFrom_Intermediary1\";
|
import {numberValue2_renamed} from \"ES6_ExportFrom_Intermediary1\";
|
||||||
var ab1: number = numberValue2_renamed;
|
var ab1: number = numberValue2_renamed;
|
||||||
var ab2: string = numberValue2_renamed;
|
var ab2: string = numberValue2_renamed;
|
||||||
|
// Error: number ~> string
|
||||||
import {numberValue1 as numberValue5} from \"ES6_ExportAllFrom_Intermediary1\";
|
import {numberValue1 as numberValue5} from \"ES6_ExportAllFrom_Intermediary1\";
|
||||||
var ac1: number = numberValue5;
|
var ac1: number = numberValue5;
|
||||||
var ac2: string = numberValue5;
|
var ac2: string = numberValue5;
|
||||||
|
// Error: number ~> string
|
||||||
|
///////////////////////////////////
|
||||||
|
// == ES6 Default -> CommonJS == //
|
||||||
|
///////////////////////////////////
|
||||||
require(\"ES6_Default_AnonFunction2\").doesntExist;
|
require(\"ES6_Default_AnonFunction2\").doesntExist;
|
||||||
|
// Error: \'doesntExist\' isn\'t an export
|
||||||
var ES6_Def_AnonFunc2 = require(\"ES6_Default_AnonFunction2\").default;
|
var ES6_Def_AnonFunc2 = require(\"ES6_Default_AnonFunction2\").default;
|
||||||
var ad1: number = ES6_Def_AnonFunc2();
|
var ad1: number = ES6_Def_AnonFunc2();
|
||||||
var ad2: string = ES6_Def_AnonFunc2();
|
var ad2: string = ES6_Def_AnonFunc2();
|
||||||
|
// Error: number ~> string
|
||||||
var ES6_Def_NamedFunc2 = require(\"ES6_Default_NamedFunction2\").default;
|
var ES6_Def_NamedFunc2 = require(\"ES6_Default_NamedFunction2\").default;
|
||||||
var ae1: number = ES6_Def_NamedFunc2();
|
var ae1: number = ES6_Def_NamedFunc2();
|
||||||
var ae2: string = ES6_Def_NamedFunc2();
|
var ae2: string = ES6_Def_NamedFunc2();
|
||||||
|
// Error: number ~> string
|
||||||
var ES6_Def_NamedClass2 = require(\"ES6_Default_NamedClass2\").default;
|
var ES6_Def_NamedClass2 = require(\"ES6_Default_NamedClass2\").default;
|
||||||
var ag1: number = new ES6_Def_NamedClass2().givesANum();
|
var ag1: number = new ES6_Def_NamedClass2().givesANum();
|
||||||
var ag2: string = new ES6_Def_NamedClass2().givesANum();
|
var ag2: string = new ES6_Def_NamedClass2().givesANum();
|
||||||
|
// Error: number ~> string
|
||||||
|
/////////////////////////////////
|
||||||
|
// == ES6 Named -> CommonJS == //
|
||||||
|
/////////////////////////////////
|
||||||
var specifierNumber4 = require(\"ES6_Named2\").specifierNumber4;
|
var specifierNumber4 = require(\"ES6_Named2\").specifierNumber4;
|
||||||
var ah1: number = specifierNumber4;
|
var ah1: number = specifierNumber4;
|
||||||
var ah2: string = specifierNumber4;
|
var ah2: string = specifierNumber4;
|
||||||
|
// Error: number ~> string
|
||||||
var specifierNumber5Renamed = require(\"ES6_Named2\").specifierNumber5Renamed;
|
var specifierNumber5Renamed = require(\"ES6_Named2\").specifierNumber5Renamed;
|
||||||
var ai1: number = specifierNumber5Renamed;
|
var ai1: number = specifierNumber5Renamed;
|
||||||
var ai2: string = specifierNumber5Renamed;
|
var ai2: string = specifierNumber5Renamed;
|
||||||
|
// Error: number ~> string
|
||||||
var groupedSpecifierNumber3 = require(\"ES6_Named2\").groupedSpecifierNumber3;
|
var groupedSpecifierNumber3 = require(\"ES6_Named2\").groupedSpecifierNumber3;
|
||||||
var groupedSpecifierNumber4 = require(\"ES6_Named2\").groupedSpecifierNumber4;
|
var groupedSpecifierNumber4 = require(\"ES6_Named2\").groupedSpecifierNumber4;
|
||||||
var aj1: number = groupedSpecifierNumber3;
|
var aj1: number = groupedSpecifierNumber3;
|
||||||
var aj2: number = groupedSpecifierNumber4;
|
var aj2: number = groupedSpecifierNumber4;
|
||||||
var aj3: string = groupedSpecifierNumber3;
|
var aj3: string = groupedSpecifierNumber3;
|
||||||
|
// Error: number ~> string
|
||||||
var aj4: string = groupedSpecifierNumber4;
|
var aj4: string = groupedSpecifierNumber4;
|
||||||
|
// Error: number ~> string
|
||||||
var givesANumber2 = require(\"ES6_Named2\").givesANumber2;
|
var givesANumber2 = require(\"ES6_Named2\").givesANumber2;
|
||||||
var ak1: number = givesANumber2();
|
var ak1: number = givesANumber2();
|
||||||
var ak2: string = givesANumber2();
|
var ak2: string = givesANumber2();
|
||||||
|
// Error: number ~> string
|
||||||
var NumberGenerator2 = require(\"ES6_Named2\").NumberGenerator2;
|
var NumberGenerator2 = require(\"ES6_Named2\").NumberGenerator2;
|
||||||
var al1: number = new NumberGenerator2().givesANumber();
|
var al1: number = new NumberGenerator2().givesANumber();
|
||||||
var al2: string = new NumberGenerator2().givesANumber();
|
var al2: string = new NumberGenerator2().givesANumber();
|
||||||
|
// Error: number ~> string
|
||||||
var varDeclNumber3 = require(\"ES6_Named2\").varDeclNumber3;
|
var varDeclNumber3 = require(\"ES6_Named2\").varDeclNumber3;
|
||||||
var varDeclNumber4 = require(\"ES6_Named2\").varDeclNumber4;
|
var varDeclNumber4 = require(\"ES6_Named2\").varDeclNumber4;
|
||||||
var am1: number = varDeclNumber3;
|
var am1: number = varDeclNumber3;
|
||||||
var am2: number = varDeclNumber4;
|
var am2: number = varDeclNumber4;
|
||||||
var am3: string = varDeclNumber3;
|
var am3: string = varDeclNumber3;
|
||||||
|
// Error: number ~> string
|
||||||
var am4: string = varDeclNumber4;
|
var am4: string = varDeclNumber4;
|
||||||
|
// Error: number ~> string
|
||||||
var numberValue6 = require(\"ES6_ExportFrom_Intermediary2\").numberValue1;
|
var numberValue6 = require(\"ES6_ExportFrom_Intermediary2\").numberValue1;
|
||||||
var ap1: number = numberValue6;
|
var ap1: number = numberValue6;
|
||||||
var ap2: string = numberValue6;
|
var ap2: string = numberValue6;
|
||||||
|
// Error: number ~> string
|
||||||
var numberValue2_renamed2 = require(
|
var numberValue2_renamed2 = require(
|
||||||
\"ES6_ExportFrom_Intermediary2\"
|
\"ES6_ExportFrom_Intermediary2\"
|
||||||
).numberValue2_renamed2;
|
).numberValue2_renamed2;
|
||||||
var aq1: number = numberValue2_renamed2;
|
var aq1: number = numberValue2_renamed2;
|
||||||
var aq2: string = numberValue2_renamed2;
|
var aq2: string = numberValue2_renamed2;
|
||||||
|
// Error: number ~> string
|
||||||
var numberValue7 = require(\"ES6_ExportAllFrom_Intermediary2\").numberValue2;
|
var numberValue7 = require(\"ES6_ExportAllFrom_Intermediary2\").numberValue2;
|
||||||
var ar1: number = numberValue7;
|
var ar1: number = numberValue7;
|
||||||
var ar2: string = numberValue7;
|
var ar2: string = numberValue7;
|
||||||
|
// Error: number ~> string
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
// == ES6 Default+Named -> ES6 import Default+Named== //
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
import defaultNum, {str as namedStr} from \"./ES6_DefaultAndNamed\";
|
import defaultNum, {str as namedStr} from \"./ES6_DefaultAndNamed\";
|
||||||
|
|
||||||
var as1: number = defaultNum;
|
var as1: number = defaultNum;
|
||||||
var as2: string = defaultNum;
|
var as2: string = defaultNum;
|
||||||
|
// Error: number ~> string
|
||||||
var as3: string = namedStr;
|
var as3: string = namedStr;
|
||||||
var as4: number = namedStr;
|
var as4: number = namedStr;
|
||||||
|
// Error: string ~> number
|
||||||
|
////////////////////////////////////////
|
||||||
|
// == Side-effect only ES6 imports == //
|
||||||
|
////////////////////////////////////////
|
||||||
import \"./SideEffects\";
|
import \"./SideEffects\";
|
||||||
|
|
||||||
|
//////////////////////////////////////////////
|
||||||
|
// == Suggest export name on likely typo == //
|
||||||
|
//////////////////////////////////////////////
|
||||||
import specifierNumber1 from \"ES6_Named1\";
|
import specifierNumber1 from \"ES6_Named1\";
|
||||||
|
// Error: Did you mean \`import {specifierNumber1} from ...\`?
|
||||||
import {specifierNumber} from \"ES6_Named1\";
|
import {specifierNumber} from \"ES6_Named1\";
|
||||||
|
// Error: Did you mean \`specifierNumber1\`?
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
// == Multi \`export *\` should combine exports == //
|
||||||
|
///////////////////////////////////////////////////
|
||||||
import {numberValue1 as numberValue8, numberValue2 as numberValue9} from \"./ES6_ExportAllFromMulti\";
|
import {numberValue1 as numberValue8, numberValue2 as numberValue9} from \"./ES6_ExportAllFromMulti\";
|
||||||
|
|
||||||
var at1: number = numberValue8;
|
var at1: number = numberValue8;
|
||||||
var at2: string = numberValue8;
|
var at2: string = numberValue8;
|
||||||
|
// Error: number ~> string
|
||||||
var at3: number = numberValue9;
|
var at3: number = numberValue9;
|
||||||
var at4: string = numberValue9;
|
var at4: string = numberValue9; // Error: number ~> string"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -7,14 +7,13 @@ declare function foo<X>(x: X): X;
|
||||||
(foo(\"hello\"): number); // OK
|
(foo(\"hello\"): number); // OK
|
||||||
(foo(false): void); // error, boolean ~/~ undefined
|
(foo(false): void); // error, boolean ~/~ undefined
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// OK
|
|
||||||
// OK
|
|
||||||
// error, boolean ~/~ undefined
|
|
||||||
declare function foo(x: number): string;
|
declare function foo(x: number): string;
|
||||||
declare function foo(x: string): number;
|
declare function foo(x: string): number;
|
||||||
declare function foo<X>(x: X): X;
|
declare function foo<X>(x: X): X;
|
||||||
|
|
||||||
(foo(0): string);
|
(foo(0): string);
|
||||||
|
// OK
|
||||||
(foo(\"hello\"): number);
|
(foo(\"hello\"): number);
|
||||||
(foo(false): void);
|
// OK
|
||||||
"
|
(foo(false): void); // error, boolean ~/~ undefined"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -26,27 +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
|
(declare_m_e_with_declare_var_e: string); // Error: number ~> string
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @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\"!
|
// 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
|
* \`declare var exports\` is deprecated, so we have a grace period where both
|
||||||
* syntaxes will work.
|
* 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);
|
|
||||||
(42: str2);
|
|
||||||
import DEPRECATED__declare_var_exports from \"DEPRECATED__declare_var_exports\";
|
import DEPRECATED__declare_var_exports from \"DEPRECATED__declare_var_exports\";
|
||||||
(DEPRECATED__declare_var_exports: number);
|
(DEPRECATED__declare_var_exports: number);
|
||||||
(DEPRECATED__declare_var_exports: string);
|
(DEPRECATED__declare_var_exports: string);
|
||||||
|
// Error: number ~> string
|
||||||
import declare_m_e_with_declare_var_e from \"declare_m_e_with_declare_var_e\";
|
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: number);
|
||||||
(declare_m_e_with_declare_var_e: string);
|
(declare_m_e_with_declare_var_e: string); // Error: number ~> string"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -30,13 +30,6 @@ declare module \"declare_m_e_with_declare_var_e\" {
|
||||||
declare var exports: string;
|
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 \"declare_module_exports\" {
|
||||||
declare module.exports: number;
|
declare module.exports: number;
|
||||||
}
|
}
|
||||||
|
@ -48,12 +41,18 @@ declare module \"declare_m_e_with_other_type_declares\" {
|
||||||
declare module.exports: number;
|
declare module.exports: number;
|
||||||
declare type str2 = string;
|
declare 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 module \"DEPRECATED__declare_var_exports\" {
|
||||||
declare var exports: number;
|
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 \"declare_m_e_with_declare_var_e\" {
|
||||||
declare module.exports: number;
|
declare module.exports: number;
|
||||||
declare var exports: string;
|
declare var exports: string;
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -33,30 +33,31 @@ blah(0, 0);
|
||||||
/**
|
/**
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// == Import Declared Type Alias From Declared Module == //
|
// == 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 type {baz} from \"ModuleAliasFoo\";
|
||||||
import {foo} from \"ModuleAliasFoo\";
|
import {foo} from \"ModuleAliasFoo\";
|
||||||
var k1: baz = 42;
|
var k1: baz = 42;
|
||||||
var k2: baz = \"shab\";
|
var k2: baz = \"shab\";
|
||||||
|
// Error: string to int
|
||||||
var k3: toz = foo(k1);
|
var k3: toz = foo(k1);
|
||||||
|
// works
|
||||||
import type {toz} from \"ModuleAliasFoo\";
|
import type {toz} from \"ModuleAliasFoo\";
|
||||||
var k4: toz = foo(k1);
|
var k4: toz = foo(k1);
|
||||||
|
// works
|
||||||
|
//////////////////////////////////////////////////////////
|
||||||
|
// == Declared Module with exports prop (issue 880) == //
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
import blah from \"foo\";
|
import blah from \"foo\";
|
||||||
import type {Foo, Bar, Id} from \"foo\";
|
import type {Foo, Bar, Id} from \"foo\";
|
||||||
|
|
||||||
blah(0, 0);
|
blah(0, 0);
|
||||||
|
|
||||||
({ toz: 3 }: Foo);
|
({ toz: 3 }: Foo);
|
||||||
|
// error : {toz : number} ~> string
|
||||||
(3: Bar);
|
(3: Bar);
|
||||||
(\"lol\": Id<number>);
|
// error : number ~> A
|
||||||
"
|
(\"lol\": Id<number>); // error : string ~> number"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -12,12 +12,12 @@ declare module ModuleAliasFoo {
|
||||||
/**
|
/**
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
declare module ModuleAliasFoo {
|
declare module ModuleAliasFoo {
|
||||||
declare type baz = number;
|
declare type baz = number;
|
||||||
declare type toz = string;
|
declare type toz = string;
|
||||||
declare function foo(bar: baz): toz;
|
declare function foo(bar: baz): toz;
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test declare_type_exports.js 1`] = `
|
exports[`test declare_type_exports.js 1`] = `
|
||||||
|
@ -40,13 +40,16 @@ declare module \'foo\' {
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
declare module \"foo\" {
|
declare module \"foo\" {
|
||||||
declare class A { toz: number }
|
declare class A { toz: number }
|
||||||
|
|
||||||
declare var n: string;
|
declare var n: string;
|
||||||
|
|
||||||
declare type Foo = typeof n;
|
declare type Foo = typeof n;
|
||||||
declare type Bar = A;
|
declare type Bar = A;
|
||||||
declare type Id<T> = T;
|
declare type Id<T> = T;
|
||||||
|
|
||||||
declare var exports: { (a: number, b: number): number };
|
declare var exports: { (a: number, b: number): number };
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -31,20 +31,6 @@ class PropVariance<+Out,-In> {
|
||||||
con_dict2: {-[k:string]: In}; // ok
|
con_dict2: {-[k:string]: In}; // ok
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// 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> {
|
class Variance<+Out, -In> {
|
||||||
foo(x: Out): Out {
|
foo(x: Out): Out {
|
||||||
return x;
|
return x;
|
||||||
|
@ -53,25 +39,39 @@ class Variance<+Out, -In> {
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class A {}
|
class A {}
|
||||||
class B extends A {}
|
class B extends A {}
|
||||||
|
|
||||||
function subtyping(v1: Variance<A, B>, v2: Variance<B, A>) {
|
function subtyping(v1: Variance<A, B>, v2: Variance<B, A>) {
|
||||||
(v1: Variance<B, A>);
|
(v1: Variance<B, A>);
|
||||||
(v2: Variance<A, B>);
|
// error on both targs (A ~/~> B)
|
||||||
|
(v2: Variance<A, B>); // OK for both targs (B ~> A)
|
||||||
}
|
}
|
||||||
|
|
||||||
class PropVariance<+Out, -In> {
|
class PropVariance<+Out, -In> {
|
||||||
inv1: Out;
|
inv1: Out;
|
||||||
|
// error
|
||||||
inv2: In;
|
inv2: In;
|
||||||
|
// error
|
||||||
-co1: Out;
|
-co1: Out;
|
||||||
|
// error
|
||||||
-co2: In;
|
-co2: In;
|
||||||
|
// ok
|
||||||
+con1: Out;
|
+con1: Out;
|
||||||
|
// ok
|
||||||
+con2: In;
|
+con2: In;
|
||||||
|
// error
|
||||||
inv_dict1: { [k: string]: Out };
|
inv_dict1: { [k: string]: Out };
|
||||||
|
// error
|
||||||
inv_dict2: { [k: string]: In };
|
inv_dict2: { [k: string]: In };
|
||||||
|
// error
|
||||||
co_dict1: { +[k: string]: Out };
|
co_dict1: { +[k: string]: Out };
|
||||||
|
// ok
|
||||||
co_dict2: { +[k: string]: In };
|
co_dict2: { +[k: string]: In };
|
||||||
|
// error
|
||||||
con_dict1: { -[k: string]: Out };
|
con_dict1: { -[k: string]: Out };
|
||||||
con_dict2: { -[k: string]: In };
|
// error
|
||||||
}
|
con_dict2: { -[k: string]: In }; // ok
|
||||||
"
|
}"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -9,11 +9,12 @@ var x = null;
|
||||||
f(x);
|
f(x);
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* demo */
|
/* demo */
|
||||||
//...
|
|
||||||
function f(x) {
|
function f(x) {
|
||||||
return 42 / x;
|
return 42 / x;
|
||||||
}
|
}
|
||||||
|
|
||||||
var x = null;
|
var x = null;
|
||||||
f(x);
|
//...
|
||||||
"
|
f(x);"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -20,26 +20,31 @@ a.onLoad(callback);
|
||||||
module.exports = A;
|
module.exports = A;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @providesModule Demo */
|
/* @providesModule Demo */
|
||||||
// instance field declaration
|
|
||||||
class A {
|
class A {
|
||||||
x: number;
|
x: number;
|
||||||
|
// instance field declaration
|
||||||
constructor(x) {
|
constructor(x) {
|
||||||
this.x = x;
|
this.x = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
getX() {
|
getX() {
|
||||||
return this.x;
|
return this.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
onLoad(callback) {
|
onLoad(callback) {
|
||||||
return callback(this.getX());
|
return callback(this.getX());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function callback(x: string) {
|
function callback(x: string) {
|
||||||
return x.length;
|
return x.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
var a = new A(42);
|
var a = new A(42);
|
||||||
a.onLoad(callback);
|
a.onLoad(callback);
|
||||||
module.exports = A;
|
|
||||||
"
|
module.exports = A;"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test B.js 1`] = `
|
exports[`test B.js 1`] = `
|
||||||
|
@ -48,6 +53,6 @@ exports[`test B.js 1`] = `
|
||||||
var z = new A(\"42\").getX();
|
var z = new A(\"42\").getX();
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
var A = require(\"Demo\");
|
var A = require(\"Demo\");
|
||||||
var z = new A(\"42\").getX();
|
|
||||||
"
|
var z = new A(\"42\").getX();"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
exports[`test A.js 1`] = `
|
exports[`test A.js 1`] = `
|
||||||
"require(\'./C\');
|
"require(\'./C\');
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
require(\"./C\");
|
require(\"./C\");"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test B.js 1`] = `
|
exports[`test B.js 1`] = `
|
||||||
"require(\'./C\');
|
"require(\'./C\');
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
require(\"./C\");
|
require(\"./C\");"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test C.js 1`] = `
|
exports[`test C.js 1`] = `
|
||||||
|
@ -21,50 +19,41 @@ require(\'./G\');
|
||||||
require(\"./D\");
|
require(\"./D\");
|
||||||
require(\"./E\");
|
require(\"./E\");
|
||||||
require(\"./F\");
|
require(\"./F\");
|
||||||
require(\"./G\");
|
require(\"./G\");"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test D.js 1`] = `
|
exports[`test D.js 1`] = `
|
||||||
"require(\'./I\');
|
"require(\'./I\');
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
require(\"./I\");
|
require(\"./I\");"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test E.js 1`] = `
|
exports[`test E.js 1`] = `
|
||||||
"require(\'./I\');
|
"require(\'./I\');
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
require(\"./I\");
|
require(\"./I\");"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test F.js 1`] = `
|
exports[`test F.js 1`] = `
|
||||||
"// empty
|
"// empty
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// empty
|
|
||||||
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test G.js 1`] = `
|
exports[`test G.js 1`] = `
|
||||||
"require(\'./H\');
|
"require(\'./H\');
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
require(\"./H\");
|
require(\"./H\");"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test H.js 1`] = `
|
exports[`test H.js 1`] = `
|
||||||
"// empty
|
"// empty
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// empty
|
|
||||||
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test I.js 1`] = `
|
exports[`test I.js 1`] = `
|
||||||
"require(\'./A\');
|
"require(\'./A\');
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
require(\"./A\");
|
require(\"./A\");"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -12,23 +12,22 @@ let d = zs[1]; // run off the end
|
||||||
|
|
||||||
let [...e] = 0;
|
let [...e] = 0;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// retain tuple info
|
|
||||||
// run off the end
|
|
||||||
// error: number ~> void
|
|
||||||
// error: string ~> void
|
|
||||||
// error: boolean ~> void
|
|
||||||
// error: number|string|boolean ~> void
|
|
||||||
let xs = [ 0, \"\", true ];
|
let xs = [ 0, \"\", true ];
|
||||||
let [ a, ...ys ] = xs;
|
let [ a, ...ys ] = xs;
|
||||||
let [ b, ...zs ] = ys;
|
let [ b, ...zs ] = ys;
|
||||||
let c = zs[0];
|
let c = zs[0];
|
||||||
|
// retain tuple info
|
||||||
let d = zs[1];
|
let d = zs[1];
|
||||||
|
// run off the end
|
||||||
(a: void);
|
(a: void);
|
||||||
|
// error: number ~> void
|
||||||
(b: void);
|
(b: void);
|
||||||
|
// error: string ~> void
|
||||||
(c: void);
|
(c: void);
|
||||||
|
// error: boolean ~> void
|
||||||
(d: void);
|
(d: void);
|
||||||
let [ ...e ] = 0;
|
// error: number|string|boolean ~> void
|
||||||
"
|
let [ ...e ] = 0;"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test computed.js 1`] = `
|
exports[`test computed.js 1`] = `
|
||||||
|
@ -42,17 +41,15 @@ var { [key]: val2 } = { key: \"val\" };
|
||||||
var { [\"key\"]: val3, ...spread } = { key: \"val\" };
|
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
|
(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\" };
|
var { [\"key\"]: val1 } = { key: \"val\" };
|
||||||
(val1: void);
|
(val1: void);
|
||||||
|
// error: string ~> void
|
||||||
var key: string = \"key\";
|
var key: string = \"key\";
|
||||||
var { [key]: val2 } = { key: \"val\" };
|
var { [key]: val2 } = { key: \"val\" };
|
||||||
(val2: void);
|
(val2: void);
|
||||||
|
// ok (gasp!) by existing StrT -> ElemT rule
|
||||||
var { [\"key\"]: val3, ...spread } = { key: \"val\" };
|
var { [\"key\"]: val3, ...spread } = { key: \"val\" };
|
||||||
(spread.key: void);
|
(spread.key: void); // error (gasp!) in general we don\'t know if a computed prop should be excluded from spread"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test defaults.js 1`] = `
|
exports[`test defaults.js 1`] = `
|
||||||
|
@ -140,90 +137,104 @@ function obj_prop_union2({p}:{p:number}|{p:string}={p:true}) {}
|
||||||
function default_expr_scope({a, b = a}) {}
|
function default_expr_scope({a, b = a}) {}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
|
function obj_prop_fun({ p: { q = 0 } = { q: true } } = { p: { q: \"\" } }) {
|
||||||
// errors:
|
// errors:
|
||||||
// * number ~> void, from default on _.p.q
|
// * number ~> void, from default on _.p.q
|
||||||
// * boolean ~> void, from default on _.p
|
// * boolean ~> void, from default on _.p
|
||||||
// * string ~> void, from default on _
|
// * string ~> void, from default on _
|
||||||
// * null ~> void, from call below
|
// * null ~> void, from call below
|
||||||
|
(q: void);
|
||||||
|
}
|
||||||
|
obj_prop_fun();
|
||||||
// ok
|
// ok
|
||||||
|
obj_prop_fun({});
|
||||||
// ok
|
// ok
|
||||||
|
obj_prop_fun({ p: {} });
|
||||||
// ok
|
// ok
|
||||||
|
obj_prop_fun({ p: { q: null } });
|
||||||
// ok, provides add\'l lower bound
|
// ok, provides add\'l lower bound
|
||||||
|
function obj_prop_var(o = { p: { q: \"\" } }) {
|
||||||
|
var { p: { q = 0 } = { q: true } } = o;
|
||||||
// errors:
|
// errors:
|
||||||
// * number ~> void, from default on o.p.q
|
// * number ~> void, from default on o.p.q
|
||||||
// * boolean ~> void, from default on o.p
|
// * boolean ~> void, from default on o.p
|
||||||
// * string ~> void, from default on o
|
// * string ~> void, from default on o
|
||||||
// * null ~> void, from call below
|
// * null ~> void, from call below
|
||||||
|
(q: void);
|
||||||
|
}
|
||||||
|
obj_prop_var();
|
||||||
// ok
|
// ok
|
||||||
|
obj_prop_var({});
|
||||||
// ok
|
// ok
|
||||||
|
obj_prop_var({ p: {} });
|
||||||
// ok
|
// ok
|
||||||
|
obj_prop_var({ p: { q: null } });
|
||||||
// ok, provides add\'l lower bound
|
// ok, provides add\'l lower bound
|
||||||
|
function obj_rest(
|
||||||
|
{ p: { q, ...o } = { q: 0, r: 0 } } = { p: { q: 0, r: \"\" } }
|
||||||
|
) {
|
||||||
// errors:
|
// errors:
|
||||||
// * number ~> void, from default on _.p
|
// * number ~> void, from default on _.p
|
||||||
// * string ~> void, from default on _
|
// * string ~> void, from default on _
|
||||||
// * null ~> void, from call below
|
// * 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 = 0 } = { q: true } } = { p: { q: \"\" } }) {
|
|
||||||
(q: void);
|
|
||||||
}
|
|
||||||
obj_prop_fun();
|
|
||||||
obj_prop_fun({});
|
|
||||||
obj_prop_fun({ p: {} });
|
|
||||||
obj_prop_fun({ p: { q: null } });
|
|
||||||
function obj_prop_var(o = { p: { q: \"\" } }) {
|
|
||||||
var { p: { q = 0 } = { q: true } } = o;
|
|
||||||
(q: void);
|
|
||||||
}
|
|
||||||
obj_prop_var();
|
|
||||||
obj_prop_var({});
|
|
||||||
obj_prop_var({ p: {} });
|
|
||||||
obj_prop_var({ p: { q: null } });
|
|
||||||
function obj_rest(
|
|
||||||
{ p: { q, ...o } = { q: 0, r: 0 } } = { p: { q: 0, r: \"\" } }
|
|
||||||
) {
|
|
||||||
(o.r: void);
|
(o.r: void);
|
||||||
}
|
}
|
||||||
obj_rest();
|
obj_rest();
|
||||||
|
// ok
|
||||||
obj_rest({});
|
obj_rest({});
|
||||||
|
// ok
|
||||||
obj_rest({ p: {} });
|
obj_rest({ p: {} });
|
||||||
|
// ok
|
||||||
obj_rest({ p: { q: 0, r: null } });
|
obj_rest({ p: { q: 0, r: null } });
|
||||||
function obj_prop_annot({ p = true }: { p: string } = { p: 0 }) {
|
|
||||||
(p: void);
|
function obj_prop_annot(
|
||||||
|
{
|
||||||
|
// error: boolean ~> string
|
||||||
|
p = true
|
||||||
|
}: { p: string } = {
|
||||||
|
// error: number ~> string
|
||||||
|
p: 0
|
||||||
}
|
}
|
||||||
var { p = true }: { p: string } = { p: 0 };
|
) {
|
||||||
|
(p: void); // error: string ~> void
|
||||||
|
}
|
||||||
|
|
||||||
|
var {
|
||||||
|
// error: boolean ~> string
|
||||||
|
p = true
|
||||||
|
}: { p: string } = {
|
||||||
|
// error: number ~> string
|
||||||
|
p: 0
|
||||||
|
};
|
||||||
(p: void);
|
(p: void);
|
||||||
|
// error: string ~> void
|
||||||
function obj_prop_err({ x: { y } } = null) {}
|
function obj_prop_err({ x: { y } } = null) {}
|
||||||
|
// error: property \`x\` cannot be accessed on null
|
||||||
function obj_rest_err({ ...o } = 0) {}
|
function obj_rest_err({ ...o } = 0) {}
|
||||||
|
// error: expected object instead of number
|
||||||
function arr_elem_err([ x ] = null) {}
|
function arr_elem_err([ x ] = null) {}
|
||||||
|
// error: element 0 cannot be accessed on null
|
||||||
function arr_rest_err([ ...a ] = null) {}
|
function arr_rest_err([ ...a ] = null) {}
|
||||||
|
// error: expected array instead of null
|
||||||
function gen<T>(x: T, { p = x }: { p: T }): T {
|
function gen<T>(x: T, { p = x }: { p: T }): T {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default values in destructuring unwrap optional types
|
||||||
obj_prop_fun(({}: { p?: { q?: null } }));
|
obj_prop_fun(({}: { p?: { q?: null } }));
|
||||||
|
// ok
|
||||||
obj_prop_var(({}: { p?: { q?: null } }));
|
obj_prop_var(({}: { p?: { q?: null } }));
|
||||||
|
// ok
|
||||||
|
// union-like upper bounds preserved through destructuring
|
||||||
function obj_prop_opt({ p }: { p?: string } = { p: 0 }) {}
|
function obj_prop_opt({ p }: { p?: string } = { p: 0 }) {}
|
||||||
function obj_prop_maybe({ p }: { p: ?string } = { p: 0 }) {}
|
function obj_prop_maybe({ p }: { p: ?string } = { p: 0 }) {}
|
||||||
function obj_prop_union({ p }: { p: number | string } = { p: true }) {}
|
function obj_prop_union({ p }: { p: number | string } = { p: true }) {}
|
||||||
|
|
||||||
|
// TODO: union-of-objects upper bounds preserved through destructuring
|
||||||
function obj_prop_union2({ p }: { p: number } | { p: string } = { p: true }) {}
|
function obj_prop_union2({ p }: { p: number } | { p: string } = { p: true }) {}
|
||||||
function default_expr_scope({ a, b = a }) {}
|
|
||||||
"
|
function default_expr_scope({ a, b = a }) {}"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test destructuring.js 1`] = `
|
exports[`test destructuring.js 1`] = `
|
||||||
|
@ -299,70 +310,81 @@ var cp1_err: string = childprop1; // Error: number ~> string
|
||||||
var cp2: number = others.childprop1;
|
var cp2: number = others.childprop1;
|
||||||
var cp2_err: string = others.childprop2; // Error: number ~> string
|
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 a: string;
|
||||||
declare var b: string;
|
declare var b: string;
|
||||||
declare var c: string;
|
declare var c: string;
|
||||||
[ { a1: a, b }, c ] = [ { a1: 0, b: 1 }, 2 ];
|
[ { a1: a, b }, c ] = [ { a1: 0, b: 1 }, 2 ];
|
||||||
|
|
||||||
var { m } = { m: 0 };
|
var { m } = { m: 0 };
|
||||||
({ m } = { m: m });
|
({ m } = { m: m });
|
||||||
|
|
||||||
var obj;
|
var obj;
|
||||||
({ n: obj.x } = { n: 3 });
|
({ n: obj.x } = { n: 3 });
|
||||||
[ obj.x ] = [ \"foo\" ];
|
[ obj.x ] = [ \"foo\" ];
|
||||||
|
|
||||||
function foo({ p, z: [ r ] }) {
|
function foo({ p, z: [ r ] }) {
|
||||||
a = p;
|
a = p;
|
||||||
b = z;
|
b = z;
|
||||||
c = r;
|
c = r;
|
||||||
}
|
}
|
||||||
foo({ p: 0, z: [ 1, 2 ] });
|
foo({ p: 0, z: [ 1, 2 ] });
|
||||||
|
|
||||||
[ a, , b, ...c ] = [ 0, 1, true, 3 ];
|
[ a, , b, ...c ] = [ 0, 1, true, 3 ];
|
||||||
|
|
||||||
function bar({ x, ...z }) {
|
function bar({ x, ...z }) {
|
||||||
var o: { x: string, y: number } = 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 };
|
var extend: { x: number, y: string, z: boolean } = { x: 0, ...spread };
|
||||||
|
|
||||||
function qux(_: { a: number }) {}
|
function qux(_: { a: number }) {}
|
||||||
qux({ a: \"\" });
|
qux({ a: \"\" });
|
||||||
function corge({ b }: { b: string }) {}
|
function corge({ b }: { b: string }) {}
|
||||||
corge({ b: 0 });
|
corge({ b: 0 });
|
||||||
|
|
||||||
var { n }: { n: number } = { n: \"\" };
|
var { n }: { n: number } = { n: \"\" };
|
||||||
|
|
||||||
function test() {
|
function test() {
|
||||||
var { foo } = { bar: 123 };
|
var { foo } = { bar: 123 };
|
||||||
var { bar, baz } = { bar: 123 };
|
// error on foo
|
||||||
|
var { bar, baz } = { bar: 123 }; // error on baz
|
||||||
}
|
}
|
||||||
|
|
||||||
function test() {
|
function test() {
|
||||||
var x = { foo: \"abc\", bar: 123 };
|
var x = { foo: \"abc\", bar: 123 };
|
||||||
var { foo, ...rest } = x;
|
var { foo, ...rest } = x;
|
||||||
(x.baz: string);
|
(x.baz: string);
|
||||||
(rest.baz: string);
|
// error, baz doesn\'t exist
|
||||||
|
(rest.baz: string); // no error, rest is unsealed
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = corge;
|
module.exports = corge;
|
||||||
|
|
||||||
class Base {
|
class Base {
|
||||||
baseprop1: number;
|
baseprop1: number;
|
||||||
baseprop2: number;
|
baseprop2: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Child extends Base {
|
class Child extends Base {
|
||||||
childprop1: number;
|
childprop1: number;
|
||||||
childprop2: number;
|
childprop2: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
var { baseprop1, childprop1, ...others } = new Child();
|
var { baseprop1, childprop1, ...others } = new Child();
|
||||||
|
|
||||||
var bp1: number = baseprop1;
|
var bp1: number = baseprop1;
|
||||||
var bp1_err: string = baseprop1;
|
var bp1_err: string = baseprop1;
|
||||||
|
// Error: number ~> string
|
||||||
var bp2: number = others.baseprop2;
|
var bp2: number = others.baseprop2;
|
||||||
var bp2_err: string = others.baseprop2;
|
var bp2_err: string = others.baseprop2;
|
||||||
|
// Error: number ~> string
|
||||||
var cp1: number = childprop1;
|
var cp1: number = childprop1;
|
||||||
var cp1_err: string = childprop1;
|
var cp1_err: string = childprop1;
|
||||||
|
// Error: number ~> string
|
||||||
var cp2: number = others.childprop1;
|
var cp2: number = others.childprop1;
|
||||||
var cp2_err: string = others.childprop2;
|
var cp2_err: string = others.childprop2; // Error: number ~> string"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test destructuring_param.js 1`] = `
|
exports[`test destructuring_param.js 1`] = `
|
||||||
|
@ -379,27 +401,24 @@ exports[`test destructuring_param.js 1`] = `
|
||||||
// return a + b + c + d;
|
// return a + b + c + d;
|
||||||
// }
|
// }
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
function f(a, { b }) {
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
// TODO: These throw errors when parsing.
|
// TODO: These throw errors when parsing.
|
||||||
// function g(a, { a }) {
|
// function g(a, { a }) {
|
||||||
// return a;
|
// return a;
|
||||||
// }
|
// }
|
||||||
// function h({ a, { b } }, { c }, { { d } }) {
|
// function h({ a, { b } }, { c }, { { d } }) {
|
||||||
// return a + b + c + d;
|
// return a + b + c + d;
|
||||||
// }
|
// }"
|
||||||
function f(a, { b }) {
|
|
||||||
return a + b;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test eager.js 1`] = `
|
exports[`test eager.js 1`] = `
|
||||||
"var x;
|
"var x;
|
||||||
({x} = null); // error, property \`x\` can not be accessed on \`null\`
|
({x} = null); // error, property \`x\` can not be accessed on \`null\`
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// error, property \`x\` can not be accessed on \`null\`
|
|
||||||
var x;
|
var x;
|
||||||
({ x } = null);
|
({ x } = null); // error, property \`x\` can not be accessed on \`null\`"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test poly.js 1`] = `
|
exports[`test poly.js 1`] = `
|
||||||
|
@ -437,44 +456,45 @@ function arr_rest_pattern<X>([ _, ...a ] : ArrRest<X>) { // a: [X]
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @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 }: { prop: X }) {}
|
function obj_pattern<X>({ prop }: { prop: X }) {}
|
||||||
|
// prop: X
|
||||||
type Prop<X> = { prop: X };
|
type Prop<X> = { prop: X };
|
||||||
function obj_pattern2<X>({ prop }: Prop<X>) {}
|
function obj_pattern2<X>({ prop }: Prop<X>) {}
|
||||||
|
// prop: X
|
||||||
function arr_pattern<X>([ elem ]: X[]) {}
|
function arr_pattern<X>([ elem ]: X[]) {}
|
||||||
|
// elem: X
|
||||||
type Elem<X> = X[];
|
type Elem<X> = X[];
|
||||||
function arr_pattern2<X>([ elem ]: Elem<X>) {}
|
function arr_pattern2<X>([ elem ]: Elem<X>) {}
|
||||||
|
// elem: X
|
||||||
function tup_pattern<X>([ proj ]: [X]) {}
|
function tup_pattern<X>([ proj ]: [X]) {}
|
||||||
|
// proj: X
|
||||||
type Proj<X> = [X];
|
type Proj<X> = [X];
|
||||||
function tup_pattern2<X>([ proj ]: Proj<X>) {}
|
function tup_pattern2<X>([ proj ]: Proj<X>) {}
|
||||||
|
// proj: X
|
||||||
function rest_antipattern<T>(...t: T) {}
|
function rest_antipattern<T>(...t: T) {}
|
||||||
|
// nonsense
|
||||||
function rest_pattern<X>(...r: X[]) {}
|
function rest_pattern<X>(...r: X[]) {}
|
||||||
|
// r: X[]
|
||||||
function obj_rest_pattern<X>({ _, ...o }: { _: any, x: X }) {
|
function obj_rest_pattern<X>({ _, ...o }: { _: any, x: X }) {
|
||||||
|
// o: { x: X }
|
||||||
o.x;
|
o.x;
|
||||||
}
|
}
|
||||||
type ObjRest<X> = { _: any, x: X };
|
type ObjRest<X> = { _: any, x: X };
|
||||||
function obj_rest_pattern<X>({ _, ...o }: ObjRest<X>) {
|
function obj_rest_pattern<X>({ _, ...o }: ObjRest<X>) {
|
||||||
|
// o: { x: X }
|
||||||
o.x;
|
o.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
function arr_rest_pattern<X>([ _, ...a ]: [any, X]) {
|
function arr_rest_pattern<X>([ _, ...a ]: [any, X]) {
|
||||||
|
// a: [X]
|
||||||
a[0];
|
a[0];
|
||||||
}
|
}
|
||||||
type ArrRest<X> = [any, X];
|
type ArrRest<X> = [any, X];
|
||||||
function arr_rest_pattern<X>([ _, ...a ]: ArrRest<X>) {
|
function arr_rest_pattern<X>([ _, ...a ]: ArrRest<X>) {
|
||||||
|
// a: [X]
|
||||||
a[0];
|
a[0];
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test rec.js 1`] = `
|
exports[`test rec.js 1`] = `
|
||||||
|
@ -500,20 +520,24 @@ declare var o;
|
||||||
var { x: o } = o;
|
var { x: o } = o;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @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
|
// funny doses of repositioning
|
||||||
// Also make sure that the following doesn\'t loop
|
|
||||||
let foo = (i: number) => [ i ];
|
let foo = (i: number) => [ i ];
|
||||||
|
|
||||||
const bar = (i: number) => {
|
const bar = (i: number) => {
|
||||||
[ i ] = foo(i);
|
[ i ] = foo(i);
|
||||||
return [ i ];
|
return [ i ];
|
||||||
};
|
};
|
||||||
|
|
||||||
foo = (i: number) => {
|
foo = (i: number) => {
|
||||||
return bar(i);
|
return bar(i);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Also make sure that the following doesn\'t loop
|
||||||
declare var o;
|
declare var o;
|
||||||
var { x: o } = o;
|
var { x: o } = o;"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test string_lit.js 1`] = `
|
exports[`test string_lit.js 1`] = `
|
||||||
|
@ -523,13 +547,11 @@ exports[`test string_lit.js 1`] = `
|
||||||
var { \"with-dash\": with_dash } = { \"with-dash\": \"motivating example\" };
|
var { \"with-dash\": with_dash } = { \"with-dash\": \"motivating example\" };
|
||||||
(with_dash: \"motivating example\"); // ok
|
(with_dash: \"motivating example\"); // ok
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// error: string ~> void
|
|
||||||
// ok
|
|
||||||
var { \"key\": val } = { key: \"val\" };
|
var { \"key\": val } = { key: \"val\" };
|
||||||
(val: void);
|
(val: void);
|
||||||
|
// error: string ~> void
|
||||||
var { \"with-dash\": with_dash } = { \"with-dash\": \"motivating example\" };
|
var { \"with-dash\": with_dash } = { \"with-dash\": \"motivating example\" };
|
||||||
(with_dash: \"motivating example\");
|
(with_dash: \"motivating example\"); // ok"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test unannotated.js 1`] = `
|
exports[`test unannotated.js 1`] = `
|
||||||
|
@ -544,9 +566,10 @@ function bar() {
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
var { x } = { x: { foo: \"foo\" } };
|
var { x } = { x: { foo: \"foo\" } };
|
||||||
|
|
||||||
function bar() {
|
function bar() {
|
||||||
x.bar;
|
x.bar;
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -6,11 +6,10 @@ const k: any = \'foo\'
|
||||||
const val: string = dict[k] // error: number incompatible with string
|
const val: string = dict[k] // error: number incompatible with string
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
// error: number incompatible with string
|
|
||||||
const dict: { [key: string]: number } = {};
|
const dict: { [key: string]: number } = {};
|
||||||
const k: any = \"foo\";
|
const k: any = \"foo\";
|
||||||
const val: string = dict[k];
|
const val: string = dict[k]; // error: number incompatible with string"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test compatible.js 1`] = `
|
exports[`test compatible.js 1`] = `
|
||||||
|
@ -31,21 +30,22 @@ function foo2(
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @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(
|
function foo0(
|
||||||
x: Array<{ [key: string]: mixed }>
|
x: Array<{ [key: string]: mixed }>
|
||||||
): 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;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
function foo2(
|
function foo2(
|
||||||
x: { [key: string]: number }
|
x: { [key: string]: number }
|
||||||
): { [key: string]: number, +toString: () => string } {
|
): { [key: string]: number, +toString: () => string } {
|
||||||
|
// x\'s prototype has a toString method
|
||||||
return x;
|
return x;
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test dictionary.js 1`] = `
|
exports[`test dictionary.js 1`] = `
|
||||||
|
@ -385,288 +385,310 @@ function subtype_optional_c_to_dict(
|
||||||
*
|
*
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Some logic is variance-sensitive.
|
// Some logic is variance-sensitive.
|
||||||
|
class A {}
|
||||||
|
class B extends A {}
|
||||||
|
class C extends B {}
|
||||||
|
|
||||||
// Just a couple of short type names. Compare to string/number.
|
// Just a couple of short type names. Compare to string/number.
|
||||||
|
class X {}
|
||||||
|
class Y {}
|
||||||
|
|
||||||
// Any property can be set on a dict with string keys.
|
// Any property can be set on a dict with string keys.
|
||||||
|
function set_prop_to_string_key(o: { [k: string]: any }) {
|
||||||
|
o.prop = \"ok\";
|
||||||
|
}
|
||||||
|
|
||||||
// **UNSOUND**
|
// **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.
|
// return type in a maybe.
|
||||||
|
function unsound_dict_has_every_key(o: { [k: string]: X }) {
|
||||||
|
(o.p: X);
|
||||||
// ok
|
// ok
|
||||||
// ok
|
(o[\"p\"]: X); // ok
|
||||||
|
}
|
||||||
|
|
||||||
// As with any object type, we can assign subtypes to properties.
|
// As with any object type, we can assign subtypes to properties.
|
||||||
|
function set_prop_covariant(o: { [k: string]: B }) {
|
||||||
|
o.p = new A();
|
||||||
// error, A ~> B
|
// error, A ~> B
|
||||||
|
o.p = new B();
|
||||||
// ok
|
// ok
|
||||||
// ok
|
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 }) {
|
||||||
|
(o.p: A);
|
||||||
// ok
|
// ok
|
||||||
|
(o.p: B);
|
||||||
// ok
|
// ok
|
||||||
// error, C ~> B
|
(o.p: C); // error, C ~> B
|
||||||
|
}
|
||||||
|
|
||||||
// Dot-notation can not be used to add properties to dictionaries with
|
// Dot-notation can not be used to add properties to dictionaries with
|
||||||
// non-string keys, because keys are strings.
|
// non-string keys, because keys are strings.
|
||||||
// error: string ~> number
|
function add_prop_to_nonstring_key_dot(o: { [k: number]: any }) {
|
||||||
|
o.prop = \"err\"; // error: string ~> number
|
||||||
|
}
|
||||||
|
|
||||||
// Bracket notation can be used to add properties to dictionaries with
|
// Bracket notation can be used to add properties to dictionaries with
|
||||||
// non-string keys, even though all keys are strings. This is a convenient
|
// non-string keys, even though all keys are strings. This is a convenient
|
||||||
// affordance.
|
// affordance.
|
||||||
|
function add_prop_to_nonstring_key_bracket(o: { [k: number]: any }) {
|
||||||
|
o[0] = \"ok\";
|
||||||
|
}
|
||||||
|
|
||||||
// Objects can be part dict, part not by mixing an indexer with declared props.
|
// Objects can be part dict, part not by mixing an indexer with declared props.
|
||||||
|
function mix_with_declared_props(o: { [k: number]: X, p: Y }, x: X, y: Y) {
|
||||||
|
(o[0]: X);
|
||||||
// ok
|
// ok
|
||||||
|
(o.p: Y);
|
||||||
// ok
|
// ok
|
||||||
|
o[0] = x;
|
||||||
// ok
|
// ok
|
||||||
// ok
|
o.p = y; // ok
|
||||||
|
}
|
||||||
|
|
||||||
// Indeed, dict types are still Objects and have Object.prototype stuff
|
// Indeed, dict types are still Objects and have Object.prototype stuff
|
||||||
|
function object_prototype(
|
||||||
|
o: { [k: string]: number }
|
||||||
|
): { [k: string]: number, +toString: () => string } {
|
||||||
|
(o.toString(): boolean);
|
||||||
// error: string ~> boolean
|
// error: string ~> boolean
|
||||||
// ok
|
return o; // ok
|
||||||
|
}
|
||||||
|
|
||||||
// **UNSOUND**
|
// **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.
|
// write into a declared prop unsoundly.
|
||||||
// a[\"0\"] no longer X
|
function unsound_string_conversion_alias_declared_prop(
|
||||||
|
o: { [k: number]: any, \"0\": X }
|
||||||
|
) {
|
||||||
|
o[0] = \"not-x\"; // a[\"0\"] no longer X
|
||||||
|
}
|
||||||
|
|
||||||
|
function unification_dict_values_invariant(x: Array<{ [k: string]: B }>) {
|
||||||
|
let a: Array<{ [k: string]: A }> = x;
|
||||||
// error
|
// error
|
||||||
|
a[0].p = new A();
|
||||||
// in[0].p no longer B
|
// in[0].p no longer B
|
||||||
|
let b: Array<{ [k: string]: B }> = x;
|
||||||
// ok
|
// ok
|
||||||
|
let c: Array<{ [k: string]: C }> = x;
|
||||||
// error
|
// error
|
||||||
// not true
|
(x[0].p: C); // not true
|
||||||
|
}
|
||||||
|
|
||||||
|
function subtype_dict_values_invariant(x: { [k: string]: B }) {
|
||||||
|
let a: { [k: string]: A } = x;
|
||||||
// error
|
// error
|
||||||
|
a.p = new A();
|
||||||
// x[0].p no longer B
|
// x[0].p no longer B
|
||||||
|
let b: { [k: string]: B } = x;
|
||||||
// ok
|
// ok
|
||||||
|
let c: { [k: string]: C } = x;
|
||||||
// error
|
// error
|
||||||
// not true
|
(x.p: C); // not true
|
||||||
|
}
|
||||||
|
|
||||||
|
function subtype_dict_values_fresh_exception() {
|
||||||
|
let a: { [k: string]: A } = {
|
||||||
|
a: new A(),
|
||||||
// ok, A == A
|
// ok, A == A
|
||||||
|
b: new B(),
|
||||||
// ok, B <: A
|
// ok, B <: A
|
||||||
// ok, C <: A
|
// ok, C <: A
|
||||||
|
c: new C()
|
||||||
|
};
|
||||||
|
|
||||||
|
let b: { [k: string]: B } = {
|
||||||
|
a: new A(),
|
||||||
// error, A not <: B
|
// error, A not <: B
|
||||||
|
b: new B(),
|
||||||
// ok, B == B
|
// ok, B == B
|
||||||
// ok, C <: A
|
// ok, C <: A
|
||||||
|
c: new C()
|
||||||
|
};
|
||||||
|
|
||||||
|
let c: { [k: string]: C } = {
|
||||||
|
a: new A(),
|
||||||
// error, A not <: C
|
// error, A not <: C
|
||||||
|
b: new B(),
|
||||||
// error, A not <: C
|
// error, A not <: C
|
||||||
// ok, C == C
|
// ok, C == C
|
||||||
|
c: new C()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Actually, unsound_string_conversion_alias_declared_prop behavior makes an
|
// 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.
|
// 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
|
// Barring some compelling use case for that in this context, though, we choose
|
||||||
// to be strict.
|
// 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[0] = \"ok\";
|
|
||||||
}
|
|
||||||
function mix_with_declared_props(o: { [k: number]: X, p: Y }, x: X, y: Y) {
|
|
||||||
(o[0]: X);
|
|
||||||
(o.p: Y);
|
|
||||||
o[0] = 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[0] = \"not-x\";
|
|
||||||
}
|
|
||||||
function unification_dict_values_invariant(x: Array<{ [k: string]: B }>) {
|
|
||||||
let a: Array<{ [k: string]: A }> = x;
|
|
||||||
a[0].p = new A();
|
|
||||||
let b: Array<{ [k: string]: B }> = x;
|
|
||||||
let c: Array<{ [k: string]: C }> = x;
|
|
||||||
(x[0].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 }>) {
|
function unification_dict_keys_invariant(x: Array<{ [k: B]: any }>) {
|
||||||
let a: Array<{ [k: A]: any }> = x;
|
let a: Array<{ [k: A]: any }> = x;
|
||||||
|
// error
|
||||||
let b: Array<{ [k: B]: any }> = x;
|
let b: Array<{ [k: B]: any }> = x;
|
||||||
let c: Array<{ [k: C]: any }> = x;
|
// ok
|
||||||
|
let c: Array<{ [k: C]: any }> = x; // error
|
||||||
}
|
}
|
||||||
|
|
||||||
function subtype_dict_keys_invariant(x: { [k: B]: any }) {
|
function subtype_dict_keys_invariant(x: { [k: B]: any }) {
|
||||||
let a: { [k: A]: any } = x;
|
let a: { [k: A]: any } = x;
|
||||||
|
// error
|
||||||
let b: { [k: B]: any } = x;
|
let b: { [k: B]: any } = x;
|
||||||
let c: { [k: C]: any } = x;
|
// ok
|
||||||
|
let c: { [k: C]: any } = x; // error
|
||||||
}
|
}
|
||||||
|
|
||||||
function unification_mix_with_declared_props_invariant_l(
|
function unification_mix_with_declared_props_invariant_l(
|
||||||
x: Array<{ [k: string]: B }>
|
x: Array<{ [k: string]: B }>
|
||||||
) {
|
) {
|
||||||
let a: Array<{ [k: string]: B, p: A }> = x;
|
let a: Array<{ [k: string]: B, p: A }> = x;
|
||||||
|
// error: A ~> B
|
||||||
a[0].p = new A();
|
a[0].p = new A();
|
||||||
|
// x[0].p no longer B
|
||||||
let b: Array<{ [k: string]: B, p: B }> = x;
|
let b: Array<{ [k: string]: B, p: B }> = x;
|
||||||
|
// ok
|
||||||
let c: Array<{ [k: string]: B, p: C }> = x;
|
let c: Array<{ [k: string]: B, p: C }> = x;
|
||||||
(x[0].p: C);
|
// error
|
||||||
|
(x[0].p: C); // not true
|
||||||
}
|
}
|
||||||
|
|
||||||
function unification_mix_with_declared_props_invariant_r(
|
function unification_mix_with_declared_props_invariant_r(
|
||||||
xa: Array<{ [k: string]: A, p: B }>,
|
xa: Array<{ [k: string]: A, p: B }>,
|
||||||
xb: Array<{ [k: string]: B, p: B }>,
|
xb: Array<{ [k: string]: B, p: B }>,
|
||||||
xc: Array<{ [k: string]: C, p: B }>
|
xc: Array<{ [k: string]: C, p: B }>
|
||||||
) {
|
) {
|
||||||
let a: Array<{ [k: string]: A }> = xa;
|
let a: Array<{ [k: string]: A }> = xa;
|
||||||
|
// error
|
||||||
a[0].p = new A();
|
a[0].p = new A();
|
||||||
|
// xa[0].p no longer B
|
||||||
let b: Array<{ [k: string]: B }> = xb;
|
let b: Array<{ [k: string]: B }> = xb;
|
||||||
|
// ok
|
||||||
let c: Array<{ [k: string]: C }> = xc;
|
let c: Array<{ [k: string]: C }> = xc;
|
||||||
(xc[0].p: C);
|
// error
|
||||||
|
(xc[0].p: C); // not true
|
||||||
}
|
}
|
||||||
|
|
||||||
function subtype_mix_with_declared_props_invariant_l(x: { [k: string]: B }) {
|
function subtype_mix_with_declared_props_invariant_l(x: { [k: string]: B }) {
|
||||||
let a: { [k: string]: B, p: A } = x;
|
let a: { [k: string]: B, p: A } = x;
|
||||||
|
// error: A ~> B
|
||||||
a.p = new A();
|
a.p = new A();
|
||||||
|
// x.p no longer B
|
||||||
let b: { [k: string]: B, p: B } = x;
|
let b: { [k: string]: B, p: B } = x;
|
||||||
|
// ok
|
||||||
let c: { [k: string]: B, p: C } = x;
|
let c: { [k: string]: B, p: C } = x;
|
||||||
(x.p: C);
|
// error
|
||||||
|
(x.p: C); // not true
|
||||||
}
|
}
|
||||||
|
|
||||||
function subtype_mix_with_declared_props_invariant_r(
|
function subtype_mix_with_declared_props_invariant_r(
|
||||||
xa: { [k: string]: A, p: B },
|
xa: { [k: string]: A, p: B },
|
||||||
xb: { [k: string]: B, p: B },
|
xb: { [k: string]: B, p: B },
|
||||||
xc: { [k: string]: C, p: B }
|
xc: { [k: string]: C, p: B }
|
||||||
) {
|
) {
|
||||||
let a: { [k: string]: A } = xa;
|
let a: { [k: string]: A } = xa;
|
||||||
|
// error
|
||||||
a.p = new A();
|
a.p = new A();
|
||||||
|
// xa.p no longer B
|
||||||
let b: { [k: string]: B } = xb;
|
let b: { [k: string]: B } = xb;
|
||||||
|
// ok
|
||||||
let c: { [k: string]: C } = xc;
|
let c: { [k: string]: C } = xc;
|
||||||
(xc.p: C);
|
// error
|
||||||
|
(xc.p: C); // not true
|
||||||
}
|
}
|
||||||
|
|
||||||
function unification_dict_to_obj(
|
function unification_dict_to_obj(
|
||||||
x: Array<{ [k: string]: X }>
|
x: Array<{ [k: string]: X }>
|
||||||
): Array<{ p: X }> {
|
): Array<{ p: X }> {
|
||||||
return x;
|
return x; // error: if allowed, could write {p:X,q:Y} into \`x\`
|
||||||
}
|
}
|
||||||
|
|
||||||
function unification_obj_to_dict(
|
function unification_obj_to_dict(
|
||||||
x: Array<{ p: X }>
|
x: Array<{ p: X }>
|
||||||
): Array<{ [k: string]: X }> {
|
): Array<{ [k: string]: X }> {
|
||||||
return x;
|
return x; // error: if allowed, could write {p:X,q:Y} into returned array
|
||||||
}
|
}
|
||||||
|
|
||||||
function subtype_dict_to_obj(x: { [k: string]: B }) {
|
function subtype_dict_to_obj(x: { [k: string]: B }) {
|
||||||
let a: { p: A } = x;
|
let a: { p: A } = x;
|
||||||
|
// error
|
||||||
a.p = new A();
|
a.p = new A();
|
||||||
|
// x.p no longer B
|
||||||
let b: { p: B } = x;
|
let b: { p: B } = x;
|
||||||
|
// ok
|
||||||
let c: { p: C } = x;
|
let c: { p: C } = x;
|
||||||
(x.p: C);
|
// error
|
||||||
|
(x.p: C); // not true
|
||||||
}
|
}
|
||||||
|
|
||||||
function subtype_obj_to_dict(x: { p: B }) {
|
function subtype_obj_to_dict(x: { p: B }) {
|
||||||
let a: { [k: string]: A } = x;
|
let a: { [k: string]: A } = x;
|
||||||
|
// error
|
||||||
a.p = new A();
|
a.p = new A();
|
||||||
|
// x.p no longer B
|
||||||
let b: { [k: string]: B } = x;
|
let b: { [k: string]: B } = x;
|
||||||
|
|
||||||
let c: { [k: string]: C } = x;
|
let c: { [k: string]: C } = x;
|
||||||
(x.p: C);
|
// error
|
||||||
|
(x.p: C); // not true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only props in l which are not in u must match indexer, but must do so
|
||||||
|
// exactly.
|
||||||
function subtype_obj_to_mixed(x: { p: B, x: X }) {
|
function subtype_obj_to_mixed(x: { p: B, x: X }) {
|
||||||
let a: { [k: string]: A, x: X } = x;
|
let a: { [k: string]: A, x: X } = x;
|
||||||
|
// error (as above), but exclusive of x
|
||||||
let b: { [k: string]: B, x: X } = x;
|
let b: { [k: string]: B, x: X } = x;
|
||||||
let c: { [k: string]: C, x: X } = x;
|
// ok,
|
||||||
|
let c: { [k: string]: C, x: X } = x; // error (as above), but exclusive of x
|
||||||
}
|
}
|
||||||
|
|
||||||
function unification_dict_to_mixed(x: Array<{ [k: string]: B }>) {
|
function unification_dict_to_mixed(x: Array<{ [k: string]: B }>) {
|
||||||
let a: Array<{ [k: string]: B, p: A }> = x;
|
let a: Array<{ [k: string]: B, p: A }> = x;
|
||||||
|
// error
|
||||||
let b: Array<{ [k: string]: B, p: B }> = x;
|
let b: Array<{ [k: string]: B, p: B }> = x;
|
||||||
let c: Array<{ [k: string]: B, p: C }> = x;
|
// ok
|
||||||
|
let c: Array<{ [k: string]: B, p: C }> = x; // error
|
||||||
}
|
}
|
||||||
|
|
||||||
function subtype_dict_to_mixed(x: { [k: string]: B }) {
|
function subtype_dict_to_mixed(x: { [k: string]: B }) {
|
||||||
let a: { [k: string]: B, p: A } = x;
|
let a: { [k: string]: B, p: A } = x;
|
||||||
|
// error
|
||||||
let b: { [k: string]: B, p: B } = x;
|
let b: { [k: string]: B, p: B } = x;
|
||||||
let c: { [k: string]: B, p: C } = x;
|
// ok
|
||||||
|
let c: { [k: string]: B, p: C } = x; // error
|
||||||
}
|
}
|
||||||
|
|
||||||
function subtype_dict_to_optional_a(x: { [k: string]: B }) {
|
function subtype_dict_to_optional_a(x: { [k: string]: B }) {
|
||||||
let a: { p?: A } = x;
|
let a: { p?: A } = x; // error
|
||||||
}
|
}
|
||||||
|
|
||||||
function subtype_dict_to_optional_b(x: { [k: string]: B }) {
|
function subtype_dict_to_optional_b(x: { [k: string]: B }) {
|
||||||
let b: { p?: B } = x;
|
let b: { p?: B } = x; // ok
|
||||||
}
|
}
|
||||||
|
|
||||||
function subtype_dict_to_optional_c(x: { [k: string]: B }) {
|
function subtype_dict_to_optional_c(x: { [k: string]: B }) {
|
||||||
let c: { p?: C } = x;
|
let c: { p?: C } = x; // error
|
||||||
}
|
}
|
||||||
|
|
||||||
function subtype_optional_a_to_dict(x: { p?: A }): { [k: string]: B } {
|
function subtype_optional_a_to_dict(x: { p?: A }): { [k: string]: B } {
|
||||||
|
// error: A ~> B
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
function subtype_optional_b_to_dict(x: { p?: B }): { [k: string]: B } {
|
function subtype_optional_b_to_dict(x: { p?: B }): { [k: string]: B } {
|
||||||
|
// ok
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
function subtype_optional_c_to_dict(x: { p?: C }): { [k: string]: B } {
|
function subtype_optional_c_to_dict(x: { p?: C }): { [k: string]: B } {
|
||||||
|
// error: C ~> B
|
||||||
return x;
|
return x;
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test incompatible.js 1`] = `
|
exports[`test incompatible.js 1`] = `
|
||||||
|
@ -729,63 +751,70 @@ function foo8(x: {[key: string]: number}) {
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @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 x: { [key: string]: string } = {};
|
||||||
var y: { [key: string]: number } = x;
|
var y: { [key: string]: number } = x;
|
||||||
|
// 2 errors, number !~> string & vice versa
|
||||||
var z: { [key: number]: string } = x;
|
var z: { [key: number]: string } = x;
|
||||||
|
// 2 errors, string !~> number & vice versa
|
||||||
var a: { [key: string]: ?string } = {};
|
var a: { [key: string]: ?string } = {};
|
||||||
var b: { [key: string]: string } = a;
|
var b: { [key: string]: string } = a;
|
||||||
|
// 2 errors (null & undefined)
|
||||||
var c: { [key: string]: ?string } = b;
|
var c: { [key: string]: ?string } = b;
|
||||||
|
// 2 errors, since c[\'x\'] = null updates b
|
||||||
|
// 2 errors (number !~> string, string !~> number)
|
||||||
function foo0(
|
function foo0(
|
||||||
x: Array<{ [key: string]: number }>
|
x: Array<{ [key: string]: number }>
|
||||||
): Array<{ [key: string]: string }> {
|
): Array<{ [key: string]: string }> {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// error, fooBar:string !~> number (x\'s dictionary)
|
||||||
function foo1(
|
function foo1(
|
||||||
x: Array<{ [key: string]: number }>
|
x: Array<{ [key: string]: number }>
|
||||||
): Array<{ [key: string]: number, fooBar: string }> {
|
): Array<{ [key: string]: number, fooBar: string }> {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
function foo2(
|
function foo2(
|
||||||
x: Array<{ [key: string]: mixed }>
|
x: Array<{ [key: string]: mixed }>
|
||||||
): Array<{ [key: string]: mixed, fooBar: string }> {
|
): Array<{ [key: string]: mixed, fooBar: string }> {
|
||||||
x[0].fooBar = 123;
|
x[0].fooBar = 123;
|
||||||
return x;
|
// OK, since number ~> mixed (x elem\'s dictionary)
|
||||||
|
return x; // error: mixed ~> string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OK, since we assume dictionaries have every key
|
||||||
function foo3(x: { [key: string]: number }): { foo: number } {
|
function foo3(x: { [key: string]: number }): { foo: number } {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// error: foo can\'t exist in x
|
||||||
function foo4(
|
function foo4(
|
||||||
x: { [key: string]: number }
|
x: { [key: string]: number }
|
||||||
): { [key: string]: number, foo: string } {
|
): { [key: string]: number, foo: string } {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// error, some prop in x could be incompatible (covariance)
|
||||||
function foo5(x: Array<{ [key: string]: number }>): Array<{ foo: number }> {
|
function foo5(x: Array<{ [key: string]: number }>): Array<{ foo: number }> {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// error, some prop in return could be incompatible
|
||||||
function foo6(x: Array<{ foo: number }>): Array<{ [key: string]: number }> {
|
function foo6(x: Array<{ foo: number }>): Array<{ [key: string]: number }> {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
function foo7(x: { [key: string]: number, bar: string }) {
|
function foo7(x: { [key: string]: number, bar: string }) {
|
||||||
(x.bar: string);
|
(x.bar: string);
|
||||||
}
|
}
|
||||||
|
|
||||||
function foo8(x: { [key: string]: number }) {
|
function foo8(x: { [key: string]: number }) {
|
||||||
(x.foo: string);
|
(x.foo: string);
|
||||||
|
// error
|
||||||
(x.foo: number);
|
(x.foo: number);
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test issue-1745.js 1`] = `
|
exports[`test issue-1745.js 1`] = `
|
||||||
|
@ -816,29 +845,30 @@ class B {
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
// no error
|
|
||||||
// no error
|
|
||||||
// no error
|
|
||||||
// no error
|
|
||||||
class A {
|
class A {
|
||||||
x: { [k: string]: number };
|
x: { [k: string]: number };
|
||||||
|
|
||||||
m1() {
|
m1() {
|
||||||
this.x = { bar: 0 };
|
this.x = { bar: 0 }; // no error
|
||||||
}
|
}
|
||||||
|
|
||||||
m2() {
|
m2() {
|
||||||
this.x.foo = 0;
|
this.x.foo = 0; // no error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class B {
|
class B {
|
||||||
x: { [k: string]: number };
|
x: { [k: string]: number };
|
||||||
|
|
||||||
m2() {
|
m2() {
|
||||||
this.x.foo = 0;
|
this.x.foo = 0; // no error
|
||||||
}
|
}
|
||||||
|
|
||||||
m1() {
|
m1() {
|
||||||
this.x = { bar: 0 };
|
this.x = { bar: 0 }; // no error
|
||||||
}
|
}
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test test.js 1`] = `
|
exports[`test test.js 1`] = `
|
||||||
|
@ -853,16 +883,16 @@ var o: { foo: QueryFunction } = {
|
||||||
|
|
||||||
module.exports = o;
|
module.exports = o;
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// error, number ~/~ string
|
|
||||||
type Params = { [name: string]: string, count: number };
|
type Params = { [name: string]: string, count: number };
|
||||||
type QueryFunction = (params: Params) => string;
|
type QueryFunction = (params: Params) => string;
|
||||||
|
|
||||||
var o: { foo: QueryFunction } = {
|
var o: { foo: QueryFunction } = {
|
||||||
foo(params) {
|
foo(params) {
|
||||||
return params.count;
|
return params.count; // error, number ~/~ string
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
module.exports = o;
|
|
||||||
"
|
module.exports = o;"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test test_client.js 1`] = `
|
exports[`test test_client.js 1`] = `
|
||||||
|
@ -872,10 +902,9 @@ o.foo = function (params) {
|
||||||
return params.count; // error, number ~/~ string
|
return params.count; // error, number ~/~ string
|
||||||
}
|
}
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// error, number ~/~ string
|
|
||||||
var o = require(\"./test\");
|
var o = require(\"./test\");
|
||||||
|
|
||||||
o.foo = function(params) {
|
o.foo = function(params) {
|
||||||
return params.count;
|
return params.count; // error, number ~/~ string
|
||||||
};
|
};"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -83,6 +83,7 @@ export type TypedNode =
|
||||||
/**
|
/**
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export type InferredType = \"unknown\" |
|
export type InferredType = \"unknown\" |
|
||||||
\"gender\" |
|
\"gender\" |
|
||||||
\"enum\" |
|
\"enum\" |
|
||||||
|
@ -90,12 +91,14 @@ export type InferredType = \"unknown\" |
|
||||||
\"number\" |
|
\"number\" |
|
||||||
\"string\" |
|
\"string\" |
|
||||||
\"error\";
|
\"error\";
|
||||||
|
|
||||||
export type Pos = {
|
export type Pos = {
|
||||||
firstLine: number,
|
firstLine: number,
|
||||||
firstColumn: number,
|
firstColumn: number,
|
||||||
lastLine: number,
|
lastLine: number,
|
||||||
lastColumn: number
|
lastColumn: number
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TypedBinaryOpNode = {
|
export type TypedBinaryOpNode = {
|
||||||
exprNodeType: \"binary_op\",
|
exprNodeType: \"binary_op\",
|
||||||
binaryOp: \"plus\" | \"multiply\" | \"divide\" | \"minus\",
|
binaryOp: \"plus\" | \"multiply\" | \"divide\" | \"minus\",
|
||||||
|
@ -105,6 +108,7 @@ export type TypedBinaryOpNode = {
|
||||||
exprType: InferredType,
|
exprType: InferredType,
|
||||||
typed: true
|
typed: true
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TypedUnaryMinusNode = {
|
export type TypedUnaryMinusNode = {
|
||||||
exprNodeType: \"unary_minus\",
|
exprNodeType: \"unary_minus\",
|
||||||
op: TypedNode,
|
op: TypedNode,
|
||||||
|
@ -112,6 +116,7 @@ export type TypedUnaryMinusNode = {
|
||||||
exprType: InferredType,
|
exprType: InferredType,
|
||||||
typed: true
|
typed: true
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TypedNumberNode = {
|
export type TypedNumberNode = {
|
||||||
exprNodeType: \"number\",
|
exprNodeType: \"number\",
|
||||||
value: number,
|
value: number,
|
||||||
|
@ -119,6 +124,7 @@ export type TypedNumberNode = {
|
||||||
exprType: \"number\",
|
exprType: \"number\",
|
||||||
typed: true
|
typed: true
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TypedStringLiteralNode = {
|
export type TypedStringLiteralNode = {
|
||||||
exprNodeType: \"string_literal\",
|
exprNodeType: \"string_literal\",
|
||||||
value: string,
|
value: string,
|
||||||
|
@ -126,6 +132,7 @@ export type TypedStringLiteralNode = {
|
||||||
exprType: \"string\",
|
exprType: \"string\",
|
||||||
typed: true
|
typed: true
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TypedVariableNode = {
|
export type TypedVariableNode = {
|
||||||
exprNodeType: \"variable\",
|
exprNodeType: \"variable\",
|
||||||
name: string,
|
name: string,
|
||||||
|
@ -133,6 +140,7 @@ export type TypedVariableNode = {
|
||||||
exprType: InferredType,
|
exprType: InferredType,
|
||||||
typed: true
|
typed: true
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TypedFunctionInvocationNode = {
|
export type TypedFunctionInvocationNode = {
|
||||||
exprNodeType: \"function_invocation\",
|
exprNodeType: \"function_invocation\",
|
||||||
name: string,
|
name: string,
|
||||||
|
@ -141,13 +149,13 @@ export type TypedFunctionInvocationNode = {
|
||||||
exprType: \"error\" | \"string\",
|
exprType: \"error\" | \"string\",
|
||||||
typed: true
|
typed: true
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TypedNode = TypedBinaryOpNode |
|
export type TypedNode = TypedBinaryOpNode |
|
||||||
TypedUnaryMinusNode |
|
TypedUnaryMinusNode |
|
||||||
TypedNumberNode |
|
TypedNumberNode |
|
||||||
TypedStringLiteralNode |
|
TypedStringLiteralNode |
|
||||||
TypedVariableNode |
|
TypedVariableNode |
|
||||||
TypedFunctionInvocationNode;
|
TypedFunctionInvocationNode;"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test emit.js 1`] = `
|
exports[`test emit.js 1`] = `
|
||||||
|
@ -220,10 +228,12 @@ export function emitExpression(node: TypedNode) : t.Expression {
|
||||||
/**
|
/**
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
// FALLTHROUGH
|
|
||||||
import * as t from \"./jsAst\";
|
import * as t from \"./jsAst\";
|
||||||
|
|
||||||
const b = t.builders;
|
const b = t.builders;
|
||||||
|
|
||||||
import type {TypedNode} from \"./ast\";
|
import type {TypedNode} from \"./ast\";
|
||||||
|
|
||||||
function getBinaryOp(
|
function getBinaryOp(
|
||||||
op: \"plus\" | \"minus\" | \"divide\" | \"multiply\"
|
op: \"plus\" | \"minus\" | \"divide\" | \"multiply\"
|
||||||
): \"+\" | \"-\" | \"*\" | \"/\" {
|
): \"+\" | \"-\" | \"*\" | \"/\" {
|
||||||
|
@ -240,9 +250,11 @@ function getBinaryOp(
|
||||||
throw new Error(\"Invalid binary operator: \" + op);
|
throw new Error(\"Invalid binary operator: \" + op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function emitExpression(node: TypedNode): t.Expression {
|
export function emitExpression(node: TypedNode): t.Expression {
|
||||||
switch (node.exprNodeType) {
|
switch (node.exprNodeType) {
|
||||||
case \"string_literal\":
|
case \"string_literal\":
|
||||||
|
// FALLTHROUGH
|
||||||
case \"number\":
|
case \"number\":
|
||||||
return b.literal(node.value);
|
return b.literal(node.value);
|
||||||
case \"variable\":
|
case \"variable\":
|
||||||
|
@ -254,6 +266,7 @@ export function emitExpression(node: TypedNode): t.Expression {
|
||||||
case \"binary_op\": {
|
case \"binary_op\": {
|
||||||
const lhs = emitExpression(node.lhs);
|
const lhs = emitExpression(node.lhs);
|
||||||
const rhs = emitExpression(node.rhs);
|
const rhs = emitExpression(node.rhs);
|
||||||
|
|
||||||
const op = getBinaryOp(node.binaryOp);
|
const op = getBinaryOp(node.binaryOp);
|
||||||
return b.binaryExpression(op, lhs, rhs);
|
return b.binaryExpression(op, lhs, rhs);
|
||||||
}
|
}
|
||||||
|
@ -267,14 +280,15 @@ export function emitExpression(node: TypedNode): t.Expression {
|
||||||
b.identifier(node.name),
|
b.identifier(node.name),
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
const args = node.parameters.map(n => emitExpression(n));
|
const args = node.parameters.map(n => emitExpression(n));
|
||||||
|
|
||||||
return b.callExpression(callee, args);
|
return b.callExpression(callee, args);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
throw new Error(\"Unknown expression type: \" + node.type);
|
throw new Error(\"Unknown expression type: \" + node.type);
|
||||||
}
|
}
|
||||||
}
|
}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test jsAst.js 1`] = `
|
exports[`test jsAst.js 1`] = `
|
||||||
|
@ -918,21 +932,21 @@ export const builders : {
|
||||||
/**
|
/**
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
/* TODO Missing from the Parser API.*/
|
|
||||||
// ast-types exports all expressions as patterns.
|
|
||||||
// That seems not like it was intended.
|
|
||||||
export type Comment = {
|
export type Comment = {
|
||||||
loc: ?SourceLocation,
|
loc: ?SourceLocation,
|
||||||
value: string,
|
value: string,
|
||||||
leading: boolean,
|
leading: boolean,
|
||||||
trailing: boolean
|
trailing: boolean
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SourceLocation = {
|
export type SourceLocation = {
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
end: SourcePosition,
|
end: SourcePosition,
|
||||||
source: ?string
|
source: ?string
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SourcePosition = { line: number, column: number };
|
export type SourcePosition = { line: number, column: number };
|
||||||
|
|
||||||
export type File = {
|
export type File = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -941,6 +955,7 @@ export type File = {
|
||||||
type: \"File\",
|
type: \"File\",
|
||||||
program: Program
|
program: Program
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Program = {
|
export type Program = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -949,6 +964,7 @@ export type Program = {
|
||||||
type: \"Program\",
|
type: \"Program\",
|
||||||
body: Statement[]
|
body: Statement[]
|
||||||
};
|
};
|
||||||
|
|
||||||
export type BinaryOperator = \"==\" |
|
export type BinaryOperator = \"==\" |
|
||||||
\"!=\" |
|
\"!=\" |
|
||||||
\"===\" |
|
\"===\" |
|
||||||
|
@ -965,12 +981,13 @@ export type BinaryOperator = \"==\" |
|
||||||
\"*\" |
|
\"*\" |
|
||||||
\"/\" |
|
\"/\" |
|
||||||
\"%\" |
|
\"%\" |
|
||||||
\"&\" |
|
\"&\" /* TODO Missing from the Parser API.*/ |
|
||||||
\"|\" |
|
\"|\" |
|
||||||
\"^\" |
|
\"^\" |
|
||||||
\"in\" |
|
\"in\" |
|
||||||
\"instanceof\" |
|
\"instanceof\" |
|
||||||
\"..\";
|
\"..\";
|
||||||
|
|
||||||
export type UnaryOperator = \"-\" |
|
export type UnaryOperator = \"-\" |
|
||||||
\"+\" |
|
\"+\" |
|
||||||
\"!\" |
|
\"!\" |
|
||||||
|
@ -978,6 +995,7 @@ export type UnaryOperator = \"-\" |
|
||||||
\"typeof\" |
|
\"typeof\" |
|
||||||
\"void\" |
|
\"void\" |
|
||||||
\"delete\";
|
\"delete\";
|
||||||
|
|
||||||
export type AssignmentOperator = \"=\" |
|
export type AssignmentOperator = \"=\" |
|
||||||
\"+=\" |
|
\"+=\" |
|
||||||
\"-=\" |
|
\"-=\" |
|
||||||
|
@ -990,8 +1008,11 @@ export type AssignmentOperator = \"=\" |
|
||||||
\"|=\" |
|
\"|=\" |
|
||||||
\"^=\" |
|
\"^=\" |
|
||||||
\"&=\";
|
\"&=\";
|
||||||
|
|
||||||
export type UpdateOperator = \"++\" | \"--\";
|
export type UpdateOperator = \"++\" | \"--\";
|
||||||
|
|
||||||
export type LogicalOperator = \"&&\" | \"||\";
|
export type LogicalOperator = \"&&\" | \"||\";
|
||||||
|
|
||||||
export type Node = EmptyStatement |
|
export type Node = EmptyStatement |
|
||||||
BlockStatement |
|
BlockStatement |
|
||||||
ExpressionStatement |
|
ExpressionStatement |
|
||||||
|
@ -1024,6 +1045,7 @@ export type Node = EmptyStatement |
|
||||||
VariableDeclaration |
|
VariableDeclaration |
|
||||||
FunctionDeclaration |
|
FunctionDeclaration |
|
||||||
VariableDeclarator;
|
VariableDeclarator;
|
||||||
|
|
||||||
export type Statement = BlockStatement |
|
export type Statement = BlockStatement |
|
||||||
EmptyStatement |
|
EmptyStatement |
|
||||||
ExpressionStatement |
|
ExpressionStatement |
|
||||||
|
@ -1037,6 +1059,7 @@ export type Statement = BlockStatement |
|
||||||
ForInStatement |
|
ForInStatement |
|
||||||
TryStatement |
|
TryStatement |
|
||||||
Declaration;
|
Declaration;
|
||||||
|
|
||||||
export type EmptyStatement = {
|
export type EmptyStatement = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1044,6 +1067,7 @@ export type EmptyStatement = {
|
||||||
comments: ?Array<Comment>,
|
comments: ?Array<Comment>,
|
||||||
type: \"EmptyStatement\"
|
type: \"EmptyStatement\"
|
||||||
};
|
};
|
||||||
|
|
||||||
export type BlockStatement = {
|
export type BlockStatement = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1052,6 +1076,7 @@ export type BlockStatement = {
|
||||||
type: \"BlockStatement\",
|
type: \"BlockStatement\",
|
||||||
body: Statement[]
|
body: Statement[]
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ExpressionStatement = {
|
export type ExpressionStatement = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1060,6 +1085,7 @@ export type ExpressionStatement = {
|
||||||
type: \"ExpressionStatement\",
|
type: \"ExpressionStatement\",
|
||||||
expression: Expression
|
expression: Expression
|
||||||
};
|
};
|
||||||
|
|
||||||
export type IfStatement = {
|
export type IfStatement = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1070,6 +1096,7 @@ export type IfStatement = {
|
||||||
consequent: Statement,
|
consequent: Statement,
|
||||||
alternate: ?Statement
|
alternate: ?Statement
|
||||||
};
|
};
|
||||||
|
|
||||||
export type BreakStatement = {
|
export type BreakStatement = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1078,6 +1105,7 @@ export type BreakStatement = {
|
||||||
type: \"BreakStatement\",
|
type: \"BreakStatement\",
|
||||||
label: ?Identifier
|
label: ?Identifier
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ContinueStatement = {
|
export type ContinueStatement = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1086,6 +1114,7 @@ export type ContinueStatement = {
|
||||||
type: \"ContinueStatement\",
|
type: \"ContinueStatement\",
|
||||||
label: ?Identifier
|
label: ?Identifier
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ReturnStatement = {
|
export type ReturnStatement = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1094,6 +1123,7 @@ export type ReturnStatement = {
|
||||||
type: \"ReturnStatement\",
|
type: \"ReturnStatement\",
|
||||||
argument: ?Expression
|
argument: ?Expression
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ThrowStatement = {
|
export type ThrowStatement = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1102,6 +1132,7 @@ export type ThrowStatement = {
|
||||||
type: \"ThrowStatement\",
|
type: \"ThrowStatement\",
|
||||||
argument: ?Expression
|
argument: ?Expression
|
||||||
};
|
};
|
||||||
|
|
||||||
export type WhileStatement = {
|
export type WhileStatement = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1111,6 +1142,7 @@ export type WhileStatement = {
|
||||||
test: Expression,
|
test: Expression,
|
||||||
body: Statement
|
body: Statement
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ForStatement = {
|
export type ForStatement = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1122,6 +1154,7 @@ export type ForStatement = {
|
||||||
update: ?Expression,
|
update: ?Expression,
|
||||||
body: Statement
|
body: Statement
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ForInStatement = {
|
export type ForInStatement = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1132,6 +1165,7 @@ export type ForInStatement = {
|
||||||
right: Expression,
|
right: Expression,
|
||||||
body: Statement
|
body: Statement
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TryStatement = {
|
export type TryStatement = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1143,6 +1177,7 @@ export type TryStatement = {
|
||||||
handlers: CatchClause[],
|
handlers: CatchClause[],
|
||||||
finalizer: ?BlockStatement
|
finalizer: ?BlockStatement
|
||||||
};
|
};
|
||||||
|
|
||||||
export type CatchClause = {
|
export type CatchClause = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1153,6 +1188,7 @@ export type CatchClause = {
|
||||||
guard: ?Expression,
|
guard: ?Expression,
|
||||||
body: BlockStatement
|
body: BlockStatement
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Expression = Identifier |
|
export type Expression = Identifier |
|
||||||
ThisExpression |
|
ThisExpression |
|
||||||
Literal |
|
Literal |
|
||||||
|
@ -1168,6 +1204,7 @@ export type Expression = Identifier |
|
||||||
MemberExpression |
|
MemberExpression |
|
||||||
ArrayExpression |
|
ArrayExpression |
|
||||||
ObjectExpreession;
|
ObjectExpreession;
|
||||||
|
|
||||||
export type Identifier = {
|
export type Identifier = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1176,6 +1213,7 @@ export type Identifier = {
|
||||||
type: \"Identifier\",
|
type: \"Identifier\",
|
||||||
name: string
|
name: string
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Literal = {
|
export type Literal = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1185,6 +1223,7 @@ export type Literal = {
|
||||||
value: ?(string | boolean | number | RegExp),
|
value: ?(string | boolean | number | RegExp),
|
||||||
regex: ?{ pattern: string, flags: string }
|
regex: ?{ pattern: string, flags: string }
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ThisExpression = {
|
export type ThisExpression = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1192,6 +1231,7 @@ export type ThisExpression = {
|
||||||
comments: ?Array<Comment>,
|
comments: ?Array<Comment>,
|
||||||
type: \"ThisExpression\"
|
type: \"ThisExpression\"
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ArrayExpression = {
|
export type ArrayExpression = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1200,6 +1240,7 @@ export type ArrayExpression = {
|
||||||
type: \"ArrayExpression\",
|
type: \"ArrayExpression\",
|
||||||
elements: Expression[]
|
elements: Expression[]
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ObjectExpreession = {
|
export type ObjectExpreession = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1208,6 +1249,7 @@ export type ObjectExpreession = {
|
||||||
type: \"ObjectExpression\",
|
type: \"ObjectExpression\",
|
||||||
properties: Property[]
|
properties: Property[]
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Property = {
|
export type Property = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1218,6 +1260,7 @@ export type Property = {
|
||||||
key: Literal | Identifier,
|
key: Literal | Identifier,
|
||||||
value: Expression
|
value: Expression
|
||||||
};
|
};
|
||||||
|
|
||||||
export type FunctionExpression = {
|
export type FunctionExpression = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1228,6 +1271,7 @@ export type FunctionExpression = {
|
||||||
params: Pattern[],
|
params: Pattern[],
|
||||||
body: BlockStatement
|
body: BlockStatement
|
||||||
};
|
};
|
||||||
|
|
||||||
export type BinaryExpression = {
|
export type BinaryExpression = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1238,6 +1282,7 @@ export type BinaryExpression = {
|
||||||
left: Expression,
|
left: Expression,
|
||||||
right: Expression
|
right: Expression
|
||||||
};
|
};
|
||||||
|
|
||||||
export type UnaryExpression = {
|
export type UnaryExpression = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1248,6 +1293,7 @@ export type UnaryExpression = {
|
||||||
argument: Expression,
|
argument: Expression,
|
||||||
prefix: boolean
|
prefix: boolean
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AssignmentExpression = {
|
export type AssignmentExpression = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1258,6 +1304,7 @@ export type AssignmentExpression = {
|
||||||
left: Pattern,
|
left: Pattern,
|
||||||
right: Expression
|
right: Expression
|
||||||
};
|
};
|
||||||
|
|
||||||
export type UpdateExpression = {
|
export type UpdateExpression = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1268,6 +1315,7 @@ export type UpdateExpression = {
|
||||||
argument: Expression,
|
argument: Expression,
|
||||||
prefix: boolean
|
prefix: boolean
|
||||||
};
|
};
|
||||||
|
|
||||||
export type LogicalExpression = {
|
export type LogicalExpression = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1278,6 +1326,7 @@ export type LogicalExpression = {
|
||||||
left: Expression,
|
left: Expression,
|
||||||
right: Expression
|
right: Expression
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ConditionalExpression = {
|
export type ConditionalExpression = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1288,6 +1337,7 @@ export type ConditionalExpression = {
|
||||||
consequent: Expression,
|
consequent: Expression,
|
||||||
alternate: Expression
|
alternate: Expression
|
||||||
};
|
};
|
||||||
|
|
||||||
export type NewExpression = {
|
export type NewExpression = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1297,6 +1347,7 @@ export type NewExpression = {
|
||||||
callee: Expression,
|
callee: Expression,
|
||||||
arguments: Expression[]
|
arguments: Expression[]
|
||||||
};
|
};
|
||||||
|
|
||||||
export type CallExpression = {
|
export type CallExpression = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1306,6 +1357,7 @@ export type CallExpression = {
|
||||||
callee: Expression,
|
callee: Expression,
|
||||||
arguments: Expression[]
|
arguments: Expression[]
|
||||||
};
|
};
|
||||||
|
|
||||||
export type MemberExpression = {
|
export type MemberExpression = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1316,8 +1368,12 @@ export type MemberExpression = {
|
||||||
property: Identifier | Expression,
|
property: Identifier | Expression,
|
||||||
computed: boolean
|
computed: boolean
|
||||||
};
|
};
|
||||||
|
// ast-types exports all expressions as patterns.
|
||||||
|
// That seems not like it was intended.
|
||||||
export type Pattern = Identifier;
|
export type Pattern = Identifier;
|
||||||
|
|
||||||
export type Declaration = VariableDeclaration | FunctionDeclaration;
|
export type Declaration = VariableDeclaration | FunctionDeclaration;
|
||||||
|
|
||||||
export type VariableDeclaration = {
|
export type VariableDeclaration = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1327,6 +1383,7 @@ export type VariableDeclaration = {
|
||||||
kind: \"var\" | \"let\" | \"const\",
|
kind: \"var\" | \"let\" | \"const\",
|
||||||
declarations: VariableDeclarator[]
|
declarations: VariableDeclarator[]
|
||||||
};
|
};
|
||||||
|
|
||||||
export type FunctionDeclaration = {
|
export type FunctionDeclaration = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1337,6 +1394,7 @@ export type FunctionDeclaration = {
|
||||||
body: BlockStatement,
|
body: BlockStatement,
|
||||||
params: Pattern[]
|
params: Pattern[]
|
||||||
};
|
};
|
||||||
|
|
||||||
export type VariableDeclarator = {
|
export type VariableDeclarator = {
|
||||||
source: ?string,
|
source: ?string,
|
||||||
start: SourcePosition,
|
start: SourcePosition,
|
||||||
|
@ -1346,7 +1404,9 @@ export type VariableDeclarator = {
|
||||||
id: Pattern,
|
id: Pattern,
|
||||||
init: ?Expression
|
init: ?Expression
|
||||||
};
|
};
|
||||||
|
|
||||||
const a: any = null;
|
const a: any = null;
|
||||||
|
|
||||||
export const builders: {
|
export const builders: {
|
||||||
emptyStatement(): EmptyStatement,
|
emptyStatement(): EmptyStatement,
|
||||||
blockStatement(body: Statement[]): BlockStatement,
|
blockStatement(body: Statement[]): BlockStatement,
|
||||||
|
@ -1448,6 +1508,5 @@ export const builders: {
|
||||||
params: Pattern[]
|
params: Pattern[]
|
||||||
): FunctionDeclaration,
|
): FunctionDeclaration,
|
||||||
variableDeclarator(id: Pattern, init?: Expression): VariableDeclarator
|
variableDeclarator(id: Pattern, init?: Expression): VariableDeclarator
|
||||||
} = a;
|
} = a;"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -6,9 +6,8 @@ exports[`test license_with_flow.js 1`] = `
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* Copyright example */
|
/* Copyright example */
|
||||||
/* @flow */
|
/* @flow */
|
||||||
// error
|
|
||||||
(\"\": void);
|
(\"\": void); // error"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test max_header_tokens.js 1`] = `
|
exports[`test max_header_tokens.js 1`] = `
|
||||||
|
@ -21,15 +20,6 @@ exports[`test max_header_tokens.js 1`] = `
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
|
||||||
/* second token */
|
|
||||||
/* third token */
|
|
||||||
/**
|
|
||||||
* After max_header_tokens (in .flowconfig), we no longer care:
|
|
||||||
*
|
|
||||||
* @flow
|
|
||||||
*/
|
|
||||||
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -37,9 +27,6 @@ exports[`test multiple_flows_1.js 1`] = `
|
||||||
"/* @flow */
|
"/* @flow */
|
||||||
/* @flow */
|
/* @flow */
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
|
||||||
/* @flow */
|
|
||||||
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -49,11 +36,6 @@ exports[`test multiple_flows_2.js 1`] = `
|
||||||
* @noflow
|
* @noflow
|
||||||
*/
|
*/
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/**
|
|
||||||
* @flow
|
|
||||||
* @noflow
|
|
||||||
*/
|
|
||||||
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -64,12 +46,6 @@ exports[`test multiple_providesModule_1.js 1`] = `
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/**
|
|
||||||
* @providesModule Foo
|
|
||||||
* @providesModule Bar
|
|
||||||
* @flow
|
|
||||||
*/
|
|
||||||
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -82,14 +58,6 @@ exports[`test multiple_providesModule_2.js 1`] = `
|
||||||
* @providesModule Bar
|
* @providesModule Bar
|
||||||
*/
|
*/
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/**
|
|
||||||
* @providesModule Foo
|
|
||||||
* @flow
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @providesModule Bar
|
|
||||||
*/
|
|
||||||
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -99,11 +67,9 @@ exports[`test use_strict_with_flow.js 1`] = `
|
||||||
|
|
||||||
(\"\": void); // error
|
(\"\": void); // error
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
|
||||||
// error
|
|
||||||
\"use strict\";
|
\"use strict\";
|
||||||
(\"\": void);
|
/* @flow */
|
||||||
"
|
(\"\": void); // error"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test with_flow.js 1`] = `
|
exports[`test with_flow.js 1`] = `
|
||||||
|
@ -112,9 +78,8 @@ exports[`test with_flow.js 1`] = `
|
||||||
(\"\": void); // error
|
(\"\": void); // error
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
// error
|
|
||||||
(\"\": void);
|
(\"\": void); // error"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test without_flow.js 1`] = `
|
exports[`test without_flow.js 1`] = `
|
||||||
|
@ -123,7 +88,6 @@ exports[`test without_flow.js 1`] = `
|
||||||
(\"\": void); // no error
|
(\"\": void); // no error
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* some other comment */
|
/* some other comment */
|
||||||
// no error
|
|
||||||
(\"\": void);
|
(\"\": void); // no error"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -14,18 +14,17 @@ let tests = [
|
||||||
];
|
];
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
// fillRect
|
|
||||||
// moveTo
|
|
||||||
// error: should be numbers
|
|
||||||
let tests = [
|
let tests = [
|
||||||
|
// fillRect
|
||||||
function(ctx: CanvasRenderingContext2D) {
|
function(ctx: CanvasRenderingContext2D) {
|
||||||
ctx.fillRect(0, 0, 200, 100);
|
ctx.fillRect(0, 0, 200, 100);
|
||||||
},
|
},
|
||||||
|
// moveTo
|
||||||
function(ctx: CanvasRenderingContext2D) {
|
function(ctx: CanvasRenderingContext2D) {
|
||||||
ctx.moveTo(\"0\", \"1\");
|
ctx.moveTo(\"0\", \"1\"); // error: should be numbers
|
||||||
}
|
}
|
||||||
];
|
];"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test CustomEvent.js 1`] = `
|
exports[`test CustomEvent.js 1`] = `
|
||||||
|
@ -40,14 +39,14 @@ let tests = [
|
||||||
];
|
];
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
// CustomEvent
|
|
||||||
let tests = [
|
let tests = [
|
||||||
|
// CustomEvent
|
||||||
function(document: Document) {
|
function(document: Document) {
|
||||||
const event = document.createEvent(\"CustomEvent\");
|
const event = document.createEvent(\"CustomEvent\");
|
||||||
event.initCustomEvent(\"butts\", true, false, { nice: 42 });
|
event.initCustomEvent(\"butts\", true, false, { nice: 42 });
|
||||||
}
|
}
|
||||||
];
|
];"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test Document.js 1`] = `
|
exports[`test Document.js 1`] = `
|
||||||
|
@ -64,16 +63,16 @@ let tests = [
|
||||||
];
|
];
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
// createElement
|
|
||||||
let tests = [
|
let tests = [
|
||||||
|
// createElement
|
||||||
function(document: Document) {
|
function(document: Document) {
|
||||||
(document.createElement(\"canvas\"): HTMLCanvasElement);
|
(document.createElement(\"canvas\"): HTMLCanvasElement);
|
||||||
(document.createElement(\"link\"): HTMLLinkElement);
|
(document.createElement(\"link\"): HTMLLinkElement);
|
||||||
(document.createElement(\"option\"): HTMLOptionElement);
|
(document.createElement(\"option\"): HTMLOptionElement);
|
||||||
(document.createElement(\"select\"): HTMLSelectElement);
|
(document.createElement(\"select\"): HTMLSelectElement);
|
||||||
}
|
}
|
||||||
];
|
];"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test Element.js 1`] = `
|
exports[`test Element.js 1`] = `
|
||||||
|
@ -97,9 +96,9 @@ let tests = [
|
||||||
];
|
];
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
// scrollIntoView
|
|
||||||
// fails
|
|
||||||
let tests = [
|
let tests = [
|
||||||
|
// scrollIntoView
|
||||||
function(element: Element) {
|
function(element: Element) {
|
||||||
element.scrollIntoView();
|
element.scrollIntoView();
|
||||||
element.scrollIntoView(false);
|
element.scrollIntoView(false);
|
||||||
|
@ -107,12 +106,13 @@ let tests = [
|
||||||
element.scrollIntoView({ behavior: \"smooth\", block: \"end\" });
|
element.scrollIntoView({ behavior: \"smooth\", block: \"end\" });
|
||||||
element.scrollIntoView({ block: \"end\" });
|
element.scrollIntoView({ block: \"end\" });
|
||||||
element.scrollIntoView({ behavior: \"smooth\" });
|
element.scrollIntoView({ behavior: \"smooth\" });
|
||||||
|
|
||||||
|
// fails
|
||||||
element.scrollIntoView({ behavior: \"invalid\" });
|
element.scrollIntoView({ behavior: \"invalid\" });
|
||||||
element.scrollIntoView({ block: \"invalid\" });
|
element.scrollIntoView({ block: \"invalid\" });
|
||||||
element.scrollIntoView(1);
|
element.scrollIntoView(1);
|
||||||
}
|
}
|
||||||
];
|
];"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test HTMLCanvasElement.js 1`] = `
|
exports[`test HTMLCanvasElement.js 1`] = `
|
||||||
|
@ -126,13 +126,13 @@ let tests = [
|
||||||
];
|
];
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
// getContext
|
|
||||||
let tests = [
|
let tests = [
|
||||||
|
// getContext
|
||||||
function(el: HTMLCanvasElement) {
|
function(el: HTMLCanvasElement) {
|
||||||
(el.getContext(\"2d\"): ?CanvasRenderingContext2D);
|
(el.getContext(\"2d\"): ?CanvasRenderingContext2D);
|
||||||
}
|
}
|
||||||
];
|
];"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test HTMLElement.js 1`] = `
|
exports[`test HTMLElement.js 1`] = `
|
||||||
|
@ -156,9 +156,9 @@ let tests = [
|
||||||
];
|
];
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
// scrollIntoView
|
|
||||||
// fails
|
|
||||||
let tests = [
|
let tests = [
|
||||||
|
// scrollIntoView
|
||||||
function(element: HTMLElement) {
|
function(element: HTMLElement) {
|
||||||
element.scrollIntoView();
|
element.scrollIntoView();
|
||||||
element.scrollIntoView(false);
|
element.scrollIntoView(false);
|
||||||
|
@ -166,12 +166,13 @@ let tests = [
|
||||||
element.scrollIntoView({ behavior: \"smooth\", block: \"end\" });
|
element.scrollIntoView({ behavior: \"smooth\", block: \"end\" });
|
||||||
element.scrollIntoView({ block: \"end\" });
|
element.scrollIntoView({ block: \"end\" });
|
||||||
element.scrollIntoView({ behavior: \"smooth\" });
|
element.scrollIntoView({ behavior: \"smooth\" });
|
||||||
|
|
||||||
|
// fails
|
||||||
element.scrollIntoView({ behavior: \"invalid\" });
|
element.scrollIntoView({ behavior: \"invalid\" });
|
||||||
element.scrollIntoView({ block: \"invalid\" });
|
element.scrollIntoView({ block: \"invalid\" });
|
||||||
element.scrollIntoView(1);
|
element.scrollIntoView(1);
|
||||||
}
|
}
|
||||||
];
|
];"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test HTMLInputElement.js 1`] = `
|
exports[`test HTMLInputElement.js 1`] = `
|
||||||
|
@ -189,19 +190,18 @@ let tests = [
|
||||||
];
|
];
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
// setRangeText
|
|
||||||
// end is required
|
|
||||||
// invalid value
|
|
||||||
let tests = [
|
let tests = [
|
||||||
|
// setRangeText
|
||||||
function(el: HTMLInputElement) {
|
function(el: HTMLInputElement) {
|
||||||
el.setRangeText(\"foo\");
|
el.setRangeText(\"foo\");
|
||||||
el.setRangeText(\"foo\", 123);
|
el.setRangeText(\"foo\", 123);
|
||||||
|
// end is required
|
||||||
el.setRangeText(\"foo\", 123, 234);
|
el.setRangeText(\"foo\", 123, 234);
|
||||||
el.setRangeText(\"foo\", 123, 234, \"select\");
|
el.setRangeText(\"foo\", 123, 234, \"select\");
|
||||||
el.setRangeText(\"foo\", 123, 234, \"bogus\");
|
el.setRangeText(\"foo\", 123, 234, \"bogus\"); // invalid value
|
||||||
}
|
}
|
||||||
];
|
];"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test URL.js 1`] = `
|
exports[`test URL.js 1`] = `
|
||||||
|
@ -227,41 +227,40 @@ const q: string = c.search; // correct
|
||||||
const r: string = c.username; // correct
|
const r: string = c.username; // correct
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
// 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 a = new URL(\"http://flowtype.org/\");
|
||||||
|
// correct
|
||||||
const b = new URL(\"/docs\", a);
|
const b = new URL(\"/docs\", a);
|
||||||
|
// correct
|
||||||
const c = new URL(\"/docs\", \"http://flowtype.org/\");
|
const c = new URL(\"/docs\", \"http://flowtype.org/\");
|
||||||
|
// correct
|
||||||
const d: URLSearchParams = c.searchParams;
|
const d: URLSearchParams = c.searchParams;
|
||||||
|
// correct
|
||||||
const e: string = c.path;
|
const e: string = c.path;
|
||||||
|
// not correct
|
||||||
const f: string = c.pathname;
|
const f: string = c.pathname;
|
||||||
|
// correct
|
||||||
const g: string = c.hash;
|
const g: string = c.hash;
|
||||||
|
// correct
|
||||||
const h: string = c.host;
|
const h: string = c.host;
|
||||||
|
// correct
|
||||||
const i: string = c.hostname;
|
const i: string = c.hostname;
|
||||||
|
// correct
|
||||||
const j: string = c.href;
|
const j: string = c.href;
|
||||||
|
// correct
|
||||||
const l: string = c.origin;
|
const l: string = c.origin;
|
||||||
|
// correct
|
||||||
const m: string = c.password;
|
const m: string = c.password;
|
||||||
|
// correct
|
||||||
const n: string = c.pathname;
|
const n: string = c.pathname;
|
||||||
|
// correct
|
||||||
const o: string = c.port;
|
const o: string = c.port;
|
||||||
|
// correct
|
||||||
const p: string = c.protocol;
|
const p: string = c.protocol;
|
||||||
|
// correct
|
||||||
const q: string = c.search;
|
const q: string = c.search;
|
||||||
const r: string = c.username;
|
// correct
|
||||||
"
|
const r: string = c.username; // correct"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test eventtarget.js 1`] = `
|
exports[`test eventtarget.js 1`] = `
|
||||||
|
@ -292,31 +291,30 @@ let tests = [
|
||||||
];
|
];
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
// attachEvent
|
|
||||||
// invalid, may be undefined
|
|
||||||
// valid
|
|
||||||
// detachEvent
|
|
||||||
// invalid, may be undefined
|
|
||||||
// valid
|
|
||||||
let listener: EventListener = function(event: Event): void {};
|
let listener: EventListener = function(event: Event): void {};
|
||||||
|
|
||||||
let tests = [
|
let tests = [
|
||||||
|
// attachEvent
|
||||||
function() {
|
function() {
|
||||||
let target = new EventTarget();
|
let target = new EventTarget();
|
||||||
(target.attachEvent(\"foo\", listener): void);
|
(target.attachEvent(\"foo\", listener): void);
|
||||||
(target.attachEvent && target.attachEvent(\"foo\", listener): void);
|
// invalid, may be undefined
|
||||||
|
(target.attachEvent && target.attachEvent(\"foo\", listener): void); // valid
|
||||||
},
|
},
|
||||||
|
// detachEvent
|
||||||
function() {
|
function() {
|
||||||
let target = new EventTarget();
|
let target = new EventTarget();
|
||||||
(target.detachEvent(\"foo\", listener): void);
|
(target.detachEvent(\"foo\", listener): void);
|
||||||
(target.detachEvent && target.detachEvent(\"foo\", listener): void);
|
// invalid, may be undefined
|
||||||
|
(target.detachEvent && target.detachEvent(\"foo\", listener): void); // valid
|
||||||
},
|
},
|
||||||
function() {
|
function() {
|
||||||
window.onmessage = (event: MessageEvent) => {
|
window.onmessage = (event: MessageEvent) => {
|
||||||
(event.target: window);
|
(event.target: window);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
];
|
];"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test path2d.js 1`] = `
|
exports[`test path2d.js 1`] = `
|
||||||
|
@ -333,19 +331,18 @@ let tests = [
|
||||||
];
|
];
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
// arcTo
|
|
||||||
// valid
|
|
||||||
// valid
|
|
||||||
// invalid
|
|
||||||
let tests = [
|
let tests = [
|
||||||
|
// arcTo
|
||||||
function() {
|
function() {
|
||||||
let path = new Path2D();
|
let path = new Path2D();
|
||||||
(path.arcTo(0, 0, 0, 0, 10): void);
|
(path.arcTo(0, 0, 0, 0, 10): void);
|
||||||
|
// valid
|
||||||
(path.arcTo(0, 0, 0, 0, 10, 20, 5): void);
|
(path.arcTo(0, 0, 0, 0, 10, 20, 5): void);
|
||||||
(path.arcTo(0, 0, 0, 0, 10, \"20\", 5): void);
|
// valid
|
||||||
|
(path.arcTo(0, 0, 0, 0, 10, \"20\", 5): void); // invalid
|
||||||
}
|
}
|
||||||
];
|
];"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test registerElement.js 1`] = `
|
exports[`test registerElement.js 1`] = `
|
||||||
|
@ -409,12 +406,9 @@ let tests = [
|
||||||
];
|
];
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @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 = [
|
let tests = [
|
||||||
|
// should work with Object.create()
|
||||||
function() {
|
function() {
|
||||||
document.registerElement(\"custom-element\", {
|
document.registerElement(\"custom-element\", {
|
||||||
prototype: Object.create(HTMLElement.prototype, {
|
prototype: Object.create(HTMLElement.prototype, {
|
||||||
|
@ -432,6 +426,7 @@ let tests = [
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
// or with Object.assign()
|
||||||
function() {
|
function() {
|
||||||
document.registerElement(\"custom-element\", {
|
document.registerElement(\"custom-element\", {
|
||||||
prototype: Object.assign(Object.create(HTMLElement.prototype), {
|
prototype: Object.assign(Object.create(HTMLElement.prototype), {
|
||||||
|
@ -447,20 +442,22 @@ let tests = [
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
// should complain about invalid callback parameters
|
||||||
function() {
|
function() {
|
||||||
document.registerElement(\"custom-element\", {
|
document.registerElement(\"custom-element\", {
|
||||||
prototype: {
|
prototype: {
|
||||||
attributeChangedCallback(
|
attributeChangedCallback(
|
||||||
localName: string,
|
localName: string,
|
||||||
oldVal: string,
|
oldVal: string,
|
||||||
|
// Error: This might be null
|
||||||
newVal: string,
|
newVal: string,
|
||||||
|
// Error: This might be null
|
||||||
namespace: string
|
namespace: string
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
];
|
];"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test traversal.js 1`] = `
|
exports[`test traversal.js 1`] = `
|
||||||
|
@ -661,24 +658,9 @@ let tests = [
|
||||||
];
|
];
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @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 = [
|
let tests = [
|
||||||
|
// basic functionality
|
||||||
function() {
|
function() {
|
||||||
const i: NodeIterator<*, *> = document.createNodeIterator(document.body);
|
const i: NodeIterator<*, *> = document.createNodeIterator(document.body);
|
||||||
const filter: NodeFilter = i.filter;
|
const filter: NodeFilter = i.filter;
|
||||||
|
@ -693,14 +675,17 @@ let tests = [
|
||||||
typeof NodeFilter.FILTER_REJECT |
|
typeof NodeFilter.FILTER_REJECT |
|
||||||
typeof NodeFilter.FILTER_SKIP = filter.acceptNode(document.body);
|
typeof NodeFilter.FILTER_SKIP = filter.acceptNode(document.body);
|
||||||
},
|
},
|
||||||
|
// rootNode must be a Node
|
||||||
function() {
|
function() {
|
||||||
document.createNodeIterator(document.body);
|
document.createNodeIterator(document.body);
|
||||||
document.createNodeIterator({});
|
// valid
|
||||||
|
document.createNodeIterator({}); // invalid
|
||||||
},
|
},
|
||||||
function() {
|
function() {
|
||||||
document.createTreeWalker(document.body);
|
document.createTreeWalker(document.body);
|
||||||
document.createTreeWalker({});
|
document.createTreeWalker({}); // invalid
|
||||||
},
|
},
|
||||||
|
// Type Parameters
|
||||||
function() {
|
function() {
|
||||||
const _root = document.body;
|
const _root = document.body;
|
||||||
const i = document.createNodeIterator(_root, NodeFilter.SHOW_ELEMENT);
|
const i = document.createNodeIterator(_root, NodeFilter.SHOW_ELEMENT);
|
||||||
|
@ -854,20 +839,25 @@ let tests = [
|
||||||
const previousNode: Node | null = w.previousNode();
|
const previousNode: Node | null = w.previousNode();
|
||||||
const nextNode: Node | null = w.nextNode();
|
const nextNode: Node | null = w.nextNode();
|
||||||
},
|
},
|
||||||
|
// NodeFilterInterface
|
||||||
function() {
|
function() {
|
||||||
document.createNodeIterator(
|
document.createNodeIterator(
|
||||||
document.body,
|
document.body,
|
||||||
-1,
|
-1,
|
||||||
node => NodeFilter.FILTER_ACCEPT
|
node => NodeFilter.FILTER_ACCEPT
|
||||||
);
|
);
|
||||||
|
// valid
|
||||||
document.createNodeIterator(document.body, -1, node => \"accept\");
|
document.createNodeIterator(document.body, -1, node => \"accept\");
|
||||||
|
// invalid
|
||||||
document.createNodeIterator(document.body, -1, {
|
document.createNodeIterator(document.body, -1, {
|
||||||
accept: node => NodeFilter.FILTER_ACCEPT
|
accept: node => NodeFilter.FILTER_ACCEPT
|
||||||
});
|
});
|
||||||
|
// valid
|
||||||
document.createNodeIterator(document.body, -1, {
|
document.createNodeIterator(document.body, -1, {
|
||||||
accept: node => \"accept\"
|
accept: node => \"accept\"
|
||||||
});
|
});
|
||||||
document.createNodeIterator(document.body, -1, {});
|
// invalid
|
||||||
|
document.createNodeIterator(document.body, -1, {}); // invalid
|
||||||
},
|
},
|
||||||
function() {
|
function() {
|
||||||
document.createTreeWalker(
|
document.createTreeWalker(
|
||||||
|
@ -875,13 +865,16 @@ let tests = [
|
||||||
-1,
|
-1,
|
||||||
node => NodeFilter.FILTER_ACCEPT
|
node => NodeFilter.FILTER_ACCEPT
|
||||||
);
|
);
|
||||||
|
// valid
|
||||||
document.createTreeWalker(document.body, -1, node => \"accept\");
|
document.createTreeWalker(document.body, -1, node => \"accept\");
|
||||||
|
// invalid
|
||||||
document.createTreeWalker(document.body, -1, {
|
document.createTreeWalker(document.body, -1, {
|
||||||
accept: node => NodeFilter.FILTER_ACCEPT
|
accept: node => NodeFilter.FILTER_ACCEPT
|
||||||
});
|
});
|
||||||
|
// valid
|
||||||
document.createTreeWalker(document.body, -1, { accept: node => \"accept\" });
|
document.createTreeWalker(document.body, -1, { accept: node => \"accept\" });
|
||||||
document.createTreeWalker(document.body, -1, {});
|
// invalid
|
||||||
|
document.createTreeWalker(document.body, -1, {}); // invalid
|
||||||
}
|
}
|
||||||
];
|
];"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -9,8 +9,7 @@ module.exports = num;
|
||||||
var num = 42;
|
var num = 42;
|
||||||
function bar() {}
|
function bar() {}
|
||||||
bar();
|
bar();
|
||||||
module.exports = num;
|
module.exports = num;"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`test test.js 1`] = `
|
exports[`test test.js 1`] = `
|
||||||
|
@ -37,15 +36,18 @@ declare var obj: {a?: {b: ?{c: null | {d: number}}}};
|
||||||
const idxResult = idx(obj, obj => obj.a.b.c.d);
|
const idxResult = idx(obj, obj => obj.a.b.c.d);
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// @flow
|
// @flow
|
||||||
// test deduping of inferred types
|
|
||||||
var num = require(\"./import\");
|
var num = require(\"./import\");
|
||||||
function foo(x) {}
|
function foo(x) {}
|
||||||
foo(0);
|
foo(0);
|
||||||
var a: string = num;
|
var a: string = num;
|
||||||
|
|
||||||
function unannotated(x) {
|
function unannotated(x) {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test deduping of inferred types
|
||||||
const nullToUndefined = val => val === null ? undefined : val;
|
const nullToUndefined = val => val === null ? undefined : val;
|
||||||
|
|
||||||
function f0(x: ?Object) {
|
function f0(x: ?Object) {
|
||||||
return nullToUndefined(x);
|
return nullToUndefined(x);
|
||||||
}
|
}
|
||||||
|
@ -58,8 +60,8 @@ function f2(x: ?string) {
|
||||||
function f3(x: ?string) {
|
function f3(x: ?string) {
|
||||||
return nullToUndefined(x);
|
return nullToUndefined(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
declare var idx: $Facebookism$Idx;
|
declare var idx: $Facebookism$Idx;
|
||||||
declare var obj: { a?: { b: ?{ c: null | { d: number } } } };
|
declare var obj: { a?: { b: ?{ c: null | { d: number } } } };
|
||||||
const idxResult = idx(obj, obj => obj.a.b.c.d);
|
const idxResult = idx(obj, obj => obj.a.b.c.d);"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -39,26 +39,34 @@ class C1 {
|
||||||
m() {}
|
m() {}
|
||||||
m() {}
|
m() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
new C1().m();
|
new C1().m();
|
||||||
|
|
||||||
class C2 {
|
class C2 {
|
||||||
get m() {
|
get m() {
|
||||||
return 42;
|
return 42;
|
||||||
}
|
}
|
||||||
m() {}
|
m() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
new C2().m();
|
new C2().m();
|
||||||
|
|
||||||
class C3 {
|
class C3 {
|
||||||
set m(x) {}
|
set m(x) {}
|
||||||
m() {}
|
m() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
new C3().m();
|
new C3().m();
|
||||||
|
|
||||||
class C4 {
|
class C4 {
|
||||||
get m() {
|
get m() {
|
||||||
return 42;
|
return 42;
|
||||||
}
|
}
|
||||||
set m(x: number) {}
|
set m(x: number) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
new C4().m = new C4().m - 42;
|
new C4().m = new C4().m - 42;
|
||||||
|
|
||||||
class C5 {
|
class C5 {
|
||||||
m() {}
|
m() {}
|
||||||
get m() {
|
get m() {
|
||||||
|
@ -66,6 +74,6 @@ class C5 {
|
||||||
}
|
}
|
||||||
set m(x: number) {}
|
set m(x: number) {}
|
||||||
}
|
}
|
||||||
new C5().m = new C5().m - 42;
|
|
||||||
"
|
new C5().m = new C5().m - 42;"
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -16,22 +16,21 @@ function tag2(strings,...values) {
|
||||||
var s3 = tag2 \`la la la\`;
|
var s3 = tag2 \`la la la\`;
|
||||||
(s3.foo: number); // error: string ~> number
|
(s3.foo: number); // error: string ~> number
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// error: no prop x in A
|
|
||||||
// error: string ~> number
|
|
||||||
// ok: tagged templates can return whatever
|
|
||||||
// error: string ~> number
|
|
||||||
class A {}
|
class A {}
|
||||||
var a = new A();
|
var a = new A();
|
||||||
var s1 = \`l\${a.x}r\`;
|
var s1 = \`l\${a.x}r\`;
|
||||||
|
// error: no prop x in A
|
||||||
function tag(strings, ...values) {
|
function tag(strings, ...values) {
|
||||||
var x: number = strings[0];
|
var x: number = strings[0];
|
||||||
|
// error: string ~> number
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
var s2 = tag\`l\${42}r\`;
|
var s2 = tag\`l\${42}r\`;
|
||||||
|
|
||||||
function tag2(strings, ...values) {
|
function tag2(strings, ...values) {
|
||||||
return { foo: \"\" };
|
return { foo: \"\" }; // ok: tagged templates can return whatever
|
||||||
}
|
}
|
||||||
|
|
||||||
var s3 = tag2\`la la la\`;
|
var s3 = tag2\`la la la\`;
|
||||||
(s3.foo: number);
|
(s3.foo: number); // error: string ~> number"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -27,26 +27,30 @@ function keys2union(s: Keys): Union { return s; } // ok
|
||||||
function union2keys(s: Union): Keys { return s; } // ok
|
function union2keys(s: Union): Keys { return s; } // ok
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/** @flow */
|
/** @flow */
|
||||||
// ok
|
|
||||||
// ok
|
|
||||||
function isActive(
|
function isActive(
|
||||||
ad: { state: $Keys<{ PAUSED: string, ACTIVE: string, DELETED: string }> }
|
ad: { state: $Keys<{ PAUSED: string, ACTIVE: string, DELETED: string }> }
|
||||||
): boolean {
|
): boolean {
|
||||||
return ad.state === \"ACTIVE\";
|
return ad.state === \"ACTIVE\";
|
||||||
}
|
}
|
||||||
|
|
||||||
isActive({ state: \"PAUSE\" });
|
isActive({ state: \"PAUSE\" });
|
||||||
|
|
||||||
var MyStates = { PAUSED: \"PAUSED\", ACTIVE: \"ACTIVE\", DELETED: \"DELETED\" };
|
var MyStates = { PAUSED: \"PAUSED\", ACTIVE: \"ACTIVE\", DELETED: \"DELETED\" };
|
||||||
function isActive2(ad: { state: $Keys<typeof MyStates> }): boolean {
|
function isActive2(ad: { state: $Keys<typeof MyStates> }): boolean {
|
||||||
return ad.state === MyStates.ACTIVE;
|
return ad.state === MyStates.ACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
isActive2({ state: \"PAUSE\" });
|
isActive2({ state: \"PAUSE\" });
|
||||||
|
|
||||||
type Keys = $Keys<{ x: any, y: any }>;
|
type Keys = $Keys<{ x: any, y: any }>;
|
||||||
type Union = \"x\" | \"y\";
|
type Union = \"x\" | \"y\";
|
||||||
|
|
||||||
function keys2union(s: Keys): Union {
|
function keys2union(s: Keys): Union {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
// ok
|
||||||
function union2keys(s: Union): Keys {
|
function union2keys(s: Union): Keys {
|
||||||
return s;
|
return s;
|
||||||
}
|
} // ok"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -13,16 +13,16 @@ var x = (null : ?number);
|
||||||
(1 == x);
|
(1 == x);
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
/* @flow */
|
/* @flow */
|
||||||
// error
|
|
||||||
// error
|
|
||||||
1 == 1;
|
1 == 1;
|
||||||
\"foo\" == \"bar\";
|
\"foo\" == \"bar\";
|
||||||
1 == null;
|
1 == null;
|
||||||
null == 1;
|
null == 1;
|
||||||
1 == \"\";
|
1 == \"\";
|
||||||
|
// error
|
||||||
\"\" == 1;
|
\"\" == 1;
|
||||||
|
// error
|
||||||
var x = (null: ?number);
|
var x = (null: ?number);
|
||||||
x == 1;
|
x == 1;
|
||||||
1 == x;
|
1 == x;"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
exports[`test errors.js 1`] = `
|
exports[`test errors.js 1`] = `
|
||||||
"if (typeof define === \'function\' && define.amd) { }
|
"if (typeof define === \'function\' && define.amd) { }
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
if (typeof define === \"function\" && define.amd) {}
|
if (typeof define === \"function\" && define.amd) {}"
|
||||||
"
|
|
||||||
`;
|
`;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue