Fix annex B block function hoisting semantics (#12512)
This commit is contained in:
parent
70fa1b3d49
commit
bfb51362c7
@ -338,6 +338,18 @@ const loopVisitor = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function isStrict(path) {
|
||||||
|
return !!path.find(({ node }) => {
|
||||||
|
if (t.isProgram(node)) {
|
||||||
|
if (node.sourceType === "module") return true;
|
||||||
|
} else if (!t.isBlockStatement(node)) return false;
|
||||||
|
|
||||||
|
return node.directives.some(
|
||||||
|
directive => directive.value.value === "use strict",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
class BlockScoping {
|
class BlockScoping {
|
||||||
constructor(
|
constructor(
|
||||||
loopPath?: NodePath,
|
loopPath?: NodePath,
|
||||||
@ -486,7 +498,10 @@ class BlockScoping {
|
|||||||
const parentBinding = scope.parent.getOwnBinding(key);
|
const parentBinding = scope.parent.getOwnBinding(key);
|
||||||
if (
|
if (
|
||||||
binding.kind === "hoisted" &&
|
binding.kind === "hoisted" &&
|
||||||
(!parentBinding || isVar(parentBinding.path.parent))
|
!binding.path.node.async &&
|
||||||
|
!binding.path.node.generator &&
|
||||||
|
(!parentBinding || isVar(parentBinding.path.parent)) &&
|
||||||
|
!isStrict(binding.path.parentPath)
|
||||||
) {
|
) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,16 @@
|
|||||||
|
// NOTE: When compiling async generators,
|
||||||
|
// we run the async-generator-functions transform
|
||||||
|
// as soon as in Program:enter, so when the block-scoping plugin
|
||||||
|
// runs it has already been transpiled to a plain function.
|
||||||
|
// The functions is thus visible to the outer scope.
|
||||||
|
// This is a bug.
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
async function* run() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
return run();
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
// NOTE: When compiling async generators,
|
||||||
|
// we run the async-generator-functions transform
|
||||||
|
// as soon as in Program:enter, so when the block-scoping plugin
|
||||||
|
// runs it has already been transpiled to a plain function.
|
||||||
|
// The functions is thus visible to the outer scope.
|
||||||
|
// This is a bug.
|
||||||
|
if (true) {
|
||||||
|
var _run = async function* () {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
return run();
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
if (true) {
|
||||||
|
async function run() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
return run();
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"plugins": [
|
||||||
|
"transform-block-scoping",
|
||||||
|
"transform-block-scoped-functions",
|
||||||
|
"transform-async-to-generator"
|
||||||
|
]
|
||||||
|
}
|
||||||
19
packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-async/output.js
vendored
Normal file
19
packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-async/output.js
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
||||||
|
|
||||||
|
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
var _run = /*#__PURE__*/function () {
|
||||||
|
var _ref = _asyncToGenerator(function* () {
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
return function _run() {
|
||||||
|
return _ref.apply(this, arguments);
|
||||||
|
};
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
return run();
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
if (true) {
|
||||||
|
function* run() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
return run();
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"plugins": [
|
||||||
|
"transform-block-scoping",
|
||||||
|
"transform-block-scoped-functions",
|
||||||
|
"transform-regenerator"
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
if (true) {
|
||||||
|
var _run = /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
|
||||||
|
return regeneratorRuntime.wrap(function _callee$(_context) {
|
||||||
|
while (1) {
|
||||||
|
switch (_context.prev = _context.next) {
|
||||||
|
case 0:
|
||||||
|
return _context.abrupt("return", true);
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
case "end":
|
||||||
|
return _context.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, _callee);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
return run();
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
if (true) {
|
||||||
|
function run() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
return run();
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
if (true) {
|
||||||
|
var _run = function () {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
return run();
|
||||||
|
}
|
||||||
11
packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-strict/input.js
vendored
Normal file
11
packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-strict/input.js
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
function run() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
return run();
|
||||||
|
}
|
||||||
11
packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-strict/output.js
vendored
Normal file
11
packages/babel-plugin-transform-block-scoping/test/fixtures/general/issue-10046-strict/output.js
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
var _run = function () {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
return run();
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user