diff --git a/packages/babel-plugin-transform-async-to-module-method/src/index.js b/packages/babel-plugin-transform-async-to-module-method/src/index.js index d32f9b0a89..515fd3b354 100644 --- a/packages/babel-plugin-transform-async-to-module-method/src/index.js +++ b/packages/babel-plugin-transform-async-to-module-method/src/index.js @@ -3,7 +3,8 @@ import syntaxAsyncFunctions from "babel-plugin-syntax-async-functions"; import { addNamed } from "babel-helper-module-imports"; -export default function({ types: t }) { +export default function({ types: t }, options) { + const { method, module } = options; return { inherits: syntaxAsyncFunctions, @@ -11,8 +12,6 @@ export default function({ types: t }) { Function(path, state) { if (!path.node.async || path.node.generator) return; - const { module, method } = state.opts; - let wrapAsync = state.methodWrapper; if (wrapAsync) { wrapAsync = t.cloneDeep(wrapAsync); diff --git a/packages/babel-plugin-transform-class-properties/src/index.js b/packages/babel-plugin-transform-class-properties/src/index.js index ff16a3c73b..7fd17a62ea 100644 --- a/packages/babel-plugin-transform-class-properties/src/index.js +++ b/packages/babel-plugin-transform-class-properties/src/index.js @@ -2,7 +2,9 @@ import nameFunction from "babel-helper-function-name"; import template from "babel-template"; import syntaxClassProperties from "babel-plugin-syntax-class-properties"; -export default function({ types: t }) { +export default function({ types: t }, options) { + const { loose } = options; + const findBareSupers = { Super(path) { if (path.parentPath.isCallExpression({ callee: path.node })) { @@ -48,14 +50,15 @@ export default function({ types: t }) { ), ); + const buildClassProperty = loose + ? buildClassPropertyLoose + : buildClassPropertySpec; + return { inherits: syntaxClassProperties, visitor: { - Class(path, state) { - const buildClassProperty = state.opts.loose - ? buildClassPropertyLoose - : buildClassPropertySpec; + Class(path) { const isDerived = !!path.node.superClass; let constructor; const props = []; diff --git a/packages/babel-plugin-transform-es2015-arrow-functions/src/index.js b/packages/babel-plugin-transform-es2015-arrow-functions/src/index.js index b259ce84ce..7152af69a4 100644 --- a/packages/babel-plugin-transform-es2015-arrow-functions/src/index.js +++ b/packages/babel-plugin-transform-es2015-arrow-functions/src/index.js @@ -1,11 +1,11 @@ import type NodePath from "babel-traverse"; -export default function() { +export default function(babel, options) { + const { spec } = options; return { visitor: { ArrowFunctionExpression( path: NodePath, - state: Object, ) { // In some conversion cases, it may have already been converted to a function while this callback // was queued up. @@ -15,7 +15,7 @@ export default function() { // While other utils may be fine inserting other arrows to make more transforms possible, // the arrow transform itself absolutely cannot insert new arrow functions. allowInsertArrow: false, - specCompliant: !!state.opts.spec, + specCompliant: !!spec, }); }, }, diff --git a/packages/babel-plugin-transform-es2015-classes/src/index.js b/packages/babel-plugin-transform-es2015-classes/src/index.js index 125be035fe..001128daf3 100644 --- a/packages/babel-plugin-transform-es2015-classes/src/index.js +++ b/packages/babel-plugin-transform-es2015-classes/src/index.js @@ -3,7 +3,10 @@ import VanillaTransformer from "./vanilla"; import annotateAsPure from "babel-helper-annotate-as-pure"; import nameFunction from "babel-helper-function-name"; -export default function({ types: t }) { +export default function({ types: t }, options) { + const { loose } = options; + const Constructor = loose ? LooseTransformer : VanillaTransformer; + // todo: investigate traversal requeueing const VISITED = Symbol(); @@ -50,9 +53,6 @@ export default function({ types: t }) { node[VISITED] = true; - let Constructor = VanillaTransformer; - if (state.opts.loose) Constructor = LooseTransformer; - path.replaceWith(new Constructor(path, state.file).run()); if (path.isCallExpression()) { diff --git a/packages/babel-plugin-transform-es2015-computed-properties/src/index.js b/packages/babel-plugin-transform-es2015-computed-properties/src/index.js index ddf582c24a..a54680fdf5 100644 --- a/packages/babel-plugin-transform-es2015-computed-properties/src/index.js +++ b/packages/babel-plugin-transform-es2015-computed-properties/src/index.js @@ -1,4 +1,9 @@ -export default function({ types: t, template }) { +export default function({ types: t, template }, options) { + const { loose } = options; + const pushComputedProps = loose + ? pushComputedPropsLoose + : pushComputedPropsSpec; + const buildMutatorMapAssign = template(` MUTATOR_MAP_REF[KEY] = MUTATOR_MAP_REF[KEY] || {}; MUTATOR_MAP_REF[KEY].KIND = VALUE; @@ -62,7 +67,7 @@ export default function({ types: t, template }) { ); } - function loose(info) { + function pushComputedPropsLoose(info) { for (const prop of info.computedProps) { if (prop.kind === "get" || prop.kind === "set") { pushMutatorDefine(info, prop); @@ -72,7 +77,7 @@ export default function({ types: t, template }) { } } - function spec(info) { + function pushComputedPropsSpec(info) { const { objId, body, computedProps, state } = info; for (const prop of computedProps) { @@ -145,9 +150,6 @@ export default function({ types: t, template }) { ]), ); - let callback = spec; - if (state.opts.loose) callback = loose; - let mutatorRef; const getMutatorId = function() { @@ -164,7 +166,7 @@ export default function({ types: t, template }) { return mutatorRef; }; - const single = callback({ + const single = pushComputedProps({ scope, objId, body, diff --git a/packages/babel-plugin-transform-es2015-for-of/src/index.js b/packages/babel-plugin-transform-es2015-for-of/src/index.js index 8f1d2cc8c5..b6b1a88bbf 100644 --- a/packages/babel-plugin-transform-es2015-for-of/src/index.js +++ b/packages/babel-plugin-transform-es2015-for-of/src/index.js @@ -1,4 +1,9 @@ -export default function({ template, types: t }) { +export default function({ template, types: t }, options) { + const { loose } = options; + const pushComputedProps = loose + ? pushComputedPropsLoose + : pushComputedPropsSpec; + const buildForOfArray = template(` for (var KEY = 0; KEY < ARR.length; KEY++) BODY; `); @@ -113,11 +118,8 @@ export default function({ template, types: t }) { return; } - let callback = spec; - if (state.opts.loose) callback = loose; - const { node } = path; - const build = callback(path, state); + const build = pushComputedProps(path, state); const declar = build.declar; const loop = build.loop; const block = loop.body; @@ -146,7 +148,7 @@ export default function({ template, types: t }) { }, }; - function loose(path, file) { + function pushComputedPropsLoose(path, file) { const { node, scope, parent } = path; const { left } = node; let declar, id, intermediate; @@ -201,7 +203,7 @@ export default function({ template, types: t }) { }; } - function spec(path, file) { + function pushComputedPropsSpec(path, file) { const { node, scope, parent } = path; const left = node.left; let declar; diff --git a/packages/babel-plugin-transform-es2015-modules-amd/src/index.js b/packages/babel-plugin-transform-es2015-modules-amd/src/index.js index b549ac4204..0d9d092543 100644 --- a/packages/babel-plugin-transform-es2015-modules-amd/src/index.js +++ b/packages/babel-plugin-transform-es2015-modules-amd/src/index.js @@ -14,21 +14,14 @@ const buildWrapper = template(` }) `); -export default function({ types: t }) { +export default function({ types: t }, options) { + const { loose, allowTopLevelThis, strict, strictMode, noInterop } = options; return { visitor: { Program: { - exit(path, state) { + exit(path) { if (!isModule(path)) return; - const { - loose, - allowTopLevelThis, - strict, - strictMode, - noInterop, - } = state.opts; - let moduleName = this.getModuleName(); if (moduleName) moduleName = t.stringLiteral(moduleName); diff --git a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js index b51b288f38..3116f209b4 100644 --- a/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js +++ b/packages/babel-plugin-transform-es2015-modules-commonjs/src/index.js @@ -8,7 +8,17 @@ import { } from "babel-helper-module-transforms"; import simplifyAccess from "babel-helper-simple-access"; -export default function({ types: t, template }) { +export default function({ types: t, template }, options) { + const { + loose, + allowTopLevelThis, + strict, + strictMode, + noInterop, + + // Defaulting to 'true' for now. May change before 7.x major. + allowCommonJSExports = true, + } = options; const moduleAssertion = template(` (function(){ throw new Error("The CommonJS 'module' variable is not available in ES6 modules."); @@ -85,22 +95,11 @@ export default function({ types: t, template }) { return { visitor: { Program: { - exit(path, state) { + exit(path) { // For now this requires unambiguous rather that just sourceType // because Babel currently parses all files as sourceType:module. if (!isModule(path, true /* requireUnambiguous */)) return; - const { - loose, - allowTopLevelThis, - strict, - strictMode, - noInterop, - - // Defaulting to 'true' for now. May change before 7.x major. - allowCommonJSExports = true, - } = state.opts; - // Rename the bindings auto-injected into the scope so there is no // risk of conflict between the bindings. path.scope.rename("exports"); diff --git a/packages/babel-plugin-transform-es2015-modules-systemjs/src/index.js b/packages/babel-plugin-transform-es2015-modules-systemjs/src/index.js index 9b04dfff3b..4738cb9f06 100644 --- a/packages/babel-plugin-transform-es2015-modules-systemjs/src/index.js +++ b/packages/babel-plugin-transform-es2015-modules-systemjs/src/index.js @@ -22,7 +22,8 @@ const buildExportAll = template(` const TYPE_IMPORT = "Import"; -export default function({ types: t }) { +export default function({ types: t }, options) { + const { systemGlobal = "System" } = options; const IGNORE_REASSIGNMENT_SYMBOL = Symbol(); const reassignmentVisitor = { @@ -359,7 +360,7 @@ export default function({ types: t }) { path.node.body = [ buildTemplate({ SYSTEM_REGISTER: t.memberExpression( - t.identifier(state.opts.systemGlobal || "System"), + t.identifier(systemGlobal), t.identifier("register"), ), BEFORE_BODY: beforeBody, diff --git a/packages/babel-plugin-transform-es2015-modules-umd/src/index.js b/packages/babel-plugin-transform-es2015-modules-umd/src/index.js index c984cb53e7..4b79fd0385 100644 --- a/packages/babel-plugin-transform-es2015-modules-umd/src/index.js +++ b/packages/babel-plugin-transform-es2015-modules-umd/src/index.js @@ -30,7 +30,17 @@ const buildWrapper = template(` }) `); -export default function({ types: t }) { +export default function({ types: t }, options) { + const { + globals, + exactGlobals, + loose, + allowTopLevelThis, + strict, + strictMode, + noInterop, + } = options; + /** * Build the assignment statements that initialize the UMD global. */ @@ -107,18 +117,9 @@ export default function({ types: t }) { return { visitor: { Program: { - exit(path, state) { + exit(path) { if (!isModule(path)) return; - const { - globals, - exactGlobals, - loose, - allowTopLevelThis, - strict, - strictMode, - noInterop, - } = state.opts; const browserGlobals = globals || {}; let moduleName = this.getModuleName(); diff --git a/packages/babel-plugin-transform-es2015-parameters/src/index.js b/packages/babel-plugin-transform-es2015-parameters/src/index.js index af12fa0399..410839188a 100644 --- a/packages/babel-plugin-transform-es2015-parameters/src/index.js +++ b/packages/babel-plugin-transform-es2015-parameters/src/index.js @@ -1,7 +1,8 @@ import convertFunctionParams from "./params"; import convertFunctionRest from "./rest"; -export default function() { +export default function(babel, options) { + const { loose } = options; return { visitor: { Function(path) { @@ -16,7 +17,7 @@ export default function() { } const convertedRest = convertFunctionRest(path); - const convertedParams = convertFunctionParams(path, this.opts.loose); + const convertedParams = convertFunctionParams(path, loose); if (convertedRest || convertedParams) { // Manually reprocess this scope to ensure that the moved params are updated. diff --git a/packages/babel-plugin-transform-es2015-spread/src/index.js b/packages/babel-plugin-transform-es2015-spread/src/index.js index 9df49cc951..a0d434baaa 100644 --- a/packages/babel-plugin-transform-es2015-spread/src/index.js +++ b/packages/babel-plugin-transform-es2015-spread/src/index.js @@ -1,9 +1,8 @@ -export default function({ types: t }) { - function getSpreadLiteral(spread, scope, state) { - if ( - state.opts.loose && - !t.isIdentifier(spread.argument, { name: "arguments" }) - ) { +export default function({ types: t }, options) { + const { loose } = options; + + function getSpreadLiteral(spread, scope) { + if (loose && !t.isIdentifier(spread.argument, { name: "arguments" })) { return spread.argument; } else { return scope.toArray(spread.argument, true); @@ -25,14 +24,14 @@ export default function({ types: t }) { return []; } - function build(props: Array, scope, state) { + function build(props: Array, scope) { const nodes = []; let _props = []; for (const prop of props) { if (t.isSpreadElement(prop)) { _props = push(_props, nodes); - nodes.push(getSpreadLiteral(prop, scope, state)); + nodes.push(getSpreadLiteral(prop, scope)); } else { _props.push(prop); } diff --git a/packages/babel-plugin-transform-es2015-template-literals/src/index.js b/packages/babel-plugin-transform-es2015-template-literals/src/index.js index 1380f0b3ca..89bdd691e6 100644 --- a/packages/babel-plugin-transform-es2015-template-literals/src/index.js +++ b/packages/babel-plugin-transform-es2015-template-literals/src/index.js @@ -1,6 +1,11 @@ import annotateAsPure from "babel-helper-annotate-as-pure"; -export default function({ types: t }) { +export default function({ types: t }, options) { + const { loose } = options; + + let helperName = "taggedTemplateLiteral"; + if (loose) helperName += "Loose"; + /** * This function groups the objects into multiple calls to `.concat()` in * order to preserve execution order of the primitive conversion, e.g. @@ -41,7 +46,7 @@ export default function({ types: t }) { this.templates = new Map(); }, visitor: { - TaggedTemplateExpression(path, state) { + TaggedTemplateExpression(path) { const { node } = path; const { quasi } = node; @@ -59,9 +64,6 @@ export default function({ types: t }) { raws.push(t.stringLiteral(raw)); } - let helperName = "taggedTemplateLiteral"; - if (state.opts.loose) helperName += "Loose"; - // Generate a unique name based on the string literals so we dedupe // identical strings used in the program. const rawParts = raws.map(s => s.value).join(","); @@ -97,7 +99,7 @@ export default function({ types: t }) { ); }, - TemplateLiteral(path, state) { + TemplateLiteral(path) { const nodes = []; const expressions = path.get("expressions"); @@ -118,14 +120,13 @@ export default function({ types: t }) { // since `+` is left-to-right associative // ensure the first node is a string if first/second isn't - const considerSecondNode = - !state.opts.loose || !t.isStringLiteral(nodes[1]); + const considerSecondNode = !loose || !t.isStringLiteral(nodes[1]); if (!t.isStringLiteral(nodes[0]) && considerSecondNode) { nodes.unshift(t.stringLiteral("")); } let root = nodes[0]; - if (state.opts.loose) { + if (loose) { for (let i = 1; i < nodes.length; i++) { root = t.binaryExpression("+", root, nodes[i]); } diff --git a/packages/babel-plugin-transform-optional-chaining/src/index.js b/packages/babel-plugin-transform-optional-chaining/src/index.js index f1a2cfd394..ca50914f83 100644 --- a/packages/babel-plugin-transform-optional-chaining/src/index.js +++ b/packages/babel-plugin-transform-optional-chaining/src/index.js @@ -1,7 +1,9 @@ import syntaxOptionalChaining from "babel-plugin-syntax-optional-chaining"; -export default function({ types: t }) { - function optional(path, replacementPath, loose = false) { +export default function({ types: t }, options) { + const { loose = false } = options; + + function optional(path, replacementPath) { const { scope } = path; const optionals = []; const nil = scope.buildUndefinedNode(); @@ -123,7 +125,7 @@ export default function({ types: t }) { return; } - optional(path, findReplacementPath(path), this.opts.loose); + optional(path, findReplacementPath(path)); }, }, }; diff --git a/packages/babel-plugin-transform-react-constant-elements/src/index.js b/packages/babel-plugin-transform-react-constant-elements/src/index.js index 219e327e0e..a81eaeecc4 100644 --- a/packages/babel-plugin-transform-react-constant-elements/src/index.js +++ b/packages/babel-plugin-transform-react-constant-elements/src/index.js @@ -1,4 +1,15 @@ -export default function transformReactConstantElement({ types: t }) { +export default function transformReactConstantElement({ types: t }, options) { + const { allowMutablePropsOnTags } = options; + + if ( + allowMutablePropsOnTags != null && + !Array.isArray(allowMutablePropsOnTags) + ) { + throw new Error( + ".allowMutablePropsOnTags must be an array, null, or undefined.", + ); + } + const HOISTED = new WeakSet(); const immutabilityVisitor = { @@ -71,12 +82,7 @@ export default function transformReactConstantElement({ types: t }) { // This transform takes the option `allowMutablePropsOnTags`, which is an array // of JSX tags to allow mutable props (such as objects, functions) on. Use sparingly // and only on tags you know will never modify their own props. - if (this.opts.allowMutablePropsOnTags != null) { - if (!Array.isArray(this.opts.allowMutablePropsOnTags)) { - throw new Error( - ".allowMutablePropsOnTags must be an array, null, or undefined.", - ); - } + if (allowMutablePropsOnTags != null) { // Get the element's name. If it's a member expression, we use the last part of the path. // So the option ["FormattedMessage"] would match "Intl.FormattedMessage". let namePath = path.get("openingElement.name"); @@ -86,7 +92,7 @@ export default function transformReactConstantElement({ types: t }) { const elementName = namePath.node.name; state.mutablePropsAllowed = - this.opts.allowMutablePropsOnTags.indexOf(elementName) > -1; + allowMutablePropsOnTags.indexOf(elementName) > -1; } // Traverse all props passed to this element for immutability. diff --git a/packages/babel-plugin-transform-react-jsx/src/index.js b/packages/babel-plugin-transform-react-jsx/src/index.js index 0ff139404e..750ab3eed7 100644 --- a/packages/babel-plugin-transform-react-jsx/src/index.js +++ b/packages/babel-plugin-transform-react-jsx/src/index.js @@ -1,7 +1,10 @@ import jsx from "babel-plugin-syntax-jsx"; import helper from "babel-helper-builder-react-jsx"; -export default function({ types: t }) { +export default function({ types: t }, options) { + const { pragma } = options; + let id = pragma || "React.createElement"; + const JSX_ANNOTATION_REGEX = /\*?\s*@jsx\s+([^\s]+)/; const visitor = helper({ @@ -22,7 +25,6 @@ export default function({ types: t }) { visitor.Program = function(path, state) { const { file } = state; - let id = state.opts.pragma || "React.createElement"; for (const comment of (file.ast.comments: Array)) { const matches = JSX_ANNOTATION_REGEX.exec(comment.value); diff --git a/packages/babel-plugin-transform-runtime/src/index.js b/packages/babel-plugin-transform-runtime/src/index.js index ed830e7b8d..f52b190abe 100644 --- a/packages/babel-plugin-transform-runtime/src/index.js +++ b/packages/babel-plugin-transform-runtime/src/index.js @@ -2,10 +2,20 @@ import { addDefault, isModule } from "babel-helper-module-imports"; import definitions from "./definitions"; -export default function({ types: t }) { - function getRuntimeModuleName(opts) { - return opts.moduleName || "babel-runtime"; - } +export default function({ types: t }, options) { + const { + helpers, + moduleName = "babel-runtime", + polyfill, + regenerator, + useBuiltIns, + useESModules, + } = options; + const notRegenerator = regenerator !== false; + const notPolyfillOrDoesUseBuiltIns = polyfill === false || useBuiltIns; + const isPolyfillAndUseBuiltIns = polyfill && useBuiltIns; + const baseHelpersDir = useBuiltIns ? "helpers/builtin" : "helpers"; + const helpersDir = useESModules ? `${baseHelpersDir}/es6` : baseHelpersDir; function has(obj, key) { return Object.prototype.hasOwnProperty.call(obj, key); @@ -15,15 +25,7 @@ export default function({ types: t }) { return { pre(file) { - const moduleName = getRuntimeModuleName(this.opts); - - if (this.opts.helpers !== false) { - const baseHelpersDir = this.opts.useBuiltIns - ? "helpers/builtin" - : "helpers"; - const helpersDir = this.opts.useESModules - ? `${baseHelpersDir}/es6` - : baseHelpersDir; + if (helpers !== false) { file.set("helperGenerator", name => { const isInteropHelper = HEADER_HELPERS.indexOf(name) !== -1; @@ -41,7 +43,7 @@ export default function({ types: t }) { }); } - if (this.opts.polyfill && this.opts.useBuiltIns) { + if (isPolyfillAndUseBuiltIns) { throw new Error( "The polyfill option conflicts with useBuiltIns; use one or the other", ); @@ -75,12 +77,9 @@ export default function({ types: t }) { }, visitor: { - ReferencedIdentifier(path, state) { + ReferencedIdentifier(path) { const { node, parent, scope } = path; - if ( - node.name === "regeneratorRuntime" && - state.opts.regenerator !== false - ) { + if (node.name === "regeneratorRuntime" && notRegenerator) { path.replaceWith( this.addDefaultImport( `${this.moduleName}/regenerator`, @@ -90,14 +89,13 @@ export default function({ types: t }) { return; } - if (state.opts.polyfill === false || state.opts.useBuiltIns) return; + if (notPolyfillOrDoesUseBuiltIns) return; if (t.isMemberExpression(parent)) return; if (!has(definitions.builtins, node.name)) return; if (scope.getBindingIdentifier(node.name)) return; // Symbol() -> _core.Symbol(); new Promise -> new _core.Promise - const moduleName = getRuntimeModuleName(state.opts); path.replaceWith( this.addDefaultImport( `${moduleName}/core-js/${definitions.builtins[node.name]}`, @@ -107,8 +105,8 @@ export default function({ types: t }) { }, // arr[Symbol.iterator]() -> _core.$for.getIterator(arr) - CallExpression(path, state) { - if (state.opts.polyfill === false || state.opts.useBuiltIns) return; + CallExpression(path) { + if (notPolyfillOrDoesUseBuiltIns) return; // we can't compile this if (path.node.arguments.length) return; @@ -120,7 +118,6 @@ export default function({ types: t }) { return; } - const moduleName = getRuntimeModuleName(state.opts); path.replaceWith( t.callExpression( this.addDefaultImport( @@ -133,13 +130,12 @@ export default function({ types: t }) { }, // Symbol.iterator in arr -> core.$for.isIterable(arr) - BinaryExpression(path, state) { - if (state.opts.polyfill === false || state.opts.useBuiltIns) return; + BinaryExpression(path) { + if (notPolyfillOrDoesUseBuiltIns) return; if (path.node.operator !== "in") return; if (!path.get("left").matchesPattern("Symbol.iterator")) return; - const moduleName = getRuntimeModuleName(state.opts); path.replaceWith( t.callExpression( this.addDefaultImport( @@ -153,8 +149,8 @@ export default function({ types: t }) { // Array.from -> _core.Array.from MemberExpression: { - enter(path, state) { - if (state.opts.polyfill === false || state.opts.useBuiltIns) return; + enter(path) { + if (notPolyfillOrDoesUseBuiltIns) return; if (!path.isReferenced()) return; const { node } = path; @@ -183,7 +179,6 @@ export default function({ types: t }) { } } - const moduleName = getRuntimeModuleName(state.opts); path.replaceWith( this.addDefaultImport( `${moduleName}/core-js/${methods[prop.name]}`, @@ -192,8 +187,8 @@ export default function({ types: t }) { ); }, - exit(path, state) { - if (state.opts.polyfill === false || state.opts.useBuiltIns) return; + exit(path) { + if (notPolyfillOrDoesUseBuiltIns) return; if (!path.isReferenced()) return; const { node } = path; @@ -202,7 +197,6 @@ export default function({ types: t }) { if (!has(definitions.builtins, obj.name)) return; if (path.scope.getBindingIdentifier(obj.name)) return; - const moduleName = getRuntimeModuleName(state.opts); path.replaceWith( t.memberExpression( this.addDefaultImport(