1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! AST walker. Each overridden visit method has full control over what
12 //! happens with its node, it can do its own traversal of the node's children,
13 //! call `visit::walk_*` to apply the default traversal algorithm, or prevent
14 //! deeper traversal by doing nothing.
16 //! Note: it is an important invariant that the default visitor walks the body
17 //! of a function in "execution order" (more concretely, reverse post-order
18 //! with respect to the CFG implied by the AST), meaning that if AST node A may
19 //! execute before AST node B, then A is visited first. The borrow checker in
20 //! particular relies on this property.
22 //! Note: walking an AST before macro expansion is probably a bad idea. For
23 //! instance, a walker looking for item names in a module will miss all of
24 //! those that are created by the expansion of a macro.
30 use parse
::token
::Token
;
31 use tokenstream
::{TokenTree, TokenStream}
;
33 #[derive(Copy, Clone, PartialEq, Eq)]
35 /// fn foo() or extern "Abi" fn foo()
36 ItemFn(Ident
, Unsafety
, Spanned
<Constness
>, Abi
, &'a Visibility
, &'a Block
),
39 Method(Ident
, &'a MethodSig
, Option
<&'a Visibility
>, &'a Block
),
45 /// Each method of the Visitor trait is a hook to be potentially
46 /// overridden. Each method's default implementation recursively visits
47 /// the substructure of the input via the corresponding `walk` method;
48 /// e.g. the `visit_mod` method by default calls `visit::walk_mod`.
50 /// If you want to ensure that your code handles every variant
51 /// explicitly, you need to override each method. (And you also need
52 /// to monitor future changes to `Visitor` in case a new method with a
53 /// new default implementation gets introduced.)
54 pub trait Visitor
<'ast
>: Sized
{
55 fn visit_name(&mut self, _span
: Span
, _name
: Name
) {
58 fn visit_ident(&mut self, span
: Span
, ident
: Ident
) {
59 walk_ident(self, span
, ident
);
61 fn visit_mod(&mut self, m
: &'ast Mod
, _s
: Span
, _attrs
: &[Attribute
], _n
: NodeId
) {
64 fn visit_foreign_item(&mut self, i
: &'ast ForeignItem
) { walk_foreign_item(self, i) }
65 fn visit_global_asm(&mut self, ga
: &'ast GlobalAsm
) { walk_global_asm(self, ga) }
66 fn visit_item(&mut self, i
: &'ast Item
) { walk_item(self, i) }
67 fn visit_local(&mut self, l
: &'ast Local
) { walk_local(self, l) }
68 fn visit_block(&mut self, b
: &'ast Block
) { walk_block(self, b) }
69 fn visit_stmt(&mut self, s
: &'ast Stmt
) { walk_stmt(self, s) }
70 fn visit_arm(&mut self, a
: &'ast Arm
) { walk_arm(self, a) }
71 fn visit_pat(&mut self, p
: &'ast Pat
) { walk_pat(self, p) }
72 fn visit_expr(&mut self, ex
: &'ast Expr
) { walk_expr(self, ex) }
73 fn visit_expr_post(&mut self, _ex
: &'ast Expr
) { }
74 fn visit_ty(&mut self, t
: &'ast Ty
) { walk_ty(self, t) }
75 fn visit_generic_param(&mut self, param
: &'ast GenericParam
) { walk_generic_param(self, param) }
76 fn visit_generics(&mut self, g
: &'ast Generics
) { walk_generics(self, g) }
77 fn visit_where_predicate(&mut self, p
: &'ast WherePredicate
) {
78 walk_where_predicate(self, p
)
80 fn visit_fn(&mut self, fk
: FnKind
<'ast
>, fd
: &'ast FnDecl
, s
: Span
, _
: NodeId
) {
81 walk_fn(self, fk
, fd
, s
)
83 fn visit_trait_item(&mut self, ti
: &'ast TraitItem
) { walk_trait_item(self, ti) }
84 fn visit_impl_item(&mut self, ii
: &'ast ImplItem
) { walk_impl_item(self, ii) }
85 fn visit_trait_ref(&mut self, t
: &'ast TraitRef
) { walk_trait_ref(self, t) }
86 fn visit_ty_param_bound(&mut self, bounds
: &'ast TyParamBound
) {
87 walk_ty_param_bound(self, bounds
)
89 fn visit_poly_trait_ref(&mut self, t
: &'ast PolyTraitRef
, m
: &'ast TraitBoundModifier
) {
90 walk_poly_trait_ref(self, t
, m
)
92 fn visit_variant_data(&mut self, s
: &'ast VariantData
, _
: Ident
,
93 _
: &'ast Generics
, _
: NodeId
, _
: Span
) {
94 walk_struct_def(self, s
)
96 fn visit_struct_field(&mut self, s
: &'ast StructField
) { walk_struct_field(self, s) }
97 fn visit_enum_def(&mut self, enum_definition
: &'ast EnumDef
,
98 generics
: &'ast Generics
, item_id
: NodeId
, _
: Span
) {
99 walk_enum_def(self, enum_definition
, generics
, item_id
)
101 fn visit_variant(&mut self, v
: &'ast Variant
, g
: &'ast Generics
, item_id
: NodeId
) {
102 walk_variant(self, v
, g
, item_id
)
104 fn visit_label(&mut self, label
: &'ast Label
) {
105 walk_label(self, label
)
107 fn visit_lifetime(&mut self, lifetime
: &'ast Lifetime
) {
108 walk_lifetime(self, lifetime
)
110 fn visit_mac(&mut self, _mac
: &'ast Mac
) {
111 panic
!("visit_mac disabled by default");
112 // NB: see note about macros above.
113 // if you really want a visitor that
114 // works on macros, use this
115 // definition in your trait impl:
116 // visit::walk_mac(self, _mac)
118 fn visit_mac_def(&mut self, _mac
: &'ast MacroDef
, _id
: NodeId
) {
121 fn visit_path(&mut self, path
: &'ast Path
, _id
: NodeId
) {
122 walk_path(self, path
)
124 fn visit_use_tree(&mut self, use_tree
: &'ast UseTree
, id
: NodeId
, _nested
: bool
) {
125 walk_use_tree(self, use_tree
, id
)
127 fn visit_path_segment(&mut self, path_span
: Span
, path_segment
: &'ast PathSegment
) {
128 walk_path_segment(self, path_span
, path_segment
)
130 fn visit_path_parameters(&mut self, path_span
: Span
, path_parameters
: &'ast PathParameters
) {
131 walk_path_parameters(self, path_span
, path_parameters
)
133 fn visit_assoc_type_binding(&mut self, type_binding
: &'ast TypeBinding
) {
134 walk_assoc_type_binding(self, type_binding
)
136 fn visit_attribute(&mut self, attr
: &'ast Attribute
) {
137 walk_attribute(self, attr
)
139 fn visit_tt(&mut self, tt
: TokenTree
) {
142 fn visit_tts(&mut self, tts
: TokenStream
) {
145 fn visit_token(&mut self, _t
: Token
) {}
146 // FIXME: add `visit_interpolated` and `walk_interpolated`
147 fn visit_vis(&mut self, vis
: &'ast Visibility
) {
150 fn visit_fn_ret_ty(&mut self, ret_ty
: &'ast FunctionRetTy
) {
151 walk_fn_ret_ty(self, ret_ty
)
156 macro_rules
! walk_list
{
157 ($visitor
: expr
, $method
: ident
, $list
: expr
) => {
159 $visitor
.$
method(elem
)
162 ($visitor
: expr
, $method
: ident
, $list
: expr
, $
($extra_args
: expr
),*) => {
164 $visitor
.$
method(elem
, $
($extra_args
,)*)
169 pub fn walk_ident
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, span
: Span
, ident
: Ident
) {
170 visitor
.visit_name(span
, ident
.name
);
173 pub fn walk_crate
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, krate
: &'a Crate
) {
174 visitor
.visit_mod(&krate
.module
, krate
.span
, &krate
.attrs
, CRATE_NODE_ID
);
175 walk_list
!(visitor
, visit_attribute
, &krate
.attrs
);
178 pub fn walk_mod
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, module
: &'a Mod
) {
179 walk_list
!(visitor
, visit_item
, &module
.items
);
182 pub fn walk_local
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, local
: &'a Local
) {
183 for attr
in local
.attrs
.iter() {
184 visitor
.visit_attribute(attr
);
186 visitor
.visit_pat(&local
.pat
);
187 walk_list
!(visitor
, visit_ty
, &local
.ty
);
188 walk_list
!(visitor
, visit_expr
, &local
.init
);
191 pub fn walk_label
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, label
: &'a Label
) {
192 visitor
.visit_ident(label
.span
, label
.ident
);
195 pub fn walk_lifetime
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, lifetime
: &'a Lifetime
) {
196 visitor
.visit_ident(lifetime
.span
, lifetime
.ident
);
199 pub fn walk_poly_trait_ref
<'a
, V
>(visitor
: &mut V
,
200 trait_ref
: &'a PolyTraitRef
,
201 _
: &TraitBoundModifier
)
202 where V
: Visitor
<'a
>,
204 walk_list
!(visitor
, visit_generic_param
, &trait_ref
.bound_generic_params
);
205 visitor
.visit_trait_ref(&trait_ref
.trait_ref
);
208 pub fn walk_trait_ref
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, trait_ref
: &'a TraitRef
) {
209 visitor
.visit_path(&trait_ref
.path
, trait_ref
.ref_id
)
212 pub fn walk_item
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, item
: &'a Item
) {
213 visitor
.visit_vis(&item
.vis
);
214 visitor
.visit_ident(item
.span
, item
.ident
);
216 ItemKind
::ExternCrate(orig_name
) => {
217 if let Some(orig_name
) = orig_name
{
218 visitor
.visit_name(item
.span
, orig_name
);
221 ItemKind
::Use(ref use_tree
) => {
222 visitor
.visit_use_tree(use_tree
, item
.id
, false)
224 ItemKind
::Static(ref typ
, _
, ref expr
) |
225 ItemKind
::Const(ref typ
, ref expr
) => {
226 visitor
.visit_ty(typ
);
227 visitor
.visit_expr(expr
);
229 ItemKind
::Fn(ref declaration
, unsafety
, constness
, abi
, ref generics
, ref body
) => {
230 visitor
.visit_generics(generics
);
231 visitor
.visit_fn(FnKind
::ItemFn(item
.ident
, unsafety
,
232 constness
, abi
, &item
.vis
, body
),
237 ItemKind
::Mod(ref module
) => {
238 visitor
.visit_mod(module
, item
.span
, &item
.attrs
, item
.id
)
240 ItemKind
::ForeignMod(ref foreign_module
) => {
241 walk_list
!(visitor
, visit_foreign_item
, &foreign_module
.items
);
243 ItemKind
::GlobalAsm(ref ga
) => visitor
.visit_global_asm(ga
),
244 ItemKind
::Ty(ref typ
, ref type_parameters
) => {
245 visitor
.visit_ty(typ
);
246 visitor
.visit_generics(type_parameters
)
248 ItemKind
::Enum(ref enum_definition
, ref type_parameters
) => {
249 visitor
.visit_generics(type_parameters
);
250 visitor
.visit_enum_def(enum_definition
, type_parameters
, item
.id
, item
.span
)
252 ItemKind
::Impl(_
, _
, _
,
254 ref opt_trait_reference
,
257 visitor
.visit_generics(type_parameters
);
258 walk_list
!(visitor
, visit_trait_ref
, opt_trait_reference
);
259 visitor
.visit_ty(typ
);
260 walk_list
!(visitor
, visit_impl_item
, impl_items
);
262 ItemKind
::Struct(ref struct_definition
, ref generics
) |
263 ItemKind
::Union(ref struct_definition
, ref generics
) => {
264 visitor
.visit_generics(generics
);
265 visitor
.visit_variant_data(struct_definition
, item
.ident
,
266 generics
, item
.id
, item
.span
);
268 ItemKind
::Trait(.., ref generics
, ref bounds
, ref methods
) => {
269 visitor
.visit_generics(generics
);
270 walk_list
!(visitor
, visit_ty_param_bound
, bounds
);
271 walk_list
!(visitor
, visit_trait_item
, methods
);
273 ItemKind
::TraitAlias(ref generics
, ref bounds
) => {
274 visitor
.visit_generics(generics
);
275 walk_list
!(visitor
, visit_ty_param_bound
, bounds
);
277 ItemKind
::Mac(ref mac
) => visitor
.visit_mac(mac
),
278 ItemKind
::MacroDef(ref ts
) => visitor
.visit_mac_def(ts
, item
.id
),
280 walk_list
!(visitor
, visit_attribute
, &item
.attrs
);
283 pub fn walk_enum_def
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
,
284 enum_definition
: &'a EnumDef
,
285 generics
: &'a Generics
,
287 walk_list
!(visitor
, visit_variant
, &enum_definition
.variants
, generics
, item_id
);
290 pub fn walk_variant
<'a
, V
>(visitor
: &mut V
,
291 variant
: &'a Variant
,
292 generics
: &'a Generics
,
294 where V
: Visitor
<'a
>,
296 visitor
.visit_ident(variant
.span
, variant
.node
.name
);
297 visitor
.visit_variant_data(&variant
.node
.data
, variant
.node
.name
,
298 generics
, item_id
, variant
.span
);
299 walk_list
!(visitor
, visit_expr
, &variant
.node
.disr_expr
);
300 walk_list
!(visitor
, visit_attribute
, &variant
.node
.attrs
);
303 pub fn walk_ty
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, typ
: &'a Ty
) {
305 TyKind
::Slice(ref ty
) | TyKind
::Paren(ref ty
) => {
308 TyKind
::Ptr(ref mutable_type
) => {
309 visitor
.visit_ty(&mutable_type
.ty
)
311 TyKind
::Rptr(ref opt_lifetime
, ref mutable_type
) => {
312 walk_list
!(visitor
, visit_lifetime
, opt_lifetime
);
313 visitor
.visit_ty(&mutable_type
.ty
)
316 TyKind
::Tup(ref tuple_element_types
) => {
317 walk_list
!(visitor
, visit_ty
, tuple_element_types
);
319 TyKind
::BareFn(ref function_declaration
) => {
320 walk_fn_decl(visitor
, &function_declaration
.decl
);
321 walk_list
!(visitor
, visit_generic_param
, &function_declaration
.generic_params
);
323 TyKind
::Path(ref maybe_qself
, ref path
) => {
324 if let Some(ref qself
) = *maybe_qself
{
325 visitor
.visit_ty(&qself
.ty
);
327 visitor
.visit_path(path
, typ
.id
);
329 TyKind
::Array(ref ty
, ref expression
) => {
330 visitor
.visit_ty(ty
);
331 visitor
.visit_expr(expression
)
333 TyKind
::TraitObject(ref bounds
, ..) |
334 TyKind
::ImplTrait(ref bounds
) => {
335 walk_list
!(visitor
, visit_ty_param_bound
, bounds
);
337 TyKind
::Typeof(ref expression
) => {
338 visitor
.visit_expr(expression
)
340 TyKind
::Infer
| TyKind
::ImplicitSelf
| TyKind
::Err
=> {}
341 TyKind
::Mac(ref mac
) => {
342 visitor
.visit_mac(mac
)
347 pub fn walk_path
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, path
: &'a Path
) {
348 for segment
in &path
.segments
{
349 visitor
.visit_path_segment(path
.span
, segment
);
353 pub fn walk_use_tree
<'a
, V
: Visitor
<'a
>>(
354 visitor
: &mut V
, use_tree
: &'a UseTree
, id
: NodeId
,
356 visitor
.visit_path(&use_tree
.prefix
, id
);
357 match use_tree
.kind
{
358 UseTreeKind
::Simple(rename
) => {
359 if let Some(rename
) = rename
{
360 visitor
.visit_ident(use_tree
.span
, rename
);
363 UseTreeKind
::Glob
=> {}
,
364 UseTreeKind
::Nested(ref use_trees
) => {
365 for &(ref nested_tree
, nested_id
) in use_trees
{
366 visitor
.visit_use_tree(nested_tree
, nested_id
, true);
372 pub fn walk_path_segment
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
,
374 segment
: &'a PathSegment
) {
375 visitor
.visit_ident(path_span
, segment
.identifier
);
376 if let Some(ref parameters
) = segment
.parameters
{
377 visitor
.visit_path_parameters(path_span
, parameters
);
381 pub fn walk_path_parameters
<'a
, V
>(visitor
: &mut V
,
383 path_parameters
: &'a PathParameters
)
384 where V
: Visitor
<'a
>,
386 match *path_parameters
{
387 PathParameters
::AngleBracketed(ref data
) => {
388 walk_list
!(visitor
, visit_ty
, &data
.types
);
389 walk_list
!(visitor
, visit_lifetime
, &data
.lifetimes
);
390 walk_list
!(visitor
, visit_assoc_type_binding
, &data
.bindings
);
392 PathParameters
::Parenthesized(ref data
) => {
393 walk_list
!(visitor
, visit_ty
, &data
.inputs
);
394 walk_list
!(visitor
, visit_ty
, &data
.output
);
399 pub fn walk_assoc_type_binding
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
,
400 type_binding
: &'a TypeBinding
) {
401 visitor
.visit_ident(type_binding
.span
, type_binding
.ident
);
402 visitor
.visit_ty(&type_binding
.ty
);
405 pub fn walk_pat
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, pattern
: &'a Pat
) {
407 PatKind
::TupleStruct(ref path
, ref children
, _
) => {
408 visitor
.visit_path(path
, pattern
.id
);
409 walk_list
!(visitor
, visit_pat
, children
);
411 PatKind
::Path(ref opt_qself
, ref path
) => {
412 if let Some(ref qself
) = *opt_qself
{
413 visitor
.visit_ty(&qself
.ty
);
415 visitor
.visit_path(path
, pattern
.id
)
417 PatKind
::Struct(ref path
, ref fields
, _
) => {
418 visitor
.visit_path(path
, pattern
.id
);
419 for field
in fields
{
420 walk_list
!(visitor
, visit_attribute
, field
.node
.attrs
.iter());
421 visitor
.visit_ident(field
.span
, field
.node
.ident
);
422 visitor
.visit_pat(&field
.node
.pat
)
425 PatKind
::Tuple(ref tuple_elements
, _
) => {
426 walk_list
!(visitor
, visit_pat
, tuple_elements
);
428 PatKind
::Box(ref subpattern
) |
429 PatKind
::Ref(ref subpattern
, _
) |
430 PatKind
::Paren(ref subpattern
) => {
431 visitor
.visit_pat(subpattern
)
433 PatKind
::Ident(_
, ref pth1
, ref optional_subpattern
) => {
434 visitor
.visit_ident(pth1
.span
, pth1
.node
);
435 walk_list
!(visitor
, visit_pat
, optional_subpattern
);
437 PatKind
::Lit(ref expression
) => visitor
.visit_expr(expression
),
438 PatKind
::Range(ref lower_bound
, ref upper_bound
, _
) => {
439 visitor
.visit_expr(lower_bound
);
440 visitor
.visit_expr(upper_bound
);
443 PatKind
::Slice(ref prepatterns
, ref slice_pattern
, ref postpatterns
) => {
444 walk_list
!(visitor
, visit_pat
, prepatterns
);
445 walk_list
!(visitor
, visit_pat
, slice_pattern
);
446 walk_list
!(visitor
, visit_pat
, postpatterns
);
448 PatKind
::Mac(ref mac
) => visitor
.visit_mac(mac
),
452 pub fn walk_foreign_item
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, foreign_item
: &'a ForeignItem
) {
453 visitor
.visit_vis(&foreign_item
.vis
);
454 visitor
.visit_ident(foreign_item
.span
, foreign_item
.ident
);
456 match foreign_item
.node
{
457 ForeignItemKind
::Fn(ref function_declaration
, ref generics
) => {
458 walk_fn_decl(visitor
, function_declaration
);
459 visitor
.visit_generics(generics
)
461 ForeignItemKind
::Static(ref typ
, _
) => visitor
.visit_ty(typ
),
462 ForeignItemKind
::Ty
=> (),
465 walk_list
!(visitor
, visit_attribute
, &foreign_item
.attrs
);
468 pub fn walk_global_asm
<'a
, V
: Visitor
<'a
>>(_
: &mut V
, _
: &'a GlobalAsm
) {
472 pub fn walk_ty_param_bound
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, bound
: &'a TyParamBound
) {
474 TraitTyParamBound(ref typ
, ref modifier
) => {
475 visitor
.visit_poly_trait_ref(typ
, modifier
);
477 RegionTyParamBound(ref lifetime
) => {
478 visitor
.visit_lifetime(lifetime
);
483 pub fn walk_generic_param
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, param
: &'a GenericParam
) {
485 GenericParam
::Lifetime(ref l
) => {
486 visitor
.visit_lifetime(&l
.lifetime
);
487 walk_list
!(visitor
, visit_lifetime
, &l
.bounds
);
488 walk_list
!(visitor
, visit_attribute
, &*l
.attrs
);
490 GenericParam
::Type(ref t
) => {
491 visitor
.visit_ident(t
.span
, t
.ident
);
492 walk_list
!(visitor
, visit_ty_param_bound
, &t
.bounds
);
493 walk_list
!(visitor
, visit_ty
, &t
.default);
494 walk_list
!(visitor
, visit_attribute
, &*t
.attrs
);
499 pub fn walk_generics
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, generics
: &'a Generics
) {
500 walk_list
!(visitor
, visit_generic_param
, &generics
.params
);
501 walk_list
!(visitor
, visit_where_predicate
, &generics
.where_clause
.predicates
);
504 pub fn walk_where_predicate
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, predicate
: &'a WherePredicate
) {
506 WherePredicate
::BoundPredicate(WhereBoundPredicate
{ref bounded_ty
,
508 ref bound_generic_params
,
510 visitor
.visit_ty(bounded_ty
);
511 walk_list
!(visitor
, visit_ty_param_bound
, bounds
);
512 walk_list
!(visitor
, visit_generic_param
, bound_generic_params
);
514 WherePredicate
::RegionPredicate(WhereRegionPredicate
{ref lifetime
,
517 visitor
.visit_lifetime(lifetime
);
518 walk_list
!(visitor
, visit_lifetime
, bounds
);
520 WherePredicate
::EqPredicate(WhereEqPredicate
{ref lhs_ty
,
523 visitor
.visit_ty(lhs_ty
);
524 visitor
.visit_ty(rhs_ty
);
529 pub fn walk_fn_ret_ty
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, ret_ty
: &'a FunctionRetTy
) {
530 if let FunctionRetTy
::Ty(ref output_ty
) = *ret_ty
{
531 visitor
.visit_ty(output_ty
)
535 pub fn walk_fn_decl
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, function_declaration
: &'a FnDecl
) {
536 for argument
in &function_declaration
.inputs
{
537 visitor
.visit_pat(&argument
.pat
);
538 visitor
.visit_ty(&argument
.ty
)
540 visitor
.visit_fn_ret_ty(&function_declaration
.output
)
543 pub fn walk_fn
<'a
, V
>(visitor
: &mut V
, kind
: FnKind
<'a
>, declaration
: &'a FnDecl
, _span
: Span
)
544 where V
: Visitor
<'a
>,
547 FnKind
::ItemFn(_
, _
, _
, _
, _
, body
) => {
548 walk_fn_decl(visitor
, declaration
);
549 visitor
.visit_block(body
);
551 FnKind
::Method(_
, _
, _
, body
) => {
552 walk_fn_decl(visitor
, declaration
);
553 visitor
.visit_block(body
);
555 FnKind
::Closure(body
) => {
556 walk_fn_decl(visitor
, declaration
);
557 visitor
.visit_expr(body
);
562 pub fn walk_trait_item
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, trait_item
: &'a TraitItem
) {
563 visitor
.visit_ident(trait_item
.span
, trait_item
.ident
);
564 walk_list
!(visitor
, visit_attribute
, &trait_item
.attrs
);
565 visitor
.visit_generics(&trait_item
.generics
);
566 match trait_item
.node
{
567 TraitItemKind
::Const(ref ty
, ref default) => {
568 visitor
.visit_ty(ty
);
569 walk_list
!(visitor
, visit_expr
, default);
571 TraitItemKind
::Method(ref sig
, None
) => {
572 walk_fn_decl(visitor
, &sig
.decl
);
574 TraitItemKind
::Method(ref sig
, Some(ref body
)) => {
575 visitor
.visit_fn(FnKind
::Method(trait_item
.ident
, sig
, None
, body
),
576 &sig
.decl
, trait_item
.span
, trait_item
.id
);
578 TraitItemKind
::Type(ref bounds
, ref default) => {
579 walk_list
!(visitor
, visit_ty_param_bound
, bounds
);
580 walk_list
!(visitor
, visit_ty
, default);
582 TraitItemKind
::Macro(ref mac
) => {
583 visitor
.visit_mac(mac
);
588 pub fn walk_impl_item
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, impl_item
: &'a ImplItem
) {
589 visitor
.visit_vis(&impl_item
.vis
);
590 visitor
.visit_ident(impl_item
.span
, impl_item
.ident
);
591 walk_list
!(visitor
, visit_attribute
, &impl_item
.attrs
);
592 visitor
.visit_generics(&impl_item
.generics
);
593 match impl_item
.node
{
594 ImplItemKind
::Const(ref ty
, ref expr
) => {
595 visitor
.visit_ty(ty
);
596 visitor
.visit_expr(expr
);
598 ImplItemKind
::Method(ref sig
, ref body
) => {
599 visitor
.visit_fn(FnKind
::Method(impl_item
.ident
, sig
, Some(&impl_item
.vis
), body
),
600 &sig
.decl
, impl_item
.span
, impl_item
.id
);
602 ImplItemKind
::Type(ref ty
) => {
603 visitor
.visit_ty(ty
);
605 ImplItemKind
::Macro(ref mac
) => {
606 visitor
.visit_mac(mac
);
611 pub fn walk_struct_def
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, struct_definition
: &'a VariantData
) {
612 walk_list
!(visitor
, visit_struct_field
, struct_definition
.fields());
615 pub fn walk_struct_field
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, struct_field
: &'a StructField
) {
616 visitor
.visit_vis(&struct_field
.vis
);
617 if let Some(ident
) = struct_field
.ident
{
618 visitor
.visit_ident(struct_field
.span
, ident
);
620 visitor
.visit_ty(&struct_field
.ty
);
621 walk_list
!(visitor
, visit_attribute
, &struct_field
.attrs
);
624 pub fn walk_block
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, block
: &'a Block
) {
625 walk_list
!(visitor
, visit_stmt
, &block
.stmts
);
628 pub fn walk_stmt
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, statement
: &'a Stmt
) {
629 match statement
.node
{
630 StmtKind
::Local(ref local
) => visitor
.visit_local(local
),
631 StmtKind
::Item(ref item
) => visitor
.visit_item(item
),
632 StmtKind
::Expr(ref expression
) | StmtKind
::Semi(ref expression
) => {
633 visitor
.visit_expr(expression
)
635 StmtKind
::Mac(ref mac
) => {
636 let (ref mac
, _
, ref attrs
) = **mac
;
637 visitor
.visit_mac(mac
);
638 for attr
in attrs
.iter() {
639 visitor
.visit_attribute(attr
);
645 pub fn walk_mac
<'a
, V
: Visitor
<'a
>>(_
: &mut V
, _
: &Mac
) {
649 pub fn walk_expr
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, expression
: &'a Expr
) {
650 for attr
in expression
.attrs
.iter() {
651 visitor
.visit_attribute(attr
);
653 match expression
.node
{
654 ExprKind
::Box(ref subexpression
) => {
655 visitor
.visit_expr(subexpression
)
657 ExprKind
::InPlace(ref place
, ref subexpression
) => {
658 visitor
.visit_expr(place
);
659 visitor
.visit_expr(subexpression
)
661 ExprKind
::Array(ref subexpressions
) => {
662 walk_list
!(visitor
, visit_expr
, subexpressions
);
664 ExprKind
::Repeat(ref element
, ref count
) => {
665 visitor
.visit_expr(element
);
666 visitor
.visit_expr(count
)
668 ExprKind
::Struct(ref path
, ref fields
, ref optional_base
) => {
669 visitor
.visit_path(path
, expression
.id
);
670 for field
in fields
{
671 walk_list
!(visitor
, visit_attribute
, field
.attrs
.iter());
672 visitor
.visit_ident(field
.ident
.span
, field
.ident
.node
);
673 visitor
.visit_expr(&field
.expr
)
675 walk_list
!(visitor
, visit_expr
, optional_base
);
677 ExprKind
::Tup(ref subexpressions
) => {
678 walk_list
!(visitor
, visit_expr
, subexpressions
);
680 ExprKind
::Call(ref callee_expression
, ref arguments
) => {
681 visitor
.visit_expr(callee_expression
);
682 walk_list
!(visitor
, visit_expr
, arguments
);
684 ExprKind
::MethodCall(ref segment
, ref arguments
) => {
685 visitor
.visit_path_segment(expression
.span
, segment
);
686 walk_list
!(visitor
, visit_expr
, arguments
);
688 ExprKind
::Binary(_
, ref left_expression
, ref right_expression
) => {
689 visitor
.visit_expr(left_expression
);
690 visitor
.visit_expr(right_expression
)
692 ExprKind
::AddrOf(_
, ref subexpression
) | ExprKind
::Unary(_
, ref subexpression
) => {
693 visitor
.visit_expr(subexpression
)
695 ExprKind
::Lit(_
) => {}
696 ExprKind
::Cast(ref subexpression
, ref typ
) | ExprKind
::Type(ref subexpression
, ref typ
) => {
697 visitor
.visit_expr(subexpression
);
698 visitor
.visit_ty(typ
)
700 ExprKind
::If(ref head_expression
, ref if_block
, ref optional_else
) => {
701 visitor
.visit_expr(head_expression
);
702 visitor
.visit_block(if_block
);
703 walk_list
!(visitor
, visit_expr
, optional_else
);
705 ExprKind
::While(ref subexpression
, ref block
, ref opt_label
) => {
706 walk_list
!(visitor
, visit_label
, opt_label
);
707 visitor
.visit_expr(subexpression
);
708 visitor
.visit_block(block
);
710 ExprKind
::IfLet(ref pats
, ref subexpression
, ref if_block
, ref optional_else
) => {
711 walk_list
!(visitor
, visit_pat
, pats
);
712 visitor
.visit_expr(subexpression
);
713 visitor
.visit_block(if_block
);
714 walk_list
!(visitor
, visit_expr
, optional_else
);
716 ExprKind
::WhileLet(ref pats
, ref subexpression
, ref block
, ref opt_label
) => {
717 walk_list
!(visitor
, visit_label
, opt_label
);
718 walk_list
!(visitor
, visit_pat
, pats
);
719 visitor
.visit_expr(subexpression
);
720 visitor
.visit_block(block
);
722 ExprKind
::ForLoop(ref pattern
, ref subexpression
, ref block
, ref opt_label
) => {
723 walk_list
!(visitor
, visit_label
, opt_label
);
724 visitor
.visit_pat(pattern
);
725 visitor
.visit_expr(subexpression
);
726 visitor
.visit_block(block
);
728 ExprKind
::Loop(ref block
, ref opt_label
) => {
729 walk_list
!(visitor
, visit_label
, opt_label
);
730 visitor
.visit_block(block
);
732 ExprKind
::Match(ref subexpression
, ref arms
) => {
733 visitor
.visit_expr(subexpression
);
734 walk_list
!(visitor
, visit_arm
, arms
);
736 ExprKind
::Closure(_
, _
, ref function_declaration
, ref body
, _decl_span
) => {
737 visitor
.visit_fn(FnKind
::Closure(body
),
738 function_declaration
,
742 ExprKind
::Block(ref block
) => visitor
.visit_block(block
),
743 ExprKind
::Assign(ref left_hand_expression
, ref right_hand_expression
) => {
744 visitor
.visit_expr(left_hand_expression
);
745 visitor
.visit_expr(right_hand_expression
);
747 ExprKind
::AssignOp(_
, ref left_expression
, ref right_expression
) => {
748 visitor
.visit_expr(left_expression
);
749 visitor
.visit_expr(right_expression
);
751 ExprKind
::Field(ref subexpression
, ref ident
) => {
752 visitor
.visit_expr(subexpression
);
753 visitor
.visit_ident(ident
.span
, ident
.node
);
755 ExprKind
::TupField(ref subexpression
, _
) => {
756 visitor
.visit_expr(subexpression
);
758 ExprKind
::Index(ref main_expression
, ref index_expression
) => {
759 visitor
.visit_expr(main_expression
);
760 visitor
.visit_expr(index_expression
)
762 ExprKind
::Range(ref start
, ref end
, _
) => {
763 walk_list
!(visitor
, visit_expr
, start
);
764 walk_list
!(visitor
, visit_expr
, end
);
766 ExprKind
::Path(ref maybe_qself
, ref path
) => {
767 if let Some(ref qself
) = *maybe_qself
{
768 visitor
.visit_ty(&qself
.ty
);
770 visitor
.visit_path(path
, expression
.id
)
772 ExprKind
::Break(ref opt_label
, ref opt_expr
) => {
773 walk_list
!(visitor
, visit_label
, opt_label
);
774 walk_list
!(visitor
, visit_expr
, opt_expr
);
776 ExprKind
::Continue(ref opt_label
) => {
777 walk_list
!(visitor
, visit_label
, opt_label
);
779 ExprKind
::Ret(ref optional_expression
) => {
780 walk_list
!(visitor
, visit_expr
, optional_expression
);
782 ExprKind
::Mac(ref mac
) => visitor
.visit_mac(mac
),
783 ExprKind
::Paren(ref subexpression
) => {
784 visitor
.visit_expr(subexpression
)
786 ExprKind
::InlineAsm(ref ia
) => {
787 for &(_
, ref input
) in &ia
.inputs
{
788 visitor
.visit_expr(input
)
790 for output
in &ia
.outputs
{
791 visitor
.visit_expr(&output
.expr
)
794 ExprKind
::Yield(ref optional_expression
) => {
795 walk_list
!(visitor
, visit_expr
, optional_expression
);
797 ExprKind
::Try(ref subexpression
) => {
798 visitor
.visit_expr(subexpression
)
800 ExprKind
::Catch(ref body
) => {
801 visitor
.visit_block(body
)
805 visitor
.visit_expr_post(expression
)
808 pub fn walk_arm
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, arm
: &'a Arm
) {
809 walk_list
!(visitor
, visit_pat
, &arm
.pats
);
810 walk_list
!(visitor
, visit_expr
, &arm
.guard
);
811 visitor
.visit_expr(&arm
.body
);
812 walk_list
!(visitor
, visit_attribute
, &arm
.attrs
);
815 pub fn walk_vis
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, vis
: &'a Visibility
) {
816 if let VisibilityKind
::Restricted { ref path, id }
= vis
.node
{
817 visitor
.visit_path(path
, id
);
821 pub fn walk_attribute
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, attr
: &'a Attribute
) {
822 visitor
.visit_tts(attr
.tokens
.clone());
825 pub fn walk_tt
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, tt
: TokenTree
) {
827 TokenTree
::Token(_
, tok
) => visitor
.visit_token(tok
),
828 TokenTree
::Delimited(_
, delimed
) => visitor
.visit_tts(delimed
.stream()),
832 pub fn walk_tts
<'a
, V
: Visitor
<'a
>>(visitor
: &mut V
, tts
: TokenStream
) {
833 for tt
in tts
.trees() {
834 visitor
.visit_tt(tt
);