Files
test-repo/tests/binding/tdz.js
T
Christopher Chedeau cf45afba61 Add testing
- This brings in the flow test suite that contains a ton of JavaScript parsing edge cases
- This creates snapshot tests using the pretty printer for all of them
- If uncomment `RUN_AST_TESTS` line in `tests/run_specs.js`, it checks ast(pretty_print(x)) == ast(x). Right now, "178 failed, 197 passed, 375 of 377 total". So half of the tests are not passing, most of them are crashes and many of the rest are subtle issues.
2016-12-23 19:51:53 +00:00

101 lines
2.3 KiB
JavaScript

/** @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)