UNPKG

node-source-walk

Version:

Execute a callback on every node of a source code's AST and stop walking when you see fit

61 lines (48 loc) 1.42 kB
var esprima = require('esprima'); var esprimaHarmony = require('esprima-fb'); /** * @param {Object} options * @param {Boolean} [options.esprimaHarmony=false] */ module.exports = function (options) { options = options || {}; // We use global state to stop the recursive traversal of the AST this.shouldStop = false; if (options.esprimaHarmony) { esprima = esprimaHarmony; } }; // Adapted from substack/node-detective // Executes cb on a non-array AST node module.exports.prototype.traverse = function (node, cb) { var that = this; if (this.shouldStop) return; if (Array.isArray(node)) { node.forEach(function (x) { if(x !== null) { // Mark that the node has been visited x.parent = node; that.traverse(x, cb); } }); } else if (node && typeof node === 'object') { cb(node); Object.keys(node).forEach(function (key) { // Avoid visited nodes if (key === 'parent' || ! node[key]) return; node[key].parent = node; that.traverse(node[key], cb); }); } }; // Executes the passed callback for every traversed node of // the passed in src's ast module.exports.prototype.walk = function (src, cb) { this.shouldStop = false; var ast = esprima.parse(src); this.traverse(ast, cb); }; // Halts further traversal of the AST module.exports.prototype.stopWalking = function () { this.shouldStop = true; };