<commit_before>
import ast::*;
import codemap::span;

// Context-passing AST walker. Each overridden visit method has full control
// over what happens with its node, it can do its own traversal of the node's
// children (potentially passing in different contexts to each), call
// visit::visit_* to apply the default traversal algorithm (again, it can
// override the context), or prevent deeper traversal by doing nothing.

// Our typesystem doesn't do circular types, so the visitor record can not
// hold functions that take visitors. A vt enum is used to break the cycle.
enum vt<E> { mk_vt(visitor<E>), }

enum fn_kind {
    fk_item_fn(ident, [ty_param]), //< an item declared with fn()
    fk_method(ident, [ty_param], @method),
    fk_res(ident, [ty_param]),
    fk_anon(proto),  //< an anonymous function like fn@(...)
    fk_fn_block,     //< a block {||...}
}

fn name_of_fn(fk: fn_kind) -> ident {
    alt fk {
      fk_item_fn(name, _) | fk_method(name, _, _) | fk_res(name, _) { name }
      fk_anon(_) | fk_fn_block { "anon" }
    }
}

fn tps_of_fn(fk: fn_kind) -> [ty_param] {
    alt fk {
      fk_item_fn(_, tps) | fk_method(_, tps, _) | fk_res(_, tps) { tps }
      fk_anon(_) | fk_fn_block { [] }
    }
}

type visitor<E> =
    // takes the components so that one function can be
    // generic over constr and ty_constr
    @{visit_mod: fn@(_mod, span, node_id, E, vt<E>),
      visit_view_item: fn@(@view_item, E, vt<E>),
      visit_native_item: fn@(@native_item, E, vt<E>),
      visit_item: fn@(@item, E, vt<E>),
      visit_local: fn@(@local, E, vt<E>),
      visit_block: fn@(ast::blk, E, vt<E>),
      visit_stmt: fn@(@stmt, E, vt<E>),
      visit_arm: fn@(arm, E, vt<E>),
      visit_pat: fn@(@pat, E, vt<E>),
      visit_decl: fn@(@decl, E, vt<E>),
      visit_expr: fn@(@expr, E, vt<E>),
      visit_ty: fn@(@ty, E, vt<E>),
      visit_ty_params: fn@([ty_param], E, vt<E>),
      visit_constr: fn@(@path, span, node_id, E, vt<E>),
      visit_fn: fn@(fn_kind, fn_decl, blk, span, node_id, E, vt<E>),
      visit_class_item: fn@(span, privacy, class_member, E, vt<E>)};

fn default_visitor<E>() -> visitor<E> {
    ret @{visit_mod: bind visit_mod::<E>(_, _, _, _, _),
          visit_view_item: bind visit_view_item::<E>(_, _, _),
          visit_native_item: bind visit_native_item::<E>(_, _, _),
          visit_item: bind visit_item::<E>(_, _, _),
          visit_local: bind visit_local::<E>(_, _, _),
          visit_block: bind visit_block::<E>(_, _, _),
          visit_stmt: bind visit_stmt::<E>(_, _, _),
          visit_arm: bind visit_arm::<E>(_, _, _),
          visit_pat: bind visit_pat::<E>(_, _, _),
          visit_decl: bind visit_decl::<E>(_, _, _),
          visit_expr: bind visit_expr::<E>(_, _, _),
          visit_ty: bind skip_ty::<E>(_, _, _),
          visit_ty_params: bind visit_ty_params::<E>(_, _, _),
          visit_constr: bind visit_constr::<E>(_, _, _, _, _),
          visit_fn: bind visit_fn::<E>(_, _, _, _, _, _, _),
          visit_class_item: bind visit_class_item::<E>(_,_,_,_,_)};
}

fn visit_crate<E>(c: crate, e: E, v: vt<E>) {
    v.visit_mod(c.node.module, c.span, crate_node_id, e, v);
}

fn visit_crate_directive<E>(cd: @crate_directive, e: E, v: vt<E>) {
    alt cd.node {
      cdir_src_mod(_, _) { }
      cdir_dir_mod(_, cdirs, _) {
        for cdir: @crate_directive in cdirs {
            visit_crate_directive(cdir, e, v);
        }
      }
      cdir_view_item(vi) { v.visit_view_item(vi, e, v); }
      cdir_syntax(_) { }
    }
}

fn visit_mod<E>(m: _mod, _sp: span, _id: node_id, e: E, v: vt<E>) {
    for vi: @view_item in m.view_items { v.visit_view_item(vi, e, v); }
    for i: @item in m.items { v.visit_item(i, e, v); }
}

fn visit_view_item<E>(_vi: @view_item, _e: E, _v: vt<E>) { }

fn visit_local<E>(loc: @local, e: E, v: vt<E>) {
    v.visit_pat(loc.node.pat, e, v);
    v.visit_ty(loc.node.ty, e, v);
    alt loc.node.init { none { } some(i) { v.visit_expr(i.expr, e, v); } }
}

fn visit_item<E>(i: @item, e: E, v: vt<E>) {
    alt i.node {
      item_const(t, ex) { v.visit_ty(t, e, v); v.visit_expr(ex, e, v); }
      item_fn(decl, tp, body) {
        v.visit_fn(fk_item_fn(i.ident, tp), decl, body, i.span, i.id, e, v);
      }
      item_mod(m) { v.visit_mod(m, i.span, i.id, e, v); }
      item_native_mod(nm) {
        for vi: @view_item in nm.view_items { v.visit_view_item(vi, e, v); }
        for ni: @native_item in nm.items { v.visit_native_item(ni, e, v); }
      }
      item_ty(t, tps) { v.visit_ty(t, e, v); v.visit_ty_params(tps, e, v); }
      item_res(decl, tps, body, dtor_id, _) {
        v.visit_fn(fk_res(i.ident, tps), decl, body, i.span,
                   dtor_id, e, v);
      }
      item_enum(variants, tps) {
        v.visit_ty_params(tps, e, v);
        for vr: variant in variants {
            for va: variant_arg in vr.node.args { v.visit_ty(va.ty, e, v); }
        }
      }
      item_impl(tps, ifce, ty, methods) {
        v.visit_ty_params(tps, e, v);
        alt ifce { some(ty) { v.visit_ty(ty, e, v); } _ {} }
        v.visit_ty(ty, e, v);
        for m in methods {
            visit_method_helper(m, e, v)
        }
      }
      item_class(tps, members, ctor) {
          v.visit_ty_params(tps, e, v);
          for m in members {
             v.visit_class_item(m.span, m.node.privacy, m.node.decl, e, v);
          }
          visit_fn_decl(ctor.node.dec, e, v);
          v.visit_block(ctor.node.body, e, v);
      }
      item_iface(tps, methods) {
        v.visit_ty_params(tps, e, v);
        for m in methods {
            for a in m.decl.inputs { v.visit_ty(a.ty, e, v); }
            v.visit_ty(m.decl.output, e, v);
        }
      }
    }
}

fn visit_class_item<E>(_s: span, _p: privacy, cm: class_member,
                       e:E, v:vt<E>) {
    alt cm {
        instance_var(ident, t, mt, id) {
            v.visit_ty(t, e, v);
        }
        class_method(i) {
            v.visit_item(i, e, v);
        }
    }
}

fn skip_ty<E>(_t: @ty, _e: E, _v: vt<E>) {}

fn visit_ty<E>(t: @ty, e: E, v: vt<E>) {
    alt t.node {
      ty_box(mt) { v.visit_ty(mt.ty, e, v); }
      ty_uniq(mt) { v.visit_ty(mt.ty, e, v); }
      ty_vec(mt) { v.visit_ty(mt.ty, e, v); }
      ty_ptr(mt) { v.visit_ty(mt.ty, e, v); }
      ty_rec(flds) {
        for f: ty_field in flds { v.visit_ty(f.node.mt.ty, e, v); }
      }
      ty_tup(ts) { for tt in ts { v.visit_ty(tt, e, v); } }
      ty_fn(_, decl) {
        for a in decl.inputs { v.visit_ty(a.ty, e, v); }
        for c: @constr in decl.constraints {
            v.visit_constr(c.node.path, c.span, c.node.id, e, v);
        }
        v.visit_ty(decl.output, e, v);
      }
      ty_path(p, _) { visit_path(p, e, v); }
      ty_constr(t, cs) {
        v.visit_ty(t, e, v);
        for tc: @spanned<constr_general_<@path, node_id>> in cs {
            v.visit_constr(tc.node.path, tc.span, tc.node.id, e, v);
        }
      }
      _ {}
    }
}

fn visit_constr<E>(_operator: @path, _sp: span, _id: node_id, _e: E,
                   _v: vt<E>) {
    // default
}

fn visit_path<E>(p: @path, e: E, v: vt<E>) {<commit_msg>rustc: Add ty_rptr support to the visitor<commit_after>
import ast::*;
import codemap::span;

// Context-passing AST walker. Each overridden visit method has full control
// over what happens with its node, it can do its own traversal of the node's
// children (potentially passing in different contexts to each), call
// visit::visit_* to apply the default traversal algorithm (again, it can
// override the context), or prevent deeper traversal by doing nothing.

// Our typesystem doesn't do circular types, so the visitor record can not
// hold functions that take visitors. A vt enum is used to break the cycle.
enum vt<E> { mk_vt(visitor<E>), }

enum fn_kind {
    fk_item_fn(ident, [ty_param]), //< an item declared with fn()
    fk_method(ident, [ty_param], @method),
    fk_res(ident, [ty_param]),
    fk_anon(proto),  //< an anonymous function like fn@(...)
    fk_fn_block,     //< a block {||...}
}

fn name_of_fn(fk: fn_kind) -> ident {
    alt fk {
      fk_item_fn(name, _) | fk_method(name, _, _) | fk_res(name, _) { name }
      fk_anon(_) | fk_fn_block { "anon" }
    }
}

fn tps_of_fn(fk: fn_kind) -> [ty_param] {
    alt fk {
      fk_item_fn(_, tps) | fk_method(_, tps, _) | fk_res(_, tps) { tps }
      fk_anon(_) | fk_fn_block { [] }
    }
}

type visitor<E> =
    // takes the components so that one function can be
    // generic over constr and ty_constr
    @{visit_mod: fn@(_mod, span, node_id, E, vt<E>),
      visit_view_item: fn@(@view_item, E, vt<E>),
      visit_native_item: fn@(@native_item, E, vt<E>),
      visit_item: fn@(@item, E, vt<E>),
      visit_local: fn@(@local, E, vt<E>),
      visit_block: fn@(ast::blk, E, vt<E>),
      visit_stmt: fn@(@stmt, E, vt<E>),
      visit_arm: fn@(arm, E, vt<E>),
      visit_pat: fn@(@pat, E, vt<E>),
      visit_decl: fn@(@decl, E, vt<E>),
      visit_expr: fn@(@expr, E, vt<E>),
      visit_ty: fn@(@ty, E, vt<E>),
      visit_ty_params: fn@([ty_param], E, vt<E>),
      visit_constr: fn@(@path, span, node_id, E, vt<E>),
      visit_fn: fn@(fn_kind, fn_decl, blk, span, node_id, E, vt<E>),
      visit_class_item: fn@(span, privacy, class_member, E, vt<E>)};

fn default_visitor<E>() -> visitor<E> {
    ret @{visit_mod: bind visit_mod::<E>(_, _, _, _, _),
          visit_view_item: bind visit_view_item::<E>(_, _, _),
          visit_native_item: bind visit_native_item::<E>(_, _, _),
          visit_item: bind visit_item::<E>(_, _, _),
          visit_local: bind visit_local::<E>(_, _, _),
          visit_block: bind visit_block::<E>(_, _, _),
          visit_stmt: bind visit_stmt::<E>(_, _, _),
          visit_arm: bind visit_arm::<E>(_, _, _),
          visit_pat: bind visit_pat::<E>(_, _, _),
          visit_decl: bind visit_decl::<E>(_, _, _),
          visit_expr: bind visit_expr::<E>(_, _, _),
          visit_ty: bind skip_ty::<E>(_, _, _),
          visit_ty_params: bind visit_ty_params::<E>(_, _, _),
          visit_constr: bind visit_constr::<E>(_, _, _, _, _),
          visit_fn: bind visit_fn::<E>(_, _, _, _, _, _, _),
          visit_class_item: bind visit_class_item::<E>(_,_,_,_,_)};
}

fn visit_crate<E>(c: crate, e: E, v: vt<E>) {
    v.visit_mod(c.node.module, c.span, crate_node_id, e, v);
}

fn visit_crate_directive<E>(cd: @crate_directive, e: E, v: vt<E>) {
    alt cd.node {
      cdir_src_mod(_, _) { }
      cdir_dir_mod(_, cdirs, _) {
        for cdir: @crate_directive in cdirs {
            visit_crate_directive(cdir, e, v);
        }
      }
      cdir_view_item(vi) { v.visit_view_item(vi, e, v); }
      cdir_syntax(_) { }
    }
}

fn visit_mod<E>(m: _mod, _sp: span, _id: node_id, e: E, v: vt<E>) {
    for vi: @view_item in m.view_items { v.visit_view_item(vi, e, v); }
    for i: @item in m.items { v.visit_item(i, e, v); }
}

fn visit_view_item<E>(_vi: @view_item, _e: E, _v: vt<E>) { }

fn visit_local<E>(loc: @local, e: E, v: vt<E>) {
    v.visit_pat(loc.node.pat, e, v);
    v.visit_ty(loc.node.ty, e, v);
    alt loc.node.init { none { } some(i) { v.visit_expr(i.expr, e, v); } }
}

fn visit_item<E>(i: @item, e: E, v: vt<E>) {
    alt i.node {
      item_const(t, ex) { v.visit_ty(t, e, v); v.visit_expr(ex, e, v); }
      item_fn(decl, tp, body) {
        v.visit_fn(fk_item_fn(i.ident, tp), decl, body, i.span, i.id, e, v);
      }
      item_mod(m) { v.visit_mod(m, i.span, i.id, e, v); }
      item_native_mod(nm) {
        for vi: @view_item in nm.view_items { v.visit_view_item(vi, e, v); }
        for ni: @native_item in nm.items { v.visit_native_item(ni, e, v); }
      }
      item_ty(t, tps) { v.visit_ty(t, e, v); v.visit_ty_params(tps, e, v); }
      item_res(decl, tps, body, dtor_id, _) {
        v.visit_fn(fk_res(i.ident, tps), decl, body, i.span,
                   dtor_id, e, v);
      }
      item_enum(variants, tps) {
        v.visit_ty_params(tps, e, v);
        for vr: variant in variants {
            for va: variant_arg in vr.node.args { v.visit_ty(va.ty, e, v); }
        }
      }
      item_impl(tps, ifce, ty, methods) {
        v.visit_ty_params(tps, e, v);
        alt ifce { some(ty) { v.visit_ty(ty, e, v); } _ {} }
        v.visit_ty(ty, e, v);
        for m in methods {
            visit_method_helper(m, e, v)
        }
      }
      item_class(tps, members, ctor) {
          v.visit_ty_params(tps, e, v);
          for m in members {
             v.visit_class_item(m.span, m.node.privacy, m.node.decl, e, v);
          }
          visit_fn_decl(ctor.node.dec, e, v);
          v.visit_block(ctor.node.body, e, v);
      }
      item_iface(tps, methods) {
        v.visit_ty_params(tps, e, v);
        for m in methods {
            for a in m.decl.inputs { v.visit_ty(a.ty, e, v); }
            v.visit_ty(m.decl.output, e, v);
        }
      }
    }
}

fn visit_class_item<E>(_s: span, _p: privacy, cm: class_member,
                       e:E, v:vt<E>) {
    alt cm {
        instance_var(ident, t, mt, id) {
            v.visit_ty(t, e, v);
        }
        class_method(i) {
            v.visit_item(i, e, v);
        }
    }
}

fn skip_ty<E>(_t: @ty, _e: E, _v: vt<E>) {}

fn visit_ty<E>(t: @ty, e: E, v: vt<E>) {
    alt t.node {
      ty_box(mt) { v.visit_ty(mt.ty, e, v); }
      ty_uniq(mt) { v.visit_ty(mt.ty, e, v); }
      ty_vec(mt) { v.visit_ty(mt.ty, e, v); }
      ty_ptr(mt) { v.visit_ty(mt.ty, e, v); }
      ty_rptr(_, mt) { v.visit_ty(mt.ty, e, v); }
      ty_rec(flds) {
        for f: ty_field in flds { v.visit_ty(f.node.mt.ty, e, v); }
      }
      ty_tup(ts) { for tt in ts { v.visit_ty(tt, e, v); } }
      ty_fn(_, decl) {
        for a in decl.inputs { v.visit_ty(a.ty, e, v); }
        for c: @constr in decl.constraints {
            v.visit_constr(c.node.path, c.span, c.node.id, e, v);
        }
        v.visit_ty(decl.output, e, v);
      }
      ty_path(p, _) { visit_path(p, e, v); }
      ty_constr(t, cs) {
        v.visit_ty(t, e, v);
        for tc: @spanned<constr_general_<@path, node_id>> in cs {
            v.visit_constr(tc.node.path, tc.span, tc.node.id, e, v);
        }
      }
      _ {}
    }
}

fn visit_constr<E>(_operator: @path, _sp: span, _id: node_id, _e: E,
                   _v: vt<E>) {
    // default
}

fn visit_path<E>(p: @path, e: E, v: vt<E>) {
{'fraction_non_alphanumeric': 0.17407407407407408, 'fraction_numerical': 0.0, 'mean_word_length': 2.4090042877560744, 'pattern_counts': {'":': 0, '<': 131, '<?xml version=': 0, '>': 131, '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': '7118092', 'n_tokens_mistral': 5918, 'n_tokens_neox': 5953, 'n_words': 1323}