( node: T, deep: boolean = true, withoutLoc: boolean = false, commentsCache: CommentCache, )
| 46 | } |
| 47 | |
| 48 | function cloneNodeInternal<T extends t.Node | undefined | null>( |
| 49 | node: T, |
| 50 | deep: boolean = true, |
| 51 | withoutLoc: boolean = false, |
| 52 | commentsCache: CommentCache, |
| 53 | ): T { |
| 54 | if (!node) return node; |
| 55 | |
| 56 | const { type } = node; |
| 57 | const newNode: any = { type: node.type }; |
| 58 | |
| 59 | // Special-case identifiers since they are the most cloned nodes. |
| 60 | if (isIdentifier(node)) { |
| 61 | newNode.name = node.name; |
| 62 | |
| 63 | if (hasOwn(node, "optional") && typeof node.optional === "boolean") { |
| 64 | newNode.optional = node.optional; |
| 65 | } |
| 66 | |
| 67 | if (hasOwn(node, "typeAnnotation")) { |
| 68 | newNode.typeAnnotation = deep |
| 69 | ? cloneIfNodeOrArray( |
| 70 | node.typeAnnotation, |
| 71 | true, |
| 72 | withoutLoc, |
| 73 | commentsCache, |
| 74 | ) |
| 75 | : node.typeAnnotation; |
| 76 | } |
| 77 | |
| 78 | if (hasOwn(node, "decorators")) { |
| 79 | newNode.decorators = deep |
| 80 | ? cloneIfNodeOrArray(node.decorators, true, withoutLoc, commentsCache) |
| 81 | : node.decorators; |
| 82 | } |
| 83 | } else if (!hasOwn(NODE_FIELDS, type)) { |
| 84 | throw new Error(`Unknown node type: "${type}"`); |
| 85 | } else { |
| 86 | for (const field of Object.keys(NODE_FIELDS[type])) { |
| 87 | if (hasOwn(node, field)) { |
| 88 | if (deep) { |
| 89 | newNode[field] = |
| 90 | isFile(node) && field === "comments" |
| 91 | ? maybeCloneComments( |
| 92 | node.comments, |
| 93 | deep, |
| 94 | withoutLoc, |
| 95 | commentsCache, |
| 96 | ) |
| 97 | : cloneIfNodeOrArray( |
| 98 | // @ts-expect-error node[field] has been guarded by has check |
| 99 | node[field], |
| 100 | true, |
| 101 | withoutLoc, |
| 102 | commentsCache, |
| 103 | ); |
| 104 | } else { |
| 105 | newNode[field] = |
no test coverage detected