<commit_before>var walk = require("acorn-walk");

exports.buildScopes = function(ast, fail) {
  var scopes = [];

  function makeScope(prev, type) {
    var scope = {vars: Object.create(null), prev: prev, type: type};
    scopes.push(scope);
    return scope;
  }
  function fnScope(scope) {
    while (scope.type != "fn") scope = scope.prev;
    return scope;
  }
  function addVar(scope, name, type, node, deadZone, written) {
    if (deadZone && (name in scope.vars))
      fail("Duplicate definition of " + name, node.loc);
    scope.vars[name] = {type: type, node: node, deadZone: deadZone && scope,
                        written: written, read: false};
  }

  function makeCx(scope, binding) {
    return {scope: scope, binding: binding};
  }

  function isBlockScopedDecl(node) {
    return node.type == "VariableDeclaration" && node.kind != "var";
  }

  var topScope = makeScope(null, "fn");

  walk.recursive(ast, makeCx(topScope), {
    Function: function(node, cx, c) {
      var inner = node.scope = node.body.scope = makeScope(cx.scope, "fn");
      var innerCx = makeCx(inner, {scope: inner, type: "argument", deadZone: true, written: true});
      for (var i = 0; i < node.params.length; ++i)
        c(node.params[i], innerCx, "Pattern");

      if (node.id) {
        var decl = node.type == "FunctionDeclaration";
        addVar(decl ? cx.scope : inner, node.id.name,
               decl ? "function" : "function name", node.id, false, true);
      }
      c(node.body, innerCx, node.expression ? "Expression" : "Statement")
    },
    TryStatement: function(node, cx, c) {
      c(node.block, cx, "Statement");
      if (node.handler) {
        var inner = node.handler.body.scope = makeScope(cx.scope, "block");
        addVar(inner, node.handler.param.name, "catch clause", node.handler.param, false, true);
        c(node.handler.body, makeCx(inner), "Statement");
      }
      if (node.finalizer) c(node.finalizer, cx, "Statement");<commit_msg>Don't crash on variable-less catch<commit_after>var walk = require("acorn-walk");

exports.buildScopes = function(ast, fail) {
  var scopes = [];

  function makeScope(prev, type) {
    var scope = {vars: Object.create(null), prev: prev, type: type};
    scopes.push(scope);
    return scope;
  }
  function fnScope(scope) {
    while (scope.type != "fn") scope = scope.prev;
    return scope;
  }
  function addVar(scope, name, type, node, deadZone, written) {
    if (deadZone && (name in scope.vars))
      fail("Duplicate definition of " + name, node.loc);
    scope.vars[name] = {type: type, node: node, deadZone: deadZone && scope,
                        written: written, read: false};
  }

  function makeCx(scope, binding) {
    return {scope: scope, binding: binding};
  }

  function isBlockScopedDecl(node) {
    return node.type == "VariableDeclaration" && node.kind != "var";
  }

  var topScope = makeScope(null, "fn");

  walk.recursive(ast, makeCx(topScope), {
    Function: function(node, cx, c) {
      var inner = node.scope = node.body.scope = makeScope(cx.scope, "fn");
      var innerCx = makeCx(inner, {scope: inner, type: "argument", deadZone: true, written: true});
      for (var i = 0; i < node.params.length; ++i)
        c(node.params[i], innerCx, "Pattern");

      if (node.id) {
        var decl = node.type == "FunctionDeclaration";
        addVar(decl ? cx.scope : inner, node.id.name,
               decl ? "function" : "function name", node.id, false, true);
      }
      c(node.body, innerCx, node.expression ? "Expression" : "Statement")
    },
    TryStatement: function(node, cx, c) {
      c(node.block, cx, "Statement");
      if (node.handler) {
        var inner = node.handler.body.scope = makeScope(cx.scope, "block");
        if (node.handler.param) addVar(inner, node.handler.param.name, "catch clause", node.handler.param, false, true);
        c(node.handler.body, makeCx(inner), "Statement");
      }
      if (node.finalizer) c(node.finalizer, cx, "Statement");
{'fraction_non_alphanumeric': 0.15701028342111864, 'fraction_numerical': 0.0005016302984700275, 'mean_word_length': 3.0364372469635628, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '840632', 'n_tokens_mistral': 1301, 'n_tokens_neox': 1267, 'n_words': 331}