Add t.cloneNode and deprecate t.clone and t.cloneDeep (#7149)
This commit is contained in:
@@ -1,16 +1,12 @@
|
||||
// @flow
|
||||
|
||||
import cloneNode from "./cloneNode";
|
||||
|
||||
/**
|
||||
* Create a shallow clone of a `node` excluding `_private` properties.
|
||||
* Create a shallow clone of a `node`, including only
|
||||
* properties belonging to the node.
|
||||
* @deprecated Use t.cloneNode instead.
|
||||
*/
|
||||
export default function clone<T: Object>(node: T): T {
|
||||
if (!node) return node;
|
||||
const newNode = (({}: any): T);
|
||||
|
||||
Object.keys(node).forEach(key => {
|
||||
if (key[0] === "_") return;
|
||||
newNode[key] = node[key];
|
||||
});
|
||||
|
||||
return newNode;
|
||||
return cloneNode(node, /* deep */ false);
|
||||
}
|
||||
|
||||
@@ -1,28 +1,12 @@
|
||||
// @flow
|
||||
|
||||
import cloneNode from "./cloneNode";
|
||||
|
||||
/**
|
||||
* Create a deep clone of a `node` and all of it's child nodes
|
||||
* excluding `_private` properties.
|
||||
* including only properties belonging to the node.
|
||||
* @deprecated Use t.cloneNode instead.
|
||||
*/
|
||||
export default function cloneDeep<T: Object>(node: T): T {
|
||||
if (!node) return node;
|
||||
const newNode = (({}: any): T);
|
||||
|
||||
Object.keys(node).forEach(key => {
|
||||
if (key[0] === "_") return;
|
||||
|
||||
let val = node[key];
|
||||
|
||||
if (val) {
|
||||
if (val.type) {
|
||||
val = cloneDeep(val);
|
||||
} else if (Array.isArray(val)) {
|
||||
val = val.map(cloneDeep);
|
||||
}
|
||||
}
|
||||
|
||||
newNode[key] = val;
|
||||
});
|
||||
|
||||
return newNode;
|
||||
return cloneNode(node);
|
||||
}
|
||||
|
||||
69
packages/babel-types/src/clone/cloneNode.js
Normal file
69
packages/babel-types/src/clone/cloneNode.js
Normal file
@@ -0,0 +1,69 @@
|
||||
import { NODE_FIELDS } from "../definitions";
|
||||
|
||||
const has = Function.call.bind(Object.prototype.hasOwnProperty);
|
||||
|
||||
function cloneIfNode(obj, deep) {
|
||||
if (
|
||||
obj &&
|
||||
typeof obj.type === "string" &&
|
||||
// CommentLine and CommentBlock are used in File#comments, but they are
|
||||
// not defined in babel-types
|
||||
obj.type !== "CommentLine" &&
|
||||
obj.type !== "CommentBlock"
|
||||
) {
|
||||
return cloneNode(obj, deep);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
function cloneIfNodeOrArray(obj, deep) {
|
||||
if (Array.isArray(obj)) {
|
||||
return obj.map(node => cloneIfNode(node, deep));
|
||||
}
|
||||
return cloneIfNode(obj, deep);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clone of a `node` including only properties belonging to the node.
|
||||
* If the second parameter is `false`, cloneNode performs a shallow clone.
|
||||
*/
|
||||
export default function cloneNode<T: Object>(node: T, deep: boolean = true): T {
|
||||
if (!node) return node;
|
||||
|
||||
const { type } = node;
|
||||
const newNode = (({ type }: any): T);
|
||||
|
||||
// Special-case identifiers since they are the most cloned nodes.
|
||||
if (type === "Identifier") {
|
||||
newNode.name = node.name;
|
||||
} else if (!has(NODE_FIELDS, type)) {
|
||||
throw new Error(`Unknown node type: "${type}"`);
|
||||
} else {
|
||||
for (const field of Object.keys(NODE_FIELDS[type])) {
|
||||
if (has(node, field)) {
|
||||
newNode[field] = deep
|
||||
? cloneIfNodeOrArray(node[field], true)
|
||||
: node[field];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (has(node, "loc")) {
|
||||
newNode.loc = node.loc;
|
||||
}
|
||||
if (has(node, "leadingComments")) {
|
||||
newNode.leadingComments = node.leadingComments;
|
||||
}
|
||||
if (has(node, "innerComments")) {
|
||||
newNode.innerComments = node.innerCmments;
|
||||
}
|
||||
if (has(node, "trailingComments")) {
|
||||
newNode.trailingComments = node.trailingComments;
|
||||
}
|
||||
if (has(node, "extra")) {
|
||||
newNode.extra = Object.assign({}, node.extra);
|
||||
}
|
||||
|
||||
return newNode;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// @flow
|
||||
import { isIdentifier, isStringLiteral } from "../validators/generated";
|
||||
import cloneDeep from "../clone/cloneDeep";
|
||||
import cloneNode from "../clone/cloneNode";
|
||||
import removePropertiesDeep from "../modifications/removePropertiesDeep";
|
||||
|
||||
export default function toKeyAlias(
|
||||
@@ -16,7 +16,7 @@ export default function toKeyAlias(
|
||||
} else if (isStringLiteral(key)) {
|
||||
alias = JSON.stringify(key.value);
|
||||
} else {
|
||||
alias = JSON.stringify(removePropertiesDeep(cloneDeep(key)));
|
||||
alias = JSON.stringify(removePropertiesDeep(cloneNode(key)));
|
||||
}
|
||||
|
||||
if (node.computed) {
|
||||
|
||||
@@ -17,6 +17,7 @@ export {
|
||||
export * from "./builders/generated";
|
||||
|
||||
// clone
|
||||
export { default as cloneNode } from "./clone/cloneNode";
|
||||
export { default as clone } from "./clone/clone";
|
||||
export { default as cloneDeep } from "./clone/cloneDeep";
|
||||
export { default as cloneWithoutLoc } from "./clone/cloneWithoutLoc";
|
||||
|
||||
Reference in New Issue
Block a user