From 0a9f136d5f21a4b5a9e02144570ef472a313ce9f Mon Sep 17 00:00:00 2001 From: Mauro Bringolf Date: Tue, 9 Jan 2018 06:49:05 +0100 Subject: [PATCH] Minor improvements to block-scoping/tdz (#6782) * Add test case for simple reference in tdz * Add more examples from old issues as test cases * Fix two testcases by excluding function declarations from being tdz checked * Document the option for block-scoping * Add test cases with destructuring assignments * Remove failing test cases * [skip ci] Include type and default value for options --- .../README.md | 17 ++++++++++++++++- .../src/tdz.js | 2 ++ .../tdz/block-ref-function-call/exec.js | 3 +++ .../tdz/block-ref-function-call/options.json | 3 +++ .../tdz/destructured-self-reference/exec.js | 1 + .../destructured-self-reference/options.json | 3 +++ .../fixtures/tdz/function-call-no-throw/exec.js | 5 +++++ .../test/fixtures/tdz/hoisted-function/exec.js | 3 +++ .../test/fixtures/tdz/hoisted-var/exec.js | 3 +++ .../test/fixtures/tdz/options.json | 3 +++ .../test/fixtures/tdz/self-reference/exec.js | 1 + .../fixtures/tdz/self-reference/options.json | 3 +++ .../test/fixtures/tdz/shadow-outer-var/exec.js | 3 +++ .../fixtures/tdz/shadow-outer-var/options.json | 3 +++ .../test/fixtures/tdz/simple-reference/exec.js | 2 ++ .../fixtures/tdz/simple-reference/options.json | 3 +++ 16 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/block-ref-function-call/exec.js create mode 100644 packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/block-ref-function-call/options.json create mode 100644 packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/destructured-self-reference/exec.js create mode 100644 packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/destructured-self-reference/options.json create mode 100644 packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/function-call-no-throw/exec.js create mode 100644 packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/hoisted-function/exec.js create mode 100644 packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/hoisted-var/exec.js create mode 100644 packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/options.json create mode 100644 packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/self-reference/exec.js create mode 100644 packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/self-reference/options.json create mode 100644 packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/shadow-outer-var/exec.js create mode 100644 packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/shadow-outer-var/options.json create mode 100644 packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/simple-reference/exec.js create mode 100644 packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/simple-reference/options.json diff --git a/packages/babel-plugin-transform-block-scoping/README.md b/packages/babel-plugin-transform-block-scoping/README.md index 75cd06e402..6cf9ed416e 100644 --- a/packages/babel-plugin-transform-block-scoping/README.md +++ b/packages/babel-plugin-transform-block-scoping/README.md @@ -70,7 +70,10 @@ require("@babel/core").transform("code", { }); ``` -## Options `throwIfClosureRequired` +## Options + +### `throwIfClosureRequired` +`boolean`, defaults to `false`. In cases such as the following it's impossible to rewrite let/const without adding an additional function and closure while transforming: @@ -81,3 +84,15 @@ for (let i = 0; i < 5; i++) { ``` In extremely performance-sensitive code, this can be undesirable. If `"throwIfClosureRequired": true` is set, Babel throws when transforming these patterns instead of automatically adding an additional function. + +### `tdz` +`boolean`, defaults to `false`. + +By default this plugin will ignore the *temporal dead zone (TDZ)* for block-scoped variables. The following code will **not throw an error when transpiled with Babel, which is not spec compliant**: + +```javascript +i +let i; +``` + +If you need these errors you can tell Babel to try and find them by setting `"tdz": true` for this plugin. However, the current implementation might not get all edge cases right and its best to just avoid code like this in the first place. diff --git a/packages/babel-plugin-transform-block-scoping/src/tdz.js b/packages/babel-plugin-transform-block-scoping/src/tdz.js index b880945b61..e142351348 100644 --- a/packages/babel-plugin-transform-block-scoping/src/tdz.js +++ b/packages/babel-plugin-transform-block-scoping/src/tdz.js @@ -38,6 +38,8 @@ export const visitor = { const bindingPath = scope.getBinding(node.name).path; + if (bindingPath.isFunctionDeclaration()) return; + const status = getTDZStatus(path, bindingPath); if (status === "inside") return; diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/block-ref-function-call/exec.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/block-ref-function-call/exec.js new file mode 100644 index 0000000000..f62c4127af --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/block-ref-function-call/exec.js @@ -0,0 +1,3 @@ +f(); + +const f = function f() {} diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/block-ref-function-call/options.json b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/block-ref-function-call/options.json new file mode 100644 index 0000000000..d121887b64 --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/block-ref-function-call/options.json @@ -0,0 +1,3 @@ +{ + "throws": "f is not defined - temporal dead zone" +} diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/destructured-self-reference/exec.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/destructured-self-reference/exec.js new file mode 100644 index 0000000000..166d7445f1 --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/destructured-self-reference/exec.js @@ -0,0 +1 @@ +let { b: d } = { d } diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/destructured-self-reference/options.json b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/destructured-self-reference/options.json new file mode 100644 index 0000000000..3aaa2434ab --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/destructured-self-reference/options.json @@ -0,0 +1,3 @@ +{ + "throws": "d is not defined - temporal dead zone" +} diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/function-call-no-throw/exec.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/function-call-no-throw/exec.js new file mode 100644 index 0000000000..695b365281 --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/function-call-no-throw/exec.js @@ -0,0 +1,5 @@ +function f() { + x; +} +let x; +f(); diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/hoisted-function/exec.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/hoisted-function/exec.js new file mode 100644 index 0000000000..4f5fd20257 --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/hoisted-function/exec.js @@ -0,0 +1,3 @@ +f(); + +function f() {} diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/hoisted-var/exec.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/hoisted-var/exec.js new file mode 100644 index 0000000000..4c3aa2b2fe --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/hoisted-var/exec.js @@ -0,0 +1,3 @@ +x = 3; + +var x; diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/options.json b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/options.json new file mode 100644 index 0000000000..e2bba884ad --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["transform-block-scoping",{"tdz": true}]] +} diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/self-reference/exec.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/self-reference/exec.js new file mode 100644 index 0000000000..29ade8c5aa --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/self-reference/exec.js @@ -0,0 +1 @@ +let x = x; diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/self-reference/options.json b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/self-reference/options.json new file mode 100644 index 0000000000..1ed16a0c18 --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/self-reference/options.json @@ -0,0 +1,3 @@ +{ + "throws": "x is not defined - temporal dead zone" +} diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/shadow-outer-var/exec.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/shadow-outer-var/exec.js new file mode 100644 index 0000000000..88558f3540 --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/shadow-outer-var/exec.js @@ -0,0 +1,3 @@ +var a = 5; +if (a){ console.log(a); let a = 2; } +console.log(a); diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/shadow-outer-var/options.json b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/shadow-outer-var/options.json new file mode 100644 index 0000000000..57b4f10104 --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/shadow-outer-var/options.json @@ -0,0 +1,3 @@ +{ + "throws": "a is not defined - temporal dead zone" +} diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/simple-reference/exec.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/simple-reference/exec.js new file mode 100644 index 0000000000..99758d9963 --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/simple-reference/exec.js @@ -0,0 +1,2 @@ +i +let i diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/simple-reference/options.json b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/simple-reference/options.json new file mode 100644 index 0000000000..8a451235db --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/tdz/simple-reference/options.json @@ -0,0 +1,3 @@ +{ + "throws": "i is not defined - temporal dead zone" +}