1
Fork 0

Make ast::visit only descend into types when necessary

If visit_ty is not overridden, it uses a stub function which does not
descend into types.

Closes #1204
This commit is contained in:
Marijn Haverbeke 2011-11-22 10:57:47 +01:00
parent 1a13504796
commit 8cc852af8c
2 changed files with 15 additions and 7 deletions

View file

@ -113,10 +113,9 @@ type ctx = {tcx: ty::ctxt, mut_map: mut_map};
fn check_crate(tcx: ty::ctxt, crate: @crate) -> mut_map { fn check_crate(tcx: ty::ctxt, crate: @crate) -> mut_map {
let cx = @{tcx: tcx, mut_map: std::map::new_int_hash()}; let cx = @{tcx: tcx, mut_map: std::map::new_int_hash()};
let v = let v = @{visit_expr: bind visit_expr(cx, _, _, _),
@{visit_expr: bind visit_expr(cx, _, _, _), visit_decl: bind visit_decl(cx, _, _, _)
visit_decl: bind visit_decl(cx, _, _, _) with *visit::default_visitor()};
with *visit::default_visitor::<()>()};
visit::visit_crate(*crate, (), visit::mk_vt(v)); visit::visit_crate(*crate, (), visit::mk_vt(v));
ret cx.mut_map; ret cx.mut_map;
} }

View file

@ -45,7 +45,7 @@ fn default_visitor<E>() -> visitor<E> {
visit_pat: bind visit_pat::<E>(_, _, _), visit_pat: bind visit_pat::<E>(_, _, _),
visit_decl: bind visit_decl::<E>(_, _, _), visit_decl: bind visit_decl::<E>(_, _, _),
visit_expr: bind visit_expr::<E>(_, _, _), visit_expr: bind visit_expr::<E>(_, _, _),
visit_ty: bind visit_ty::<E>(_, _, _), visit_ty: bind skip_ty::<E>(_, _, _),
visit_constr: bind visit_constr::<E>(_, _, _, _, _), visit_constr: bind visit_constr::<E>(_, _, _, _, _),
visit_fn: bind visit_fn::<E>(_, _, _, _, _, _, _)}; visit_fn: bind visit_fn::<E>(_, _, _, _, _, _, _)};
} }
@ -109,6 +109,8 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
} }
} }
fn skip_ty<E>(_t: @ty, _e: E, _v: vt<E>) {}
fn visit_ty<E>(t: @ty, e: E, v: vt<E>) { fn visit_ty<E>(t: @ty, e: E, v: vt<E>) {
alt t.node { alt t.node {
ty_nil. {/* no-op */ } ty_nil. {/* no-op */ }
@ -355,6 +357,8 @@ type simple_visitor =
visit_constr: fn@(path, span, node_id), visit_constr: fn@(path, span, node_id),
visit_fn: fn@(_fn, [ty_param], span, fn_ident, node_id)}; visit_fn: fn@(_fn, [ty_param], span, fn_ident, node_id)};
fn simple_ignore_ty(_t: @ty) {}
fn default_simple_visitor() -> simple_visitor { fn default_simple_visitor() -> simple_visitor {
ret @{visit_mod: fn(_m: _mod, _sp: span) { }, ret @{visit_mod: fn(_m: _mod, _sp: span) { },
visit_view_item: fn(_vi: @view_item) { }, visit_view_item: fn(_vi: @view_item) { },
@ -367,7 +371,7 @@ fn default_simple_visitor() -> simple_visitor {
visit_pat: fn(_p: @pat) { }, visit_pat: fn(_p: @pat) { },
visit_decl: fn(_d: @decl) { }, visit_decl: fn(_d: @decl) { },
visit_expr: fn(_e: @expr) { }, visit_expr: fn(_e: @expr) { },
visit_ty: fn(_t: @ty) { }, visit_ty: simple_ignore_ty,
visit_constr: fn(_p: path, _sp: span, _id: node_id) { }, visit_constr: fn(_p: path, _sp: span, _id: node_id) { },
visit_fn: visit_fn:
fn(_f: _fn, _tps: [ty_param], _sp: span, _ident: fn_ident, fn(_f: _fn, _tps: [ty_param], _sp: span, _ident: fn_ident,
@ -436,6 +440,11 @@ fn mk_simple_visitor(v: simple_visitor) -> vt<()> {
f(ff, tps, sp, ident, id); f(ff, tps, sp, ident, id);
visit_fn(ff, tps, sp, ident, id, e, v); visit_fn(ff, tps, sp, ident, id, e, v);
} }
let visit_ty = if v.visit_ty == simple_ignore_ty {
bind skip_ty(_, _, _)
} else {
bind v_ty(v.visit_ty, _, _, _)
};
ret mk_vt(@{visit_mod: bind v_mod(v.visit_mod, _, _, _, _), ret mk_vt(@{visit_mod: bind v_mod(v.visit_mod, _, _, _, _),
visit_view_item: bind v_view_item(v.visit_view_item, _, _, _), visit_view_item: bind v_view_item(v.visit_view_item, _, _, _),
visit_native_item: visit_native_item:
@ -448,7 +457,7 @@ fn mk_simple_visitor(v: simple_visitor) -> vt<()> {
visit_pat: bind v_pat(v.visit_pat, _, _, _), visit_pat: bind v_pat(v.visit_pat, _, _, _),
visit_decl: bind v_decl(v.visit_decl, _, _, _), visit_decl: bind v_decl(v.visit_decl, _, _, _),
visit_expr: bind v_expr(v.visit_expr, _, _, _), visit_expr: bind v_expr(v.visit_expr, _, _, _),
visit_ty: bind v_ty(v.visit_ty, _, _, _), visit_ty: visit_ty,
visit_constr: bind v_constr(v.visit_constr, _, _, _, _, _), visit_constr: bind v_constr(v.visit_constr, _, _, _, _, _),
visit_fn: bind v_fn(v.visit_fn, _, _, _, _, _, _, _)}); visit_fn: bind v_fn(v.visit_fn, _, _, _, _, _, _, _)});
} }