2011-06-15 13:19:50 -05:00
|
|
|
|
2011-07-05 04:48:19 -05:00
|
|
|
import ast::*;
|
2011-06-08 15:48:19 -05:00
|
|
|
import std::option;
|
|
|
|
import std::option::some;
|
|
|
|
import std::option::none;
|
2011-07-05 04:48:19 -05:00
|
|
|
import codemap::span;
|
2011-06-08 15:48:19 -05:00
|
|
|
|
2011-06-15 13:19:50 -05:00
|
|
|
|
2011-06-10 10:29:34 -05:00
|
|
|
// 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.
|
|
|
|
|
2011-07-26 09:35:31 -05:00
|
|
|
// Our typesystem doesn't do circular types, so the visitor record can not
|
|
|
|
// hold functions that take visitors. A vt tag is used to break the cycle.
|
2011-08-12 08:36:51 -05:00
|
|
|
tag vt<E> { mk_vt(visitor<E>); }
|
2011-06-08 15:48:19 -05:00
|
|
|
|
2011-08-12 08:36:51 -05:00
|
|
|
type visitor<E> =
|
2011-07-27 07:19:39 -05:00
|
|
|
// takes the components so that one function can be
|
|
|
|
// generic over constr and ty_constr
|
2011-08-12 09:15:18 -05:00
|
|
|
@{visit_mod: fn(&_mod, &span, &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_constr: fn(&path, &span, node_id, &E, &vt<E>),
|
2011-08-19 17:16:48 -05:00
|
|
|
visit_fn: fn(&_fn, &[ty_param], &span, &fn_ident, node_id, &E, &vt<E>)};
|
2011-06-08 15:48:19 -05:00
|
|
|
|
2011-08-12 08:36:51 -05:00
|
|
|
fn default_visitor<E>() -> visitor<E> {
|
2011-08-13 02:09:25 -05:00
|
|
|
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 visit_ty::<E>(_, _, _),
|
|
|
|
visit_constr: bind visit_constr::<E>(_, _, _, _, _),
|
|
|
|
visit_fn: bind visit_fn::<E>(_, _, _, _, _, _, _)};
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
|
2011-08-12 08:36:51 -05:00
|
|
|
fn visit_crate<E>(c: &crate, e: &E, v: &vt<E>) {
|
2011-07-01 07:05:54 -05:00
|
|
|
v.visit_mod(c.node.module, c.span, e, v);
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
|
2011-08-12 08:36:51 -05:00
|
|
|
fn visit_crate_directive<E>(cd: &@crate_directive, e: &E, v: &vt<E>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
alt cd.node {
|
|
|
|
cdir_src_mod(_, _, _) { }
|
|
|
|
cdir_dir_mod(_, _, cdirs, _) {
|
2011-08-15 23:54:52 -05:00
|
|
|
for cdir: @crate_directive in cdirs {
|
2011-07-27 07:19:39 -05:00
|
|
|
visit_crate_directive(cdir, e, v);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cdir_view_item(vi) { v.visit_view_item(vi, e, v); }
|
|
|
|
cdir_syntax(_) { }
|
|
|
|
cdir_auth(_, _) { }
|
2011-06-09 08:50:20 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-18 03:01:39 -05:00
|
|
|
fn visit_mod<E>(m: &_mod, _sp: &span, e: &E, v: &vt<E>) {
|
2011-08-15 23:54:52 -05:00
|
|
|
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); }
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
|
2011-08-18 03:01:39 -05:00
|
|
|
fn visit_view_item<E>(_vi: &@view_item, _e: &E, _v: &vt<E>) { }
|
2011-06-09 08:50:20 -05:00
|
|
|
|
2011-08-12 08:36:51 -05:00
|
|
|
fn visit_local<E>(loc: &@local, e: &E, v: &vt<E>) {
|
2011-07-28 05:01:45 -05:00
|
|
|
v.visit_pat(loc.node.pat, e, v);
|
2011-08-10 14:51:50 -05:00
|
|
|
v.visit_ty(loc.node.ty, e, v);
|
2011-07-27 07:19:39 -05:00
|
|
|
alt loc.node.init { none. { } some(i) { v.visit_expr(i.expr, e, v); } }
|
2011-06-13 19:04:15 -05:00
|
|
|
}
|
|
|
|
|
2011-08-12 08:36:51 -05:00
|
|
|
fn visit_item<E>(i: &@item, e: &E, v: &vt<E>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
alt i.node {
|
|
|
|
item_const(t, ex) { v.visit_ty(t, e, v); v.visit_expr(ex, e, v); }
|
|
|
|
item_fn(f, tp) { v.visit_fn(f, tp, i.span, some(i.ident), i.id, e, v); }
|
|
|
|
item_mod(m) { v.visit_mod(m, i.span, e, v); }
|
|
|
|
item_native_mod(nm) {
|
2011-08-15 23:54:52 -05:00
|
|
|
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); }
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
|
|
|
item_ty(t, _) { v.visit_ty(t, e, v); }
|
|
|
|
item_res(f, dtor_id, tps, _) {
|
|
|
|
v.visit_fn(f, tps, i.span, some(i.ident), dtor_id, e, v);
|
|
|
|
}
|
|
|
|
item_tag(variants, _) {
|
2011-08-15 23:54:52 -05:00
|
|
|
for vr: variant in variants {
|
|
|
|
for va: variant_arg in vr.node.args { v.visit_ty(va.ty, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
item_obj(ob, _, _) {
|
2011-08-15 23:54:52 -05:00
|
|
|
for f: obj_field in ob.fields { v.visit_ty(f.ty, e, v); }
|
|
|
|
for m: @method in ob.methods {
|
2011-08-19 17:16:48 -05:00
|
|
|
v.visit_fn(m.node.meth, [], m.span, some(m.node.ident), m.node.id,
|
|
|
|
e, v);
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
|
|
|
}
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-12 08:36:51 -05:00
|
|
|
fn visit_ty<E>(t: &@ty, e: &E, v: &vt<E>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
alt t.node {
|
|
|
|
ty_nil. {/* no-op */ }
|
|
|
|
ty_bot. {/* no-op */ }
|
|
|
|
ty_bool. {/* no-op */ }
|
|
|
|
ty_int. {/* no-op */ }
|
|
|
|
ty_float. {/* no-op */ }
|
|
|
|
ty_uint. {/* no-op */ }
|
|
|
|
ty_machine(_) {/* no-op */ }
|
|
|
|
ty_char. {/* no-op */ }
|
2011-09-02 18:45:00 -05:00
|
|
|
ty_str. {/* no-op */ }
|
2011-07-27 07:19:39 -05:00
|
|
|
ty_box(mt) { v.visit_ty(mt.ty, e, v); }
|
2011-08-18 16:11:06 -05:00
|
|
|
ty_vec(mt) { v.visit_ty(mt.ty, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
ty_ptr(mt) { v.visit_ty(mt.ty, e, v); }
|
|
|
|
ty_port(t) { v.visit_ty(t, e, v); }
|
|
|
|
ty_chan(t) { v.visit_ty(t, e, v); }
|
|
|
|
ty_task. {/* no-op */ }
|
|
|
|
ty_rec(flds) {
|
2011-08-15 23:54:52 -05:00
|
|
|
for f: ty_field in flds { v.visit_ty(f.node.mt.ty, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
2011-08-19 17:16:48 -05:00
|
|
|
ty_tup(ts) { for tt in ts { v.visit_ty(tt, e, v); } }
|
2011-07-27 07:19:39 -05:00
|
|
|
ty_fn(_, args, out, _, constrs) {
|
2011-08-15 23:54:52 -05:00
|
|
|
for a: ty_arg in args { v.visit_ty(a.node.ty, e, v); }
|
|
|
|
for c: @constr in constrs {
|
2011-07-27 07:19:39 -05:00
|
|
|
v.visit_constr(c.node.path, c.span, c.node.id, e, v);
|
|
|
|
}
|
|
|
|
v.visit_ty(out, e, v);
|
|
|
|
}
|
|
|
|
ty_obj(tmeths) {
|
2011-08-15 23:54:52 -05:00
|
|
|
for m: ty_method in tmeths {
|
|
|
|
for a: ty_arg in m.node.inputs { v.visit_ty(a.node.ty, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
v.visit_ty(m.node.output, e, v);
|
|
|
|
}
|
|
|
|
}
|
2011-08-15 23:54:52 -05:00
|
|
|
ty_path(p, _) { for tp: @ty in p.node.types { v.visit_ty(tp, e, v); } }
|
2011-07-27 07:19:39 -05:00
|
|
|
ty_type. {/* no-op */ }
|
|
|
|
ty_constr(t, cs) {
|
|
|
|
v.visit_ty(t, e, v);
|
2011-08-12 09:15:18 -05:00
|
|
|
for tc: @spanned<constr_general_<path, node_id>> in cs {
|
2011-07-27 07:19:39 -05:00
|
|
|
v.visit_constr(tc.node.path, tc.span, tc.node.id, e, v);
|
|
|
|
}
|
|
|
|
}
|
2011-08-10 14:51:50 -05:00
|
|
|
ty_infer. {/* no-op */ }
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-18 03:01:39 -05:00
|
|
|
fn visit_constr<E>(_operator: &path, _sp: &span, _id: node_id, _e: &E,
|
|
|
|
_v: &vt<E>) {
|
2011-06-10 21:12:42 -05:00
|
|
|
// default
|
|
|
|
}
|
|
|
|
|
2011-08-12 08:36:51 -05:00
|
|
|
fn visit_pat<E>(p: &@pat, e: &E, v: &vt<E>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
alt p.node {
|
|
|
|
pat_tag(path, children) {
|
2011-08-15 23:54:52 -05:00
|
|
|
for tp: @ty in path.node.types { v.visit_ty(tp, e, v); }
|
|
|
|
for child: @pat in children { v.visit_pat(child, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
|
|
|
pat_rec(fields, _) {
|
2011-08-15 23:54:52 -05:00
|
|
|
for f: field_pat in fields { v.visit_pat(f.pat, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
2011-08-19 17:16:48 -05:00
|
|
|
pat_tup(elts) { for elt in elts { v.visit_pat(elt, e, v); } }
|
2011-07-27 07:19:39 -05:00
|
|
|
pat_box(inner) { v.visit_pat(inner, e, v); }
|
|
|
|
_ { }
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-12 08:36:51 -05:00
|
|
|
fn visit_native_item<E>(ni: &@native_item, e: &E, v: &vt<E>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
alt ni.node {
|
|
|
|
native_item_fn(_, fd, _) { visit_fn_decl(fd, e, v); }
|
|
|
|
native_item_ty. { }
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-12 08:36:51 -05:00
|
|
|
fn visit_fn_decl<E>(fd: &fn_decl, e: &E, v: &vt<E>) {
|
2011-08-15 23:54:52 -05:00
|
|
|
for a: arg in fd.inputs { v.visit_ty(a.ty, e, v); }
|
|
|
|
for c: @constr in fd.constraints {
|
2011-07-19 19:52:34 -05:00
|
|
|
v.visit_constr(c.node.path, c.span, c.node.id, e, v);
|
|
|
|
}
|
2011-07-01 07:05:54 -05:00
|
|
|
v.visit_ty(fd.output, e, v);
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
|
2011-08-18 03:01:39 -05:00
|
|
|
fn visit_fn<E>(f: &_fn, _tp: &[ty_param], _sp: &span, _i: &fn_ident,
|
|
|
|
_id: node_id, e: &E, v: &vt<E>) {
|
2011-06-08 15:48:19 -05:00
|
|
|
visit_fn_decl(f.decl, e, v);
|
2011-07-01 07:05:54 -05:00
|
|
|
v.visit_block(f.body, e, v);
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
|
2011-08-12 08:36:51 -05:00
|
|
|
fn visit_block<E>(b: &ast::blk, e: &E, v: &vt<E>) {
|
2011-08-15 23:54:52 -05:00
|
|
|
for s: @stmt in b.node.stmts { v.visit_stmt(s, e, v); }
|
2011-06-08 15:48:19 -05:00
|
|
|
visit_expr_opt(b.node.expr, e, v);
|
|
|
|
}
|
|
|
|
|
2011-08-12 08:36:51 -05:00
|
|
|
fn visit_stmt<E>(s: &@stmt, e: &E, v: &vt<E>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
alt s.node {
|
|
|
|
stmt_decl(d, _) { v.visit_decl(d, e, v); }
|
|
|
|
stmt_expr(ex, _) { v.visit_expr(ex, e, v); }
|
|
|
|
stmt_crate_directive(cd) { visit_crate_directive(cd, e, v); }
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-12 08:36:51 -05:00
|
|
|
fn visit_decl<E>(d: &@decl, e: &E, v: &vt<E>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
alt d.node {
|
|
|
|
decl_local(locs) {
|
2011-08-15 23:54:52 -05:00
|
|
|
for loc: @ast::local in locs { v.visit_local(loc, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
|
|
|
decl_item(it) { v.visit_item(it, e, v); }
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-12 08:36:51 -05:00
|
|
|
fn visit_expr_opt<E>(eo: option::t<@expr>, e: &E, v: &vt<E>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
alt eo { none. { } some(ex) { v.visit_expr(ex, e, v); } }
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
|
2011-08-12 08:36:51 -05:00
|
|
|
fn visit_exprs<E>(exprs: &[@expr], e: &E, v: &vt<E>) {
|
2011-08-15 23:54:52 -05:00
|
|
|
for ex: @expr in exprs { v.visit_expr(ex, e, v); }
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
|
2011-08-12 08:36:51 -05:00
|
|
|
fn visit_mac<E>(m: mac, e: &E, v: &vt<E>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
alt m.node {
|
2011-07-27 19:36:37 -05:00
|
|
|
ast::mac_invoc(pth, arg, body) { visit_expr(arg, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
ast::mac_embed_type(ty) { v.visit_ty(ty, e, v); }
|
|
|
|
ast::mac_embed_block(blk) { v.visit_block(blk, e, v); }
|
|
|
|
ast::mac_ellipsis. { }
|
2011-07-08 18:35:09 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-12 08:36:51 -05:00
|
|
|
fn visit_expr<E>(ex: &@expr, e: &E, v: &vt<E>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
alt ex.node {
|
2011-08-18 13:37:19 -05:00
|
|
|
expr_vec(es, _) { visit_exprs(es, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
expr_rec(flds, base) {
|
2011-08-15 23:54:52 -05:00
|
|
|
for f: field in flds { v.visit_expr(f.node.expr, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
visit_expr_opt(base, e, v);
|
|
|
|
}
|
2011-08-19 17:16:48 -05:00
|
|
|
expr_tup(elts) { for el in elts { v.visit_expr(el, e, v); } }
|
2011-07-27 07:19:39 -05:00
|
|
|
expr_call(callee, args) {
|
|
|
|
visit_exprs(args, e, v);
|
2011-08-30 10:03:00 -05:00
|
|
|
v.visit_expr(callee, e, v);
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
|
|
|
expr_self_method(_) { }
|
|
|
|
expr_bind(callee, args) {
|
|
|
|
v.visit_expr(callee, e, v);
|
2011-08-12 09:15:18 -05:00
|
|
|
for eo: option::t<@expr> in args { visit_expr_opt(eo, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
|
|
|
expr_binary(_, a, b) { v.visit_expr(a, e, v); v.visit_expr(b, e, v); }
|
|
|
|
expr_unary(_, a) { v.visit_expr(a, e, v); }
|
|
|
|
expr_lit(_) { }
|
|
|
|
expr_cast(x, t) { v.visit_expr(x, e, v); v.visit_ty(t, e, v); }
|
|
|
|
expr_if(x, b, eo) {
|
|
|
|
v.visit_expr(x, e, v);
|
|
|
|
v.visit_block(b, e, v);
|
|
|
|
visit_expr_opt(eo, e, v);
|
|
|
|
}
|
|
|
|
expr_if_check(x, b, eo) {
|
|
|
|
v.visit_expr(x, e, v);
|
|
|
|
v.visit_block(b, e, v);
|
|
|
|
visit_expr_opt(eo, e, v);
|
|
|
|
}
|
|
|
|
expr_ternary(c, t, el) {
|
|
|
|
v.visit_expr(c, e, v);
|
|
|
|
v.visit_expr(t, e, v);
|
|
|
|
v.visit_expr(el, e, v);
|
|
|
|
}
|
|
|
|
expr_while(x, b) { v.visit_expr(x, e, v); v.visit_block(b, e, v); }
|
|
|
|
expr_for(dcl, x, b) | expr_for_each(dcl, x, b) {
|
|
|
|
v.visit_local(dcl, e, v);
|
|
|
|
v.visit_expr(x, e, v);
|
|
|
|
v.visit_block(b, e, v);
|
|
|
|
}
|
|
|
|
expr_do_while(b, x) { v.visit_block(b, e, v); v.visit_expr(x, e, v); }
|
|
|
|
expr_alt(x, arms) {
|
|
|
|
v.visit_expr(x, e, v);
|
2011-08-15 23:54:52 -05:00
|
|
|
for a: arm in arms { v.visit_arm(a, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
2011-08-19 17:16:48 -05:00
|
|
|
expr_fn(f) { v.visit_fn(f, [], ex.span, none, ex.id, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
expr_block(b) { v.visit_block(b, e, v); }
|
|
|
|
expr_assign(a, b) { v.visit_expr(b, e, v); v.visit_expr(a, e, v); }
|
2011-08-15 17:35:40 -05:00
|
|
|
expr_copy(a) { v.visit_expr(a, e, v); }
|
2011-07-27 07:19:39 -05:00
|
|
|
expr_move(a, b) { v.visit_expr(b, e, v); v.visit_expr(a, e, v); }
|
|
|
|
expr_swap(a, b) { v.visit_expr(a, e, v); v.visit_expr(b, e, v); }
|
|
|
|
expr_assign_op(_, a, b) {
|
|
|
|
v.visit_expr(b, e, v);
|
|
|
|
v.visit_expr(a, e, v);
|
|
|
|
}
|
|
|
|
expr_field(x, _) { v.visit_expr(x, e, v); }
|
|
|
|
expr_index(a, b) { v.visit_expr(a, e, v); v.visit_expr(b, e, v); }
|
2011-08-15 23:54:52 -05:00
|
|
|
expr_path(p) { for tp: @ty in p.node.types { v.visit_ty(tp, e, v); } }
|
2011-07-27 07:19:39 -05:00
|
|
|
expr_fail(eo) { visit_expr_opt(eo, e, v); }
|
|
|
|
expr_break. { }
|
|
|
|
expr_cont. { }
|
|
|
|
expr_ret(eo) { visit_expr_opt(eo, e, v); }
|
|
|
|
expr_put(eo) { visit_expr_opt(eo, e, v); }
|
|
|
|
expr_be(x) { v.visit_expr(x, e, v); }
|
|
|
|
expr_log(_, x) { v.visit_expr(x, e, v); }
|
|
|
|
expr_check(_, x) { v.visit_expr(x, e, v); }
|
|
|
|
expr_assert(x) { v.visit_expr(x, e, v); }
|
|
|
|
expr_anon_obj(anon_obj) {
|
|
|
|
alt anon_obj.fields {
|
|
|
|
none. { }
|
|
|
|
some(fields) {
|
2011-08-15 23:54:52 -05:00
|
|
|
for f: anon_obj_field in fields {
|
2011-07-27 07:19:39 -05:00
|
|
|
v.visit_ty(f.ty, e, v);
|
|
|
|
v.visit_expr(f.expr, e, v);
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
|
|
|
}
|
2011-07-28 16:43:19 -05:00
|
|
|
alt anon_obj.inner_obj {
|
2011-07-27 07:19:39 -05:00
|
|
|
none. { }
|
|
|
|
some(ex) { v.visit_expr(ex, e, v); }
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
2011-08-15 23:54:52 -05:00
|
|
|
for m: @method in anon_obj.methods {
|
2011-08-19 17:16:48 -05:00
|
|
|
v.visit_fn(m.node.meth, [], m.span, some(m.node.ident), m.node.id,
|
|
|
|
e, v);
|
2011-06-29 20:07:04 -05:00
|
|
|
}
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
|
|
|
expr_mac(mac) { visit_mac(mac, e, v); }
|
2011-08-15 16:36:52 -05:00
|
|
|
expr_uniq(x) { v.visit_expr(x, e, v); }
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-12 08:36:51 -05:00
|
|
|
fn visit_arm<E>(a: &arm, e: &E, v: &vt<E>) {
|
2011-08-15 23:54:52 -05:00
|
|
|
for p: @pat in a.pats { v.visit_pat(p, e, v); }
|
2011-08-22 07:38:48 -05:00
|
|
|
visit_expr_opt(a.guard, e, v);
|
2011-08-10 17:38:41 -05:00
|
|
|
v.visit_block(a.body, e, v);
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
2011-07-01 07:05:54 -05:00
|
|
|
|
2011-07-26 09:35:31 -05:00
|
|
|
// Simpler, non-context passing interface. Always walks the whole tree, simply
|
|
|
|
// calls the given functions on the nodes.
|
|
|
|
|
|
|
|
type simple_visitor =
|
2011-07-27 07:19:39 -05:00
|
|
|
// takes the components so that one function can be
|
|
|
|
// generic over constr and ty_constr
|
2011-08-19 17:16:48 -05:00
|
|
|
@{visit_mod: fn(&_mod, &span),
|
|
|
|
visit_view_item: fn(&@view_item),
|
|
|
|
visit_native_item: fn(&@native_item),
|
|
|
|
visit_item: fn(&@item),
|
|
|
|
visit_local: fn(&@local),
|
|
|
|
visit_block: fn(&ast::blk),
|
|
|
|
visit_stmt: fn(&@stmt),
|
|
|
|
visit_arm: fn(&arm),
|
|
|
|
visit_pat: fn(&@pat),
|
|
|
|
visit_decl: fn(&@decl),
|
|
|
|
visit_expr: fn(&@expr),
|
|
|
|
visit_ty: fn(&@ty),
|
|
|
|
visit_constr: fn(&path, &span, node_id),
|
|
|
|
visit_fn: fn(&_fn, &[ty_param], &span, &fn_ident, node_id)};
|
2011-07-26 09:35:31 -05:00
|
|
|
|
|
|
|
fn default_simple_visitor() -> simple_visitor {
|
2011-08-18 03:01:39 -05:00
|
|
|
ret @{visit_mod: fn (_m: &_mod, _sp: &span) { },
|
|
|
|
visit_view_item: fn (_vi: &@view_item) { },
|
|
|
|
visit_native_item: fn (_ni: &@native_item) { },
|
|
|
|
visit_item: fn (_i: &@item) { },
|
|
|
|
visit_local: fn (_l: &@local) { },
|
|
|
|
visit_block: fn (_b: &ast::blk) { },
|
|
|
|
visit_stmt: fn (_s: &@stmt) { },
|
|
|
|
visit_arm: fn (_a: &arm) { },
|
|
|
|
visit_pat: fn (_p: &@pat) { },
|
|
|
|
visit_decl: fn (_d: &@decl) { },
|
|
|
|
visit_expr: fn (_e: &@expr) { },
|
|
|
|
visit_ty: fn (_t: &@ty) { },
|
|
|
|
visit_constr: fn (_p: &path, _sp: &span, _id: node_id) { },
|
2011-07-27 07:19:39 -05:00
|
|
|
visit_fn:
|
2011-08-18 03:01:39 -05:00
|
|
|
fn (_f: &_fn, _tps: &[ty_param], _sp: &span, _ident: &fn_ident,
|
|
|
|
_id: node_id) {
|
2011-07-27 07:19:39 -05:00
|
|
|
}};
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
|
|
|
|
2011-08-12 09:15:18 -05:00
|
|
|
fn mk_simple_visitor(v: &simple_visitor) -> vt<()> {
|
2011-08-19 17:16:48 -05:00
|
|
|
fn v_mod(f: fn(&_mod, &span), m: &_mod, sp: &span, e: &(), v: &vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(m, sp);
|
|
|
|
visit_mod(m, sp, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-08-19 17:16:48 -05:00
|
|
|
fn v_view_item(f: fn(&@view_item), vi: &@view_item, e: &(), v: &vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(vi);
|
|
|
|
visit_view_item(vi, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-08-19 17:16:48 -05:00
|
|
|
fn v_native_item(f: fn(&@native_item), ni: &@native_item, e: &(),
|
2011-08-12 09:15:18 -05:00
|
|
|
v: &vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(ni);
|
|
|
|
visit_native_item(ni, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-08-19 17:16:48 -05:00
|
|
|
fn v_item(f: fn(&@item), i: &@item, e: &(), v: &vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(i);
|
|
|
|
visit_item(i, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-08-19 17:16:48 -05:00
|
|
|
fn v_local(f: fn(&@local), l: &@local, e: &(), v: &vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(l);
|
|
|
|
visit_local(l, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-08-19 17:16:48 -05:00
|
|
|
fn v_block(f: fn(&ast::blk), bl: &ast::blk, e: &(), v: &vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(bl);
|
|
|
|
visit_block(bl, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-08-19 17:16:48 -05:00
|
|
|
fn v_stmt(f: fn(&@stmt), st: &@stmt, e: &(), v: &vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(st);
|
|
|
|
visit_stmt(st, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-08-19 17:16:48 -05:00
|
|
|
fn v_arm(f: fn(&arm), a: &arm, e: &(), v: &vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(a);
|
|
|
|
visit_arm(a, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-08-19 17:16:48 -05:00
|
|
|
fn v_pat(f: fn(&@pat), p: &@pat, e: &(), v: &vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(p);
|
|
|
|
visit_pat(p, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-08-19 17:16:48 -05:00
|
|
|
fn v_decl(f: fn(&@decl), d: &@decl, e: &(), v: &vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(d);
|
|
|
|
visit_decl(d, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-08-19 17:16:48 -05:00
|
|
|
fn v_expr(f: fn(&@expr), ex: &@expr, e: &(), v: &vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(ex);
|
|
|
|
visit_expr(ex, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-08-19 17:16:48 -05:00
|
|
|
fn v_ty(f: fn(&@ty), ty: &@ty, e: &(), v: &vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(ty);
|
|
|
|
visit_ty(ty, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-08-19 17:16:48 -05:00
|
|
|
fn v_constr(f: fn(&path, &span, node_id), pt: &path, sp: &span,
|
2011-08-12 09:15:18 -05:00
|
|
|
id: node_id, e: &(), v: &vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(pt, sp, id);
|
|
|
|
visit_constr(pt, sp, id, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-08-19 17:16:48 -05:00
|
|
|
fn v_fn(f: fn(&_fn, &[ty_param], &span, &fn_ident, node_id), ff: &_fn,
|
2011-08-04 18:20:09 -05:00
|
|
|
tps: &[ty_param], sp: &span, ident: &fn_ident, id: node_id,
|
2011-08-12 09:15:18 -05:00
|
|
|
e: &(), v: &vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(ff, tps, sp, ident, id);
|
|
|
|
visit_fn(ff, tps, sp, ident, id, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-07-27 07:19:39 -05:00
|
|
|
ret mk_vt(@{visit_mod: bind v_mod(v.visit_mod, _, _, _, _),
|
|
|
|
visit_view_item: bind v_view_item(v.visit_view_item, _, _, _),
|
|
|
|
visit_native_item:
|
|
|
|
bind v_native_item(v.visit_native_item, _, _, _),
|
|
|
|
visit_item: bind v_item(v.visit_item, _, _, _),
|
|
|
|
visit_local: bind v_local(v.visit_local, _, _, _),
|
|
|
|
visit_block: bind v_block(v.visit_block, _, _, _),
|
|
|
|
visit_stmt: bind v_stmt(v.visit_stmt, _, _, _),
|
|
|
|
visit_arm: bind v_arm(v.visit_arm, _, _, _),
|
|
|
|
visit_pat: bind v_pat(v.visit_pat, _, _, _),
|
|
|
|
visit_decl: bind v_decl(v.visit_decl, _, _, _),
|
|
|
|
visit_expr: bind v_expr(v.visit_expr, _, _, _),
|
|
|
|
visit_ty: bind v_ty(v.visit_ty, _, _, _),
|
|
|
|
visit_constr: bind v_constr(v.visit_constr, _, _, _, _, _),
|
|
|
|
visit_fn: bind v_fn(v.visit_fn, _, _, _, _, _, _, _)});
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
|
|
|
|
2011-06-08 15:48:19 -05:00
|
|
|
// Local Variables:
|
|
|
|
// mode: rust
|
|
|
|
// fill-column: 78;
|
|
|
|
// indent-tabs-mode: nil
|
|
|
|
// c-basic-offset: 4
|
|
|
|
// buffer-file-coding-system: utf-8-unix
|
|
|
|
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
|
|
|
|
// End:
|