From d67e7f9325f221b121a718a28f3c31327a8cf803 Mon Sep 17 00:00:00 2001 From: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com> Date: Tue, 17 May 2022 00:00:44 +0800 Subject: [PATCH] review --- packages/babel-types/src/clone/cloneNode.ts | 53 +++++++++++++++------ 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/packages/babel-types/src/clone/cloneNode.ts b/packages/babel-types/src/clone/cloneNode.ts index 1a5631cd7d7a..2c978fb72358 100644 --- a/packages/babel-types/src/clone/cloneNode.ts +++ b/packages/babel-types/src/clone/cloneNode.ts @@ -3,22 +3,23 @@ import type * as t from ".."; import { isFile, isIdentifier } from "../validators/generated"; const has = Function.call.bind(Object.prototype.hasOwnProperty); -const commentsCache: Map = new Map(); // This function will never be called for comments, only for real nodes. -function cloneIfNode(obj, deep, withoutLoc) { +function cloneIfNode(obj, deep, withoutLoc, commentsCache) { if (obj && typeof obj.type === "string") { - return cloneNode(obj, deep, withoutLoc); + return cloneNodeInternal(obj, deep, withoutLoc, commentsCache || new Map()); } return obj; } -function cloneIfNodeOrArray(obj, deep, withoutLoc) { +function cloneIfNodeOrArray(obj, deep, withoutLoc, commentsCache) { + commentsCache ??= new Map(); + if (Array.isArray(obj)) { - return obj.map(node => cloneIfNode(node, deep, withoutLoc)); + return obj.map(node => cloneIfNode(node, deep, withoutLoc, commentsCache)); } - return cloneIfNode(obj, deep, withoutLoc); + return cloneIfNode(obj, deep, withoutLoc, commentsCache); } /** @@ -31,10 +32,16 @@ export default function cloneNode( deep: boolean = true, withoutLoc: boolean = false, ): T { - if (!node) return node; + return cloneNodeInternal(node, deep, withoutLoc, new Map()); +} - const isTop = !commentsCache.get("inCloning"); - if (isTop) commentsCache.set("inCloning", true); +function cloneNodeInternal( + node: T, + deep: boolean = true, + withoutLoc: boolean = false, + commentsCache: Map, +): T { + if (!node) return node; const { type } = node; const newNode: any = { type: node.type }; @@ -49,11 +56,15 @@ export default function cloneNode( if (has(node, "typeAnnotation")) { newNode.typeAnnotation = deep - ? cloneIfNodeOrArray(node.typeAnnotation, true, withoutLoc) + ? cloneIfNodeOrArray( + node.typeAnnotation, + true, + withoutLoc, + commentsCache, + ) : node.typeAnnotation; } } else if (!has(NODE_FIELDS, type)) { - if (isTop) commentsCache.clear(); throw new Error(`Unknown node type: "${type}"`); } else { for (const field of Object.keys(NODE_FIELDS[type])) { @@ -61,8 +72,18 @@ export default function cloneNode( if (deep) { newNode[field] = isFile(node) && field === "comments" - ? maybeCloneComments(node.comments, deep, withoutLoc) - : cloneIfNodeOrArray(node[field], true, withoutLoc); + ? maybeCloneComments( + node.comments, + deep, + withoutLoc, + commentsCache, + ) + : cloneIfNodeOrArray( + node[field], + true, + withoutLoc, + commentsCache, + ); } else { newNode[field] = node[field]; } @@ -82,6 +103,7 @@ export default function cloneNode( node.leadingComments, deep, withoutLoc, + commentsCache, ); } if (has(node, "innerComments")) { @@ -89,6 +111,7 @@ export default function cloneNode( node.innerComments, deep, withoutLoc, + commentsCache, ); } if (has(node, "trailingComments")) { @@ -96,6 +119,7 @@ export default function cloneNode( node.trailingComments, deep, withoutLoc, + commentsCache, ); } if (has(node, "extra")) { @@ -104,8 +128,6 @@ export default function cloneNode( }; } - if (isTop) commentsCache.clear(); - return newNode; } @@ -113,6 +135,7 @@ function maybeCloneComments( comments: ReadonlyArray | null, deep: boolean, withoutLoc: boolean, + commentsCache: Map, ): ReadonlyArray | null { if (!comments || !deep) { return comments;