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
|
// replaces impure computed keys with new identifiers
|
||||||
// and returns variable declarators of these new identifiers
|
// and returns variable declarators of these new identifiers
|
||||||
function replaceImpureComputedKeys(path) {
|
function replaceImpureComputedKeys(properties, scope) {
|
||||||
const impureComputedPropertyDeclarators = [];
|
const impureComputedPropertyDeclarators = [];
|
||||||
for (const propPath of path.get("properties")) {
|
for (const propPath of properties) {
|
||||||
const key = propPath.get("key");
|
const key = propPath.get("key");
|
||||||
if (propPath.node.computed && !key.isPure()) {
|
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);
|
const declarator = t.variableDeclarator(t.identifier(name), key.node);
|
||||||
impureComputedPropertyDeclarators.push(declarator);
|
impureComputedPropertyDeclarators.push(declarator);
|
||||||
key.replaceWith(t.identifier(name));
|
key.replaceWith(t.identifier(name));
|
||||||
@ -139,7 +139,10 @@ export default declare((api, opts) => {
|
|||||||
const restElement = t.cloneNode(last.node);
|
const restElement = t.cloneNode(last.node);
|
||||||
last.remove();
|
last.remove();
|
||||||
|
|
||||||
const impureComputedPropertyDeclarators = replaceImpureComputedKeys(path);
|
const impureComputedPropertyDeclarators = replaceImpureComputedKeys(
|
||||||
|
path.get("properties"),
|
||||||
|
path.scope,
|
||||||
|
);
|
||||||
const { keys, allLiteral } = extractNormalizedKeys(path);
|
const { keys, allLiteral } = extractNormalizedKeys(path);
|
||||||
|
|
||||||
if (keys.length === 0) {
|
if (keys.length === 0) {
|
||||||
@ -265,18 +268,21 @@ export default declare((api, opts) => {
|
|||||||
|
|
||||||
path.findParent(path => {
|
path.findParent(path => {
|
||||||
if (path.isObjectProperty()) {
|
if (path.isObjectProperty()) {
|
||||||
refPropertyPath.unshift(path.node.key.name);
|
refPropertyPath.unshift(path);
|
||||||
} else if (path.isVariableDeclarator()) {
|
} else if (path.isVariableDeclarator()) {
|
||||||
kind = path.parentPath.node.kind;
|
kind = path.parentPath.node.kind;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (refPropertyPath.length) {
|
const impureObjRefComputedDeclarators = replaceImpureComputedKeys(
|
||||||
|
refPropertyPath,
|
||||||
|
path.scope,
|
||||||
|
);
|
||||||
refPropertyPath.forEach(prop => {
|
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 =>
|
const objectPatternPath = path.findParent(path =>
|
||||||
path.isObjectPattern(),
|
path.isObjectPattern(),
|
||||||
@ -296,6 +302,8 @@ export default declare((api, opts) => {
|
|||||||
|
|
||||||
insertionPath.insertBefore(impureComputedPropertyDeclarators);
|
insertionPath.insertBefore(impureComputedPropertyDeclarators);
|
||||||
|
|
||||||
|
insertionPath.insertBefore(impureObjRefComputedDeclarators);
|
||||||
|
|
||||||
insertionPath.insertAfter(
|
insertionPath.insertAfter(
|
||||||
t.variableDeclarator(argument, callExpression),
|
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