cloneNode.js
1 "use strict"; 2 3 Object.defineProperty(exports, "__esModule", { 4 value: true 5 }); 6 exports.default = cloneNode; 7 8 var _definitions = require("../definitions"); 9 10 var _generated = require("../validators/generated"); 11 12 const has = Function.call.bind(Object.prototype.hasOwnProperty); 13 14 function cloneIfNode(obj, deep, withoutLoc) { 15 if (obj && typeof obj.type === "string") { 16 return cloneNode(obj, deep, withoutLoc); 17 } 18 19 return obj; 20 } 21 22 function cloneIfNodeOrArray(obj, deep, withoutLoc) { 23 if (Array.isArray(obj)) { 24 return obj.map(node => cloneIfNode(node, deep, withoutLoc)); 25 } 26 27 return cloneIfNode(obj, deep, withoutLoc); 28 } 29 30 function cloneNode(node, deep = true, withoutLoc = false) { 31 if (!node) return node; 32 const { 33 type 34 } = node; 35 const newNode = { 36 type: node.type 37 }; 38 39 if ((0, _generated.isIdentifier)(node)) { 40 newNode.name = node.name; 41 42 if (has(node, "optional") && typeof node.optional === "boolean") { 43 newNode.optional = node.optional; 44 } 45 46 if (has(node, "typeAnnotation")) { 47 newNode.typeAnnotation = deep ? cloneIfNodeOrArray(node.typeAnnotation, true, withoutLoc) : node.typeAnnotation; 48 } 49 } else if (!has(_definitions.NODE_FIELDS, type)) { 50 throw new Error(`Unknown node type: "${type}"`); 51 } else { 52 for (const field of Object.keys(_definitions.NODE_FIELDS[type])) { 53 if (has(node, field)) { 54 if (deep) { 55 newNode[field] = (0, _generated.isFile)(node) && field === "comments" ? maybeCloneComments(node.comments, deep, withoutLoc) : cloneIfNodeOrArray(node[field], true, withoutLoc); 56 } else { 57 newNode[field] = node[field]; 58 } 59 } 60 } 61 } 62 63 if (has(node, "loc")) { 64 if (withoutLoc) { 65 newNode.loc = null; 66 } else { 67 newNode.loc = node.loc; 68 } 69 } 70 71 if (has(node, "leadingComments")) { 72 newNode.leadingComments = maybeCloneComments(node.leadingComments, deep, withoutLoc); 73 } 74 75 if (has(node, "innerComments")) { 76 newNode.innerComments = maybeCloneComments(node.innerComments, deep, withoutLoc); 77 } 78 79 if (has(node, "trailingComments")) { 80 newNode.trailingComments = maybeCloneComments(node.trailingComments, deep, withoutLoc); 81 } 82 83 if (has(node, "extra")) { 84 newNode.extra = Object.assign({}, node.extra); 85 } 86 87 return newNode; 88 } 89 90 function maybeCloneComments(comments, deep, withoutLoc) { 91 if (!comments || !deep) { 92 return comments; 93 } 94 95 return comments.map(({ 96 type, 97 value, 98 loc 99 }) => { 100 if (withoutLoc) { 101 return { 102 type, 103 value, 104 loc: null 105 }; 106 } 107 108 return { 109 type, 110 value, 111 loc 112 }; 113 }); 114 }