babel-core
Version:
Turn ES6 code into readable vanilla ES5 with source maps
125 lines (98 loc) • 3.08 kB
JavaScript
;
var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; };
var _interopRequire = function (obj) { return obj && obj.__esModule ? obj["default"] : obj; };
module.exports = traverse;
var TraversalContext = _interopRequire(require("./context"));
var includes = _interopRequire(require("lodash/collection/includes"));
var t = _interopRequireWildcard(require("../types"));
function traverse(parent, opts, scope, state, parentPath) {
if (!parent) return;
if (!opts.noScope && !scope) {
if (parent.type !== "Program" && parent.type !== "File") {
throw new Error("Must pass a scope unless traversing a Program/File got a " + parent.type + " node");
}
}
if (!opts) opts = {};
if (!opts.enter) opts.enter = function () {};
if (!opts.exit) opts.exit = function () {};
// array of nodes
if (Array.isArray(parent)) {
for (var i = 0; i < parent.length; i++) {
traverse.node(parent[i], opts, scope, state, parentPath);
}
} else {
traverse.node(parent, opts, scope, state, parentPath);
}
}
traverse.node = function (node, opts, scope, state, parentPath) {
var keys = t.VISITOR_KEYS[node.type];
if (!keys) return;
var context = new TraversalContext(scope, opts, state, parentPath);
for (var i = 0; i < keys.length; i++) {
if (context.visit(node, keys[i])) {
return;
}
}
};
var CLEAR_KEYS = ["trailingComments", "leadingComments", "extendedRange", "_declarations", "_scopeInfo", "_paths", "tokens", "range", "start", "end", "loc", "raw"];
function clearNode(node) {
for (var i = 0; i < CLEAR_KEYS.length; i++) {
var key = CLEAR_KEYS[i];
if (node[key] != null) node[key] = null;
}
for (var key in node) {
var val = node[key];
if (Array.isArray(val)) {
delete val._paths;
}
}
}
var clearVisitor = {
noScope: true,
exit: clearNode
};
function clearComments(comments) {
for (var i = 0; i < comments.length; i++) {
clearNode(comments[i]);
}
}
traverse.removeProperties = function (tree) {
traverse(tree, clearVisitor);
clearNode(tree);
return tree;
};
traverse.explode = function (obj) {
for (var type in obj) {
var fns = obj[type];
var aliases = t.FLIPPED_ALIAS_KEYS[type];
if (aliases) {
for (var i = 0; i < aliases.length; i++) {
var _obj = obj;
var _aliases$i = aliases[i];
if (!_obj[_aliases$i]) _obj[_aliases$i] = fns;
}
}
}
return obj;
};
function hasBlacklistedType(node, parent, scope, state) {
if (node.type === state.type) {
state.has = true;
this.skip();
}
}
traverse.hasType = function (tree, scope, type, blacklistTypes) {
// the node we're searching in is blacklisted
if (includes(blacklistTypes, tree.type)) return false;
// the type we're looking for is the same as the passed node
if (tree.type === type) return true;
var state = {
has: false,
type: type
};
traverse(tree, {
blacklist: blacklistTypes,
enter: hasBlacklistedType
}, scope, state);
return state.has;
};