From 401873951ea77e4a63b6846786d6580472ab055f Mon Sep 17 00:00:00 2001 From: coderaiser Date: Mon, 29 May 2023 15:12:59 +0300 Subject: [PATCH] Set `shorthand:false` when rename Identifier inside obj prop (#15649) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nicolò Ribaudo Co-authored-by: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com> --- .../babel-traverse/src/scope/lib/renamer.ts | 18 ++++ packages/babel-traverse/test/scope.js | 88 +++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/packages/babel-traverse/src/scope/lib/renamer.ts b/packages/babel-traverse/src/scope/lib/renamer.ts index 67663c67172d..80f79d6df10e 100644 --- a/packages/babel-traverse/src/scope/lib/renamer.ts +++ b/packages/babel-traverse/src/scope/lib/renamer.ts @@ -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 = { ReferencedIdentifier({ node }, state) { @@ -27,6 +28,23 @@ const renameVisitor: Visitor = { } }, + 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, state, diff --git a/packages/babel-traverse/test/scope.js b/packages/babel-traverse/test/scope.js index 5a15dfae581f..a27d20efb38b 100644 --- a/packages/babel-traverse/test/scope.js +++ b/packages/babel-traverse/test/scope.js @@ -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 + }; + }" + `); + }); }); });