Skip to content

Commit e2600c3

Browse files
committed
Added ability to whitelist specific property/function names to use loose mode when transforming destructuring
1 parent 3a9743f commit e2600c3

File tree

5 files changed

+85
-2
lines changed

5 files changed

+85
-2
lines changed

packages/babel-plugin-transform-destructuring/src/index.js

+39-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,43 @@
11
import { declare } from "@babel/helper-plugin-utils";
22
import { types as t } from "@babel/core";
3+
import escapeRegExp from "lodash/escapeRegExp";
4+
5+
function checkNameMatchesSelectiveLoose(name, selectiveLoose) {
6+
for (let i = 0; i < selectiveLoose.length; i++) {
7+
if (selectiveLoose[i].test(name)) {
8+
return true;
9+
}
10+
}
11+
return false;
12+
}
313

414
export default declare((api, options) => {
515
api.assertVersion(7);
616

7-
const { loose = false, useBuiltIns = false } = options;
17+
const {
18+
loose = false,
19+
useBuiltIns = false,
20+
selectiveLoose = false,
21+
} = options;
822

923
if (typeof loose !== "boolean") {
1024
throw new Error(`.loose must be a boolean or undefined`);
1125
}
1226

27+
// Format selectiveLoose entries to RegExp expressions that can
28+
// match generated babel names, i.e. `_x`, `_x2`, `_x3`, etc.
29+
if (selectiveLoose) {
30+
if (selectiveLoose instanceof Array) {
31+
for (let i = 0; i < selectiveLoose.length; i++) {
32+
selectiveLoose[i] = new RegExp(
33+
`^_${escapeRegExp(selectiveLoose[i])}\\d*$`,
34+
);
35+
}
36+
} else {
37+
throw new Error(`.selectiveLoose must be an array or undefined`);
38+
}
39+
}
40+
1341
const arrayOnlySpread = loose;
1442

1543
function getExtendsHelper(file) {
@@ -73,6 +101,7 @@ export default declare((api, options) => {
73101
this.kind = opts.kind;
74102
this.arrayOnlySpread = opts.arrayOnlySpread;
75103
this.addHelper = opts.addHelper;
104+
this.selectiveLoose = opts.selectiveLoose;
76105
}
77106

78107
buildVariableAssignment(id, init) {
@@ -210,8 +239,12 @@ export default declare((api, options) => {
210239
);
211240
}
212241

242+
const isLoose =
243+
(this.selectiveLoose &&
244+
checkNameMatchesSelectiveLoose(objRef.name, this.selectiveLoose)) ||
245+
loose;
213246
value = t.callExpression(
214-
this.addHelper(`objectWithoutProperties${loose ? "Loose" : ""}`),
247+
this.addHelper(`objectWithoutProperties${isLoose ? "Loose" : ""}`),
215248
[t.cloneNode(objRef), keyExpression],
216249
);
217250
}
@@ -479,6 +512,7 @@ export default declare((api, options) => {
479512
scope: scope,
480513
nodes: nodes,
481514
arrayOnlySpread,
515+
selectiveLoose,
482516
addHelper: name => this.addHelper(name),
483517
});
484518

@@ -504,6 +538,7 @@ export default declare((api, options) => {
504538
scope: scope,
505539
nodes: nodes,
506540
arrayOnlySpread,
541+
selectiveLoose,
507542
addHelper: name => this.addHelper(name),
508543
});
509544
destructuring.init(pattern, ref);
@@ -522,6 +557,7 @@ export default declare((api, options) => {
522557
scope: scope,
523558
nodes: nodes,
524559
arrayOnlySpread,
560+
selectiveLoose,
525561
addHelper: name => this.addHelper(name),
526562
});
527563

@@ -579,6 +615,7 @@ export default declare((api, options) => {
579615
scope: scope,
580616
kind: node.kind,
581617
arrayOnlySpread,
618+
selectiveLoose,
582619
addHelper: name => this.addHelper(name),
583620
});
584621

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
const useState = () => (["state", "dispatch"]);
2+
3+
var [state, dispatch] = useState();
4+
5+
expect(state).toBe("state");
6+
expect(dispatch).toBe("dispatch");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
var z = {};
2+
var { ...x } = z;
3+
var { x, ...y } = z;
4+
var { [x]: x, ...y } = z;
5+
(function({ x, ...y }) { });
6+
7+
({ x, y, ...z } = o);
8+
9+
var [state, dispatch] = useState();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"plugins": [
3+
["transform-destructuring", { "selectiveLoose": ["z", "useState"] }],
4+
"proposal-object-rest-spread",
5+
["external-helpers", { "helperVersion": "7.1.5" }]
6+
]
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
var z = {};
2+
var _z = z,
3+
x = babelHelpers.extends({}, _z);
4+
var _z2 = z,
5+
x = _z2.x,
6+
y = babelHelpers.objectWithoutPropertiesLoose(_z2, ["x"]);
7+
var _z3 = z,
8+
x = _z3[x],
9+
y = babelHelpers.objectWithoutPropertiesLoose(_z3, [x].map(babelHelpers.toPropertyKey));
10+
11+
(function (_ref) {
12+
let x = _ref.x,
13+
y = babelHelpers.objectWithoutProperties(_ref, ["x"]);
14+
});
15+
16+
var _o = o;
17+
x = _o.x;
18+
y = _o.y;
19+
z = babelHelpers.objectWithoutProperties(_o, ["x", "y"]);
20+
21+
var _useState = useState(),
22+
_useState2 = babelHelpers.slicedToArray(_useState, 2),
23+
state = _useState2[0],
24+
dispatch = _useState2[1];

0 commit comments

Comments
 (0)