Skip to content

Commit

Permalink
fix: ObjectPattern used as id inside for-of (#16830)
Browse files Browse the repository at this point in the history
Co-authored-by: Nicolò Ribaudo <[email protected]>
  • Loading branch information
coderaiser and nicolo-ribaudo authored Sep 17, 2024
1 parent 3435b56 commit 63af126
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 26 deletions.
22 changes: 22 additions & 0 deletions packages/babel-template/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,14 @@ describe("@babel/template", function () {
}).toThrow('Unknown substitution "ANOTHER_ID" given');
});

it("should throw if VariableDeclaration without init", () => {
expect(() => {
template(`
const %%ID%%;
`)({ ID: t.identifier("someIdent") });
}).toThrow("Missing initializer in destructuring declaration. (3:22)");
});

it("should throw if placeholders are not given explicit values", () => {
expect(() => {
template(`
Expand Down Expand Up @@ -466,6 +474,20 @@ describe("@babel/template", function () {
expect(generator(output).code).toMatchInlineSnapshot(`"const x = 7;"`);
});

it("works in const declaration inside for-of without init", () => {
const output = template("for (const %%LHS%% of %%RHS%%){}")({
LHS: t.ObjectPattern([
t.ObjectProperty(t.identifier("x"), t.identifier("x")),
]),
RHS: t.identifier("y"),
});
expect(generator(output).code).toMatchInlineSnapshot(`
"for (const {
x: x
} of y) {}"
`);
});

it("works in let declaration", () => {
const output = template("let %%LHS%% = %%RHS%%")({
LHS: t.identifier("x"),
Expand Down
44 changes: 18 additions & 26 deletions packages/babel-types/src/definitions/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1237,14 +1237,23 @@ defineType("VariableDeclaration", {
},
validate:
process.env.BABEL_8_BREAKING || process.env.BABEL_TYPES_8_BREAKING
? function (parent, key, node) {
if (!is("ForXStatement", parent, { left: node })) return;
if (node.declarations.length !== 1) {
throw new TypeError(
`Exactly one VariableDeclarator is required in the VariableDeclaration of a ${parent.type}`,
);
}
}
? (() => {
const withoutInit = assertNodeType("Identifier");

return function (parent, key, node: t.VariableDeclaration) {
if (is("ForXStatement", parent, { left: node })) {
if (node.declarations.length !== 1) {
throw new TypeError(
`Exactly one VariableDeclarator is required in the VariableDeclaration of a ${parent.type}`,
);
}
} else {
node.declarations.forEach(decl => {
if (!decl.init) withoutInit(decl, "id", decl.id);
});
}
};
})()
: undefined,
});

Expand All @@ -1255,24 +1264,7 @@ defineType("VariableDeclarator", {
validate:
!process.env.BABEL_8_BREAKING && !process.env.BABEL_TYPES_8_BREAKING
? assertNodeType("LVal")
: Object.assign(
(function () {
const normal = assertNodeType(
"Identifier",
"ArrayPattern",
"ObjectPattern",
);
const without = assertNodeType("Identifier");

return function (node: t.VariableDeclarator, key, val) {
const validator = node.init ? normal : without;
validator(node, key, val);
} as Validator;
})(),
{
oneOfNodeTypes: ["Identifier", "ArrayPattern", "ObjectPattern"],
},
),
: assertNodeType("Identifier", "ArrayPattern", "ObjectPattern"),
},
definite: {
optional: true,
Expand Down
27 changes: 27 additions & 0 deletions packages/babel-types/test/validate.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { itBabel8 } from "$repo-utils";
import * as t from "../lib/index.js";

describe("validate", () => {
Expand Down Expand Up @@ -27,4 +28,30 @@ describe("validate", () => {
});
});
});

describe("VariableDeclarator", () => {
const ast = t.variableDeclaration("const", [
t.variableDeclarator(
t.objectPattern([
t.objectProperty(t.identifier("x"), t.identifier("x")),
]),
),
]);

it("destructuring, no initializer, in for-of", () => {
expect(() => {
t.forOfStatement(
t.cloneNode(ast),
t.identifier("x"),
t.blockStatement([]),
);
}).not.toThrow();
});

itBabel8("destructuring, no initializer, in block", () => {
expect(() => {
t.blockStatement([t.cloneNode(ast)]);
}).toThrow();
});
});
});

0 comments on commit 63af126

Please sign in to comment.