Add t.cloneNode and deprecate t.clone and t.cloneDeep (#7149)
This commit is contained in:
parent
dde9274986
commit
63ae923987
@ -69,7 +69,7 @@ function buildModule(whitelist) {
|
|||||||
t.exportNamedDeclaration(
|
t.exportNamedDeclaration(
|
||||||
null,
|
null,
|
||||||
Object.keys(refs).map(name => {
|
Object.keys(refs).map(name => {
|
||||||
return t.exportSpecifier(t.clone(refs[name]), t.identifier(name));
|
return t.exportSpecifier(t.cloneNode(refs[name]), t.identifier(name));
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -50,7 +50,7 @@ export default class ImportBuilder {
|
|||||||
assert(statement.type === "ImportDeclaration");
|
assert(statement.type === "ImportDeclaration");
|
||||||
assert(statement.specifiers.length === 0);
|
assert(statement.specifiers.length === 0);
|
||||||
statement.specifiers = [t.importNamespaceSpecifier(name)];
|
statement.specifiers = [t.importNamespaceSpecifier(name)];
|
||||||
this._resultName = t.clone(name);
|
this._resultName = t.cloneNode(name);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
default(name) {
|
default(name) {
|
||||||
@ -59,7 +59,7 @@ export default class ImportBuilder {
|
|||||||
assert(statement.type === "ImportDeclaration");
|
assert(statement.type === "ImportDeclaration");
|
||||||
assert(statement.specifiers.length === 0);
|
assert(statement.specifiers.length === 0);
|
||||||
statement.specifiers = [t.importDefaultSpecifier(name)];
|
statement.specifiers = [t.importDefaultSpecifier(name)];
|
||||||
this._resultName = t.clone(name);
|
this._resultName = t.cloneNode(name);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
named(name, importName) {
|
named(name, importName) {
|
||||||
@ -70,7 +70,7 @@ export default class ImportBuilder {
|
|||||||
assert(statement.type === "ImportDeclaration");
|
assert(statement.type === "ImportDeclaration");
|
||||||
assert(statement.specifiers.length === 0);
|
assert(statement.specifiers.length === 0);
|
||||||
statement.specifiers = [t.importSpecifier(name, t.identifier(importName))];
|
statement.specifiers = [t.importSpecifier(name, t.identifier(importName))];
|
||||||
this._resultName = t.clone(name);
|
this._resultName = t.cloneNode(name);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ export default class ImportBuilder {
|
|||||||
"var",
|
"var",
|
||||||
[t.variableDeclarator(name, statement.expression)],
|
[t.variableDeclarator(name, statement.expression)],
|
||||||
);
|
);
|
||||||
this._resultName = t.clone(name);
|
this._resultName = t.cloneNode(name);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -128,7 +128,7 @@ export function buildNamespaceInitStatements(
|
|||||||
statements.push(
|
statements.push(
|
||||||
template.statement`var NAME = SOURCE;`({
|
template.statement`var NAME = SOURCE;`({
|
||||||
NAME: localName,
|
NAME: localName,
|
||||||
SOURCE: t.cloneDeep(srcNamespace),
|
SOURCE: t.cloneNode(srcNamespace),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -150,14 +150,14 @@ export function buildNamespaceInitStatements(
|
|||||||
: template.statement`EXPORTS.NAME = NAMESPACE;`)({
|
: template.statement`EXPORTS.NAME = NAMESPACE;`)({
|
||||||
EXPORTS: metadata.exportName,
|
EXPORTS: metadata.exportName,
|
||||||
NAME: exportName,
|
NAME: exportName,
|
||||||
NAMESPACE: t.cloneDeep(srcNamespace),
|
NAMESPACE: t.cloneNode(srcNamespace),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (sourceMetadata.reexportAll) {
|
if (sourceMetadata.reexportAll) {
|
||||||
const statement = buildNamespaceReexport(
|
const statement = buildNamespaceReexport(
|
||||||
metadata,
|
metadata,
|
||||||
t.cloneDeep(srcNamespace),
|
t.cloneNode(srcNamespace),
|
||||||
loose,
|
loose,
|
||||||
);
|
);
|
||||||
statement.loc = sourceMetadata.reexportAll.loc;
|
statement.loc = sourceMetadata.reexportAll.loc;
|
||||||
@ -191,7 +191,7 @@ const buildReexportsFromMeta = (meta, metadata, loose) => {
|
|||||||
templateForCurrentMode({
|
templateForCurrentMode({
|
||||||
EXPORTS: meta.exportName,
|
EXPORTS: meta.exportName,
|
||||||
EXPORT_NAME: exportName,
|
EXPORT_NAME: exportName,
|
||||||
NAMESPACE: t.cloneDeep(namespace),
|
NAMESPACE: t.cloneNode(namespace),
|
||||||
IMPORT_NAME: importName,
|
IMPORT_NAME: importName,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -309,7 +309,7 @@ function checkDuplicatedNodes(ast) {
|
|||||||
if (isByRegenerator(node)) return;
|
if (isByRegenerator(node)) return;
|
||||||
if (nodes.has(node)) {
|
if (nodes.has(node)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Do not reuse nodes. Use `t.clone` or `t.cloneDeep` to copy them.\n" +
|
"Do not reuse nodes. Use `t.cloneNode` to copy them.\n" +
|
||||||
JSON.stringify(node, hidePrivateProperties, 2) +
|
JSON.stringify(node, hidePrivateProperties, 2) +
|
||||||
"\nParent:\n" +
|
"\nParent:\n" +
|
||||||
JSON.stringify(parents.get(node), hidePrivateProperties, 2),
|
JSON.stringify(parents.get(node), hidePrivateProperties, 2),
|
||||||
|
|||||||
@ -215,7 +215,7 @@ function permuteHelperAST(file, metadata, id, localBindings, getDependency) {
|
|||||||
|
|
||||||
for (const path of imps) path.remove();
|
for (const path of imps) path.remove();
|
||||||
for (const path of impsBindingRefs) {
|
for (const path of impsBindingRefs) {
|
||||||
const node = t.cloneDeep(dependenciesRefs[path.node.name]);
|
const node = t.cloneNode(dependenciesRefs[path.node.name]);
|
||||||
path.replaceWith(node);
|
path.replaceWith(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -128,7 +128,7 @@ export default function(api, options) {
|
|||||||
t.variableDeclarator(ident, computedNode.key),
|
t.variableDeclarator(ident, computedNode.key),
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
computedNode.key = t.clone(ident);
|
computedNode.key = t.cloneNode(ident);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@ export default function() {
|
|||||||
|
|
||||||
function inferBindContext(bind, scope) {
|
function inferBindContext(bind, scope) {
|
||||||
const staticContext = getStaticContext(bind, scope);
|
const staticContext = getStaticContext(bind, scope);
|
||||||
if (staticContext) return t.cloneDeep(staticContext);
|
if (staticContext) return t.cloneNode(staticContext);
|
||||||
|
|
||||||
const tempId = getTempId(scope);
|
const tempId = getTempId(scope);
|
||||||
if (bind.object) {
|
if (bind.object) {
|
||||||
|
|||||||
@ -15,7 +15,11 @@ export default function(api, { loose = false }) {
|
|||||||
const ref = scope.generateUidIdentifierBasedOnNode(node.left);
|
const ref = scope.generateUidIdentifierBasedOnNode(node.left);
|
||||||
scope.push({ id: ref });
|
scope.push({ id: ref });
|
||||||
|
|
||||||
const assignment = t.assignmentExpression("=", t.clone(ref), node.left);
|
const assignment = t.assignmentExpression(
|
||||||
|
"=",
|
||||||
|
t.cloneNode(ref),
|
||||||
|
node.left,
|
||||||
|
);
|
||||||
|
|
||||||
path.replaceWith(
|
path.replaceWith(
|
||||||
t.conditionalExpression(
|
t.conditionalExpression(
|
||||||
@ -28,11 +32,11 @@ export default function(api, { loose = false }) {
|
|||||||
t.binaryExpression("!==", assignment, t.nullLiteral()),
|
t.binaryExpression("!==", assignment, t.nullLiteral()),
|
||||||
t.binaryExpression(
|
t.binaryExpression(
|
||||||
"!==",
|
"!==",
|
||||||
t.clone(ref),
|
t.cloneNode(ref),
|
||||||
scope.buildUndefinedNode(),
|
scope.buildUndefinedNode(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
t.clone(ref),
|
t.cloneNode(ref),
|
||||||
node.right,
|
node.right,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -74,7 +74,7 @@ export default function(api, opts) {
|
|||||||
const props = path.get("properties");
|
const props = path.get("properties");
|
||||||
const last = props[props.length - 1];
|
const last = props[props.length - 1];
|
||||||
t.assertRestElement(last.node);
|
t.assertRestElement(last.node);
|
||||||
const restElement = t.clone(last.node);
|
const restElement = t.cloneNode(last.node);
|
||||||
last.remove();
|
last.remove();
|
||||||
|
|
||||||
const impureComputedPropertyDeclarators = replaceImpureComputedKeys(path);
|
const impureComputedPropertyDeclarators = replaceImpureComputedKeys(path);
|
||||||
@ -291,7 +291,7 @@ export default function(api, opts) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const nodeWithoutSpread = t.clone(path.node);
|
const nodeWithoutSpread = t.cloneNode(path.node);
|
||||||
nodeWithoutSpread.right = ref;
|
nodeWithoutSpread.right = ref;
|
||||||
nodes.push(t.expressionStatement(nodeWithoutSpread));
|
nodes.push(t.expressionStatement(nodeWithoutSpread));
|
||||||
nodes.push(
|
nodes.push(
|
||||||
|
|||||||
@ -73,13 +73,13 @@ export default function(api, options) {
|
|||||||
replacementPath.replaceWith(
|
replacementPath.replaceWith(
|
||||||
t.conditionalExpression(
|
t.conditionalExpression(
|
||||||
loose
|
loose
|
||||||
? t.binaryExpression("==", t.clone(check), t.nullLiteral())
|
? t.binaryExpression("==", t.cloneNode(check), t.nullLiteral())
|
||||||
: t.logicalExpression(
|
: t.logicalExpression(
|
||||||
"||",
|
"||",
|
||||||
t.binaryExpression("===", t.clone(check), t.nullLiteral()),
|
t.binaryExpression("===", t.cloneNode(check), t.nullLiteral()),
|
||||||
t.binaryExpression(
|
t.binaryExpression(
|
||||||
"===",
|
"===",
|
||||||
t.clone(ref),
|
t.cloneNode(ref),
|
||||||
scope.buildUndefinedNode(),
|
scope.buildUndefinedNode(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -13,7 +13,7 @@ export default function(api, options) {
|
|||||||
|
|
||||||
let wrapAsync = state.methodWrapper;
|
let wrapAsync = state.methodWrapper;
|
||||||
if (wrapAsync) {
|
if (wrapAsync) {
|
||||||
wrapAsync = t.cloneDeep(wrapAsync);
|
wrapAsync = t.cloneNode(wrapAsync);
|
||||||
} else {
|
} else {
|
||||||
wrapAsync = state.methodWrapper = addNamed(path, method, module);
|
wrapAsync = state.methodWrapper = addNamed(path, method, module);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -525,7 +525,7 @@ class BlockScoping {
|
|||||||
|
|
||||||
// turn outsideLetReferences into an array
|
// turn outsideLetReferences into an array
|
||||||
const args = values(outsideRefs);
|
const args = values(outsideRefs);
|
||||||
const params = args.map(id => t.clone(id));
|
const params = args.map(id => t.cloneNode(id));
|
||||||
|
|
||||||
const isSwitch = this.blockPath.isSwitchStatement();
|
const isSwitch = this.blockPath.isSwitchStatement();
|
||||||
|
|
||||||
|
|||||||
@ -221,7 +221,7 @@ export default function(api, options) {
|
|||||||
if (t.isRestElement(prop)) {
|
if (t.isRestElement(prop)) {
|
||||||
this.pushObjectRest(pattern, objRef, prop, i);
|
this.pushObjectRest(pattern, objRef, prop, i);
|
||||||
} else {
|
} else {
|
||||||
this.pushObjectProperty(prop, t.clone(objRef));
|
this.pushObjectProperty(prop, t.cloneNode(objRef));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,7 +25,7 @@ export default function(api, options) {
|
|||||||
array = right;
|
array = right;
|
||||||
}
|
}
|
||||||
|
|
||||||
const item = t.memberExpression(array, t.clone(i), true);
|
const item = t.memberExpression(array, t.cloneNode(i), true);
|
||||||
let assignment;
|
let assignment;
|
||||||
if (t.isVariableDeclaration(left)) {
|
if (t.isVariableDeclaration(left)) {
|
||||||
assignment = left;
|
assignment = left;
|
||||||
@ -44,10 +44,10 @@ export default function(api, options) {
|
|||||||
t.variableDeclaration("let", inits),
|
t.variableDeclaration("let", inits),
|
||||||
t.binaryExpression(
|
t.binaryExpression(
|
||||||
"<",
|
"<",
|
||||||
t.clone(i),
|
t.cloneNode(i),
|
||||||
t.memberExpression(t.clone(array), t.identifier("length")),
|
t.memberExpression(t.cloneNode(array), t.identifier("length")),
|
||||||
),
|
),
|
||||||
t.updateExpression("++", t.clone(i)),
|
t.updateExpression("++", t.cloneNode(i)),
|
||||||
block,
|
block,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -63,7 +63,7 @@ export default function(api, options) {
|
|||||||
|
|
||||||
let cached = cache.get(key);
|
let cached = cache.get(key);
|
||||||
if (cached) {
|
if (cached) {
|
||||||
cached = t.cloneDeep(cached);
|
cached = t.cloneNode(cached);
|
||||||
} else {
|
} else {
|
||||||
cached = addDefault(file.path, source, {
|
cached = addDefault(file.path, source, {
|
||||||
importedInterop: "uncompiled",
|
importedInterop: "uncompiled",
|
||||||
|
|||||||
@ -107,7 +107,7 @@ export default function(api, options) {
|
|||||||
callee.object = t.assignmentExpression("=", temp, callee.object);
|
callee.object = t.assignmentExpression("=", temp, callee.object);
|
||||||
contextLiteral = temp;
|
contextLiteral = temp;
|
||||||
} else {
|
} else {
|
||||||
contextLiteral = t.cloneDeep(callee.object);
|
contextLiteral = t.cloneNode(callee.object);
|
||||||
}
|
}
|
||||||
t.appendToMemberExpression(callee, t.identifier("apply"));
|
t.appendToMemberExpression(callee, t.identifier("apply"));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -72,7 +72,7 @@ export default function(api, options) {
|
|||||||
|
|
||||||
let templateObject = this.templates.get(name);
|
let templateObject = this.templates.get(name);
|
||||||
if (templateObject) {
|
if (templateObject) {
|
||||||
templateObject = t.clone(templateObject);
|
templateObject = t.cloneNode(templateObject);
|
||||||
} else {
|
} else {
|
||||||
const programPath = path.find(p => p.isProgram());
|
const programPath = path.find(p => p.isProgram());
|
||||||
templateObject = programPath.scope.generateUidIdentifier(
|
templateObject = programPath.scope.generateUidIdentifier(
|
||||||
|
|||||||
@ -8,7 +8,7 @@ export default function populatePlaceholders(
|
|||||||
metadata: Metadata,
|
metadata: Metadata,
|
||||||
replacements: TemplateReplacements,
|
replacements: TemplateReplacements,
|
||||||
): BabelNodeFile {
|
): BabelNodeFile {
|
||||||
const ast = t.cloneDeep(metadata.ast);
|
const ast = t.cloneNode(metadata.ast);
|
||||||
|
|
||||||
if (replacements) {
|
if (replacements) {
|
||||||
metadata.placeholders.forEach(placeholder => {
|
metadata.placeholders.forEach(placeholder => {
|
||||||
@ -57,9 +57,9 @@ function applyReplacement(
|
|||||||
// once to avoid injecting the same node multiple times.
|
// once to avoid injecting the same node multiple times.
|
||||||
if (placeholder.isDuplicate) {
|
if (placeholder.isDuplicate) {
|
||||||
if (Array.isArray(replacement)) {
|
if (Array.isArray(replacement)) {
|
||||||
replacement = replacement.map(node => t.cloneDeep(node));
|
replacement = replacement.map(node => t.cloneNode(node));
|
||||||
} else if (typeof replacement === "object") {
|
} else if (typeof replacement === "object") {
|
||||||
replacement = t.cloneDeep(replacement);
|
replacement = t.cloneNode(replacement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,16 +1,12 @@
|
|||||||
// @flow
|
// @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 {
|
export default function clone<T: Object>(node: T): T {
|
||||||
if (!node) return node;
|
return cloneNode(node, /* deep */ false);
|
||||||
const newNode = (({}: any): T);
|
|
||||||
|
|
||||||
Object.keys(node).forEach(key => {
|
|
||||||
if (key[0] === "_") return;
|
|
||||||
newNode[key] = node[key];
|
|
||||||
});
|
|
||||||
|
|
||||||
return newNode;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,28 +1,12 @@
|
|||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
|
import cloneNode from "./cloneNode";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a deep clone of a `node` and all of it's child nodes
|
* 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 {
|
export default function cloneDeep<T: Object>(node: T): T {
|
||||||
if (!node) return node;
|
return cloneNode(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;
|
|
||||||
}
|
}
|
||||||
|
|||||||
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
|
// @flow
|
||||||
import { isIdentifier, isStringLiteral } from "../validators/generated";
|
import { isIdentifier, isStringLiteral } from "../validators/generated";
|
||||||
import cloneDeep from "../clone/cloneDeep";
|
import cloneNode from "../clone/cloneNode";
|
||||||
import removePropertiesDeep from "../modifications/removePropertiesDeep";
|
import removePropertiesDeep from "../modifications/removePropertiesDeep";
|
||||||
|
|
||||||
export default function toKeyAlias(
|
export default function toKeyAlias(
|
||||||
@ -16,7 +16,7 @@ export default function toKeyAlias(
|
|||||||
} else if (isStringLiteral(key)) {
|
} else if (isStringLiteral(key)) {
|
||||||
alias = JSON.stringify(key.value);
|
alias = JSON.stringify(key.value);
|
||||||
} else {
|
} else {
|
||||||
alias = JSON.stringify(removePropertiesDeep(cloneDeep(key)));
|
alias = JSON.stringify(removePropertiesDeep(cloneNode(key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.computed) {
|
if (node.computed) {
|
||||||
|
|||||||
@ -17,6 +17,7 @@ export {
|
|||||||
export * from "./builders/generated";
|
export * from "./builders/generated";
|
||||||
|
|
||||||
// clone
|
// clone
|
||||||
|
export { default as cloneNode } from "./clone/cloneNode";
|
||||||
export { default as clone } from "./clone/clone";
|
export { default as clone } from "./clone/clone";
|
||||||
export { default as cloneDeep } from "./clone/cloneDeep";
|
export { default as cloneDeep } from "./clone/cloneDeep";
|
||||||
export { default as cloneWithoutLoc } from "./clone/cloneWithoutLoc";
|
export { default as cloneWithoutLoc } from "./clone/cloneWithoutLoc";
|
||||||
|
|||||||
@ -2,68 +2,61 @@ import * as t from "../lib";
|
|||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
import { parse } from "babylon";
|
import { parse } from "babylon";
|
||||||
|
|
||||||
suite("cloning", function() {
|
suite("cloneNode", function() {
|
||||||
suite("clone", function() {
|
it("should handle undefined", function() {
|
||||||
it("should handle undefined", function() {
|
const node = undefined;
|
||||||
const node = undefined;
|
const cloned = t.cloneNode(node);
|
||||||
const cloned = t.clone(node);
|
assert(cloned === undefined);
|
||||||
assert(cloned === undefined);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should handle null", function() {
|
|
||||||
const node = null;
|
|
||||||
const cloned = t.clone(node);
|
|
||||||
assert(cloned === null);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should handle simple cases", function() {
|
|
||||||
const node = t.arrayExpression([null, t.identifier("a")]);
|
|
||||||
const cloned = t.clone(node);
|
|
||||||
assert(node !== cloned);
|
|
||||||
assert(t.isNodesEquivalent(node, cloned) === true);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
suite("cloneDeep", function() {
|
it("should handle null", function() {
|
||||||
it("should handle undefined", function() {
|
const node = null;
|
||||||
const node = undefined;
|
const cloned = t.cloneNode(node);
|
||||||
const cloned = t.cloneDeep(node);
|
assert(cloned === null);
|
||||||
assert(cloned === undefined);
|
});
|
||||||
});
|
|
||||||
|
|
||||||
it("should handle null", function() {
|
it("should handle simple cases", function() {
|
||||||
const node = null;
|
const node = t.identifier("a");
|
||||||
const cloned = t.cloneDeep(node);
|
const cloned = t.cloneNode(node);
|
||||||
assert(cloned === null);
|
assert(node !== cloned);
|
||||||
});
|
assert(t.isNodesEquivalent(node, cloned) === true);
|
||||||
|
});
|
||||||
|
|
||||||
it("should handle simple cases", function() {
|
it("should handle full programs", function() {
|
||||||
const node = t.arrayExpression([null, t.identifier("a")]);
|
const file = parse("1 + 1");
|
||||||
const cloned = t.cloneDeep(node);
|
const cloned = t.cloneNode(file);
|
||||||
assert(node !== cloned);
|
assert(file !== cloned);
|
||||||
assert(t.isNodesEquivalent(node, cloned) === true);
|
assert(
|
||||||
});
|
file.program.body[0].expression.right !==
|
||||||
|
cloned.program.body[0].expression.right,
|
||||||
|
);
|
||||||
|
assert(
|
||||||
|
file.program.body[0].expression.left !==
|
||||||
|
cloned.program.body[0].expression.left,
|
||||||
|
);
|
||||||
|
assert(t.isNodesEquivalent(file, cloned) === true);
|
||||||
|
});
|
||||||
|
|
||||||
it("should handle full programs", function() {
|
it("should handle complex programs", function() {
|
||||||
const node = parse("1 + 1");
|
const program = "'use strict'; function lol() { wow();return 1; }";
|
||||||
const cloned = t.cloneDeep(node);
|
const node = parse(program);
|
||||||
assert(node !== cloned);
|
const cloned = t.cloneNode(node);
|
||||||
assert(t.isNodesEquivalent(node, cloned) === true);
|
assert(node !== cloned);
|
||||||
});
|
assert(t.isNodesEquivalent(node, cloned) === true);
|
||||||
|
});
|
||||||
|
|
||||||
it("should handle complex programs", function() {
|
it("should handle missing array element", function() {
|
||||||
const program = "'use strict'; function lol() { wow();return 1; }";
|
const node = parse("[,0]");
|
||||||
const node = parse(program);
|
const cloned = t.cloneNode(node);
|
||||||
const cloned = t.cloneDeep(node);
|
assert(node !== cloned);
|
||||||
assert(node !== cloned);
|
assert(t.isNodesEquivalent(node, cloned) === true);
|
||||||
assert(t.isNodesEquivalent(node, cloned) === true);
|
});
|
||||||
});
|
|
||||||
|
|
||||||
it("should handle missing array element", function() {
|
it("should support shallow cloning", function() {
|
||||||
const node = parse("[,0]");
|
const node = t.memberExpression(t.identifier("foo"), t.identifier("bar"));
|
||||||
const cloned = t.cloneDeep(node);
|
const cloned = t.cloneNode(node, /* deep */ false);
|
||||||
assert(node !== cloned);
|
assert.notStrictEqual(node, cloned);
|
||||||
assert(t.isNodesEquivalent(node, cloned) === true);
|
assert.strictEqual(node.object, cloned.object);
|
||||||
});
|
assert.strictEqual(node.property, cloned.property);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user