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

Statements: 96.23% (51 / 53)      Branches: 91.18% (31 / 34)      Functions: 100% (9 / 9)      Lines: 97.78% (44 / 45)      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 901 1   1 52131   52131 73 107   73     52058 52058   52058 546     52058 53254 53254   49172 49699 49699     49688     49681     49673     49669   49669     49662     49172 15389 15916       15382 15940     33783   33775               1   1 237   233 233   233 72 159     161 982 4 4         161    
var VISITOR_KEYS = require("./visitor-keys");
var _            = require("lodash");
 
var traverse = module.exports = function (parent, callbacks, blacklistTypes) {
  Iif (!parent) return;
 
  if (_.isArray(parent)) {
    _.each(parent, function (node) {
      traverse(node, callbacks, blacklistTypes);
    });
    return;
  }
 
  var keys = VISITOR_KEYS[parent.type] || [];
  blacklistTypes = blacklistTypes || [];
 
  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 (blacklistTypes.indexOf(node.type) >= 0) return;
 
      // enter
      var result = callbacks.enter(node, parent, obj, key);
 
      // stop iteration
      if (result === false) return;
 
      // replace node
      if (result != null) node = obj[key] = result;
 
      traverse(node, callbacks, blacklistTypes);
 
      // exit
      if (callbacks.exit) callbacks.exit(node, parent, obj, key);
    };
 
    if (_.isArray(nodes)) {
      _.each(nodes, function (node, i) {
        handle(nodes, i);
      });
 
      // remove deleted nodes
      parent[key] = _.flatten(parent[key]).filter(function (node) {
        return node !== traverse.Delete;
      });
    } else {
      handle(parent, key);
 
      Iif (parent[key] === traverse.Delete) {
        throw new Error("trying to delete property " + key + " from " +
                        parent.type + " but can't because it's required");
      }
    }
  });
};
 
traverse.Delete = {};
 
traverse.hasType = function (tree, type, blacklistTypes) {
  if (tree.type === type) return true;
 
  var has = false;
  blacklistTypes = blacklistTypes || [];
 
  if (_.isArray(tree)) {
    return !!_.find(tree, function (node) {
      return traverse.hasType(node, type, blacklistTypes);
    });
  } else {
    traverse(tree, function (node) {
      if (node.type === type) {
        has = true;
        return false;
      }
    }, blacklistTypes);
  }
 
  return has;
};