Skip to content

Commit 2b289fb

Browse files
authored
fix: skip computed key when renaming (#16756)
* fix * review
1 parent 575863c commit 2b289fb

File tree

2 files changed

+101
-3
lines changed

2 files changed

+101
-3
lines changed

packages/babel-traverse/src/scope/lib/renamer.ts

+20-3
Original file line numberDiff line numberDiff line change
@@ -162,15 +162,32 @@ export default class Renamer {
162162
const blockToTraverse = process.env.BABEL_8_BREAKING
163163
? scope.block
164164
: (arguments[0] as t.Pattern | t.Scopable) || scope.block;
165+
166+
// When blockToTraverse is a SwitchStatement, the discriminant
167+
// is not part of the current scope and thus should be skipped.
168+
169+
// const foo = {
170+
// get [x]() {
171+
// return x;
172+
// },
173+
// };
174+
const skipKeys: Record<string, true> = { discriminant: true };
175+
if (t.isMethod(blockToTraverse)) {
176+
if (blockToTraverse.computed) {
177+
skipKeys.key = true;
178+
}
179+
if (!t.isObjectMethod(blockToTraverse)) {
180+
skipKeys.decorators = true;
181+
}
182+
}
183+
165184
traverseNode(
166185
blockToTraverse,
167186
explode(renameVisitor),
168187
scope,
169188
this,
170189
scope.path,
171-
// When blockToTraverse is a SwitchStatement, the discriminant
172-
// is not part of the current scope and thus should be skipped.
173-
{ discriminant: true },
190+
skipKeys,
174191
);
175192

176193
if (process.env.BABEL_8_BREAKING) {

packages/babel-traverse/test/scope.js

+81
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,87 @@ describe("scope", () => {
11371137
}"
11381138
`);
11391139
});
1140+
1141+
it(`computed key should not be renamed`, () => {
1142+
const program = getPath(`
1143+
let x = 1
1144+
const foo = {
1145+
get [x]() {
1146+
return x
1147+
},
1148+
}`);
1149+
program.traverse({
1150+
Function(path) {
1151+
const bodyPath = path.get("body");
1152+
// create a declaration that shadows parent variable
1153+
bodyPath.scope.push({
1154+
id: t.identifier("x"),
1155+
kind: "const",
1156+
init: t.nullLiteral(),
1157+
});
1158+
// rename the new "local" declaration
1159+
bodyPath.scope.rename("x", "y");
1160+
},
1161+
});
1162+
expect(program + "").toMatchInlineSnapshot(`
1163+
"let x = 1;
1164+
const foo = {
1165+
get [x]() {
1166+
const y = null;
1167+
return y;
1168+
}
1169+
};"
1170+
`);
1171+
});
1172+
1173+
it(`decorators should not be renamed`, () => {
1174+
const program = getPath(
1175+
`
1176+
let x;
1177+
class Foo {
1178+
@x
1179+
[x]() {
1180+
return x;
1181+
}
1182+
@x
1183+
#method() {
1184+
return x;
1185+
}
1186+
}`,
1187+
{
1188+
plugins: [["decorators"]],
1189+
},
1190+
);
1191+
1192+
program.traverse({
1193+
Function(path) {
1194+
const bodyPath = path.get("body");
1195+
// create a declaration that shadows parent variable
1196+
bodyPath.scope.push({
1197+
id: t.identifier("x"),
1198+
kind: "const",
1199+
init: t.nullLiteral(),
1200+
});
1201+
// rename the new "local" declaration
1202+
bodyPath.scope.rename("x", "y");
1203+
},
1204+
});
1205+
expect(program + "").toMatchInlineSnapshot(`
1206+
"let x;
1207+
class Foo {
1208+
@x
1209+
[x]() {
1210+
const y = null;
1211+
return y;
1212+
}
1213+
@x
1214+
#method() {
1215+
const y = null;
1216+
return y;
1217+
}
1218+
}"
1219+
`);
1220+
});
11401221
});
11411222

11421223
describe("constantViolations", () => {

0 commit comments

Comments
 (0)