optimise traverse, improves traversal speed by 50%

This commit is contained in:
Sebastian McKenzie 2014-11-16 18:50:07 +11:00
parent fa3b24e5b4
commit f1183505b1

View File

@ -18,7 +18,7 @@ function traverse(parent, callbacks, opts) {
// unknown node type to traverse // unknown node type to traverse
var keys = t.VISITOR_KEYS[parent.type]; var keys = t.VISITOR_KEYS[parent.type];
if (!keys) return; if (!keys) throw new Error("unknown node " + parent.type);
opts = opts || {}; opts = opts || {};
if (_.isArray(opts)) opts = { blacklist: opts }; if (_.isArray(opts)) opts = { blacklist: opts };
@ -29,25 +29,32 @@ function traverse(parent, callbacks, opts) {
// normalise callbacks // normalise callbacks
if (_.isFunction(callbacks)) callbacks = { enter: callbacks }; if (_.isFunction(callbacks)) callbacks = { enter: callbacks };
_.each(keys, function (key) { for (var i in keys) {
var key = keys[i];
var nodes = parent[key]; var nodes = parent[key];
if (!nodes) return; if (!nodes) continue;
var updated = false;
var handle = function (obj, key) { var handle = function (obj, key) {
var node = obj[key]; var node = obj[key];
if (!node) return; if (!node) return;
// type is blacklisted // type is blacklisted
if (_.contains(blacklistTypes, node.type)) return; if (blacklistTypes.indexOf(node.type) > -1) return;
// replace node // replace node
var maybeReplace = function (result) { var maybeReplace = function (result) {
if (result === false) return; if (result === false) return;
if (result != null) node = obj[key] = result;
if (result != null) {
updated = true;
node = obj[key] = result;
}
}; };
// //
var opts2 = _.clone(opts); var opts2 = { scope: opts.scope, blacklist: opts.blacklist };
if (t.isScope(node)) opts2.scope = new Scope(opts.scope, node); if (t.isScope(node)) opts2.scope = new Scope(opts.scope, node);
// enter // enter
@ -69,15 +76,15 @@ function traverse(parent, callbacks, opts) {
}; };
if (_.isArray(nodes)) { if (_.isArray(nodes)) {
_.each(nodes, function (node, i) { for (var i in nodes) {
handle(nodes, i); handle(nodes, i);
}); }
parent[key] = _.flatten(parent[key]); if (updated) parent[key] = _.flatten(parent[key]);
} else { } else {
handle(parent, key); handle(parent, key);
} }
}); }
} }
traverse.removeProperties = function (tree) { traverse.removeProperties = function (tree) {