2012-12-03 18:48:01 -06:00
|
|
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2013-01-08 21:37:25 -06:00
|
|
|
use core::prelude::*;
|
|
|
|
|
2012-09-04 13:37:29 -05:00
|
|
|
use ast::*;
|
2012-12-23 16:41:37 -06:00
|
|
|
use ast;
|
|
|
|
use ast_util;
|
2012-09-04 13:37:29 -05:00
|
|
|
use codemap::span;
|
2012-12-23 16:41:37 -06:00
|
|
|
use parse;
|
|
|
|
|
|
|
|
use core::option;
|
|
|
|
use core::vec;
|
2011-06-08 15:48:19 -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
|
2012-01-19 16:24:03 -06:00
|
|
|
// hold functions that take visitors. A vt enum is used to break the cycle.
|
2013-01-29 16:41:40 -06:00
|
|
|
pub enum vt<E> { mk_vt(visitor<E>), }
|
2011-06-08 15:48:19 -05:00
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub enum fn_kind {
|
2013-02-18 23:25:44 -06:00
|
|
|
fk_item_fn(ident, &[ty_param], purity), // fn foo()
|
|
|
|
fk_method(ident, &[ty_param], &method), // fn foo(&self)
|
2013-01-31 19:12:29 -06:00
|
|
|
fk_anon(ast::Sigil), // fn@(x, y) { ... }
|
|
|
|
fk_fn_block, // |x, y| ...
|
2013-02-18 23:25:44 -06:00
|
|
|
fk_dtor( // class destructor
|
|
|
|
&[ty_param],
|
|
|
|
&[attribute],
|
|
|
|
node_id /* self id */,
|
|
|
|
def_id /* parent class id */
|
|
|
|
)
|
2012-05-14 16:13:32 -05:00
|
|
|
|
2011-12-29 22:07:55 -06:00
|
|
|
}
|
|
|
|
|
2013-02-18 23:25:44 -06:00
|
|
|
pub fn name_of_fn(fk: &fn_kind) -> ident {
|
|
|
|
match *fk {
|
2012-10-08 13:49:01 -05:00
|
|
|
fk_item_fn(name, _, _) | fk_method(name, _, _) => {
|
|
|
|
/* FIXME (#2543) */ copy name
|
|
|
|
}
|
2012-07-18 18:18:02 -05:00
|
|
|
fk_anon(*) | fk_fn_block(*) => parse::token::special_idents::anon,
|
|
|
|
fk_dtor(*) => parse::token::special_idents::dtor
|
2011-12-29 22:07:55 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-18 23:25:44 -06:00
|
|
|
pub fn tps_of_fn(fk: &fn_kind) -> ~[ty_param] {
|
|
|
|
match *fk {
|
2012-10-08 13:49:01 -05:00
|
|
|
fk_item_fn(_, tps, _) | fk_method(_, tps, _) |
|
2013-02-18 23:25:44 -06:00
|
|
|
fk_dtor(tps, _, _, _) => /* FIXME (#2543) */ vec::from_slice(tps),
|
2012-10-08 13:49:01 -05:00
|
|
|
fk_anon(*) | fk_fn_block(*) => ~[]
|
2011-12-29 22:07:55 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub struct Visitor<E> {
|
2013-02-18 23:25:44 -06:00
|
|
|
visit_mod: fn@(&_mod, span, node_id, E, vt<E>),
|
2013-01-08 16:00:45 -06:00
|
|
|
visit_view_item: fn@(@view_item, E, vt<E>),
|
|
|
|
visit_foreign_item: fn@(@foreign_item, E, vt<E>),
|
|
|
|
visit_item: fn@(@item, E, vt<E>),
|
|
|
|
visit_local: fn@(@local, E, vt<E>),
|
2013-02-18 00:20:36 -06:00
|
|
|
visit_block: fn@(&blk, E, vt<E>),
|
2013-01-08 16:00:45 -06:00
|
|
|
visit_stmt: fn@(@stmt, E, vt<E>),
|
2013-02-18 00:20:36 -06:00
|
|
|
visit_arm: fn@(&arm, E, vt<E>),
|
2013-01-08 16:00:45 -06:00
|
|
|
visit_pat: fn@(@pat, E, vt<E>),
|
|
|
|
visit_decl: fn@(@decl, E, vt<E>),
|
|
|
|
visit_expr: fn@(@expr, E, vt<E>),
|
|
|
|
visit_expr_post: fn@(@expr, E, vt<E>),
|
|
|
|
visit_ty: fn@(@Ty, E, vt<E>),
|
2013-02-18 23:25:44 -06:00
|
|
|
visit_ty_params: fn@(&[ty_param], E, vt<E>),
|
2013-02-18 00:20:36 -06:00
|
|
|
visit_fn: fn@(&fn_kind, &fn_decl, &blk, span, node_id, E, vt<E>),
|
|
|
|
visit_ty_method: fn@(&ty_method, E, vt<E>),
|
|
|
|
visit_trait_method: fn@(&trait_method, E, vt<E>),
|
2013-02-18 23:25:44 -06:00
|
|
|
visit_struct_def: fn@(@struct_def, ident, &[ty_param], node_id, E,
|
2013-01-08 16:00:45 -06:00
|
|
|
vt<E>),
|
|
|
|
visit_struct_field: fn@(@struct_field, E, vt<E>),
|
|
|
|
visit_struct_method: fn@(@method, E, vt<E>)
|
|
|
|
}
|
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub type visitor<E> = @Visitor<E>;
|
2011-06-08 15:48:19 -05:00
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub fn default_visitor<E>() -> visitor<E> {
|
2013-01-08 16:00:45 -06:00
|
|
|
return @Visitor {
|
|
|
|
visit_mod: |a,b,c,d,e|visit_mod::<E>(a, b, c, d, e),
|
|
|
|
visit_view_item: |a,b,c|visit_view_item::<E>(a, b, c),
|
|
|
|
visit_foreign_item: |a,b,c|visit_foreign_item::<E>(a, b, c),
|
|
|
|
visit_item: |a,b,c|visit_item::<E>(a, b, c),
|
|
|
|
visit_local: |a,b,c|visit_local::<E>(a, b, c),
|
|
|
|
visit_block: |a,b,c|visit_block::<E>(a, b, c),
|
|
|
|
visit_stmt: |a,b,c|visit_stmt::<E>(a, b, c),
|
|
|
|
visit_arm: |a,b,c|visit_arm::<E>(a, b, c),
|
|
|
|
visit_pat: |a,b,c|visit_pat::<E>(a, b, c),
|
|
|
|
visit_decl: |a,b,c|visit_decl::<E>(a, b, c),
|
|
|
|
visit_expr: |a,b,c|visit_expr::<E>(a, b, c),
|
|
|
|
visit_expr_post: |_a,_b,_c| (),
|
|
|
|
visit_ty: |a,b,c|skip_ty::<E>(a, b, c),
|
|
|
|
visit_ty_params: |a,b,c|visit_ty_params::<E>(a, b, c),
|
|
|
|
visit_fn: |a,b,c,d,e,f,g|visit_fn::<E>(a, b, c, d, e, f, g),
|
|
|
|
visit_ty_method: |a,b,c|visit_ty_method::<E>(a, b, c),
|
|
|
|
visit_trait_method: |a,b,c|visit_trait_method::<E>(a, b, c),
|
|
|
|
visit_struct_def: |a,b,c,d,e,f|visit_struct_def::<E>(a, b, c,
|
|
|
|
d, e, f),
|
|
|
|
visit_struct_field: |a,b,c|visit_struct_field::<E>(a, b, c),
|
|
|
|
visit_struct_method: |a,b,c|visit_struct_method::<E>(a, b, c)
|
|
|
|
};
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub fn visit_crate<E>(c: crate, e: E, v: vt<E>) {
|
2013-02-18 23:25:44 -06:00
|
|
|
(v.visit_mod)(&c.node.module, c.span, crate_node_id, e, v);
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
|
2013-02-18 23:25:44 -06:00
|
|
|
pub fn visit_mod<E>(m: &_mod, _sp: span, _id: node_id, e: E, v: vt<E>) {
|
2012-11-29 19:51:16 -06:00
|
|
|
for m.view_items.each |vi| { (v.visit_view_item)(*vi, e, v); }
|
|
|
|
for m.items.each |i| { (v.visit_item)(*i, e, v); }
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub fn visit_view_item<E>(_vi: @view_item, _e: E, _v: vt<E>) { }
|
2011-06-09 08:50:20 -05:00
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub fn visit_local<E>(loc: @local, e: E, v: vt<E>) {
|
2012-11-29 19:51:16 -06:00
|
|
|
(v.visit_pat)(loc.node.pat, e, v);
|
|
|
|
(v.visit_ty)(loc.node.ty, e, v);
|
2012-08-06 14:34:08 -05:00
|
|
|
match loc.node.init {
|
2012-08-20 14:23:37 -05:00
|
|
|
None => (),
|
2012-11-29 19:51:16 -06:00
|
|
|
Some(ex) => (v.visit_expr)(ex, e, v)
|
2012-08-03 21:59:04 -05:00
|
|
|
}
|
2011-06-13 19:04:15 -05:00
|
|
|
}
|
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub fn visit_item<E>(i: @item, e: E, v: vt<E>) {
|
2012-08-06 14:34:08 -05:00
|
|
|
match i.node {
|
2013-02-18 23:25:44 -06:00
|
|
|
item_const(t, ex) => {
|
|
|
|
(v.visit_ty)(t, e, v);
|
|
|
|
(v.visit_expr)(ex, e, v);
|
2012-07-18 11:31:53 -05:00
|
|
|
}
|
2013-02-18 23:25:44 -06:00
|
|
|
item_fn(ref decl, purity, ref tps, ref body) => {
|
|
|
|
(v.visit_fn)(
|
|
|
|
&fk_item_fn(
|
|
|
|
/* FIXME (#2543) */ copy i.ident,
|
|
|
|
*tps,
|
|
|
|
purity
|
|
|
|
),
|
2013-02-18 00:20:36 -06:00
|
|
|
decl,
|
|
|
|
body,
|
2013-02-18 23:25:44 -06:00
|
|
|
i.span,
|
|
|
|
i.id,
|
|
|
|
e,
|
|
|
|
v
|
|
|
|
);
|
2011-12-13 06:19:56 -06:00
|
|
|
}
|
2013-02-18 23:25:44 -06:00
|
|
|
item_mod(ref m) => (v.visit_mod)(m, i.span, i.id, e, v),
|
|
|
|
item_foreign_mod(ref nm) => {
|
|
|
|
for nm.view_items.each |vi| { (v.visit_view_item)(*vi, e, v); }
|
|
|
|
for nm.items.each |ni| { (v.visit_foreign_item)(*ni, e, v); }
|
2011-12-20 09:33:55 -06:00
|
|
|
}
|
2013-02-18 23:25:44 -06:00
|
|
|
item_ty(t, ref tps) => {
|
|
|
|
(v.visit_ty)(t, e, v);
|
|
|
|
(v.visit_ty_params)(*tps, e, v);
|
|
|
|
}
|
|
|
|
item_enum(ref enum_definition, ref tps) => {
|
|
|
|
(v.visit_ty_params)(*tps, e, v);
|
|
|
|
visit_enum_def(
|
|
|
|
*enum_definition,
|
|
|
|
/* FIXME (#2543) */ copy *tps,
|
|
|
|
e,
|
|
|
|
v
|
|
|
|
);
|
|
|
|
}
|
|
|
|
item_impl(ref tps, ref traits, ty, ref methods) => {
|
|
|
|
(v.visit_ty_params)(*tps, e, v);
|
|
|
|
for traits.each |p| {
|
|
|
|
visit_path(p.path, e, v);
|
|
|
|
}
|
|
|
|
(v.visit_ty)(ty, e, v);
|
|
|
|
for methods.each |m| {
|
|
|
|
visit_method_helper(*m, e, v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
item_struct(struct_def, ref tps) => {
|
|
|
|
(v.visit_ty_params)(*tps, e, v);
|
|
|
|
(v.visit_struct_def)(struct_def, i.ident, *tps, i.id, e, v);
|
|
|
|
}
|
|
|
|
item_trait(ref tps, ref traits, ref methods) => {
|
|
|
|
(v.visit_ty_params)(*tps, e, v);
|
|
|
|
for traits.each |p| { visit_path(p.path, e, v); }
|
|
|
|
for (*methods).each |m| {
|
2013-02-18 00:20:36 -06:00
|
|
|
(v.visit_trait_method)(m, e, v);
|
2013-02-18 23:25:44 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
item_mac(ref m) => visit_mac((*m), e, v)
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub fn visit_enum_def<E>(enum_definition: ast::enum_def,
|
2013-02-18 00:20:36 -06:00
|
|
|
tps: &[ast::ty_param],
|
2013-01-29 16:41:40 -06:00
|
|
|
e: E,
|
|
|
|
v: vt<E>) {
|
2012-08-08 19:14:25 -05:00
|
|
|
for enum_definition.variants.each |vr| {
|
2012-08-08 16:17:52 -05:00
|
|
|
match vr.node.kind {
|
2013-02-18 00:20:36 -06:00
|
|
|
tuple_variant_kind(ref variant_args) => {
|
2012-11-29 19:51:16 -06:00
|
|
|
for variant_args.each |va| { (v.visit_ty)(va.ty, e, v); }
|
2012-08-08 16:17:52 -05:00
|
|
|
}
|
|
|
|
struct_variant_kind(struct_def) => {
|
2012-11-29 19:51:16 -06:00
|
|
|
(v.visit_struct_def)(struct_def, vr.node.name, tps,
|
2012-08-08 16:17:52 -05:00
|
|
|
vr.node.id, e, v);
|
|
|
|
}
|
2012-12-04 12:50:00 -06:00
|
|
|
enum_variant_kind(ref enum_definition) => {
|
|
|
|
visit_enum_def((*enum_definition), tps, e, v);
|
2012-08-08 16:17:52 -05:00
|
|
|
}
|
|
|
|
}
|
2012-10-15 14:27:09 -05:00
|
|
|
// Visit the disr expr if it exists
|
2012-11-29 19:51:16 -06:00
|
|
|
vr.node.disr_expr.iter(|ex| (v.visit_expr)(*ex, e, v));
|
2012-08-08 16:17:52 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub fn skip_ty<E>(_t: @Ty, _e: E, _v: vt<E>) {}
|
2011-11-22 03:57:47 -06:00
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub fn visit_ty<E>(t: @Ty, e: E, v: vt<E>) {
|
2012-08-06 14:34:08 -05:00
|
|
|
match t.node {
|
2013-02-18 00:20:36 -06:00
|
|
|
ty_box(mt) | ty_uniq(mt) |
|
|
|
|
ty_vec(mt) | ty_ptr(mt) | ty_rptr(_, mt) => {
|
|
|
|
(v.visit_ty)(mt.ty, e, v);
|
|
|
|
},
|
|
|
|
ty_rec(ref flds) => {
|
|
|
|
for flds.each |f| {
|
|
|
|
(v.visit_ty)(f.node.mt.ty, e, v);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
ty_tup(ref ts) => {
|
|
|
|
for ts.each |tt| {
|
|
|
|
(v.visit_ty)(*tt, e, v);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
ty_closure(ref f) => {
|
|
|
|
for f.decl.inputs.each |a| { (v.visit_ty)(a.ty, e, v); }
|
|
|
|
(v.visit_ty)(f.decl.output, e, v);
|
|
|
|
},
|
|
|
|
ty_bare_fn(ref f) => {
|
|
|
|
for f.decl.inputs.each |a| { (v.visit_ty)(a.ty, e, v); }
|
|
|
|
(v.visit_ty)(f.decl.output, e, v);
|
|
|
|
},
|
|
|
|
ty_path(p, _) => visit_path(p, e, v),
|
|
|
|
ty_fixed_length_vec(ref mt, _) => (v.visit_ty)(mt.ty, e, v),
|
|
|
|
ty_nil | ty_bot | ty_mac(_) | ty_infer => ()
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub fn visit_path<E>(p: @path, e: E, v: vt<E>) {
|
2012-11-29 19:51:16 -06:00
|
|
|
for p.types.each |tp| { (v.visit_ty)(*tp, e, v); }
|
2011-12-13 06:19:56 -06:00
|
|
|
}
|
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub fn visit_pat<E>(p: @pat, e: E, v: vt<E>) {
|
2012-08-06 14:34:08 -05:00
|
|
|
match p.node {
|
2013-02-18 00:20:36 -06:00
|
|
|
pat_enum(path, ref children) => {
|
|
|
|
visit_path(path, e, v);
|
|
|
|
do children.iter |children| {
|
|
|
|
for children.each |child| { (v.visit_pat)(*child, e, v); }
|
|
|
|
}
|
2012-08-06 19:01:14 -05:00
|
|
|
}
|
2013-02-18 00:20:36 -06:00
|
|
|
pat_rec(ref fields, _) => {
|
|
|
|
for fields.each |f| {
|
|
|
|
(v.visit_pat)(f.pat, e, v)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
pat_struct(path, ref fields, _) => {
|
|
|
|
visit_path(path, e, v);
|
|
|
|
for fields.each |f| {
|
|
|
|
(v.visit_pat)(f.pat, e, v);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pat_tup(ref elts) => {
|
|
|
|
for elts.each |elt| {
|
|
|
|
(v.visit_pat)(*elt, e, v)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
pat_box(inner) | pat_uniq(inner) | pat_region(inner) => {
|
|
|
|
(v.visit_pat)(inner, e, v)
|
|
|
|
},
|
|
|
|
pat_ident(_, path, ref inner) => {
|
|
|
|
visit_path(path, e, v);
|
|
|
|
do inner.iter |subpat| { (v.visit_pat)(*subpat, e, v) }
|
2012-12-08 14:22:43 -06:00
|
|
|
}
|
2013-02-18 00:20:36 -06:00
|
|
|
pat_lit(ex) => (v.visit_expr)(ex, e, v),
|
|
|
|
pat_range(e1, e2) => {
|
|
|
|
(v.visit_expr)(e1, e, v);
|
|
|
|
(v.visit_expr)(e2, e, v);
|
|
|
|
}
|
|
|
|
pat_wild => (),
|
|
|
|
pat_vec(ref elts, ref tail) => {
|
|
|
|
for elts.each |elt| {
|
|
|
|
(v.visit_pat)(*elt, e, v);
|
|
|
|
}
|
|
|
|
do tail.iter |tail| {
|
|
|
|
(v.visit_pat)(*tail, e, v);
|
|
|
|
}
|
2012-12-08 14:22:43 -06:00
|
|
|
}
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub fn visit_foreign_item<E>(ni: @foreign_item, e: E, v: vt<E>) {
|
2012-08-06 14:34:08 -05:00
|
|
|
match ni.node {
|
2013-02-18 00:20:36 -06:00
|
|
|
foreign_item_fn(ref fd, _, ref tps) => {
|
2013-02-18 23:25:44 -06:00
|
|
|
(v.visit_ty_params)(*tps, e, v);
|
|
|
|
visit_fn_decl(fd, e, v);
|
|
|
|
}
|
|
|
|
foreign_item_const(t) => {
|
|
|
|
(v.visit_ty)(t, e, v);
|
|
|
|
}
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub fn visit_ty_param_bounds<E>(bounds: @~[ty_param_bound], e: E, v: vt<E>) {
|
2013-01-10 13:16:54 -06:00
|
|
|
for bounds.each |&bound| {
|
|
|
|
match bound {
|
|
|
|
TraitTyParamBound(ty) => (v.visit_ty)(ty, e, v),
|
|
|
|
RegionTyParamBound => ()
|
|
|
|
}
|
2012-08-06 20:54:20 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-18 23:25:44 -06:00
|
|
|
pub fn visit_ty_params<E>(tps: &[ty_param], e: E, v: vt<E>) {
|
2012-06-30 18:19:07 -05:00
|
|
|
for tps.each |tp| {
|
2012-08-06 20:54:20 -05:00
|
|
|
visit_ty_param_bounds(tp.bounds, e, v);
|
2011-12-28 10:50:12 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-18 00:20:36 -06:00
|
|
|
pub fn visit_fn_decl<E>(fd: &fn_decl, e: E, v: vt<E>) {
|
2012-11-06 20:41:06 -06:00
|
|
|
for fd.inputs.each |a| {
|
2012-11-29 19:51:16 -06:00
|
|
|
(v.visit_pat)(a.pat, e, v);
|
|
|
|
(v.visit_ty)(a.ty, e, v);
|
2012-11-06 20:41:06 -06:00
|
|
|
}
|
2012-11-29 19:51:16 -06:00
|
|
|
(v.visit_ty)(fd.output, e, v);
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
|
2012-03-01 12:36:22 -06:00
|
|
|
// Note: there is no visit_method() method in the visitor, instead override
|
|
|
|
// visit_fn() and check for fk_method(). I named this visit_method_helper()
|
|
|
|
// because it is not a default impl of any method, though I doubt that really
|
|
|
|
// clarifies anything. - Niko
|
2013-02-18 23:25:44 -06:00
|
|
|
pub fn visit_method_helper<E>(m: &method, e: E, v: vt<E>) {
|
|
|
|
(v.visit_fn)(
|
|
|
|
&fk_method(
|
|
|
|
/* FIXME (#2543) */ copy m.ident,
|
|
|
|
m.tps,
|
|
|
|
m
|
|
|
|
),
|
2013-02-18 00:20:36 -06:00
|
|
|
&m.decl,
|
|
|
|
&m.body,
|
2013-02-18 23:25:44 -06:00
|
|
|
m.span,
|
|
|
|
m.id,
|
|
|
|
e,
|
|
|
|
v
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn visit_struct_dtor_helper<E>(dtor: struct_dtor, tps: &[ty_param],
|
2013-01-29 16:41:40 -06:00
|
|
|
parent_id: def_id, e: E, v: vt<E>) {
|
2013-02-18 23:25:44 -06:00
|
|
|
(v.visit_fn)(
|
|
|
|
&fk_dtor(
|
|
|
|
tps,
|
|
|
|
dtor.node.attrs,
|
|
|
|
dtor.node.self_id,
|
|
|
|
parent_id
|
|
|
|
),
|
2013-02-18 00:20:36 -06:00
|
|
|
&ast_util::dtor_dec(),
|
|
|
|
&dtor.node.body,
|
2013-02-18 23:25:44 -06:00
|
|
|
dtor.span,
|
|
|
|
dtor.node.id,
|
|
|
|
e,
|
|
|
|
v
|
|
|
|
)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-02-18 00:20:36 -06:00
|
|
|
pub fn visit_fn<E>(fk: &fn_kind, decl: &fn_decl, body: &blk, _sp: span,
|
2013-01-29 16:41:40 -06:00
|
|
|
_id: node_id, e: E, v: vt<E>) {
|
2011-12-20 13:03:21 -06:00
|
|
|
visit_fn_decl(decl, e, v);
|
2012-11-29 19:51:16 -06:00
|
|
|
(v.visit_ty_params)(tps_of_fn(fk), e, v);
|
|
|
|
(v.visit_block)(body, e, v);
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
|
2013-02-18 00:20:36 -06:00
|
|
|
pub fn visit_ty_method<E>(m: &ty_method, e: E, v: vt<E>) {
|
2012-11-29 19:51:16 -06:00
|
|
|
for m.decl.inputs.each |a| { (v.visit_ty)(a.ty, e, v); }
|
|
|
|
(v.visit_ty_params)(m.tps, e, v);
|
|
|
|
(v.visit_ty)(m.decl.output, e, v);
|
2012-07-11 12:28:30 -05:00
|
|
|
}
|
|
|
|
|
2013-02-18 00:20:36 -06:00
|
|
|
pub fn visit_trait_method<E>(m: &trait_method, e: E, v: vt<E>) {
|
|
|
|
match *m {
|
|
|
|
required(ref ty_m) => (v.visit_ty_method)(ty_m, e, v),
|
2012-08-03 21:59:04 -05:00
|
|
|
provided(m) => visit_method_helper(m, e, v)
|
2012-07-10 15:44:20 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-18 23:25:44 -06:00
|
|
|
pub fn visit_struct_def<E>(sd: @struct_def, _nm: ast::ident, tps: &[ty_param],
|
2013-01-29 16:41:40 -06:00
|
|
|
id: node_id, e: E, v: vt<E>) {
|
2012-08-15 17:53:58 -05:00
|
|
|
for sd.fields.each |f| {
|
2012-11-29 19:51:16 -06:00
|
|
|
(v.visit_struct_field)(*f, e, v);
|
2012-08-15 17:53:58 -05:00
|
|
|
}
|
2013-02-18 23:25:44 -06:00
|
|
|
do sd.dtor.iter |dtor| {
|
|
|
|
visit_struct_dtor_helper(*dtor, tps, ast_util::local_def(id), e, v)
|
2012-08-07 17:54:59 -05:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub fn visit_struct_field<E>(sf: @struct_field, e: E, v: vt<E>) {
|
2012-11-29 19:51:16 -06:00
|
|
|
(v.visit_ty)(sf.node.ty, e, v);
|
2012-08-15 17:53:58 -05:00
|
|
|
}
|
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub fn visit_struct_method<E>(m: @method, e: E, v: vt<E>) {
|
2012-08-15 17:53:58 -05:00
|
|
|
visit_method_helper(m, e, v);
|
|
|
|
}
|
|
|
|
|
2013-02-18 00:20:36 -06:00
|
|
|
pub fn visit_block<E>(b: &blk, e: E, v: vt<E>) {
|
2012-09-19 18:55:01 -05:00
|
|
|
for b.node.view_items.each |vi| {
|
2012-11-29 19:51:16 -06:00
|
|
|
(v.visit_view_item)(*vi, e, v);
|
2012-09-19 18:55:01 -05:00
|
|
|
}
|
|
|
|
for b.node.stmts.each |s| {
|
2012-11-29 19:51:16 -06:00
|
|
|
(v.visit_stmt)(*s, e, v);
|
2012-09-19 18:55:01 -05:00
|
|
|
}
|
2011-06-08 15:48:19 -05:00
|
|
|
visit_expr_opt(b.node.expr, e, v);
|
|
|
|
}
|
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub fn visit_stmt<E>(s: @stmt, e: E, v: vt<E>) {
|
2012-08-06 14:34:08 -05:00
|
|
|
match s.node {
|
2012-11-29 19:51:16 -06:00
|
|
|
stmt_decl(d, _) => (v.visit_decl)(d, e, v),
|
|
|
|
stmt_expr(ex, _) => (v.visit_expr)(ex, e, v),
|
|
|
|
stmt_semi(ex, _) => (v.visit_expr)(ex, e, v),
|
2012-12-04 12:50:00 -06:00
|
|
|
stmt_mac(ref mac, _) => visit_mac((*mac), e, v)
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub fn visit_decl<E>(d: @decl, e: E, v: vt<E>) {
|
2012-08-06 14:34:08 -05:00
|
|
|
match d.node {
|
2013-02-18 00:20:36 -06:00
|
|
|
decl_local(ref locs) => {
|
|
|
|
for locs.each |loc| {
|
|
|
|
(v.visit_local)(*loc, e, v)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
decl_item(it) => (v.visit_item)(it, e, v)
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub fn visit_expr_opt<E>(eo: Option<@expr>, e: E, v: vt<E>) {
|
2012-11-29 19:51:16 -06:00
|
|
|
match eo { None => (), Some(ex) => (v.visit_expr)(ex, e, v) }
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
|
2013-02-18 00:20:36 -06:00
|
|
|
pub fn visit_exprs<E>(exprs: &[@expr], e: E, v: vt<E>) {
|
2012-11-29 19:51:16 -06:00
|
|
|
for exprs.each |ex| { (v.visit_expr)(*ex, e, v); }
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub fn visit_mac<E>(_m: mac, _e: E, _v: vt<E>) {
|
2012-12-12 14:25:40 -06:00
|
|
|
/* no user-serviceable parts inside */
|
2011-07-08 18:35:09 -05:00
|
|
|
}
|
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
|
2012-08-06 14:34:08 -05:00
|
|
|
match ex.node {
|
2013-02-18 00:20:36 -06:00
|
|
|
expr_vstore(x, _) => (v.visit_expr)(x, e, v),
|
|
|
|
expr_vec(ref es, _) => visit_exprs(*es, e, v),
|
|
|
|
expr_repeat(element, count, _) => {
|
|
|
|
(v.visit_expr)(element, e, v);
|
|
|
|
(v.visit_expr)(count, e, v);
|
|
|
|
}
|
|
|
|
expr_rec(ref flds, base) => {
|
|
|
|
for flds.each |f| { (v.visit_expr)(f.node.expr, e, v); }
|
|
|
|
visit_expr_opt(base, e, v);
|
|
|
|
}
|
|
|
|
expr_struct(p, ref flds, base) => {
|
|
|
|
visit_path(p, e, v);
|
|
|
|
for flds.each |f| { (v.visit_expr)(f.node.expr, e, v); }
|
|
|
|
visit_expr_opt(base, e, v);
|
|
|
|
}
|
|
|
|
expr_tup(ref elts) => {
|
|
|
|
for elts.each |el| { (v.visit_expr)(*el, e, v) }
|
|
|
|
}
|
|
|
|
expr_call(callee, ref args, _) => {
|
|
|
|
visit_exprs(*args, e, v);
|
|
|
|
(v.visit_expr)(callee, e, v);
|
|
|
|
}
|
|
|
|
expr_method_call(callee, _, ref tys, ref args, _) => {
|
|
|
|
visit_exprs(*args, e, v);
|
|
|
|
for tys.each |tp| { (v.visit_ty)(*tp, e, v); }
|
|
|
|
(v.visit_expr)(callee, e, v);
|
|
|
|
}
|
|
|
|
expr_binary(_, a, b) => {
|
|
|
|
(v.visit_expr)(a, e, v);
|
|
|
|
(v.visit_expr)(b, e, v);
|
|
|
|
}
|
|
|
|
expr_addr_of(_, x) | expr_unary(_, x) |
|
|
|
|
expr_loop_body(x) | expr_do_body(x) |
|
|
|
|
expr_assert(x) => (v.visit_expr)(x, e, v),
|
|
|
|
expr_lit(_) => (),
|
|
|
|
expr_cast(x, t) => {
|
|
|
|
(v.visit_expr)(x, e, v);
|
|
|
|
(v.visit_ty)(t, e, v);
|
|
|
|
}
|
|
|
|
expr_if(x, ref b, eo) => {
|
|
|
|
(v.visit_expr)(x, e, v);
|
|
|
|
(v.visit_block)(b, e, v);
|
|
|
|
visit_expr_opt(eo, e, v);
|
|
|
|
}
|
|
|
|
expr_while(x, ref b) => {
|
|
|
|
(v.visit_expr)(x, e, v);
|
|
|
|
(v.visit_block)(b, e, v);
|
|
|
|
}
|
|
|
|
expr_loop(ref b, _) => (v.visit_block)(b, e, v),
|
|
|
|
expr_match(x, ref arms) => {
|
|
|
|
(v.visit_expr)(x, e, v);
|
|
|
|
for arms.each |a| { (v.visit_arm)(a, e, v); }
|
|
|
|
}
|
|
|
|
expr_fn(proto, ref decl, ref body, _) => {
|
|
|
|
(v.visit_fn)(
|
|
|
|
&fk_anon(proto),
|
|
|
|
decl,
|
|
|
|
body,
|
|
|
|
ex.span,
|
|
|
|
ex.id,
|
|
|
|
e,
|
|
|
|
v
|
|
|
|
);
|
|
|
|
}
|
|
|
|
expr_fn_block(ref decl, ref body) => {
|
|
|
|
(v.visit_fn)(
|
|
|
|
&fk_fn_block,
|
|
|
|
decl,
|
|
|
|
body,
|
|
|
|
ex.span,
|
|
|
|
ex.id,
|
|
|
|
e,
|
|
|
|
v
|
|
|
|
);
|
|
|
|
}
|
|
|
|
expr_block(ref b) => (v.visit_block)(b, e, v),
|
|
|
|
expr_assign(a, b) => {
|
|
|
|
(v.visit_expr)(b, e, v);
|
|
|
|
(v.visit_expr)(a, e, v);
|
|
|
|
}
|
|
|
|
expr_copy(a) => (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, _, ref tys) => {
|
|
|
|
(v.visit_expr)(x, e, v);
|
|
|
|
for tys.each |tp| { (v.visit_ty)(*tp, e, v); }
|
|
|
|
}
|
|
|
|
expr_index(a, b) => {
|
|
|
|
(v.visit_expr)(a, e, v);
|
|
|
|
(v.visit_expr)(b, e, v);
|
|
|
|
}
|
|
|
|
expr_path(p) => visit_path(p, e, v),
|
|
|
|
expr_break(_) => (),
|
|
|
|
expr_again(_) => (),
|
|
|
|
expr_ret(eo) => visit_expr_opt(eo, e, v),
|
|
|
|
expr_log(_, lv, x) => {
|
|
|
|
(v.visit_expr)(lv, e, v);
|
|
|
|
(v.visit_expr)(x, e, v);
|
|
|
|
}
|
|
|
|
expr_mac(ref mac) => visit_mac((*mac), e, v),
|
|
|
|
expr_paren(x) => (v.visit_expr)(x, e, v),
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
2012-11-29 19:51:16 -06:00
|
|
|
(v.visit_expr_post)(ex, e, v);
|
2011-06-08 15:48:19 -05:00
|
|
|
}
|
|
|
|
|
2013-02-18 00:20:36 -06:00
|
|
|
pub fn visit_arm<E>(a: &arm, e: E, v: vt<E>) {
|
2012-11-29 19:51:16 -06:00
|
|
|
for a.pats.each |p| { (v.visit_pat)(*p, e, v); }
|
2011-08-22 07:38:48 -05:00
|
|
|
visit_expr_opt(a.guard, e, v);
|
2013-02-18 00:20:36 -06: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.
|
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub struct SimpleVisitor {
|
2013-02-18 23:25:44 -06:00
|
|
|
visit_mod: fn@(&_mod, span, node_id),
|
2013-01-08 16:00:45 -06:00
|
|
|
visit_view_item: fn@(@view_item),
|
|
|
|
visit_foreign_item: fn@(@foreign_item),
|
|
|
|
visit_item: fn@(@item),
|
|
|
|
visit_local: fn@(@local),
|
2013-02-18 00:20:36 -06:00
|
|
|
visit_block: fn@(&blk),
|
2013-01-08 16:00:45 -06:00
|
|
|
visit_stmt: fn@(@stmt),
|
2013-02-18 00:20:36 -06:00
|
|
|
visit_arm: fn@(&arm),
|
2013-01-08 16:00:45 -06:00
|
|
|
visit_pat: fn@(@pat),
|
|
|
|
visit_decl: fn@(@decl),
|
|
|
|
visit_expr: fn@(@expr),
|
|
|
|
visit_expr_post: fn@(@expr),
|
|
|
|
visit_ty: fn@(@Ty),
|
2013-02-18 23:25:44 -06:00
|
|
|
visit_ty_params: fn@(&[ty_param]),
|
2013-02-18 00:20:36 -06:00
|
|
|
visit_fn: fn@(&fn_kind, &fn_decl, &blk, span, node_id),
|
|
|
|
visit_ty_method: fn@(&ty_method),
|
|
|
|
visit_trait_method: fn@(&trait_method),
|
2013-02-18 23:25:44 -06:00
|
|
|
visit_struct_def: fn@(@struct_def, ident, &[ty_param], node_id),
|
2013-01-08 16:00:45 -06:00
|
|
|
visit_struct_field: fn@(@struct_field),
|
|
|
|
visit_struct_method: fn@(@method)
|
|
|
|
}
|
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub type simple_visitor = @SimpleVisitor;
|
2011-07-26 09:35:31 -05:00
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub fn simple_ignore_ty(_t: @Ty) {}
|
2011-11-22 03:57:47 -06:00
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub fn default_simple_visitor() -> @SimpleVisitor {
|
2013-02-17 11:42:50 -06:00
|
|
|
@SimpleVisitor {
|
|
|
|
visit_mod: |_m, _sp, _id| { },
|
|
|
|
visit_view_item: |_vi| { },
|
|
|
|
visit_foreign_item: |_ni| { },
|
|
|
|
visit_item: |_i| { },
|
|
|
|
visit_local: |_l| { },
|
|
|
|
visit_block: |_b| { },
|
|
|
|
visit_stmt: |_s| { },
|
|
|
|
visit_arm: |_a| { },
|
|
|
|
visit_pat: |_p| { },
|
|
|
|
visit_decl: |_d| { },
|
|
|
|
visit_expr: |_e| { },
|
|
|
|
visit_expr_post: |_e| { },
|
|
|
|
visit_ty: simple_ignore_ty,
|
2013-02-18 23:25:44 -06:00
|
|
|
visit_ty_params: fn@(_ps: &[ty_param]) { },
|
2013-02-18 00:20:36 -06:00
|
|
|
visit_fn: fn@(_fk: &fn_kind, _d: &fn_decl, _b: &blk, _sp: span,
|
2013-02-17 11:42:50 -06:00
|
|
|
_id: node_id) { },
|
2013-02-18 00:20:36 -06:00
|
|
|
visit_ty_method: fn@(_m: &ty_method) { },
|
|
|
|
visit_trait_method: fn@(_m: &trait_method) { },
|
2013-02-17 11:42:50 -06:00
|
|
|
visit_struct_def: fn@(_sd: @struct_def, _nm: ident,
|
2013-02-18 23:25:44 -06:00
|
|
|
_tps: &[ty_param], _id: node_id) { },
|
2013-02-17 11:42:50 -06:00
|
|
|
visit_struct_field: fn@(_f: @struct_field) { },
|
|
|
|
visit_struct_method: fn@(_m: @method) { }
|
|
|
|
}
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
|
|
|
|
2013-01-29 16:41:40 -06:00
|
|
|
pub fn mk_simple_visitor(v: simple_visitor) -> vt<()> {
|
2013-02-18 23:25:44 -06:00
|
|
|
fn v_mod(
|
|
|
|
f: fn@(&_mod, span, node_id),
|
|
|
|
m: &_mod,
|
|
|
|
sp: span,
|
|
|
|
id: node_id,
|
|
|
|
&&e: (),
|
|
|
|
v: vt<()>
|
|
|
|
) {
|
2012-01-26 10:33:12 -06:00
|
|
|
f(m, sp, id);
|
|
|
|
visit_mod(m, sp, id, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-10-18 17:07:40 -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
|
|
|
}
|
2012-06-26 18:18:37 -05:00
|
|
|
fn v_foreign_item(f: fn@(@foreign_item), ni: @foreign_item, &&e: (),
|
2011-09-12 04:27:30 -05:00
|
|
|
v: vt<()>) {
|
2011-07-27 07:19:39 -05:00
|
|
|
f(ni);
|
2012-06-26 18:18:37 -05:00
|
|
|
visit_foreign_item(ni, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2011-10-18 17:07:40 -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-10-18 17:07:40 -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
|
|
|
}
|
2013-02-18 00:20:36 -06:00
|
|
|
fn v_block(f: fn@(&blk), bl: &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-10-18 17:07:40 -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
|
|
|
}
|
2013-02-18 00:20:36 -06: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-10-18 17:07:40 -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-10-18 17:07:40 -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-10-18 17:07:40 -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
|
|
|
}
|
2012-07-30 21:05:56 -05:00
|
|
|
fn v_expr_post(f: fn@(@expr), ex: @expr, &&_e: (), _v: vt<()>) {
|
|
|
|
f(ex);
|
|
|
|
}
|
2012-10-15 16:56:42 -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
|
|
|
}
|
2013-02-18 00:20:36 -06:00
|
|
|
fn v_ty_method(f: fn@(&ty_method), ty: &ty_method, &&e: (), v: vt<()>) {
|
2012-07-11 12:28:30 -05:00
|
|
|
f(ty);
|
|
|
|
visit_ty_method(ty, e, v);
|
|
|
|
}
|
2013-02-18 00:20:36 -06:00
|
|
|
fn v_trait_method(f: fn@(&trait_method), m: &trait_method, &&e: (),
|
2012-07-10 15:44:20 -05:00
|
|
|
v: vt<()>) {
|
|
|
|
f(m);
|
|
|
|
visit_trait_method(m, e, v);
|
|
|
|
}
|
2013-02-18 23:25:44 -06:00
|
|
|
fn v_struct_def(f: fn@(@struct_def, ident, &[ty_param], node_id),
|
|
|
|
sd: @struct_def, nm: ident, tps: &[ty_param], id: node_id,
|
2012-08-07 17:54:59 -05:00
|
|
|
&&e: (), v: vt<()>) {
|
|
|
|
f(sd, nm, tps, id);
|
|
|
|
visit_struct_def(sd, nm, tps, id, e, v);
|
|
|
|
}
|
2013-02-18 23:25:44 -06:00
|
|
|
fn v_ty_params(f: fn@(&[ty_param]),
|
|
|
|
ps: &[ty_param],
|
|
|
|
&&e: (),
|
|
|
|
v: vt<()>) {
|
2012-01-04 09:37:39 -06:00
|
|
|
f(ps);
|
|
|
|
visit_ty_params(ps, e, v);
|
|
|
|
}
|
2013-02-18 00:20:36 -06:00
|
|
|
fn v_fn(
|
|
|
|
f: fn@(&fn_kind, &fn_decl, &blk, span, node_id),
|
|
|
|
fk: &fn_kind,
|
|
|
|
decl: &fn_decl,
|
|
|
|
body: &blk,
|
|
|
|
sp: span,
|
|
|
|
id: node_id,
|
|
|
|
&&e: (),
|
|
|
|
v: vt<()>
|
|
|
|
) {
|
2011-12-29 22:07:55 -06:00
|
|
|
f(fk, decl, body, sp, id);
|
|
|
|
visit_fn(fk, decl, body, sp, id, e, v);
|
2011-07-26 09:35:31 -05:00
|
|
|
}
|
2013-01-15 18:33:20 -06:00
|
|
|
let visit_ty: @fn(@Ty, &&x: (), vt<()>) =
|
|
|
|
|a,b,c| v_ty(v.visit_ty, a, b, c);
|
2012-08-15 17:53:58 -05:00
|
|
|
fn v_struct_field(f: fn@(@struct_field), sf: @struct_field, &&e: (),
|
|
|
|
v: vt<()>) {
|
|
|
|
f(sf);
|
|
|
|
visit_struct_field(sf, e, v);
|
|
|
|
}
|
|
|
|
fn v_struct_method(f: fn@(@method), m: @method, &&e: (), v: vt<()>) {
|
|
|
|
f(m);
|
|
|
|
visit_struct_method(m, e, v);
|
2012-01-31 21:30:40 -06:00
|
|
|
}
|
2013-01-08 16:00:45 -06:00
|
|
|
return mk_vt(@Visitor {
|
|
|
|
visit_mod: |a,b,c,d,e|v_mod(v.visit_mod, a, b, c, d, e),
|
|
|
|
visit_view_item: |a,b,c| v_view_item(v.visit_view_item, a, b, c),
|
|
|
|
visit_foreign_item:
|
|
|
|
|a,b,c|v_foreign_item(v.visit_foreign_item, a, b, c),
|
|
|
|
visit_item: |a,b,c|v_item(v.visit_item, a, b, c),
|
|
|
|
visit_local: |a,b,c|v_local(v.visit_local, a, b, c),
|
|
|
|
visit_block: |a,b,c|v_block(v.visit_block, a, b, c),
|
|
|
|
visit_stmt: |a,b,c|v_stmt(v.visit_stmt, a, b, c),
|
|
|
|
visit_arm: |a,b,c|v_arm(v.visit_arm, a, b, c),
|
|
|
|
visit_pat: |a,b,c|v_pat(v.visit_pat, a, b, c),
|
|
|
|
visit_decl: |a,b,c|v_decl(v.visit_decl, a, b, c),
|
|
|
|
visit_expr: |a,b,c|v_expr(v.visit_expr, a, b, c),
|
|
|
|
visit_expr_post: |a,b,c| v_expr_post(v.visit_expr_post,
|
|
|
|
a, b, c),
|
|
|
|
visit_ty: visit_ty,
|
2013-02-18 23:25:44 -06:00
|
|
|
visit_ty_params: |a,b,c| v_ty_params(v.visit_ty_params, a, b, c),
|
|
|
|
visit_fn: |a,b,c,d,e,f,g| v_fn(v.visit_fn, a, b, c, d, e, f, g),
|
|
|
|
visit_ty_method: |a,b,c| v_ty_method(v.visit_ty_method, a, b, c),
|
2013-01-08 16:00:45 -06:00
|
|
|
visit_trait_method: |a,b,c|
|
|
|
|
v_trait_method(v.visit_trait_method, a, b, c),
|
|
|
|
visit_struct_def: |a,b,c,d,e,f|
|
|
|
|
v_struct_def(v.visit_struct_def, a, b, c, d, e, f),
|
|
|
|
visit_struct_field: |a,b,c|
|
|
|
|
v_struct_field(v.visit_struct_field, a, b, c),
|
|
|
|
visit_struct_method: |a,b,c|
|
|
|
|
v_struct_method(v.visit_struct_method, a, b, c)
|
|
|
|
});
|
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
|
|
|
|
// End:
|