Skip to content

Commit

Permalink
Set shorthand:false when rename Identifier inside obj prop (#15649)
Browse files Browse the repository at this point in the history
Co-authored-by: Nicol貌 Ribaudo <nicolo.ribaudo@gmail.com>
Co-authored-by: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com>
  • Loading branch information
3 people committed May 29, 2023
1 parent 3511622 commit 4018739
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 0 deletions.
18 changes: 18 additions & 0 deletions packages/babel-traverse/src/scope/lib/renamer.ts
Expand Up @@ -5,6 +5,7 @@ import type { NodePath, Visitor } from "../..";
import { requeueComputedKeyAndDecorators } from "@babel/helper-environment-visitor";
import { traverseNode } from "../../traverse-node";
import { explode } from "../../visitors";
import type { Identifier } from "@babel/types";

const renameVisitor: Visitor<Renamer> = {
ReferencedIdentifier({ node }, state) {
Expand All @@ -27,6 +28,23 @@ const renameVisitor: Visitor<Renamer> = {
}
},

ObjectProperty({ node, scope }, state) {
const { name } = node.key as Identifier;
if (
node.shorthand &&
// In destructuring the identifier is already renamed by the
// AssignmentExpression|Declaration|VariableDeclarator visitor,
// while in object literals it's renamed later by the
// ReferencedIdentifier visitor.
(name === state.oldName || name === state.newName) &&
// Ignore shadowed bindings
scope.getBindingIdentifier(name) === state.binding.identifier
) {
node.shorthand = false;
if (node.extra?.shorthand) node.extra.shorthand = false;
}
},

"AssignmentExpression|Declaration|VariableDeclarator"(
path: NodePath<t.AssignmentPattern | t.Declaration | t.VariableDeclarator>,
state,
Expand Down
88 changes: 88 additions & 0 deletions packages/babel-traverse/test/scope.js
Expand Up @@ -1038,5 +1038,93 @@ describe("scope", () => {
},
});
});

it(".shorthand after renaming `ObjectProperty`", () => {
const program = getPath(`
const { a } = b;
({ a } = b);
c = { a };
`);
program.scope.rename("a");

const renamedPropertyMatcher = expect.objectContaining({
type: "ObjectProperty",
shorthand: false,
extra: expect.objectContaining({ shorthand: false }),
key: expect.objectContaining({ name: "a" }),
value: expect.objectContaining({
name: expect.not.stringMatching(/^a$/),
}),
});

const { body } = program.node;
expect(body[0].declarations[0].id.properties[0]).toStrictEqual(
renamedPropertyMatcher,
);
expect(body[1].expression.left.properties[0]).toStrictEqual(
renamedPropertyMatcher,
);
expect(body[2].expression.right.properties[0]).toStrictEqual(
renamedPropertyMatcher,
);

expect(String(program)).toMatchInlineSnapshot(`
"const {
a: _a
} = b;
({
a: _a
} = b);
c = {
a: _a
};"
`);
});

it(".shorthand after renaming `ObjectProperty` - shadowed", () => {
const program = getPath(`
const a = 1;
{
const { b } = 2;
({ b } = 3);
(_ = { b });
}
`);
program.scope.rename("a", "b");

const originalPropertyMatcher = expect.objectContaining({
type: "ObjectProperty",
shorthand: true,
extra: expect.objectContaining({ shorthand: true }),
key: expect.objectContaining({ name: "b" }),
value: expect.objectContaining({ name: "b" }),
});

const { body } = program.node;
expect(body[1].body[0].declarations[0].id.properties[0]).toStrictEqual(
originalPropertyMatcher,
);
expect(body[1].body[1].expression.left.properties[0]).toStrictEqual(
originalPropertyMatcher,
);
expect(body[1].body[2].expression.right.properties[0]).toStrictEqual(
originalPropertyMatcher,
);

expect(String(program)).toMatchInlineSnapshot(`
"const b = 1;
{
const {
b
} = 2;
({
b
} = 3);
_ = {
b
};
}"
`);
});
});
});

0 comments on commit 4018739

Please sign in to comment.