fix: add computed property support for object Ref (#10863)
* fix: add computed property support for object Ref * Apply suggestions from code review Co-Authored-By: Nicolò Ribaudo <nicolo.ribaudo@gmail.com> * Update output.js
This commit is contained in:
parent
c0d0bf2e5e
commit
9be27bcfea
@ -102,12 +102,12 @@ export default declare((api, opts) => {
|
||||
|
||||
// replaces impure computed keys with new identifiers
|
||||
// and returns variable declarators of these new identifiers
|
||||
function replaceImpureComputedKeys(path) {
|
||||
function replaceImpureComputedKeys(properties, scope) {
|
||||
const impureComputedPropertyDeclarators = [];
|
||||
for (const propPath of path.get("properties")) {
|
||||
for (const propPath of properties) {
|
||||
const key = propPath.get("key");
|
||||
if (propPath.node.computed && !key.isPure()) {
|
||||
const name = path.scope.generateUidBasedOnNode(key.node);
|
||||
const name = scope.generateUidBasedOnNode(key.node);
|
||||
const declarator = t.variableDeclarator(t.identifier(name), key.node);
|
||||
impureComputedPropertyDeclarators.push(declarator);
|
||||
key.replaceWith(t.identifier(name));
|
||||
@ -139,7 +139,10 @@ export default declare((api, opts) => {
|
||||
const restElement = t.cloneNode(last.node);
|
||||
last.remove();
|
||||
|
||||
const impureComputedPropertyDeclarators = replaceImpureComputedKeys(path);
|
||||
const impureComputedPropertyDeclarators = replaceImpureComputedKeys(
|
||||
path.get("properties"),
|
||||
path.scope,
|
||||
);
|
||||
const { keys, allLiteral } = extractNormalizedKeys(path);
|
||||
|
||||
if (keys.length === 0) {
|
||||
@ -265,18 +268,21 @@ export default declare((api, opts) => {
|
||||
|
||||
path.findParent(path => {
|
||||
if (path.isObjectProperty()) {
|
||||
refPropertyPath.unshift(path.node.key.name);
|
||||
refPropertyPath.unshift(path);
|
||||
} else if (path.isVariableDeclarator()) {
|
||||
kind = path.parentPath.node.kind;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
if (refPropertyPath.length) {
|
||||
const impureObjRefComputedDeclarators = replaceImpureComputedKeys(
|
||||
refPropertyPath,
|
||||
path.scope,
|
||||
);
|
||||
refPropertyPath.forEach(prop => {
|
||||
ref = t.memberExpression(ref, t.identifier(prop));
|
||||
const { node } = prop;
|
||||
ref = t.memberExpression(ref, t.cloneNode(node.key), node.computed);
|
||||
});
|
||||
}
|
||||
|
||||
const objectPatternPath = path.findParent(path =>
|
||||
path.isObjectPattern(),
|
||||
@ -296,6 +302,8 @@ export default declare((api, opts) => {
|
||||
|
||||
insertionPath.insertBefore(impureComputedPropertyDeclarators);
|
||||
|
||||
insertionPath.insertBefore(impureObjRefComputedDeclarators);
|
||||
|
||||
insertionPath.insertAfter(
|
||||
t.variableDeclarator(argument, callExpression),
|
||||
);
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
var key, x, y, z;
|
||||
// impure
|
||||
key = 1;
|
||||
var { [key++]: { y, ...x } } = { 1: { a: 1, y: 1 } };
|
||||
expect(x).toEqual({ a: 1 });
|
||||
expect(key).toBe(2);
|
||||
expect(y).toBe(1);
|
||||
|
||||
// takes care of the order
|
||||
|
||||
key = 1;
|
||||
var {
|
||||
[++key]: { y, ...rest_y },
|
||||
[++key]: { z, ...rest_z }
|
||||
} = {2: { y: 2, z: 3 }, 3: { y: 2, z: 3 } };
|
||||
expect(y).toBe(2);
|
||||
expect(rest_y).toEqual({z: 3});
|
||||
expect(z).toBe(3);
|
||||
expect(rest_z).toEqual({ y: 2 });
|
||||
expect(key).toBe(3);
|
||||
@ -0,0 +1,20 @@
|
||||
var key, x, y, z;
|
||||
// impure
|
||||
key = 1;
|
||||
var { [key++]: { y, ...x } } = { 1: { a: 1, y: 1 } };
|
||||
expect(x).toEqual({ a: 1 });
|
||||
expect(key).toBe(2);
|
||||
expect(y).toBe(1);
|
||||
|
||||
// takes care of the order
|
||||
|
||||
key = 1;
|
||||
var {
|
||||
[++key]: { y, ...rest_y },
|
||||
[++key]: { z, ...rest_z }
|
||||
} = {2: { y: 2, z: 3 }, 3: { y: 2, z: 3 } };
|
||||
expect(y).toBe(2);
|
||||
expect(rest_y).toEqual({z: 3});
|
||||
expect(z).toBe(3);
|
||||
expect(rest_z).toEqual({ y: 2 });
|
||||
expect(key).toBe(3);
|
||||
@ -0,0 +1,62 @@
|
||||
var key, x, y, z; // impure
|
||||
|
||||
key = 1;
|
||||
|
||||
var _ref = key++,
|
||||
{
|
||||
[_ref]: {
|
||||
y
|
||||
}
|
||||
} = {
|
||||
1: {
|
||||
a: 1,
|
||||
y: 1
|
||||
}
|
||||
},
|
||||
x = babelHelpers.objectWithoutProperties({
|
||||
1: {
|
||||
a: 1,
|
||||
y: 1
|
||||
}
|
||||
}[_ref], ["y"]);
|
||||
|
||||
expect(x).toEqual({
|
||||
a: 1
|
||||
});
|
||||
expect(key).toBe(2);
|
||||
expect(y).toBe(1); // takes care of the order
|
||||
|
||||
key = 1;
|
||||
|
||||
var _$ = {
|
||||
2: {
|
||||
y: 2,
|
||||
z: 3
|
||||
},
|
||||
3: {
|
||||
y: 2,
|
||||
z: 3
|
||||
}
|
||||
},
|
||||
_ref2 = ++key,
|
||||
_ref3 = ++key,
|
||||
{
|
||||
[_ref3]: {
|
||||
y
|
||||
},
|
||||
[_ref2]: {
|
||||
z
|
||||
}
|
||||
} = _$,
|
||||
rest_y = babelHelpers.objectWithoutProperties(_$[_ref3], ["y"]),
|
||||
rest_z = babelHelpers.objectWithoutProperties(_$[_ref2], ["z"]);
|
||||
|
||||
expect(y).toBe(2);
|
||||
expect(rest_y).toEqual({
|
||||
z: 3
|
||||
});
|
||||
expect(z).toBe(3);
|
||||
expect(rest_z).toEqual({
|
||||
y: 2
|
||||
});
|
||||
expect(key).toBe(3);
|
||||
Loading…
x
Reference in New Issue
Block a user