fix: cloneNode(deep, withoutLoc) handles absent comments (#12602)

This fragment (maybe all fragments?) throw during cloning, as
'comments' is unset here. Handle it being unset, by returning
undefined.
This commit is contained in:
Chris West 2021-01-13 01:40:23 +00:00 committed by GitHub
parent 62290aa1ba
commit bd4590e546
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 3 deletions

View File

@ -102,7 +102,9 @@ export default function cloneNode<T extends t.Node>(
return newNode;
}
function cloneCommentsWithoutLoc<T extends t.Comment>(comments: T[]): T[] {
function cloneCommentsWithoutLoc<T extends t.Comment>(
comments: ReadonlyArray<T>,
): T[] {
return comments.map(
({ type, value }) =>
({
@ -113,6 +115,12 @@ function cloneCommentsWithoutLoc<T extends t.Comment>(comments: T[]): T[] {
);
}
function maybeCloneComments(comments, deep, withoutLoc) {
return deep && withoutLoc ? cloneCommentsWithoutLoc(comments) : comments;
function maybeCloneComments<T extends t.Comment>(
comments: ReadonlyArray<T> | null,
deep: boolean,
withoutLoc: boolean,
): ReadonlyArray<T> | null {
return deep && withoutLoc && comments
? cloneCommentsWithoutLoc(comments)
: comments;
}

View File

@ -42,6 +42,14 @@ describe("cloneNode", function () {
expect(t.isNodesEquivalent(node, cloned)).toBe(true);
});
it("should handle deep cloning without loc of fragments", function () {
const program = "foo();";
const node = parse(program);
const cloned = t.cloneNode(node, /* deep */ true, /* withoutLoc */ true);
expect(node).not.toBe(cloned);
expect(t.isNodesEquivalent(node, cloned)).toBe(true);
});
it("should handle missing array element", function () {
const node = parse("[,0]");
const cloned = t.cloneNode(node);