diff --git a/packages/babel-plugin-proposal-object-rest-spread/src/index.js b/packages/babel-plugin-proposal-object-rest-spread/src/index.js index 2c827b9506..7e35ea3220 100644 --- a/packages/babel-plugin-proposal-object-rest-spread/src/index.js +++ b/packages/babel-plugin-proposal-object-rest-spread/src/index.js @@ -1,7 +1,12 @@ import syntaxObjectRestSpread from "@babel/plugin-syntax-object-rest-spread"; import { types as t } from "@babel/core"; -export default function() { +export default function(api, opts) { + const { useBuiltIns = false } = opts; + if (typeof useBuiltIns !== "boolean") { + throw new Error(".useBuiltIns must be a boolean, or undefined"); + } + function hasRestElement(path) { let foundRestElement = false; path.traverse({ @@ -347,14 +352,6 @@ export default function() { ObjectExpression(path, file) { if (!hasSpread(path.node)) return; - const useBuiltIns = file.opts.useBuiltIns || false; - if (typeof useBuiltIns !== "boolean") { - throw new Error( - "proposal-object-rest-spread currently only accepts a boolean " + - "option for useBuiltIns (defaults to false)", - ); - } - const args = []; let props = []; diff --git a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/useBuiltIns/assignment-invalid-option/options.json b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/useBuiltIns/assignment-invalid-option/options.json index 55bda53fec..b3c8b7856d 100644 --- a/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/useBuiltIns/assignment-invalid-option/options.json +++ b/packages/babel-plugin-proposal-object-rest-spread/test/fixtures/useBuiltIns/assignment-invalid-option/options.json @@ -1,4 +1,4 @@ { "plugins": [["proposal-object-rest-spread", { "useBuiltIns": "invalidOption" }]], - "throws": "proposal-object-rest-spread currently only accepts a boolean option for useBuiltIns (defaults to false)" + "throws": ".useBuiltIns must be a boolean, or undefined" } diff --git a/packages/babel-plugin-proposal-unicode-property-regex/README.md b/packages/babel-plugin-proposal-unicode-property-regex/README.md index c474291cff..483cdbbf2e 100644 --- a/packages/babel-plugin-proposal-unicode-property-regex/README.md +++ b/packages/babel-plugin-proposal-unicode-property-regex/README.md @@ -43,11 +43,18 @@ To transpile to ES6/ES2015: ```js require("@babel/core").transform(code, { "plugins": [ - ["@babel/proposal-unicode-property-regex", { "useUnicodeFlag": true }] + ["@babel/proposal-unicode-property-regex", { "useUnicodeFlag": false }] ] }); ``` +## Options + +* `useUnicodeFlag` (defaults to `true`) + +When disabled with `false`, the transform will convert unicode regexes to +non-unicode regexes, removing the `u` flag. See https://www.npmjs.com/package/regexpu-core#useunicodeflag-default-false- for more information. + ## Author | [![twitter/mathias](https://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter") | diff --git a/packages/babel-plugin-proposal-unicode-property-regex/src/index.js b/packages/babel-plugin-proposal-unicode-property-regex/src/index.js index b4d8f8d398..5da0afc52b 100644 --- a/packages/babel-plugin-proposal-unicode-property-regex/src/index.js +++ b/packages/babel-plugin-proposal-unicode-property-regex/src/index.js @@ -1,18 +1,22 @@ import rewritePattern from "regexpu-core"; import * as regex from "@babel/helper-regex"; -export default function() { +export default function(api, options) { + const { useUnicodeFlag = true } = options; + if (typeof useUnicodeFlag !== "boolean") { + throw new Error(".useUnicodeFlag must be a boolean, or undefined"); + } + return { visitor: { - RegExpLiteral(path, state) { + RegExpLiteral(path) { const node = path.node; if (!regex.is(node, "u")) { return; } - const useUnicodeFlag = state.opts.useUnicodeFlag || false; node.pattern = rewritePattern(node.pattern, node.flags, { unicodePropertyEscape: true, - useUnicodeFlag: useUnicodeFlag, + useUnicodeFlag, }); if (!useUnicodeFlag) { regex.pullFlag(node, "u"); diff --git a/packages/babel-plugin-proposal-unicode-property-regex/test/fixtures/without-unicode-flag/options.json b/packages/babel-plugin-proposal-unicode-property-regex/test/fixtures/without-unicode-flag/options.json index 7569ea5f63..755ed1dae5 100644 --- a/packages/babel-plugin-proposal-unicode-property-regex/test/fixtures/without-unicode-flag/options.json +++ b/packages/babel-plugin-proposal-unicode-property-regex/test/fixtures/without-unicode-flag/options.json @@ -1,5 +1,7 @@ { "plugins": [ - ["proposal-unicode-property-regex"] + ["proposal-unicode-property-regex", { + "useUnicodeFlag": false + }] ] } diff --git a/packages/babel-plugin-transform-block-scoping/src/index.js b/packages/babel-plugin-transform-block-scoping/src/index.js index c6b49b63b9..c8519b2b89 100644 --- a/packages/babel-plugin-transform-block-scoping/src/index.js +++ b/packages/babel-plugin-transform-block-scoping/src/index.js @@ -1,6 +1,5 @@ import type NodePath from "@babel/traverse"; import type Scope from "@babel/traverse"; -import type File from "../../../file"; import { visitor as tdzVisitor } from "./tdz"; import values from "lodash/values"; import extend from "lodash/extend"; @@ -8,10 +7,18 @@ import { traverse, template, types as t } from "@babel/core"; const DONE = new WeakSet(); -export default function() { +export default function(api, opts) { + const { throwIfClosureRequired = false, tdz: tdzEnabled = false } = opts; + if (typeof throwIfClosureRequired !== "boolean") { + throw new Error(`.throwIfClosureRequired must be a boolean, or undefined`); + } + if (typeof tdzEnabled !== "boolean") { + throw new Error(`.throwIfClosureRequired must be a boolean, or undefined`); + } + return { visitor: { - VariableDeclaration(path, file) { + VariableDeclaration(path) { const { node, parent, scope } = path; if (!isBlockScoped(node)) return; convertBlockScopedToVar(path, null, parent, scope, true); @@ -26,7 +33,7 @@ export default function() { assign._ignoreBlockScopingTDZ = true; nodes.push(t.expressionStatement(assign)); } - decl.init = file.addHelper("temporalUndefined"); + decl.init = this.addHelper("temporalUndefined"); } node._blockHoist = 2; @@ -41,7 +48,7 @@ export default function() { } }, - Loop(path, file) { + Loop(path) { const { parent, scope } = path; path.ensureBlock(); const blockScoping = new BlockScoping( @@ -49,32 +56,35 @@ export default function() { path.get("body"), parent, scope, - file, + throwIfClosureRequired, + tdzEnabled, ); const replace = blockScoping.run(); if (replace) path.replaceWith(replace); }, - CatchClause(path, file) { + CatchClause(path) { const { parent, scope } = path; const blockScoping = new BlockScoping( null, path.get("body"), parent, scope, - file, + throwIfClosureRequired, + tdzEnabled, ); blockScoping.run(); }, - "BlockStatement|SwitchStatement|Program"(path, file) { + "BlockStatement|SwitchStatement|Program"(path) { if (!ignoreBlock(path)) { const blockScoping = new BlockScoping( null, path, path.parent, path.scope, - file, + throwIfClosureRequired, + tdzEnabled, ); blockScoping.run(); } @@ -324,11 +334,13 @@ class BlockScoping { blockPath: NodePath, parent: Object, scope: Scope, - file: File, + throwIfClosureRequired: boolean, + tdzEnabled: boolean, ) { this.parent = parent; this.scope = scope; - this.file = file; + this.throwIfClosureRequired = throwIfClosureRequired; + this.tdzEnabled = tdzEnabled; this.blockPath = blockPath; this.block = blockPath.node; @@ -432,7 +444,7 @@ class BlockScoping { } wrapClosure() { - if (this.file.opts.throwIfClosureRequired) { + if (this.throwIfClosureRequired) { throw this.blockPath.buildCodeFrameError( "Compiling let/const in this block would add a closure " + "(throwIfClosureRequired).", @@ -662,8 +674,9 @@ class BlockScoping { const state = { letReferences: this.letReferences, closurify: false, - file: this.file, loopDepth: 0, + tdzEnabled: this.tdzEnabled, + addHelper: name => this.addHelper(name), }; if (isInLoop(this.blockPath)) { diff --git a/packages/babel-plugin-transform-block-scoping/src/tdz.js b/packages/babel-plugin-transform-block-scoping/src/tdz.js index 48a5f1d143..b880945b61 100644 --- a/packages/babel-plugin-transform-block-scoping/src/tdz.js +++ b/packages/babel-plugin-transform-block-scoping/src/tdz.js @@ -12,8 +12,8 @@ function getTDZStatus(refPath, bindingPath) { } } -function buildTDZAssert(node, file) { - return t.callExpression(file.addHelper("temporalRef"), [ +function buildTDZAssert(node, state) { + return t.callExpression(state.addHelper("temporalRef"), [ node, t.stringLiteral(node.name), ]); @@ -29,7 +29,7 @@ function isReference(node, scope, state) { export const visitor = { ReferencedIdentifier(path, state) { - if (!this.file.opts.tdz) return; + if (!state.tdzEnabled) return; const { node, parent, scope } = path; @@ -42,7 +42,7 @@ export const visitor = { if (status === "inside") return; if (status === "maybe") { - const assert = buildTDZAssert(node, state.file); + const assert = buildTDZAssert(node, state); // add tdzThis to parent variable declarator so it's exploded bindingPath.parent._tdzThis = true; @@ -73,7 +73,7 @@ export const visitor = { AssignmentExpression: { exit(path, state) { - if (!this.file.opts.tdz) return; + if (!state.tdzEnabled) return; const { node } = path; if (node._ignoreBlockScopingTDZ) return; @@ -85,7 +85,7 @@ export const visitor = { const id = ids[name]; if (isReference(id, path.scope, state)) { - nodes.push(buildTDZAssert(id, state.file)); + nodes.push(buildTDZAssert(id, state)); } } diff --git a/packages/babel-plugin-transform-destructuring/src/index.js b/packages/babel-plugin-transform-destructuring/src/index.js index 1d72fdb439..e858c9bbf2 100644 --- a/packages/babel-plugin-transform-destructuring/src/index.js +++ b/packages/babel-plugin-transform-destructuring/src/index.js @@ -1,6 +1,13 @@ import { types as t } from "@babel/core"; -export default function() { +export default function(api, options) { + const { loose = false } = options; + if (typeof loose !== "boolean") { + throw new Error(`.loose must be a boolean or undefined`); + } + + const arrayOnlySpread = loose; + /** * Test if a VariableDeclaration's declarations contains any Patterns. */ @@ -43,8 +50,9 @@ export default function() { this.arrays = {}; this.nodes = opts.nodes || []; this.scope = opts.scope; - this.file = opts.file; this.kind = opts.kind; + this.arrayOnlySpread = opts.arrayOnlySpread; + this.addHelper = opts.addHelper; } buildVariableAssignment(id, init) { @@ -88,7 +96,7 @@ export default function() { toArray(node, count) { if ( - this.file.opts.loose || + this.arrayOnlySpread || (t.isIdentifier(node) && this.arrays[node.name]) ) { return node; @@ -164,7 +172,7 @@ export default function() { // const value = t.callExpression( - this.file.addHelper("objectWithoutProperties"), + this.addHelper("objectWithoutProperties"), [objRef, keys], ); this.nodes.push(this.buildVariableAssignment(spreadProp.argument, value)); @@ -189,7 +197,7 @@ export default function() { if (!pattern.properties.length) { this.nodes.push( t.expressionStatement( - t.callExpression(this.file.addHelper("objectDestructuringEmpty"), [ + t.callExpression(this.addHelper("objectDestructuringEmpty"), [ objRef, ]), ), @@ -370,7 +378,7 @@ export default function() { path.insertAfter(t.exportNamedDeclaration(null, specifiers)); }, - ForXStatement(path, file) { + ForXStatement(path) { const { node, scope } = path; const left = node.left; @@ -406,9 +414,10 @@ export default function() { const destructuring = new DestructuringTransformer({ kind: left.kind, - file: file, scope: scope, nodes: nodes, + arrayOnlySpread, + addHelper: name => this.addHelper(name), }); destructuring.init(pattern, key); @@ -419,7 +428,7 @@ export default function() { block.body = nodes.concat(block.body); }, - CatchClause({ node, scope }, file) { + CatchClause({ node, scope }) { const pattern = node.param; if (!t.isPattern(pattern)) return; @@ -430,16 +439,17 @@ export default function() { const destructuring = new DestructuringTransformer({ kind: "let", - file: file, scope: scope, nodes: nodes, + arrayOnlySpread, + addHelper: name => this.addHelper(name), }); destructuring.init(pattern, ref); node.body.body = nodes.concat(node.body.body); }, - AssignmentExpression(path, file) { + AssignmentExpression(path) { const { node, scope } = path; if (!t.isPattern(node.left)) return; @@ -447,9 +457,10 @@ export default function() { const destructuring = new DestructuringTransformer({ operator: node.operator, - file: file, scope: scope, nodes: nodes, + arrayOnlySpread, + addHelper: name => this.addHelper(name), }); let ref; @@ -479,7 +490,7 @@ export default function() { path.replaceWithMultiple(nodes); }, - VariableDeclaration(path, file) { + VariableDeclaration(path) { const { node, scope, parent } = path; if (t.isForXStatement(parent)) return; if (!parent || !path.container) return; // i don't know why this is necessary - TODO @@ -500,7 +511,8 @@ export default function() { nodes: nodes, scope: scope, kind: node.kind, - file: file, + arrayOnlySpread, + addHelper: name => this.addHelper(name), }); if (t.isPattern(pattern)) {