Code coverage report for 6to5/traverse/index.js

Statements: 100% (81 / 81)      Branches: 97.62% (41 / 42)      Functions: 100% (11 / 11)      Lines: 100% (68 / 68)      Ignored: none     

All files » 6to5/traverse/ » index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 1291   1 1 1   1   525493     525492 227 243   227       525265 525265   525264 525264     525264     525264   525264 534102 534102   489924 492184 492184     492145     492142 647908 643628       492142 492142     492142 492142 492128     492128       487848     487840 155780       489924 150790 153050     150782   339134         1 8790 109875 109875 109875 109875 109875 109875 109875 109875 109875   109875 109875     8790 219750     8790 8790   8790     1 7   7     7     6   5 42 2 2       5    
module.exports = traverse;
 
var Scope = require("./scope");
var t     = require("../types");
var _     = require("lodash");
 
function traverse(parent, callbacks, opts) {
  // falsy node
  if (!parent) return;
 
  // array of nodes
  if (_.isArray(parent)) {
    _.each(parent, function (node) {
      traverse(node, callbacks, opts);
    });
    return;
  }
 
  // unknown node type to traverse
  var keys = t.VISITOR_KEYS[parent.type];
  if (!keys) return;
 
  opts = opts || {};
  if (_.isArray(opts)) opts = { blacklist: opts };
 
  // blacklist these node types from being traversed
  var blacklistTypes = opts.blacklist || [];
 
  // normalise callbacks
  if (_.isFunction(callbacks)) callbacks = { enter: callbacks };
 
  _.each(keys, function (key) {
    var nodes = parent[key];
    if (!nodes) return;
 
    var handle = function (obj, key) {
      var node = obj[key];
      if (!node) return;
 
      // type is blacklisted
      if (_.contains(blacklistTypes, node.type)) return;
 
      // replace node
      var maybeReplace = function (result) {
        if (result === false) return;
        if (result != null) node = obj[key] = result;
      };
 
      //
      var opts2 = _.clone(opts);
      if (t.isScope(node)) opts2.scope = new Scope(opts.scope, node);
 
      // enter
      Eif (callbacks.enter) {
        var result = callbacks.enter(node, parent, opts2.scope);
        maybeReplace(result);
 
        // stop iteration
        if (result === false) return;
      }
 
      // traverse node
      traverse(node, callbacks, opts2);
 
      // exit
      if (callbacks.exit) {
        maybeReplace(callbacks.exit(node, parent, opts2.scope));
      }
    };
 
    if (_.isArray(nodes)) {
      _.each(nodes, function (node, i) {
        handle(nodes, i);
      });
 
      parent[key] = _.flatten(parent[key]);
    } else {
      handle(parent, key);
    }
  });
}
 
traverse.removeProperties = function (tree) {
  var clear = function (node) {
    delete node.extendedRange;
    delete node._scopeIds;
    delete node._parent;
    delete node.tokens;
    delete node.range;
    delete node.start;
    delete node.end;
    delete node.loc;
    delete node.raw;
 
    clearComments(node.trailingComments);
    clearComments(node.leadingComments);
  };
 
  var clearComments = function (comments) {
    _.each(comments, clear);
  };
 
  clear(tree);
  traverse(tree, clear);
 
  return tree;
};
 
traverse.hasType = function (tree, type, blacklistTypes) {
  blacklistTypes = [].concat(blacklistTypes || []);
 
  var has = false;
 
  // the node we're searching in is blacklisted
  if (_.contains(blacklistTypes, tree.type)) return false;
 
  // the type we're looking for is the same as the passed node
  if (tree.type === type) return true;
 
  traverse(tree, function (node) {
    if (node.type === type) {
      has = true;
      return false;
    }
  }, { blacklist: blacklistTypes });
 
  return has;
};