prettier/tests/flow/binding/__snapshots__/jsfmt.spec.js.snap

902 lines
17 KiB
Plaintext

// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`const.js 1`] = `
const x = 0;
// errors: const cannot be reassigned
x++;
x--;
x += 0;
x -= 0;
x /= 0;
x %= 0;
x <<= 0
x >>= 0;
x >>>= 0;
x |= 0;
x ^= 0;
x &= 0;
// regression tests -- OK to assign consts like this:
const { foo } = { foo: "foo" }
const [ bar ] = ["bar"];
(foo: number); // error: string ~> number
(bar: number); // error: string ~> number
declare var bazzes: { baz: string }[];
for (const { baz } of bazzes) {
(baz: number); // error: string ~> number
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const x = 0;
// errors: const cannot be reassigned
x++;
x--;
x += 0;
x -= 0;
x /= 0;
x %= 0;
x <<= 0;
x >>= 0;
x >>>= 0;
x |= 0;
x ^= 0;
x &= 0;
// regression tests -- OK to assign consts like this:
const { foo } = { foo: "foo" };
const [bar] = ["bar"];
(foo: number); // error: string ~> number
(bar: number); // error: string ~> number
declare var bazzes: { baz: string }[];
for (const { baz } of bazzes) {
(baz: number); // error: string ~> number
}
`;
exports[`rebinding.js 1`] = `
/* @flow
* test errors on illegal rebinding/reassignment
*
* type class let const var (reassign)
* type x x x x x x
* class x x x x x
* let x x x x x
* const x x x x x x
* var x x x x
*/
// type x *
function type_type() {
type A = number;
type A = number; // error: name already bound
}
function type_class() {
type A = number;
class A {} // error: name already bound
}
function type_let() {
type A = number;
let A = 0; // error: name already bound
}
function type_const() {
type A = number;
const A = 0; // error: name already bound
}
function type_var() {
type A = number;
var A = 0; // error: name already bound
}
function type_reassign() {
type A = number;
A = 42; // error: type alias ref'd from value pos
}
// class x *
function class_type() {
class A {}
type A = number; // error: name already bound
}
function class_class() {
class A {}
class A {} // error: name already bound
}
function class_let() {
class A {}
let A = 0; // error: name already bound
}
function class_const() {
class A {}
const A = 0; // error: name already bound
}
function class_var() {
class A {}
var A = 0; // error: name already bound
}
// let x *
function let_type() {
let A = 0;
type A = number; // error: name already bound
}
function let_class() {
let A = 0;
class A {} // error: name already bound
}
function let_let() {
let A = 0;
let A = 0; // error: name already bound
}
function let_const() {
let A = 0;
const A = 0; // error: name already bound
}
function let_var() {
let A = 0;
var A = 0; // error: name already bound
}
// const x *
function const_type() {
const A = 0;
type A = number; // error: name already bound
}
function const_class() {
const A = 0;
class A {} // error: name already bound
}
function const_let() {
const A = 0;
let A = 0; // error: name already bound
}
function const_const() {
const A = 0;
const A = 0; // error: name already bound
}
function const_var() {
const A = 0;
var A = 0; // error: name already bound
}
function const_reassign() {
const A = 0;
A = 42; // error: cannot be reassigned
}
// var x *
function var_type() {
var A = 0;
type A = number; // error: name already bound
}
function var_class() {
var A = 0;
class A {} // error: name already bound
}
function var_let() {
var A = 0;
let A = 0; // error: name already bound
}
function var_const() {
var A = 0;
const A = 0; // error: name already bound
}
function var_var() {
var A = 0;
var A = 0; // OK
}
// function x *
function function_toplevel() {
function a() {};
function a() {}; // OK
}
function function_block() {
{
function a() {};
function a() {}; // error: name already bound
}
}
// corner cases
function var_shadow_nested_scope() {
{
let x = 0;
{
var x = 0; // error: name already bound
}
}
}
function type_shadow_nested_scope() {
{
let x = 0;
{
type x = string; // error: name already bound
}
}
}
// fn params name clash
function fn_params_name_clash(x, x /* error: x already bound */) {}
function fn_params_clash_fn_binding(x,y) {
let x = 0; // error: x already bound
var y = 0; // OK
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* @flow
* test errors on illegal rebinding/reassignment
*
* type class let const var (reassign)
* type x x x x x x
* class x x x x x
* let x x x x x
* const x x x x x x
* var x x x x
*/
// type x *
function type_type() {
type A = number;
type A = number; // error: name already bound
}
function type_class() {
type A = number;
class A {} // error: name already bound
}
function type_let() {
type A = number;
let A = 0; // error: name already bound
}
function type_const() {
type A = number;
const A = 0; // error: name already bound
}
function type_var() {
type A = number;
var A = 0; // error: name already bound
}
function type_reassign() {
type A = number;
A = 42; // error: type alias ref'd from value pos
}
// class x *
function class_type() {
class A {}
type A = number; // error: name already bound
}
function class_class() {
class A {}
class A {} // error: name already bound
}
function class_let() {
class A {}
let A = 0; // error: name already bound
}
function class_const() {
class A {}
const A = 0; // error: name already bound
}
function class_var() {
class A {}
var A = 0; // error: name already bound
}
// let x *
function let_type() {
let A = 0;
type A = number; // error: name already bound
}
function let_class() {
let A = 0;
class A {} // error: name already bound
}
function let_let() {
let A = 0;
let A = 0; // error: name already bound
}
function let_const() {
let A = 0;
const A = 0; // error: name already bound
}
function let_var() {
let A = 0;
var A = 0; // error: name already bound
}
// const x *
function const_type() {
const A = 0;
type A = number; // error: name already bound
}
function const_class() {
const A = 0;
class A {} // error: name already bound
}
function const_let() {
const A = 0;
let A = 0; // error: name already bound
}
function const_const() {
const A = 0;
const A = 0; // error: name already bound
}
function const_var() {
const A = 0;
var A = 0; // error: name already bound
}
function const_reassign() {
const A = 0;
A = 42; // error: cannot be reassigned
}
// var x *
function var_type() {
var A = 0;
type A = number; // error: name already bound
}
function var_class() {
var A = 0;
class A {} // error: name already bound
}
function var_let() {
var A = 0;
let A = 0; // error: name already bound
}
function var_const() {
var A = 0;
const A = 0; // error: name already bound
}
function var_var() {
var A = 0;
var A = 0; // OK
}
// function x *
function function_toplevel() {
function a() {}
function a() {} // OK
}
function function_block() {
{
function a() {}
function a() {} // error: name already bound
}
}
// corner cases
function var_shadow_nested_scope() {
{
let x = 0;
{
var x = 0; // error: name already bound
}
}
}
function type_shadow_nested_scope() {
{
let x = 0;
{
type x = string; // error: name already bound
}
}
}
// fn params name clash
function fn_params_name_clash(x, x /* error: x already bound */) {}
function fn_params_clash_fn_binding(x, y) {
let x = 0; // error: x already bound
var y = 0; // OK
}
`;
exports[`scope.js 1`] = `
function block_scope() {
let a: number = 0;
var b: number = 0;
{
let a = ""; // ok: local to block
var b = ""; // error: string ~> number
}
}
function switch_scope(x: string) {
let a: number = 0;
var b: number = 0;
switch (x) {
case "foo":
let a = ""; // ok: local to switch
var b = ""; // error: string ~> number
break;
case "bar":
let a = ""; // error: a already bound in switch
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) {
switch (x) {
case 0:
a = ""; // error: assign before declaration
break;
case 1:
var b = a; // error: use before declaration
break;
case 2:
let a = "";
break;
case 3:
a = ""; // error: skipped initializer
break;
case 4:
var c:string = a; // error: skipped initializer
break;
}
a = ""; // error: a no longer in scope
}
function try_scope() {
let a: number = 0;
try {
let a = ""; // ok
} catch (e) {
let a = ""; // ok
} finally {
let a = ""; // ok
}
}
function for_scope_let() {
let a: number = 0;
for (let a = "" /* ok: local to init */;;) {}
}
function for_scope_var() {
var a: number = 0;
for (var a = "" /* error: string ~> number */;;) {}
}
function for_in_scope_let(o: Object) {
let a: number = 0;
for (let a /* ok: local to init */ in o) {}
}
function for_in_scope_var(o: Object) {
var a: number = 0;
for (var a /* error: string ~> number */ in o) {}
}
function for_of_scope_let(xs: string[]) {
let a: number = 0;
for (let a /* ok: local to init */ of xs) {}
}
function for_of_scope_var(xs: string[]) {
var a: number = 0;
for (var a /* error: string ~> number */ of xs) {}
}
function default_param_1() {
// function binding in scope in default expr
function f(
x: () => string = f // error: number ~> string
): number {
return 0;
}
}
function default_param_2() {
// fn body bindings not visible from param scope
let a = "";
function f0(x = () => a): number {
let a = 0;
return x(); // error: string ~> number
}
function f1(x = b /* error: cannot resolve b */): number {
let b = 0;
return x;
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function block_scope() {
let a: number = 0;
var b: number = 0;
{
let a = ""; // ok: local to block
var b = ""; // error: string ~> number
}
}
function switch_scope(x: string) {
let a: number = 0;
var b: number = 0;
switch (x) {
case "foo":
let a = ""; // ok: local to switch
var b = ""; // error: string ~> number
break;
case "bar":
let a = ""; // error: a already bound in switch
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) {
switch (x) {
case 0:
a = ""; // error: assign before declaration
break;
case 1:
var b = a; // error: use before declaration
break;
case 2:
let a = "";
break;
case 3:
a = ""; // error: skipped initializer
break;
case 4:
var c: string = a; // error: skipped initializer
break;
}
a = ""; // error: a no longer in scope
}
function try_scope() {
let a: number = 0;
try {
let a = ""; // ok
} catch (e) {
let a = ""; // ok
} finally {
let a = ""; // ok
}
}
function for_scope_let() {
let a: number = 0;
for (let a = "" /* ok: local to init */; ; ) {}
}
function for_scope_var() {
var a: number = 0;
for (var a = "" /* error: string ~> number */; ; ) {}
}
function for_in_scope_let(o: Object) {
let a: number = 0;
for (let a /* ok: local to init */ in o) {
}
}
function for_in_scope_var(o: Object) {
var a: number = 0;
for (var a /* error: string ~> number */ in o) {
}
}
function for_of_scope_let(xs: string[]) {
let a: number = 0;
for (let a /* ok: local to init */ of xs) {
}
}
function for_of_scope_var(xs: string[]) {
var a: number = 0;
for (var a /* error: string ~> number */ of xs) {
}
}
function default_param_1() {
// function binding in scope in default expr
function f(
x: () => string = f // error: number ~> string
): number {
return 0;
}
}
function default_param_2() {
// fn body bindings not visible from param scope
let a = "";
function f0(x = () => a): number {
let a = 0;
return x(); // error: string ~> number
}
function f1(x = b /* error: cannot resolve b */): number {
let b = 0;
return x;
}
}
`;
exports[`tdz.js 1`] = `
/** @flow */
// -- types ---
// type aliases are hoisted and always available
type T1 = T2; // ok
type T2 = number;
// --- lets ---
// to be correct, we would
// - not allow forward refs to lets from value positions,
// while let is in TDZ.
// - allow forward refs to lets from type positions.
//
// currently we're too lenient about TDZ in closures -
// from value positions, we currently enforce TDZ only in-scope.
// this is unsound - a let or const may remain uninitialized when
// a lambda runs. But a simple conservative approach would prohibit
// forward references to let/consts from within lambdas entirely,
// which would be annoying. TODO
function f0() {
var v = x * c; // errors, let + const referenced before decl
let x = 0;
const c = 0;
}
function f1(b) {
x = 10; // error, attempt to write to let before decl
let x = 0;
if (b) {
y = 10; // error, attempt to write to let before decl
let y = 0;
}
}
function f2() {
{
var v = x * c; // errors, let + const referenced before decl
}
let x = 0;
const c = 0;
}
// functions are let-scoped and hoisted
function f3() {
var s: string = foo(); // ok, finds hoisted outer
{
var n: number = foo(); // ok, finds hoisted inner
function foo() { return 0; }
}
var s2: string = foo(); // ok, hoisted outer not clobbered
function foo() { return ""; }
}
// out-of-scope TDZ not enforced. sometimes right...
function f4() {
function g() { return x + c; } // ok, g doesn't run in TDZ
let x = 0;
const c = 0;
}
// ...sometimes wrong
function f5() {
function g() { return x; }
g(); // should error, but doesn't currently
let x = 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; // ok
var y = new C(); // error: let ref before decl from value position
class 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; // not an error per se - only if used before init
function f(n: number) { return n; }
f(a); // error: undefined ~/> number
a = 10;
f(a); // ok, a: number (not ?number)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/** @flow */
// -- types ---
// type aliases are hoisted and always available
type T1 = T2; // ok
type T2 = number;
// --- lets ---
// to be correct, we would
// - not allow forward refs to lets from value positions,
// while let is in TDZ.
// - allow forward refs to lets from type positions.
//
// currently we're too lenient about TDZ in closures -
// from value positions, we currently enforce TDZ only in-scope.
// this is unsound - a let or const may remain uninitialized when
// a lambda runs. But a simple conservative approach would prohibit
// forward references to let/consts from within lambdas entirely,
// which would be annoying. TODO
function f0() {
var v = x * c; // errors, let + const referenced before decl
let x = 0;
const c = 0;
}
function f1(b) {
x = 10; // error, attempt to write to let before decl
let x = 0;
if (b) {
y = 10; // error, attempt to write to let before decl
let y = 0;
}
}
function f2() {
{
var v = x * c; // errors, let + const referenced before decl
}
let x = 0;
const c = 0;
}
// functions are let-scoped and hoisted
function f3() {
var s: string = foo(); // ok, finds hoisted outer
{
var n: number = foo(); // ok, finds hoisted inner
function foo() {
return 0;
}
}
var s2: string = foo(); // ok, hoisted outer not clobbered
function foo() {
return "";
}
}
// out-of-scope TDZ not enforced. sometimes right...
function f4() {
function g() {
return x + c;
} // ok, g doesn't run in TDZ
let x = 0;
const c = 0;
}
// ...sometimes wrong
function f5() {
function g() {
return x;
}
g(); // should error, but doesn't currently
let x = 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; // ok
var y = new C(); // error: let ref before decl from value position
class 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; // not an error per se - only if used before init
function f(n: number) {
return n;
}
f(a); // error: undefined ~/> number
a = 10;
f(a); // ok, a: number (not ?number)
`;