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

Statements: 97.01% (65 / 67)      Branches: 95.24% (40 / 42)      Functions: 90.91% (10 / 11)      Lines: 96.43% (54 / 56)      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 1251 1   1   102581     102580 65 111   65       102515 102515     102512     102512   102512 102933 102933   95667 99123 99123     99100   99097     99097 99097     99083     98886       98886     98875 89337 89337       95667 29588 33044       29577 33072     66079   66065 1             1   1           1 5239     1 472     1   1 7   7   7             7     6   5 42 2 2         5    
var VISITOR_KEYS = require("./visitor-keys");
var _            = require("lodash");
 
var traverse = module.exports = function (parent, callbacks, blacklistTypes) {
  // falsy node
  if (!parent) return;
 
  // array of nodes
  if (_.isArray(parent)) {
    _.each(parent, function (node) {
      traverse(node, callbacks, blacklistTypes);
    });
    return;
  }
 
  // unknown node type to traverse
  var keys = 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;
 
      // enter
      Eif (callbacks.enter) {
        result = callbacks.enter(node, parent, obj, key);
 
        // stop iteration
        if (result === false) return;
 
        // replace node
        if (result != null) node = obj[key] = result;
      }
 
      // traverse node
      traverse(node, callbacks, blacklistTypes);
 
      // exit
      if (callbacks.exit) {
        result = callbacks.exit(node, parent, obj, key);
        if (result != null) obj[key] = result;
      }
    };
 
    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);
 
      if (parent[key] === traverse.Delete) {
        throw new Error("trying to delete property " + key + " from " +
                        parent.type + " but can't because it's required");
      }
    }
  });
};
 
traverse.FUNCTION_TYPES = ["ArrowFunctionExpression", "FunctionDeclaration", "FunctionExpression"];
 
traverse.aliases = {
  ArrowFunctionExpression: ["Function"],
  FunctionDeclaration:     ["Function"],
  FunctionExpression:      ["Function"]
};
 
traverse.isFunction = function (node) {
  return _.contains(traverse.FUNCTION_TYPES, node.type);
};
 
traverse.isPattern = function (node) {
  return node.type === "ArrayPattern" || node.type === "ObjectPattern";
};
 
traverse.Delete = {};
 
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;
};