UNPKG

@babel/plugin-transform-block-scoped-functions

Version:

Babel plugin to ensure function declarations at the block level are block scoped

64 lines (61 loc) 1.95 kB
import { declare } from '@babel/helper-plugin-utils'; import { types } from '@babel/core'; const index = declare(api => { api.assertVersion("^7.0.0-0 || ^8.0.0"); function transformStatementList(parentPath, paths) { const isInStrictMode = parentPath.isInStrictMode(); for (const path of paths) { if (!path.isFunctionDeclaration()) continue; const useLet = isInStrictMode || path.node.async || path.node.generator || path.getData("@babel/plugin-transform-async-generator-functions/async_generator_function"); const func = path.node; const declar = types.variableDeclaration(useLet ? "let" : "var", [types.variableDeclarator(func.id, types.toExpression(func))]); declar._blockHoist = 2; func.id = null; path.replaceWith(declar); } } const visitor = { BlockStatement(path) { const { node, parent } = path; if (types.isFunction(parent, { body: node }) || types.isExportDeclaration(parent)) { return; } transformStatementList(path, path.get("body")); }, SwitchStatement(path) { const { node } = path; const fns = []; for (const caseNode of node.cases) { const { consequent } = caseNode; for (let i = consequent.length - 1; i >= 0; i--) { if (types.isFunctionDeclaration(consequent[i])) { fns.push(consequent[i]); consequent.splice(i, 1); } } } if (!fns.length) return; path.replaceWith(types.blockStatement([types.variableDeclaration("let", fns.map(fn => types.variableDeclarator(types.cloneNode(fn.id), types.toExpression(fn)))), node])); } }; return { name: "transform-block-scoped-functions", visitor: { ...visitor, Loop(path) { path.traverse(visitor); } } }; }); export { index as default }; //# sourceMappingURL=index.js.map