diff options
Diffstat (limited to 'node_modules/@babel/preset-modules/src')
8 files changed, 397 insertions, 0 deletions
diff --git a/node_modules/@babel/preset-modules/src/index.js b/node_modules/@babel/preset-modules/src/index.js new file mode 100644 index 00000000..d2139897 --- /dev/null +++ b/node_modules/@babel/preset-modules/src/index.js @@ -0,0 +1,26 @@ +import path from "path"; +import { declare } from "@babel/helper-plugin-utils"; + +/** + * @babel/preset-modules produces clean, minimal output for ES Modules-supporting browsers. + * @param {Object} [options] + * @param {boolean} [options.loose=false] Loose mode skips seldom-needed transforms that increase output size. + */ +export default declare((api, opts) => { + api.assertVersion(7); + + const loose = opts.loose === true; + + return { + plugins: [ + path.resolve(__dirname, "./plugins/transform-edge-default-parameters"), + path.resolve(__dirname, "./plugins/transform-tagged-template-caching"), + path.resolve(__dirname, "./plugins/transform-jsx-spread"), + path.resolve(__dirname, "./plugins/transform-safari-for-shadowing"), + path.resolve(__dirname, "./plugins/transform-safari-block-shadowing"), + path.resolve(__dirname, "./plugins/transform-async-arrows-in-class"), + !loose && + path.resolve(__dirname, "./plugins/transform-edge-function-name"), + ].filter(Boolean), + }; +}); diff --git a/node_modules/@babel/preset-modules/src/plugins/transform-async-arrows-in-class/index.js b/node_modules/@babel/preset-modules/src/plugins/transform-async-arrows-in-class/index.js new file mode 100644 index 00000000..b0594777 --- /dev/null +++ b/node_modules/@babel/preset-modules/src/plugins/transform-async-arrows-in-class/index.js @@ -0,0 +1,35 @@ +/** + * Safari 10.3 had an issue where async arrow function expressions within any class method would throw. + * After an initial fix, any references to the instance via `this` within those methods would also throw. + * This is fixed by converting arrow functions in class methods into equivalent function expressions. + * @see https://bugs.webkit.org/show_bug.cgi?id=166879 + * + * @example + * class X{ a(){ async () => {}; } } // throws + * class X{ a(){ async function() {}; } } // works + * + * @example + * class X{ a(){ + * async () => this.a; // throws + * } } + * class X{ a(){ + * var _this=this; + * async function() { return _this.a }; // works + * } } + */ + +const OPTS = { + allowInsertArrow: false, + specCompliant: false, +}; + +export default ({ types: t }) => ({ + name: "transform-async-arrows-in-class", + visitor: { + ArrowFunctionExpression(path) { + if (path.node.async && path.findParent(t.isClassMethod)) { + path.arrowFunctionToExpression(OPTS); + } + }, + }, +}); diff --git a/node_modules/@babel/preset-modules/src/plugins/transform-edge-default-parameters/index.js b/node_modules/@babel/preset-modules/src/plugins/transform-edge-default-parameters/index.js new file mode 100644 index 00000000..fff50f19 --- /dev/null +++ b/node_modules/@babel/preset-modules/src/plugins/transform-edge-default-parameters/index.js @@ -0,0 +1,29 @@ +/** + * Converts destructured parameters with default values to non-shorthand syntax. + * This fixes the only arguments-related bug in ES Modules-supporting browsers (Edge 16 & 17). + * Use this plugin instead of @babel/plugin-transform-parameters when targeting ES Modules. + */ + +export default ({ types: t }) => { + const isArrowParent = p => + p.parentKey === "params" && + p.parentPath && + t.isArrowFunctionExpression(p.parentPath); + + return { + name: "transform-edge-default-parameters", + visitor: { + AssignmentPattern(path) { + const arrowArgParent = path.find(isArrowParent); + if (arrowArgParent && path.parent.shorthand) { + // In Babel 7+, there is no way to force non-shorthand properties. + path.parent.shorthand = false; + (path.parent.extra || {}).shorthand = false; + + // So, to ensure non-shorthand, rename the local identifier so it no longer matches: + path.scope.rename(path.parent.key.name); + } + }, + }, + }; +}; diff --git a/node_modules/@babel/preset-modules/src/plugins/transform-edge-function-name/index.js b/node_modules/@babel/preset-modules/src/plugins/transform-edge-function-name/index.js new file mode 100644 index 00000000..f6873283 --- /dev/null +++ b/node_modules/@babel/preset-modules/src/plugins/transform-edge-function-name/index.js @@ -0,0 +1,31 @@ +/** + * Edge 16 & 17 do not infer function.name from variable assignment. + * All other `function.name` behavior works fine, so we can skip most of @babel/transform-function-name. + * @see https://kangax.github.io/compat-table/es6/#test-function_name_property_variables_(function) + * + * Note: contrary to various Github issues, Edge 16+ *does* correctly infer the name of Arrow Functions. + * The variable declarator name inference issue only affects function expressions, so that's all we fix here. + * + * A Note on Minification: Terser undoes this transform *by default* unless `keep_fnames` is set to true. + * There is by design - if Function.name is critical to your application, you must configure + * your minifier to preserve function names. + */ + +export default ({ types: t }) => ({ + name: "transform-edge-function-name", + visitor: { + FunctionExpression: { + exit(path) { + if (!path.node.id && t.isIdentifier(path.parent.id)) { + const id = t.cloneNode(path.parent.id); + const binding = path.scope.getBinding(id.name); + // if the binding gets reassigned anywhere, rename it + if (binding?.constantViolations.length) { + path.scope.rename(id.name); + } + path.node.id = id; + } + }, + }, + }, +}); diff --git a/node_modules/@babel/preset-modules/src/plugins/transform-jsx-spread/index.js b/node_modules/@babel/preset-modules/src/plugins/transform-jsx-spread/index.js new file mode 100644 index 00000000..ef015245 --- /dev/null +++ b/node_modules/@babel/preset-modules/src/plugins/transform-jsx-spread/index.js @@ -0,0 +1,111 @@ +import esutils from "esutils"; + +/** + * Converts JSX Spread arguments into Object Spread, avoiding Babel's helper or Object.assign injection. + * Input: + * <div a="1" {...b} /> + * Output: + * <div {...{ a: "1", ...b }} /> + * ...which Babel converts to: + * h("div", { a: "1", ...b }) + */ +export default ({ types: t }) => { + // converts a set of JSXAttributes to an Object.assign() call + function convertAttributesAssign(attributes) { + const args = []; + for (let i = 0, current; i < attributes.length; i++) { + const node = attributes[i]; + if (t.isJSXSpreadAttribute(node)) { + // the first attribute is a spread, avoid copying all other attributes onto it + if (i === 0) { + args.push(t.objectExpression([])); + } + current = null; + args.push(node.argument); + } else { + const name = getAttributeName(node); + const value = getAttributeValue(node); + if (!current) { + current = t.objectExpression([]); + args.push(current); + } + current.properties.push(t.objectProperty(name, value)); + } + } + return t.callExpression( + t.memberExpression(t.identifier("Object"), t.identifier("assign")), + args + ); + } + + // Converts a JSXAttribute to the equivalent ObjectExpression property + function convertAttributeSpread(node) { + if (t.isJSXSpreadAttribute(node)) { + return t.spreadElement(node.argument); + } + + const name = getAttributeName(node); + const value = getAttributeValue(node); + return t.inherits(t.objectProperty(name, value), node); + } + + // Convert a JSX attribute name to an Object expression property name + function getAttributeName(node) { + if (t.isJSXNamespacedName(node.name)) { + return t.stringLiteral( + node.name.namespace.name + ":" + node.name.name.name + ); + } + if (esutils.keyword.isIdentifierNameES6(node.name.name)) { + return t.identifier(node.name.name); + } + return t.stringLiteral(node.name.name); + } + + // Convert a JSX attribute value to a JavaScript expression value + function getAttributeValue(node) { + let value = node.value || t.booleanLiteral(true); + + if (t.isJSXExpressionContainer(value)) { + value = value.expression; + } else if (t.isStringLiteral(value)) { + value.value = value.value.replace(/\n\s+/g, " "); + + // "raw" JSXText should not be used from a StringLiteral because it needs to be escaped. + if (value.extra && value.extra.raw) { + delete value.extra.raw; + } + } + + return value; + } + + return { + name: "transform-jsx-spread", + visitor: { + JSXOpeningElement(path, state) { + const useSpread = state.opts.useSpread === true; + const hasSpread = path.node.attributes.some(attr => + t.isJSXSpreadAttribute(attr) + ); + + // ignore JSX Elements without spread or with lone spread: + if (!hasSpread || path.node.attributes.length === 1) return; + + if (useSpread) { + path.node.attributes = [ + t.jsxSpreadAttribute( + t.objectExpression( + path.node.attributes.map(convertAttributeSpread) + ) + ), + ]; + } else { + path.node.attributes = [ + t.jsxSpreadAttribute(convertAttributesAssign(path.node.attributes)), + ]; + } + }, + }, + }; +}; diff --git a/node_modules/@babel/preset-modules/src/plugins/transform-safari-block-shadowing/index.js b/node_modules/@babel/preset-modules/src/plugins/transform-safari-block-shadowing/index.js new file mode 100644 index 00000000..f509c6b6 --- /dev/null +++ b/node_modules/@babel/preset-modules/src/plugins/transform-safari-block-shadowing/index.js @@ -0,0 +1,39 @@ +/** + * Fixes block-shadowed let/const bindings in Safari 10/11. + * https://kangax.github.io/compat-table/es6/#test-let_scope_shadow_resolution + */ +export default function({ types: t }) { + return { + name: "transform-safari-block-shadowing", + visitor: { + VariableDeclarator(path) { + // the issue only affects let and const bindings: + const kind = path.parent.kind; + if (kind !== "let" && kind !== "const") return; + + // ignore non-block-scoped bindings: + const block = path.scope.block; + if (t.isFunction(block) || t.isProgram(block)) return; + + const bindings = t.getOuterBindingIdentifiers(path.node.id); + for (const name of Object.keys(bindings)) { + let scope = path.scope; + + // ignore parent bindings (note: impossible due to let/const?) + if (!scope.hasOwnBinding(name)) continue; + + // check if shadowed within the nearest function/program boundary + while ((scope = scope.parent)) { + if (scope.hasOwnBinding(name)) { + path.scope.rename(name); + break; + } + if (t.isFunction(scope.block) || t.isProgram(scope.block)) { + break; + } + } + } + }, + }, + }; +} diff --git a/node_modules/@babel/preset-modules/src/plugins/transform-safari-for-shadowing/index.js b/node_modules/@babel/preset-modules/src/plugins/transform-safari-for-shadowing/index.js new file mode 100644 index 00000000..83b4eafd --- /dev/null +++ b/node_modules/@babel/preset-modules/src/plugins/transform-safari-for-shadowing/index.js @@ -0,0 +1,38 @@ +/** + * Safari ~11 has an issue where variable declarations in a For statement throw if they shadow parameters. + * This is fixed by renaming any declarations in the left/init part of a For* statement so they don't shadow. + * @see https://bugs.webkit.org/show_bug.cgi?id=171041 + * + * @example + * e => { for (let e of []) e } // throws + * e => { for (let _e of []) _e } // works + */ + +function handle(declaration) { + if (!declaration.isVariableDeclaration()) return; + + const fn = declaration.getFunctionParent(); + const { name } = declaration.node.declarations[0].id; + + // check if there is a shadowed binding coming from a parameter + if ( + fn && + fn.scope.hasOwnBinding(name) && + fn.scope.getOwnBinding(name).kind === "param" + ) { + declaration.scope.rename(name); + } +} + +export default () => ({ + name: "transform-safari-for-shadowing", + visitor: { + ForXStatement(path) { + handle(path.get("left")); + }, + + ForStatement(path) { + handle(path.get("init")); + }, + }, +}); diff --git a/node_modules/@babel/preset-modules/src/plugins/transform-tagged-template-caching/index.js b/node_modules/@babel/preset-modules/src/plugins/transform-tagged-template-caching/index.js new file mode 100644 index 00000000..65d03999 --- /dev/null +++ b/node_modules/@babel/preset-modules/src/plugins/transform-tagged-template-caching/index.js @@ -0,0 +1,88 @@ +/** + * Converts destructured parameters with default values to non-shorthand syntax. + * This fixes the only Tagged Templates-related bug in ES Modules-supporting browsers (Safari 10 & 11). + * Use this plugin instead of `@babel/plugin-transform-template-literals` when targeting ES Modules. + * + * @example + * // Bug 1: Safari 10/11 doesn't reliably return the same Strings value. + * // The value changes depending on invocation and function optimization state. + * function f() { return Object`` } + * f() === new f() // false, should be true. + * + * @example + * // Bug 2: Safari 10/11 use the same cached strings value when the string parts are the same. + * // This behavior comes from an earlier version of the spec, and can cause tricky bugs. + * Object``===Object`` // true, should be false. + * + * Benchmarks: https://jsperf.com/compiled-tagged-template-performance + */ +export default ({ types: t }) => ({ + name: "transform-tagged-template-caching", + visitor: { + TaggedTemplateExpression(path, state) { + // tagged templates we've already dealt with + let processed = state.get("processed"); + if (!processed) { + processed = new WeakSet(); + state.set("processed", processed); + } + + if (processed.has(path.node)) return path.skip(); + + // Grab the expressions from the original tag. + // tag`a${'hello'}` // ['hello'] + const expressions = path.node.quasi.expressions; + + // Create an identity function helper: + // identity = t => t + let identity = state.get("identity"); + if (!identity) { + identity = path.scope + .getProgramParent() + .generateDeclaredUidIdentifier("_"); + state.set("identity", identity); + const binding = path.scope.getBinding(identity.name); + binding.path.get("init").replaceWith( + t.arrowFunctionExpression( + // re-use the helper identifier for compressability + [t.identifier("t")], + t.identifier("t") + ) + ); + } + + // Use the identity function helper to get a reference to the template's Strings. + // We replace all expressions with `0` ensure Strings has the same shape. + // identity`a${0}` + const template = t.taggedTemplateExpression( + t.cloneNode(identity), + t.templateLiteral( + path.node.quasi.quasis, + expressions.map(() => t.numericLiteral(0)) + ) + ); + processed.add(template); + + // Install an inline cache at the callsite using the global variable: + // _t || (_t = identity`a${0}`) + const ident = path.scope + .getProgramParent() + .generateDeclaredUidIdentifier("t"); + path.scope.getBinding(ident.name).path.parent.kind = "let"; + const inlineCache = t.logicalExpression( + "||", + ident, + t.assignmentExpression("=", t.cloneNode(ident), template) + ); + + // The original tag function becomes a plain function call. + // The expressions omitted from the cached Strings tag are directly applied as arguments. + // tag(_t || (_t = Object`a${0}`), 'hello') + const node = t.callExpression(path.node.tag, [ + inlineCache, + ...expressions, + ]); + path.replaceWith(node); + }, + }, +}); |
