2016-12-23 22:31:38 +03:00
|
|
|
exports[`test conversion.js 1`] = `
|
|
|
|
"/* @flow */
|
|
|
|
|
2016-12-30 19:56:42 +03:00
|
|
|
(Object({foo: \'bar\'}): {foo: string});
|
|
|
|
(Object(\"123\"): String);
|
2016-12-23 22:31:38 +03:00
|
|
|
(Object(123): Number);
|
|
|
|
(Object(true): Boolean);
|
|
|
|
(Object(null): {});
|
|
|
|
(Object(undefined): {});
|
|
|
|
(Object(void(0)): {});
|
|
|
|
(Object(undefined): Number); // error
|
|
|
|
|
|
|
|
var x = Object(null);
|
2016-12-30 19:56:42 +03:00
|
|
|
x.foo = \"bar\";
|
2016-12-23 22:31:38 +03:00
|
|
|
|
2016-12-30 19:56:42 +03:00
|
|
|
var y = Object(\"123\");
|
2016-12-23 22:31:38 +03:00
|
|
|
(y.charAt(0): string);
|
|
|
|
|
|
|
|
var z = Object(123); // error (next line makes this not match any signatures)
|
|
|
|
(z.charAt(0): string);
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
/* @flow */
|
2017-01-10 05:49:06 +03:00
|
|
|
|
2016-12-30 19:56:42 +03:00
|
|
|
(Object({ foo: \"bar\" }): { foo: string });
|
|
|
|
(Object(\"123\"): String);
|
2016-12-28 05:40:04 +03:00
|
|
|
(Object(123): Number);
|
|
|
|
(Object(true): Boolean);
|
|
|
|
(Object(null): {});
|
2016-12-23 22:31:38 +03:00
|
|
|
(Object(undefined): {});
|
2016-12-28 05:40:04 +03:00
|
|
|
(Object(void 0): {});
|
2016-12-27 21:29:31 +03:00
|
|
|
(Object(undefined): Number);
|
2017-01-18 06:33:55 +03:00
|
|
|
|
2017-01-10 05:49:06 +03:00
|
|
|
// error
|
2016-12-28 05:40:04 +03:00
|
|
|
var x = Object(null);
|
2016-12-30 19:56:42 +03:00
|
|
|
x.foo = \"bar\";
|
2017-01-10 05:49:06 +03:00
|
|
|
|
2016-12-30 19:56:42 +03:00
|
|
|
var y = Object(\"123\");
|
2016-12-28 05:40:04 +03:00
|
|
|
(y.charAt(0): string);
|
2017-01-10 05:49:06 +03:00
|
|
|
|
2016-12-28 05:40:04 +03:00
|
|
|
var z = Object(123);
|
2017-01-10 05:49:06 +03:00
|
|
|
// error (next line makes this not match any signatures)
|
2017-01-11 18:16:38 +03:00
|
|
|
(z.charAt(0): string);
|
|
|
|
"
|
2016-12-23 22:31:38 +03:00
|
|
|
`;
|
|
|
|
|
|
|
|
exports[`test objects.js 1`] = `
|
|
|
|
"/* @flow */
|
|
|
|
|
2016-12-30 19:56:42 +03:00
|
|
|
var x : {\'123\': string, bar: string} = {\'123\': \'val\', bar: \'bar\'};
|
|
|
|
(x.foo : string); // error, key doesn\'t exist
|
|
|
|
(x[\'foo\'] : string); // error, key doesn\'t exist
|
|
|
|
(x[123] : boolean); // TODO: use the number\'s value to error here
|
2016-12-23 22:31:38 +03:00
|
|
|
(x.bar: boolean); // error, string !~> boolean
|
2016-12-30 19:56:42 +03:00
|
|
|
(x[\'123\'] : boolean); // error, string !~> boolean
|
|
|
|
x[\'123\'] = false; // error, boolean !~> string
|
|
|
|
x[123] = false; // TODO: use the number\'s value to error here
|
|
|
|
x[\'foo\'+\'bar\'] = \'derp\'; // ok since we can\'t tell
|
|
|
|
(x[\`foo\`]: string); // error, key doesn\'t exist
|
2016-12-23 22:31:38 +03:00
|
|
|
|
2016-12-30 19:56:42 +03:00
|
|
|
var y : {foo: string} = {foo: \'bar\'};
|
|
|
|
y[\'foo\'] = 123; // error, number !~> string
|
|
|
|
y[\'bar\'] = \'abc\'; // error, property not found
|
2016-12-23 22:31:38 +03:00
|
|
|
|
2016-12-30 19:56:42 +03:00
|
|
|
(y[\'hasOwnProperty\']: string); // error, prototype method is not a string
|
2016-12-23 22:31:38 +03:00
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
/* @flow */
|
2017-01-10 05:49:06 +03:00
|
|
|
|
2017-01-05 01:26:44 +03:00
|
|
|
var x: { \"123\": string, bar: string } = { \"123\": \"val\", bar: \"bar\" };
|
2016-12-27 21:29:31 +03:00
|
|
|
(x.foo: string);
|
2017-01-10 05:49:06 +03:00
|
|
|
// error, key doesn\'t exist
|
2016-12-30 19:56:42 +03:00
|
|
|
(x[\"foo\"]: string);
|
2017-01-10 05:49:06 +03:00
|
|
|
// error, key doesn\'t exist
|
2016-12-28 05:40:04 +03:00
|
|
|
(x[123]: boolean);
|
2017-01-10 05:49:06 +03:00
|
|
|
// TODO: use the number\'s value to error here
|
2016-12-27 21:29:31 +03:00
|
|
|
(x.bar: boolean);
|
2017-01-10 05:49:06 +03:00
|
|
|
// error, string !~> boolean
|
2016-12-30 19:56:42 +03:00
|
|
|
(x[\"123\"]: boolean);
|
2017-01-10 05:49:06 +03:00
|
|
|
// error, string !~> boolean
|
2016-12-30 19:56:42 +03:00
|
|
|
x[\"123\"] = false;
|
2017-01-10 05:49:06 +03:00
|
|
|
// error, boolean !~> string
|
2016-12-28 05:40:04 +03:00
|
|
|
x[123] = false;
|
2017-01-10 05:49:06 +03:00
|
|
|
// TODO: use the number\'s value to error here
|
2016-12-30 19:56:42 +03:00
|
|
|
x[\"foo\" + \"bar\"] = \"derp\";
|
2017-01-10 05:49:06 +03:00
|
|
|
// ok since we can\'t tell
|
2016-12-27 21:29:31 +03:00
|
|
|
(x[\`foo\`]: string);
|
2017-01-18 06:33:55 +03:00
|
|
|
|
2017-01-10 05:49:06 +03:00
|
|
|
// error, key doesn\'t exist
|
2016-12-30 19:56:42 +03:00
|
|
|
var y: { foo: string } = { foo: \"bar\" };
|
|
|
|
y[\"foo\"] = 123;
|
2017-01-10 05:49:06 +03:00
|
|
|
// error, number !~> string
|
2016-12-30 19:56:42 +03:00
|
|
|
y[\"bar\"] = \"abc\";
|
2017-01-18 06:33:55 +03:00
|
|
|
|
2017-01-10 05:49:06 +03:00
|
|
|
// error, property not found
|
2017-01-11 18:16:38 +03:00
|
|
|
(y[\"hasOwnProperty\"]: string); // error, prototype method is not a string
|
|
|
|
"
|
2016-12-23 22:31:38 +03:00
|
|
|
`;
|
|
|
|
|
|
|
|
exports[`test unaliased_assign.js 1`] = `
|
|
|
|
"/**
|
|
|
|
* test handling of unaliased value assignment.
|
|
|
|
*
|
|
|
|
* An unaliased object rvalue may be assigned to a supertype lvalue,
|
2016-12-30 19:56:42 +03:00
|
|
|
* because later widening mutations on the rvalue can\'t break assumptions
|
2016-12-23 22:31:38 +03:00
|
|
|
* made by other lvalues.
|
|
|
|
*
|
|
|
|
* However, upon assignment the rvalue must take on the type of the
|
|
|
|
* lvalue, to avoid both false positives and false negatives
|
|
|
|
* (unsoundness), as shown below.
|
|
|
|
*
|
|
|
|
* @flow
|
|
|
|
*/
|
|
|
|
|
2016-12-30 19:56:42 +03:00
|
|
|
var glob: { x: string } = { x: \"hey\" };
|
2016-12-23 22:31:38 +03:00
|
|
|
|
|
|
|
function assign_then_alias() {
|
|
|
|
var obj: { x: string | number };
|
2016-12-30 19:56:42 +03:00
|
|
|
obj = { x: \"hey\" };
|
2016-12-23 22:31:38 +03:00
|
|
|
glob = obj; // error: subsequent assignment might make glob.x a number
|
|
|
|
}
|
|
|
|
|
|
|
|
function assign_then_widen() {
|
|
|
|
var obj: { x: string | number };
|
2016-12-30 19:56:42 +03:00
|
|
|
obj = { x: \"hey\" };
|
|
|
|
obj.x = 10; // ok, by lvalue\'s given type
|
2016-12-23 22:31:38 +03:00
|
|
|
}
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2016-12-27 21:29:31 +03:00
|
|
|
/**
|
|
|
|
* test handling of unaliased value assignment.
|
|
|
|
*
|
|
|
|
* An unaliased object rvalue may be assigned to a supertype lvalue,
|
2016-12-30 19:56:42 +03:00
|
|
|
* because later widening mutations on the rvalue can\'t break assumptions
|
2016-12-27 21:29:31 +03:00
|
|
|
* made by other lvalues.
|
|
|
|
*
|
|
|
|
* However, upon assignment the rvalue must take on the type of the
|
|
|
|
* lvalue, to avoid both false positives and false negatives
|
|
|
|
* (unsoundness), as shown below.
|
|
|
|
*
|
|
|
|
* @flow
|
|
|
|
*/
|
2017-01-10 05:49:06 +03:00
|
|
|
|
2016-12-30 19:56:42 +03:00
|
|
|
var glob: { x: string } = { x: \"hey\" };
|
2017-01-10 05:49:06 +03:00
|
|
|
|
2016-12-27 21:29:31 +03:00
|
|
|
function assign_then_alias() {
|
|
|
|
var obj: { x: string | number };
|
2016-12-30 19:56:42 +03:00
|
|
|
obj = { x: \"hey\" };
|
2017-01-10 05:49:06 +03:00
|
|
|
glob = obj; // error: subsequent assignment might make glob.x a number
|
2016-12-27 21:29:31 +03:00
|
|
|
}
|
2017-01-10 05:49:06 +03:00
|
|
|
|
2016-12-27 21:29:31 +03:00
|
|
|
function assign_then_widen() {
|
|
|
|
var obj: { x: string | number };
|
2016-12-30 19:56:42 +03:00
|
|
|
obj = { x: \"hey\" };
|
2017-01-10 05:49:06 +03:00
|
|
|
obj.x = 10; // ok, by lvalue\'s given type
|
2017-01-11 18:16:38 +03:00
|
|
|
}
|
|
|
|
"
|
2016-12-23 22:31:38 +03:00
|
|
|
`;
|