diff --git a/packages/babel-plugin-transform-block-scoping/src/annex-B_3_3.ts b/packages/babel-plugin-transform-block-scoping/src/annex-B_3_3.ts index 79ac2cb0200b..346c1bdcbc74 100644 --- a/packages/babel-plugin-transform-block-scoping/src/annex-B_3_3.ts +++ b/packages/babel-plugin-transform-block-scoping/src/annex-B_3_3.ts @@ -51,6 +51,8 @@ export const annexB33FunctionsVisitor: Visitor = { function transformStatementList(paths: NodePath[]) { outer: for (const path of paths) { if (!path.isFunctionDeclaration()) continue; + // Annex B.3.3 only applies to plain functions. + if (path.node.async || path.node.generator) return; const { scope } = path.parentPath; if (isVarScope(scope)) return; @@ -74,9 +76,6 @@ function maybeTransformBlockScopedFunction( parentPath: { scope }, } = path; - // Annex B.3.3 only applies to plain functions. - if (node.async || node.generator) return; - const { id } = node; scope.removeOwnBinding(id.name); node.id = null; @@ -115,7 +114,11 @@ function isStrict(path: NodePath) { return !!path.find(({ node }) => { if (t.isProgram(node)) { if (node.sourceType === "module") return true; - } else if (!t.isBlockStatement(node)) return false; + } else if (t.isClass(node)) { + return true; + } else if (!t.isBlockStatement(node)) { + return false; + } return node.directives?.some( directive => directive.value.value === "use strict", diff --git a/packages/babel-plugin-transform-block-scoping/src/index.ts b/packages/babel-plugin-transform-block-scoping/src/index.ts index 9f664f3efc2f..9b578fcf5409 100644 --- a/packages/babel-plugin-transform-block-scoping/src/index.ts +++ b/packages/babel-plugin-transform-block-scoping/src/index.ts @@ -93,7 +93,7 @@ export default declare((api, opts: Options) => { if (headPath?.isVariableDeclaration()) { // If we wrap the loop body, we transform the var - // declaration in the loop head now, to avoid having + // declaration in the loop head now, to avoid // invalid references that break other plugins: // // for (let head of x) { diff --git a/packages/babel-plugin-transform-block-scoping/src/loop.ts b/packages/babel-plugin-transform-block-scoping/src/loop.ts index 3a1b27084781..05c5908e631d 100644 --- a/packages/babel-plugin-transform-block-scoping/src/loop.ts +++ b/packages/babel-plugin-transform-block-scoping/src/loop.ts @@ -75,7 +75,7 @@ function relativeLoopLocation(path: NodePath, loopPath: NodePath) { let inClosure = false; for (let currPath = path; currPath; currPath = currPath.parentPath) { - if (currPath.isFunction()) inClosure = true; + if (currPath.isFunction() || currPath.isClass()) inClosure = true; if (currPath === bodyPath) { return { inBody: true, inClosure }; } else if (currPath === loopPath) { diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-async-generator/input.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-async-generator/input.js similarity index 100% rename from packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-async-generator/input.js rename to packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-async-generator/input.js diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-async-generator/output.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-async-generator/output.js similarity index 100% rename from packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-async-generator/output.js rename to packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-async-generator/output.js diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-async/input.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-async/input.js similarity index 100% rename from packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-async/input.js rename to packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-async/input.js diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-async/options.json b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-async/options.json similarity index 100% rename from packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-async/options.json rename to packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-async/options.json diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-async/output.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-async/output.js similarity index 100% rename from packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-async/output.js rename to packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-async/output.js diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-collision-const/input.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-collision-const/input.js similarity index 100% rename from packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-collision-const/input.js rename to packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-collision-const/input.js diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-collision-const/output.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-collision-const/output.js similarity index 100% rename from packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-collision-const/output.js rename to packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-collision-const/output.js diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-collision-let/input.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-collision-let/input.js similarity index 100% rename from packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-collision-let/input.js rename to packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-collision-let/input.js diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-collision-let/output.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-collision-let/output.js similarity index 100% rename from packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-collision-let/output.js rename to packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-collision-let/output.js diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-collision-var/input.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-collision-var/input.js similarity index 100% rename from packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-collision-var/input.js rename to packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-collision-var/input.js diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-collision-var/output.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-collision-var/output.js similarity index 100% rename from packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-collision-var/output.js rename to packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-collision-var/output.js diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-generator/input.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-generator/input.js similarity index 100% rename from packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-generator/input.js rename to packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-generator/input.js diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-generator/options.json b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-generator/options.json similarity index 100% rename from packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-generator/options.json rename to packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-generator/options.json diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-generator/output.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-generator/output.js similarity index 100% rename from packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-generator/output.js rename to packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-generator/output.js diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-in-class/exec.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-in-class/exec.js new file mode 100644 index 000000000000..b7308d71d5a0 --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-in-class/exec.js @@ -0,0 +1,17 @@ +class A { + m() { + if (true) { + function f() { + return true; + } + } + + function g() { + return f(); + } + + return g(); + } +} + +expect(new A().m).toThrow(ReferenceError); \ No newline at end of file diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-in-class/input.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-in-class/input.js new file mode 100644 index 000000000000..b7308d71d5a0 --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-in-class/input.js @@ -0,0 +1,17 @@ +class A { + m() { + if (true) { + function f() { + return true; + } + } + + function g() { + return f(); + } + + return g(); + } +} + +expect(new A().m).toThrow(ReferenceError); \ No newline at end of file diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-in-class/output.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-in-class/output.js new file mode 100644 index 000000000000..5e870864f2b0 --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-in-class/output.js @@ -0,0 +1,14 @@ +class A { + m() { + if (true) { + var _f = function () { + return true; + }; + } + function g() { + return f(); + } + return g(); + } +} +expect(new A().m).toThrow(ReferenceError); diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-in-module-expression/input.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-in-module-expression/input.js new file mode 100644 index 000000000000..04519fd7a1ee --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-in-module-expression/input.js @@ -0,0 +1,11 @@ +const m = module { + if (true) { + function f() { + return true; + } + } + + function g() { + return f(); + } +}; diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-in-module-expression/options.json b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-in-module-expression/options.json new file mode 100644 index 000000000000..19328f031d2e --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-in-module-expression/options.json @@ -0,0 +1,7 @@ +{ + "plugins": [ + "transform-block-scoping", + "transform-block-scoped-functions", + "syntax-module-blocks" + ] +} diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-in-module-expression/output.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-in-module-expression/output.js new file mode 100644 index 000000000000..b583fee7d2fc --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-in-module-expression/output.js @@ -0,0 +1,10 @@ +var m = module { + if (true) { + var _f = function () { + return true; + }; + } + function g() { + return f(); + } +}; diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-module/input.mjs b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-module/input.mjs similarity index 100% rename from packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-module/input.mjs rename to packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-module/input.mjs diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-module/output.mjs b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-module/output.mjs similarity index 100% rename from packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-module/output.mjs rename to packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3-module/output.mjs diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046/input.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3/input.js similarity index 100% rename from packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046/input.js rename to packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3/input.js diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046/output.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3/output.js similarity index 100% rename from packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046/output.js rename to packages/babel-plugin-transform-block-scoping/test/fixtures/general/annex-B_3_3/output.js diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-strict/input.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-strict/input.js deleted file mode 100644 index 26283df2072e..000000000000 --- a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-strict/input.js +++ /dev/null @@ -1,11 +0,0 @@ -"use strict"; - -if (true) { - function run() { - return true; - } -} - -function test() { - return run(); -} diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-strict/output.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-strict/output.js deleted file mode 100644 index 6ad0f6e042a7..000000000000 --- a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-strict/output.js +++ /dev/null @@ -1,10 +0,0 @@ -"use strict"; - -if (true) { - var _run = function () { - return true; - }; -} -function test() { - return run(); -} diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/loop-closure-in-class/exec.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/loop-closure-in-class/exec.js new file mode 100644 index 000000000000..fb0aa668e016 --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/loop-closure-in-class/exec.js @@ -0,0 +1,10 @@ +let run = []; + +for (let i = 0; i < 2; i++) { + run.push(class C { + x = i; + }); +} + +expect(new run[0]().x).toBe(0); +expect(new run[1]().x).toBe(1); diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/loop-closure-in-class/input.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/loop-closure-in-class/input.js new file mode 100644 index 000000000000..f6a35700916a --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/loop-closure-in-class/input.js @@ -0,0 +1,5 @@ +for (let i = 0; i < 2; i++) { + class C { + x = i; + } +} diff --git a/packages/babel-plugin-transform-block-scoping/test/fixtures/general/loop-closure-in-class/output.js b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/loop-closure-in-class/output.js new file mode 100644 index 000000000000..54716df47a75 --- /dev/null +++ b/packages/babel-plugin-transform-block-scoping/test/fixtures/general/loop-closure-in-class/output.js @@ -0,0 +1,8 @@ +var _loop = function (i) { + class C { + x = i; + } +}; +for (var i = 0; i < 2; i++) { + _loop(i); +}