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

Statements: 93.15% (68 / 73)      Branches: 91.67% (33 / 36)      Functions: 84.62% (11 / 13)      Lines: 92.06% (58 / 63)      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 1281   1   152194     152193               152193 152193     152192     152192   152192 151410 151410   140905 147037 147037     147002   146999     146999 280150       146999 146999     146983   146773       146773     146761 133377       140905 41947 48079     41936   98958         1   1 90 2144 2144 2144 2144 2144   2144 2144     90 4288 8 8       90 90   90     1 7   7   7             7     6   5 42 2 2         5    
var _ = require("lodash");
 
var traverse = module.exports = function (parent, callbacks, blacklistTypes) {
  // falsy node
  if (!parent) return;
 
  // array of nodes
  Iif (_.isArray(parent)) {
    _.each(parent, function (node) {
      traverse(node, callbacks, blacklistTypes);
    });
    return;
  }
 
  // unknown node type to traverse
  var keys = traverse.VISITOR_KEYS[parent.type];
  if (!keys) return;
 
  // blacklist these node types from being traversed
  blacklistTypes = blacklistTypes || [];
 
  // 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;
 
      var result;
 
      // replace node
      var maybeReplace = function (result) {
        if (result != null) obj[key] = result;
      };
 
      // enter
      Eif (callbacks.enter) {
        result = callbacks.enter(node, parent, obj, key);
 
        // stop iteration
        if (result === false) return;
 
        maybeReplace(result);
      }
 
      // traverse node
      traverse(node, callbacks, blacklistTypes);
 
      // exit
      if (callbacks.exit) {
        maybeReplace(callbacks.exit(node, parent, obj, key));
      }
    };
 
    if (_.isArray(nodes)) {
      _.each(nodes, function (node, i) {
        handle(nodes, i);
      });
 
      parent[key] = _.flatten(parent[key]);
    } else {
      handle(parent, key);
    }
  });
};
 
traverse.VISITOR_KEYS = require("./visitor-keys");
 
traverse.removeProperties = function (tree) {
  var clear = function (node) {
    delete node.tokens;
    delete node.range;
    delete node.start;
    delete node.end;
    delete node.loc;
 
    clearComments(node.trailingComments);
    clearComments(node.leadingComments);
  };
 
  var clearComments = function (comments) {
    _.each(comments, function (comment) {
      delete comment.extendedRange;
      clear(comment);
    });
  };
 
  clear(tree);
  traverse(tree, clear);
 
  return tree;
};
 
traverse.hasType = function (tree, type, blacklistTypes) {
  blacklistTypes = [].concat(blacklistTypes || []);
 
  var has = false;
 
  Iif (_.isArray(tree)) {
    // array of nodes, find the first
    return !!_.find(tree, function (node) {
      return traverse.hasType(node, type, blacklistTypes);
    });
  } else {
    // 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;
      }
    }, blacklistTypes);
  }
 
  return has;
};