| "use strict"; |
| |
| Object.defineProperty(exports, "__esModule", { |
| value: true |
| }); |
| exports.default = cloneNode; |
| |
| var _definitions = require("../definitions"); |
| |
| var _generated = require("../validators/generated"); |
| |
| const has = Function.call.bind(Object.prototype.hasOwnProperty); |
| |
| function cloneIfNode(obj, deep, withoutLoc) { |
| if (obj && typeof obj.type === "string") { |
| return cloneNode(obj, deep, withoutLoc); |
| } |
| |
| return obj; |
| } |
| |
| function cloneIfNodeOrArray(obj, deep, withoutLoc) { |
| if (Array.isArray(obj)) { |
| return obj.map(node => cloneIfNode(node, deep, withoutLoc)); |
| } |
| |
| return cloneIfNode(obj, deep, withoutLoc); |
| } |
| |
| function cloneNode(node, deep = true, withoutLoc = false) { |
| if (!node) return node; |
| const { |
| type |
| } = node; |
| const newNode = { |
| type: node.type |
| }; |
| |
| if ((0, _generated.isIdentifier)(node)) { |
| newNode.name = node.name; |
| |
| if (has(node, "optional") && typeof node.optional === "boolean") { |
| newNode.optional = node.optional; |
| } |
| |
| if (has(node, "typeAnnotation")) { |
| newNode.typeAnnotation = deep ? cloneIfNodeOrArray(node.typeAnnotation, true, withoutLoc) : node.typeAnnotation; |
| } |
| } else if (!has(_definitions.NODE_FIELDS, type)) { |
| throw new Error(`Unknown node type: "${type}"`); |
| } else { |
| for (const field of Object.keys(_definitions.NODE_FIELDS[type])) { |
| if (has(node, field)) { |
| if (deep) { |
| newNode[field] = (0, _generated.isFile)(node) && field === "comments" ? maybeCloneComments(node.comments, deep, withoutLoc) : cloneIfNodeOrArray(node[field], true, withoutLoc); |
| } else { |
| newNode[field] = node[field]; |
| } |
| } |
| } |
| } |
| |
| if (has(node, "loc")) { |
| if (withoutLoc) { |
| newNode.loc = null; |
| } else { |
| newNode.loc = node.loc; |
| } |
| } |
| |
| if (has(node, "leadingComments")) { |
| newNode.leadingComments = maybeCloneComments(node.leadingComments, deep, withoutLoc); |
| } |
| |
| if (has(node, "innerComments")) { |
| newNode.innerComments = maybeCloneComments(node.innerComments, deep, withoutLoc); |
| } |
| |
| if (has(node, "trailingComments")) { |
| newNode.trailingComments = maybeCloneComments(node.trailingComments, deep, withoutLoc); |
| } |
| |
| if (has(node, "extra")) { |
| newNode.extra = Object.assign({}, node.extra); |
| } |
| |
| return newNode; |
| } |
| |
| function maybeCloneComments(comments, deep, withoutLoc) { |
| if (!comments || !deep) { |
| return comments; |
| } |
| |
| return comments.map(({ |
| type, |
| value, |
| loc |
| }) => { |
| if (withoutLoc) { |
| return { |
| type, |
| value, |
| loc: null |
| }; |
| } |
| |
| return { |
| type, |
| value, |
| loc |
| }; |
| }); |
| } |