UNPKG

2.63 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.default = cloneNode;
7
8var _definitions = require("../definitions");
9
10var _generated = require("../validators/generated");
11
12const has = Function.call.bind(Object.prototype.hasOwnProperty);
13
14function cloneIfNode(obj, deep, withoutLoc) {
15 if (obj && typeof obj.type === "string") {
16 return cloneNode(obj, deep, withoutLoc);
17 }
18
19 return obj;
20}
21
22function 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
30function 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
90function 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}
\No newline at end of file