Merge pull request #6776 from loganfsmyth/more-plugin-options
Hoist more plugin options and default useUnicodeFlag to 'true'.
This commit is contained in:
commit
617d35245f
@ -1,7 +1,12 @@
|
|||||||
import syntaxObjectRestSpread from "@babel/plugin-syntax-object-rest-spread";
|
import syntaxObjectRestSpread from "@babel/plugin-syntax-object-rest-spread";
|
||||||
import { types as t } from "@babel/core";
|
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) {
|
function hasRestElement(path) {
|
||||||
let foundRestElement = false;
|
let foundRestElement = false;
|
||||||
path.traverse({
|
path.traverse({
|
||||||
@ -347,14 +352,6 @@ export default function() {
|
|||||||
ObjectExpression(path, file) {
|
ObjectExpression(path, file) {
|
||||||
if (!hasSpread(path.node)) return;
|
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 = [];
|
const args = [];
|
||||||
let props = [];
|
let props = [];
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"plugins": [["proposal-object-rest-spread", { "useBuiltIns": "invalidOption" }]],
|
"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"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,11 +43,18 @@ To transpile to ES6/ES2015:
|
|||||||
```js
|
```js
|
||||||
require("@babel/core").transform(code, {
|
require("@babel/core").transform(code, {
|
||||||
"plugins": [
|
"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
|
## Author
|
||||||
|
|
||||||
| [](https://twitter.com/mathias "Follow @mathias on Twitter") |
|
| [](https://twitter.com/mathias "Follow @mathias on Twitter") |
|
||||||
|
|||||||
@ -1,18 +1,22 @@
|
|||||||
import rewritePattern from "regexpu-core";
|
import rewritePattern from "regexpu-core";
|
||||||
import * as regex from "@babel/helper-regex";
|
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 {
|
return {
|
||||||
visitor: {
|
visitor: {
|
||||||
RegExpLiteral(path, state) {
|
RegExpLiteral(path) {
|
||||||
const node = path.node;
|
const node = path.node;
|
||||||
if (!regex.is(node, "u")) {
|
if (!regex.is(node, "u")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const useUnicodeFlag = state.opts.useUnicodeFlag || false;
|
|
||||||
node.pattern = rewritePattern(node.pattern, node.flags, {
|
node.pattern = rewritePattern(node.pattern, node.flags, {
|
||||||
unicodePropertyEscape: true,
|
unicodePropertyEscape: true,
|
||||||
useUnicodeFlag: useUnicodeFlag,
|
useUnicodeFlag,
|
||||||
});
|
});
|
||||||
if (!useUnicodeFlag) {
|
if (!useUnicodeFlag) {
|
||||||
regex.pullFlag(node, "u");
|
regex.pullFlag(node, "u");
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
{
|
{
|
||||||
"plugins": [
|
"plugins": [
|
||||||
["proposal-unicode-property-regex"]
|
["proposal-unicode-property-regex", {
|
||||||
|
"useUnicodeFlag": false
|
||||||
|
}]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import type NodePath from "@babel/traverse";
|
import type NodePath from "@babel/traverse";
|
||||||
import type Scope from "@babel/traverse";
|
import type Scope from "@babel/traverse";
|
||||||
import type File from "../../../file";
|
|
||||||
import { visitor as tdzVisitor } from "./tdz";
|
import { visitor as tdzVisitor } from "./tdz";
|
||||||
import values from "lodash/values";
|
import values from "lodash/values";
|
||||||
import extend from "lodash/extend";
|
import extend from "lodash/extend";
|
||||||
@ -8,10 +7,18 @@ import { traverse, template, types as t } from "@babel/core";
|
|||||||
|
|
||||||
const DONE = new WeakSet();
|
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 {
|
return {
|
||||||
visitor: {
|
visitor: {
|
||||||
VariableDeclaration(path, file) {
|
VariableDeclaration(path) {
|
||||||
const { node, parent, scope } = path;
|
const { node, parent, scope } = path;
|
||||||
if (!isBlockScoped(node)) return;
|
if (!isBlockScoped(node)) return;
|
||||||
convertBlockScopedToVar(path, null, parent, scope, true);
|
convertBlockScopedToVar(path, null, parent, scope, true);
|
||||||
@ -26,7 +33,7 @@ export default function() {
|
|||||||
assign._ignoreBlockScopingTDZ = true;
|
assign._ignoreBlockScopingTDZ = true;
|
||||||
nodes.push(t.expressionStatement(assign));
|
nodes.push(t.expressionStatement(assign));
|
||||||
}
|
}
|
||||||
decl.init = file.addHelper("temporalUndefined");
|
decl.init = this.addHelper("temporalUndefined");
|
||||||
}
|
}
|
||||||
|
|
||||||
node._blockHoist = 2;
|
node._blockHoist = 2;
|
||||||
@ -41,7 +48,7 @@ export default function() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
Loop(path, file) {
|
Loop(path) {
|
||||||
const { parent, scope } = path;
|
const { parent, scope } = path;
|
||||||
path.ensureBlock();
|
path.ensureBlock();
|
||||||
const blockScoping = new BlockScoping(
|
const blockScoping = new BlockScoping(
|
||||||
@ -49,32 +56,35 @@ export default function() {
|
|||||||
path.get("body"),
|
path.get("body"),
|
||||||
parent,
|
parent,
|
||||||
scope,
|
scope,
|
||||||
file,
|
throwIfClosureRequired,
|
||||||
|
tdzEnabled,
|
||||||
);
|
);
|
||||||
const replace = blockScoping.run();
|
const replace = blockScoping.run();
|
||||||
if (replace) path.replaceWith(replace);
|
if (replace) path.replaceWith(replace);
|
||||||
},
|
},
|
||||||
|
|
||||||
CatchClause(path, file) {
|
CatchClause(path) {
|
||||||
const { parent, scope } = path;
|
const { parent, scope } = path;
|
||||||
const blockScoping = new BlockScoping(
|
const blockScoping = new BlockScoping(
|
||||||
null,
|
null,
|
||||||
path.get("body"),
|
path.get("body"),
|
||||||
parent,
|
parent,
|
||||||
scope,
|
scope,
|
||||||
file,
|
throwIfClosureRequired,
|
||||||
|
tdzEnabled,
|
||||||
);
|
);
|
||||||
blockScoping.run();
|
blockScoping.run();
|
||||||
},
|
},
|
||||||
|
|
||||||
"BlockStatement|SwitchStatement|Program"(path, file) {
|
"BlockStatement|SwitchStatement|Program"(path) {
|
||||||
if (!ignoreBlock(path)) {
|
if (!ignoreBlock(path)) {
|
||||||
const blockScoping = new BlockScoping(
|
const blockScoping = new BlockScoping(
|
||||||
null,
|
null,
|
||||||
path,
|
path,
|
||||||
path.parent,
|
path.parent,
|
||||||
path.scope,
|
path.scope,
|
||||||
file,
|
throwIfClosureRequired,
|
||||||
|
tdzEnabled,
|
||||||
);
|
);
|
||||||
blockScoping.run();
|
blockScoping.run();
|
||||||
}
|
}
|
||||||
@ -324,11 +334,13 @@ class BlockScoping {
|
|||||||
blockPath: NodePath,
|
blockPath: NodePath,
|
||||||
parent: Object,
|
parent: Object,
|
||||||
scope: Scope,
|
scope: Scope,
|
||||||
file: File,
|
throwIfClosureRequired: boolean,
|
||||||
|
tdzEnabled: boolean,
|
||||||
) {
|
) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.scope = scope;
|
this.scope = scope;
|
||||||
this.file = file;
|
this.throwIfClosureRequired = throwIfClosureRequired;
|
||||||
|
this.tdzEnabled = tdzEnabled;
|
||||||
|
|
||||||
this.blockPath = blockPath;
|
this.blockPath = blockPath;
|
||||||
this.block = blockPath.node;
|
this.block = blockPath.node;
|
||||||
@ -432,7 +444,7 @@ class BlockScoping {
|
|||||||
}
|
}
|
||||||
|
|
||||||
wrapClosure() {
|
wrapClosure() {
|
||||||
if (this.file.opts.throwIfClosureRequired) {
|
if (this.throwIfClosureRequired) {
|
||||||
throw this.blockPath.buildCodeFrameError(
|
throw this.blockPath.buildCodeFrameError(
|
||||||
"Compiling let/const in this block would add a closure " +
|
"Compiling let/const in this block would add a closure " +
|
||||||
"(throwIfClosureRequired).",
|
"(throwIfClosureRequired).",
|
||||||
@ -662,8 +674,9 @@ class BlockScoping {
|
|||||||
const state = {
|
const state = {
|
||||||
letReferences: this.letReferences,
|
letReferences: this.letReferences,
|
||||||
closurify: false,
|
closurify: false,
|
||||||
file: this.file,
|
|
||||||
loopDepth: 0,
|
loopDepth: 0,
|
||||||
|
tdzEnabled: this.tdzEnabled,
|
||||||
|
addHelper: name => this.addHelper(name),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isInLoop(this.blockPath)) {
|
if (isInLoop(this.blockPath)) {
|
||||||
|
|||||||
@ -12,8 +12,8 @@ function getTDZStatus(refPath, bindingPath) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildTDZAssert(node, file) {
|
function buildTDZAssert(node, state) {
|
||||||
return t.callExpression(file.addHelper("temporalRef"), [
|
return t.callExpression(state.addHelper("temporalRef"), [
|
||||||
node,
|
node,
|
||||||
t.stringLiteral(node.name),
|
t.stringLiteral(node.name),
|
||||||
]);
|
]);
|
||||||
@ -29,7 +29,7 @@ function isReference(node, scope, state) {
|
|||||||
|
|
||||||
export const visitor = {
|
export const visitor = {
|
||||||
ReferencedIdentifier(path, state) {
|
ReferencedIdentifier(path, state) {
|
||||||
if (!this.file.opts.tdz) return;
|
if (!state.tdzEnabled) return;
|
||||||
|
|
||||||
const { node, parent, scope } = path;
|
const { node, parent, scope } = path;
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ export const visitor = {
|
|||||||
if (status === "inside") return;
|
if (status === "inside") return;
|
||||||
|
|
||||||
if (status === "maybe") {
|
if (status === "maybe") {
|
||||||
const assert = buildTDZAssert(node, state.file);
|
const assert = buildTDZAssert(node, state);
|
||||||
|
|
||||||
// add tdzThis to parent variable declarator so it's exploded
|
// add tdzThis to parent variable declarator so it's exploded
|
||||||
bindingPath.parent._tdzThis = true;
|
bindingPath.parent._tdzThis = true;
|
||||||
@ -73,7 +73,7 @@ export const visitor = {
|
|||||||
|
|
||||||
AssignmentExpression: {
|
AssignmentExpression: {
|
||||||
exit(path, state) {
|
exit(path, state) {
|
||||||
if (!this.file.opts.tdz) return;
|
if (!state.tdzEnabled) return;
|
||||||
|
|
||||||
const { node } = path;
|
const { node } = path;
|
||||||
if (node._ignoreBlockScopingTDZ) return;
|
if (node._ignoreBlockScopingTDZ) return;
|
||||||
@ -85,7 +85,7 @@ export const visitor = {
|
|||||||
const id = ids[name];
|
const id = ids[name];
|
||||||
|
|
||||||
if (isReference(id, path.scope, state)) {
|
if (isReference(id, path.scope, state)) {
|
||||||
nodes.push(buildTDZAssert(id, state.file));
|
nodes.push(buildTDZAssert(id, state));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,13 @@
|
|||||||
import { types as t } from "@babel/core";
|
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.
|
* Test if a VariableDeclaration's declarations contains any Patterns.
|
||||||
*/
|
*/
|
||||||
@ -43,8 +50,9 @@ export default function() {
|
|||||||
this.arrays = {};
|
this.arrays = {};
|
||||||
this.nodes = opts.nodes || [];
|
this.nodes = opts.nodes || [];
|
||||||
this.scope = opts.scope;
|
this.scope = opts.scope;
|
||||||
this.file = opts.file;
|
|
||||||
this.kind = opts.kind;
|
this.kind = opts.kind;
|
||||||
|
this.arrayOnlySpread = opts.arrayOnlySpread;
|
||||||
|
this.addHelper = opts.addHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
buildVariableAssignment(id, init) {
|
buildVariableAssignment(id, init) {
|
||||||
@ -88,7 +96,7 @@ export default function() {
|
|||||||
|
|
||||||
toArray(node, count) {
|
toArray(node, count) {
|
||||||
if (
|
if (
|
||||||
this.file.opts.loose ||
|
this.arrayOnlySpread ||
|
||||||
(t.isIdentifier(node) && this.arrays[node.name])
|
(t.isIdentifier(node) && this.arrays[node.name])
|
||||||
) {
|
) {
|
||||||
return node;
|
return node;
|
||||||
@ -164,7 +172,7 @@ export default function() {
|
|||||||
//
|
//
|
||||||
|
|
||||||
const value = t.callExpression(
|
const value = t.callExpression(
|
||||||
this.file.addHelper("objectWithoutProperties"),
|
this.addHelper("objectWithoutProperties"),
|
||||||
[objRef, keys],
|
[objRef, keys],
|
||||||
);
|
);
|
||||||
this.nodes.push(this.buildVariableAssignment(spreadProp.argument, value));
|
this.nodes.push(this.buildVariableAssignment(spreadProp.argument, value));
|
||||||
@ -189,7 +197,7 @@ export default function() {
|
|||||||
if (!pattern.properties.length) {
|
if (!pattern.properties.length) {
|
||||||
this.nodes.push(
|
this.nodes.push(
|
||||||
t.expressionStatement(
|
t.expressionStatement(
|
||||||
t.callExpression(this.file.addHelper("objectDestructuringEmpty"), [
|
t.callExpression(this.addHelper("objectDestructuringEmpty"), [
|
||||||
objRef,
|
objRef,
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
@ -370,7 +378,7 @@ export default function() {
|
|||||||
path.insertAfter(t.exportNamedDeclaration(null, specifiers));
|
path.insertAfter(t.exportNamedDeclaration(null, specifiers));
|
||||||
},
|
},
|
||||||
|
|
||||||
ForXStatement(path, file) {
|
ForXStatement(path) {
|
||||||
const { node, scope } = path;
|
const { node, scope } = path;
|
||||||
const left = node.left;
|
const left = node.left;
|
||||||
|
|
||||||
@ -406,9 +414,10 @@ export default function() {
|
|||||||
|
|
||||||
const destructuring = new DestructuringTransformer({
|
const destructuring = new DestructuringTransformer({
|
||||||
kind: left.kind,
|
kind: left.kind,
|
||||||
file: file,
|
|
||||||
scope: scope,
|
scope: scope,
|
||||||
nodes: nodes,
|
nodes: nodes,
|
||||||
|
arrayOnlySpread,
|
||||||
|
addHelper: name => this.addHelper(name),
|
||||||
});
|
});
|
||||||
|
|
||||||
destructuring.init(pattern, key);
|
destructuring.init(pattern, key);
|
||||||
@ -419,7 +428,7 @@ export default function() {
|
|||||||
block.body = nodes.concat(block.body);
|
block.body = nodes.concat(block.body);
|
||||||
},
|
},
|
||||||
|
|
||||||
CatchClause({ node, scope }, file) {
|
CatchClause({ node, scope }) {
|
||||||
const pattern = node.param;
|
const pattern = node.param;
|
||||||
if (!t.isPattern(pattern)) return;
|
if (!t.isPattern(pattern)) return;
|
||||||
|
|
||||||
@ -430,16 +439,17 @@ export default function() {
|
|||||||
|
|
||||||
const destructuring = new DestructuringTransformer({
|
const destructuring = new DestructuringTransformer({
|
||||||
kind: "let",
|
kind: "let",
|
||||||
file: file,
|
|
||||||
scope: scope,
|
scope: scope,
|
||||||
nodes: nodes,
|
nodes: nodes,
|
||||||
|
arrayOnlySpread,
|
||||||
|
addHelper: name => this.addHelper(name),
|
||||||
});
|
});
|
||||||
destructuring.init(pattern, ref);
|
destructuring.init(pattern, ref);
|
||||||
|
|
||||||
node.body.body = nodes.concat(node.body.body);
|
node.body.body = nodes.concat(node.body.body);
|
||||||
},
|
},
|
||||||
|
|
||||||
AssignmentExpression(path, file) {
|
AssignmentExpression(path) {
|
||||||
const { node, scope } = path;
|
const { node, scope } = path;
|
||||||
if (!t.isPattern(node.left)) return;
|
if (!t.isPattern(node.left)) return;
|
||||||
|
|
||||||
@ -447,9 +457,10 @@ export default function() {
|
|||||||
|
|
||||||
const destructuring = new DestructuringTransformer({
|
const destructuring = new DestructuringTransformer({
|
||||||
operator: node.operator,
|
operator: node.operator,
|
||||||
file: file,
|
|
||||||
scope: scope,
|
scope: scope,
|
||||||
nodes: nodes,
|
nodes: nodes,
|
||||||
|
arrayOnlySpread,
|
||||||
|
addHelper: name => this.addHelper(name),
|
||||||
});
|
});
|
||||||
|
|
||||||
let ref;
|
let ref;
|
||||||
@ -479,7 +490,7 @@ export default function() {
|
|||||||
path.replaceWithMultiple(nodes);
|
path.replaceWithMultiple(nodes);
|
||||||
},
|
},
|
||||||
|
|
||||||
VariableDeclaration(path, file) {
|
VariableDeclaration(path) {
|
||||||
const { node, scope, parent } = path;
|
const { node, scope, parent } = path;
|
||||||
if (t.isForXStatement(parent)) return;
|
if (t.isForXStatement(parent)) return;
|
||||||
if (!parent || !path.container) return; // i don't know why this is necessary - TODO
|
if (!parent || !path.container) return; // i don't know why this is necessary - TODO
|
||||||
@ -500,7 +511,8 @@ export default function() {
|
|||||||
nodes: nodes,
|
nodes: nodes,
|
||||||
scope: scope,
|
scope: scope,
|
||||||
kind: node.kind,
|
kind: node.kind,
|
||||||
file: file,
|
arrayOnlySpread,
|
||||||
|
addHelper: name => this.addHelper(name),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (t.isPattern(pattern)) {
|
if (t.isPattern(pattern)) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user