ast-util
Version:
Utilities for AST transformers.
96 lines (85 loc) • 2.36 kB
JavaScript
/* jshint node:true, undef:true, unused:true */
/**
* Represents a replacement of a node path with zero or more nodes.
*
* @constructor
* @param {NodePath} nodePath
* @param {Array.<Node>} nodes
*/
function Replacement(nodePath, nodes) {
this.queue = [];
if (nodePath && nodes) {
this.queue.push([nodePath, nodes]);
}
}
/**
* Performs the replacement.
*/
Replacement.prototype.replace = function() {
for (var i = 0, length = this.queue.length; i < length; i++) {
var item = this.queue[i];
item[0].replace.apply(item[0], item[1]);
}
};
/**
* Incorporates the replacements from the given Replacement into this one.
*
* @param {Replacement} anotherReplacement
*/
Replacement.prototype.and = function(anotherReplacement) {
this.queue.push.apply(this.queue, anotherReplacement.queue);
return this;
};
/**
* Constructs a Replacement that, when run, will remove the node from the AST.
*
* @param {NodePath} nodePath
* @returns {Replacement}
*/
Replacement.removes = function(nodePath) {
return new Replacement(nodePath, []);
};
/**
* Constructs a Replacement that, when run, will insert the given nodes after
* the one in nodePath.
*
* @param {NodePath} nodePath
* @param {Array.<Node>} nodes
* @returns {Replacement}
*/
Replacement.adds = function(nodePath, nodes) {
return new Replacement(nodePath, [nodePath.node].concat(nodes));
};
/**
* Constructs a Replacement that, when run, swaps the node in nodePath with the
* given node or nodes.
*
* @param {NodePath} nodePath
* @param {Node|Array.<Node>} nodes
*/
Replacement.swaps = function(nodePath, nodes) {
if ({}.toString.call(nodes) !== '[object Array]') {
nodes = [nodes];
}
return new Replacement(nodePath, nodes);
};
/**
* Build replacements for each of the items in nodePaths by passing them to the
* given callback. If the callback returns null for a given node path then no
* replacement will be created for that node.
*
* @param {Array.<NodePath>} nodePaths
* @param {function(NodePath): ?Replacement} callback
* @returns {Replacement}
*/
Replacement.map = function(nodePaths, callback) {
var result = new Replacement();
nodePaths.each(function(nodePath) {
var replacement = callback(nodePath);
if (replacement) {
result.and(replacement);
}
});
return result;
};
module.exports = Replacement;