1 //! AST visitors (i.e. on-the-fly mutation at different places in the AST).
2 //!
3 //! Visitors are mutable objects that can mutate parts of an AST while traversing it. You can see
4 //! them as flexible mutations taking place on *patterns* representing your AST – they get called
5 //! everytime an interesting node gets visited. Because of their mutable nature, you can accumulate
6 //! a state as you traverse the AST and implement exotic filtering.
7 //!
8 //! Visitors must implement the [`Visitor`] trait in order to be usable.
9 //!
10 //! In order to visit any part of an AST (from its very top root or from any part of it), you must
11 //! use the [`Host`] interface, that provides the [`Host::visit`] function.
12 //!
13 //! For instance, we can imagine visiting an AST to count how many variables are declared:
14 //!
15 //! ```
16 //! use glsl::syntax::{CompoundStatement, Expr, SingleDeclaration, Statement, TypeSpecifierNonArray};
17 //! use glsl::visitor::{Host, Visit, Visitor};
18 //! use std::iter::FromIterator;
19 //!
20 //! let decl0 = Statement::declare_var(
21 //!   TypeSpecifierNonArray::Float,
22 //!   "x",
23 //!   None,
24 //!   Some(Expr::from(3.14).into())
25 //! );
26 //!
27 //! let decl1 = Statement::declare_var(
28 //!   TypeSpecifierNonArray::Int,
29 //!   "y",
30 //!   None,
31 //!   None
32 //! );
33 //!
34 //! let decl2 = Statement::declare_var(
35 //!   TypeSpecifierNonArray::Vec4,
36 //!   "z",
37 //!   None,
38 //!   None
39 //! );
40 //!
41 //! let mut compound = CompoundStatement::from_iter(vec![decl0, decl1, decl2]);
42 //!
43 //! // our visitor that will count the number of variables it saw
44 //! struct Counter {
45 //!   var_nb: usize
46 //! }
47 //!
48 //! impl Visitor for Counter {
49 //!   // we are only interested in single declaration with a name
50 //!   fn visit_single_declaration(&mut self, declaration: &mut SingleDeclaration) -> Visit {
51 //!     if declaration.name.is_some() {
52 //!       self.var_nb += 1;
53 //!     }
54 //!
55 //!     // do not go deeper
56 //!     Visit::Parent
57 //!   }
58 //! }
59 //!
60 //! let mut counter = Counter { var_nb: 0 };
61 //! compound.visit(&mut counter);
62 //! assert_eq!(counter.var_nb, 3);
63 //! ```
64 //!
65 //! [`Host`]: visitor::Host
66 //! [`Host::visit`]: visitor::Host::visit
67 //! [`Visitor`]: visitor::Visitor
68 
69 use crate::syntax;
70 
71 /// Visit strategy after having visited an AST node.
72 ///
73 /// Some AST nodes have *children* – in enum’s variants, in some fields as nested in [`Vec`], etc.
74 /// Those nodes can be visited depending on the strategy you chose.
75 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
76 pub enum Visit {
77   /// The visitor will go deeper in the AST by visiting all the children, if any. If no children are
78   /// present or if having children doesn’t make sense for a specific part of the AST, this
79   /// strategy will be ignored.
80   Children,
81   /// The visitor won’t visit children nor siblings and will go up.
82   Parent,
83 }
84 
85 /// Visitor object, visiting AST nodes.
86 pub trait Visitor {
visit_translation_unit(&mut self, _: &mut syntax::TranslationUnit) -> Visit87   fn visit_translation_unit(&mut self, _: &mut syntax::TranslationUnit) -> Visit {
88     Visit::Children
89   }
90 
visit_external_declaration(&mut self, _: &mut syntax::ExternalDeclaration) -> Visit91   fn visit_external_declaration(&mut self, _: &mut syntax::ExternalDeclaration) -> Visit {
92     Visit::Children
93   }
94 
visit_identifier(&mut self, _: &mut syntax::Identifier) -> Visit95   fn visit_identifier(&mut self, _: &mut syntax::Identifier) -> Visit {
96     Visit::Children
97   }
98 
visit_arrayed_identifier(&mut self, _: &mut syntax::ArrayedIdentifier) -> Visit99   fn visit_arrayed_identifier(&mut self, _: &mut syntax::ArrayedIdentifier) -> Visit {
100     Visit::Children
101   }
102 
visit_type_name(&mut self, _: &mut syntax::TypeName) -> Visit103   fn visit_type_name(&mut self, _: &mut syntax::TypeName) -> Visit {
104     Visit::Children
105   }
106 
visit_block(&mut self, _: &mut syntax::Block) -> Visit107   fn visit_block(&mut self, _: &mut syntax::Block) -> Visit {
108     Visit::Children
109   }
110 
visit_for_init_statement(&mut self, _: &mut syntax::ForInitStatement) -> Visit111   fn visit_for_init_statement(&mut self, _: &mut syntax::ForInitStatement) -> Visit {
112     Visit::Children
113   }
114 
visit_for_rest_statement(&mut self, _: &mut syntax::ForRestStatement) -> Visit115   fn visit_for_rest_statement(&mut self, _: &mut syntax::ForRestStatement) -> Visit {
116     Visit::Children
117   }
118 
visit_function_definition(&mut self, _: &mut syntax::FunctionDefinition) -> Visit119   fn visit_function_definition(&mut self, _: &mut syntax::FunctionDefinition) -> Visit {
120     Visit::Children
121   }
122 
visit_function_parameter_declarator( &mut self, _: &mut syntax::FunctionParameterDeclarator, ) -> Visit123   fn visit_function_parameter_declarator(
124     &mut self,
125     _: &mut syntax::FunctionParameterDeclarator,
126   ) -> Visit {
127     Visit::Children
128   }
129 
visit_function_prototype(&mut self, _: &mut syntax::FunctionPrototype) -> Visit130   fn visit_function_prototype(&mut self, _: &mut syntax::FunctionPrototype) -> Visit {
131     Visit::Children
132   }
133 
visit_init_declarator_list(&mut self, _: &mut syntax::InitDeclaratorList) -> Visit134   fn visit_init_declarator_list(&mut self, _: &mut syntax::InitDeclaratorList) -> Visit {
135     Visit::Children
136   }
137 
visit_layout_qualifier(&mut self, _: &mut syntax::LayoutQualifier) -> Visit138   fn visit_layout_qualifier(&mut self, _: &mut syntax::LayoutQualifier) -> Visit {
139     Visit::Children
140   }
141 
visit_preprocessor(&mut self, _: &mut syntax::Preprocessor) -> Visit142   fn visit_preprocessor(&mut self, _: &mut syntax::Preprocessor) -> Visit {
143     Visit::Children
144   }
145 
visit_preprocessor_define(&mut self, _: &mut syntax::PreprocessorDefine) -> Visit146   fn visit_preprocessor_define(&mut self, _: &mut syntax::PreprocessorDefine) -> Visit {
147     Visit::Children
148   }
149 
visit_preprocessor_elseif(&mut self, _: &mut syntax::PreprocessorElseIf) -> Visit150   fn visit_preprocessor_elseif(&mut self, _: &mut syntax::PreprocessorElseIf) -> Visit {
151     Visit::Children
152   }
153 
visit_preprocessor_error(&mut self, _: &mut syntax::PreprocessorError) -> Visit154   fn visit_preprocessor_error(&mut self, _: &mut syntax::PreprocessorError) -> Visit {
155     Visit::Children
156   }
157 
visit_preprocessor_extension(&mut self, _: &mut syntax::PreprocessorExtension) -> Visit158   fn visit_preprocessor_extension(&mut self, _: &mut syntax::PreprocessorExtension) -> Visit {
159     Visit::Children
160   }
161 
visit_preprocessor_extension_behavior( &mut self, _: &mut syntax::PreprocessorExtensionBehavior, ) -> Visit162   fn visit_preprocessor_extension_behavior(
163     &mut self,
164     _: &mut syntax::PreprocessorExtensionBehavior,
165   ) -> Visit {
166     Visit::Children
167   }
168 
visit_preprocessor_extension_name( &mut self, _: &mut syntax::PreprocessorExtensionName, ) -> Visit169   fn visit_preprocessor_extension_name(
170     &mut self,
171     _: &mut syntax::PreprocessorExtensionName,
172   ) -> Visit {
173     Visit::Children
174   }
175 
visit_preprocessor_if(&mut self, _: &mut syntax::PreprocessorIf) -> Visit176   fn visit_preprocessor_if(&mut self, _: &mut syntax::PreprocessorIf) -> Visit {
177     Visit::Children
178   }
179 
visit_preprocessor_ifdef(&mut self, _: &mut syntax::PreprocessorIfDef) -> Visit180   fn visit_preprocessor_ifdef(&mut self, _: &mut syntax::PreprocessorIfDef) -> Visit {
181     Visit::Children
182   }
183 
visit_preprocessor_ifndef(&mut self, _: &mut syntax::PreprocessorIfNDef) -> Visit184   fn visit_preprocessor_ifndef(&mut self, _: &mut syntax::PreprocessorIfNDef) -> Visit {
185     Visit::Children
186   }
187 
visit_preprocessor_include(&mut self, _: &mut syntax::PreprocessorInclude) -> Visit188   fn visit_preprocessor_include(&mut self, _: &mut syntax::PreprocessorInclude) -> Visit {
189     Visit::Children
190   }
191 
visit_preprocessor_line(&mut self, _: &mut syntax::PreprocessorLine) -> Visit192   fn visit_preprocessor_line(&mut self, _: &mut syntax::PreprocessorLine) -> Visit {
193     Visit::Children
194   }
195 
visit_preprocessor_pragma(&mut self, _: &mut syntax::PreprocessorPragma) -> Visit196   fn visit_preprocessor_pragma(&mut self, _: &mut syntax::PreprocessorPragma) -> Visit {
197     Visit::Children
198   }
199 
visit_preprocessor_undef(&mut self, _: &mut syntax::PreprocessorUndef) -> Visit200   fn visit_preprocessor_undef(&mut self, _: &mut syntax::PreprocessorUndef) -> Visit {
201     Visit::Children
202   }
203 
visit_preprocessor_version(&mut self, _: &mut syntax::PreprocessorVersion) -> Visit204   fn visit_preprocessor_version(&mut self, _: &mut syntax::PreprocessorVersion) -> Visit {
205     Visit::Children
206   }
207 
visit_preprocessor_version_profile( &mut self, _: &mut syntax::PreprocessorVersionProfile, ) -> Visit208   fn visit_preprocessor_version_profile(
209     &mut self,
210     _: &mut syntax::PreprocessorVersionProfile,
211   ) -> Visit {
212     Visit::Children
213   }
214 
visit_selection_statement(&mut self, _: &mut syntax::SelectionStatement) -> Visit215   fn visit_selection_statement(&mut self, _: &mut syntax::SelectionStatement) -> Visit {
216     Visit::Children
217   }
218 
visit_selection_rest_statement(&mut self, _: &mut syntax::SelectionRestStatement) -> Visit219   fn visit_selection_rest_statement(&mut self, _: &mut syntax::SelectionRestStatement) -> Visit {
220     Visit::Children
221   }
222 
visit_single_declaration(&mut self, _: &mut syntax::SingleDeclaration) -> Visit223   fn visit_single_declaration(&mut self, _: &mut syntax::SingleDeclaration) -> Visit {
224     Visit::Children
225   }
226 
visit_single_declaration_no_type(&mut self, _: &mut syntax::SingleDeclarationNoType) -> Visit227   fn visit_single_declaration_no_type(&mut self, _: &mut syntax::SingleDeclarationNoType) -> Visit {
228     Visit::Children
229   }
230 
visit_struct_field_specifier(&mut self, _: &mut syntax::StructFieldSpecifier) -> Visit231   fn visit_struct_field_specifier(&mut self, _: &mut syntax::StructFieldSpecifier) -> Visit {
232     Visit::Children
233   }
234 
visit_struct_specifier(&mut self, _: &mut syntax::StructSpecifier) -> Visit235   fn visit_struct_specifier(&mut self, _: &mut syntax::StructSpecifier) -> Visit {
236     Visit::Children
237   }
238 
visit_switch_statement(&mut self, _: &mut syntax::SwitchStatement) -> Visit239   fn visit_switch_statement(&mut self, _: &mut syntax::SwitchStatement) -> Visit {
240     Visit::Children
241   }
242 
visit_type_qualifier(&mut self, _: &mut syntax::TypeQualifier) -> Visit243   fn visit_type_qualifier(&mut self, _: &mut syntax::TypeQualifier) -> Visit {
244     Visit::Children
245   }
246 
visit_type_specifier(&mut self, _: &mut syntax::TypeSpecifier) -> Visit247   fn visit_type_specifier(&mut self, _: &mut syntax::TypeSpecifier) -> Visit {
248     Visit::Children
249   }
250 
visit_full_specified_type(&mut self, _: &mut syntax::FullySpecifiedType) -> Visit251   fn visit_full_specified_type(&mut self, _: &mut syntax::FullySpecifiedType) -> Visit {
252     Visit::Children
253   }
254 
visit_array_specifier(&mut self, _: &mut syntax::ArraySpecifier) -> Visit255   fn visit_array_specifier(&mut self, _: &mut syntax::ArraySpecifier) -> Visit {
256     Visit::Children
257   }
258 
visit_assignment_op(&mut self, _: &mut syntax::AssignmentOp) -> Visit259   fn visit_assignment_op(&mut self, _: &mut syntax::AssignmentOp) -> Visit {
260     Visit::Children
261   }
262 
visit_binary_op(&mut self, _: &mut syntax::BinaryOp) -> Visit263   fn visit_binary_op(&mut self, _: &mut syntax::BinaryOp) -> Visit {
264     Visit::Children
265   }
266 
visit_case_label(&mut self, _: &mut syntax::CaseLabel) -> Visit267   fn visit_case_label(&mut self, _: &mut syntax::CaseLabel) -> Visit {
268     Visit::Children
269   }
270 
visit_condition(&mut self, _: &mut syntax::Condition) -> Visit271   fn visit_condition(&mut self, _: &mut syntax::Condition) -> Visit {
272     Visit::Children
273   }
274 
visit_declaration(&mut self, _: &mut syntax::Declaration) -> Visit275   fn visit_declaration(&mut self, _: &mut syntax::Declaration) -> Visit {
276     Visit::Children
277   }
278 
visit_expr(&mut self, _: &mut syntax::Expr) -> Visit279   fn visit_expr(&mut self, _: &mut syntax::Expr) -> Visit {
280     Visit::Children
281   }
282 
visit_fun_identifier(&mut self, _: &mut syntax::FunIdentifier) -> Visit283   fn visit_fun_identifier(&mut self, _: &mut syntax::FunIdentifier) -> Visit {
284     Visit::Children
285   }
286 
visit_function_parameter_declaration( &mut self, _: &mut syntax::FunctionParameterDeclaration, ) -> Visit287   fn visit_function_parameter_declaration(
288     &mut self,
289     _: &mut syntax::FunctionParameterDeclaration,
290   ) -> Visit {
291     Visit::Children
292   }
293 
visit_initializer(&mut self, _: &mut syntax::Initializer) -> Visit294   fn visit_initializer(&mut self, _: &mut syntax::Initializer) -> Visit {
295     Visit::Children
296   }
297 
visit_interpolation_qualifier(&mut self, _: &mut syntax::InterpolationQualifier) -> Visit298   fn visit_interpolation_qualifier(&mut self, _: &mut syntax::InterpolationQualifier) -> Visit {
299     Visit::Children
300   }
301 
visit_iteration_statement(&mut self, _: &mut syntax::IterationStatement) -> Visit302   fn visit_iteration_statement(&mut self, _: &mut syntax::IterationStatement) -> Visit {
303     Visit::Children
304   }
305 
visit_jump_statement(&mut self, _: &mut syntax::JumpStatement) -> Visit306   fn visit_jump_statement(&mut self, _: &mut syntax::JumpStatement) -> Visit {
307     Visit::Children
308   }
309 
visit_layout_qualifier_spec(&mut self, _: &mut syntax::LayoutQualifierSpec) -> Visit310   fn visit_layout_qualifier_spec(&mut self, _: &mut syntax::LayoutQualifierSpec) -> Visit {
311     Visit::Children
312   }
313 
visit_precision_qualifier(&mut self, _: &mut syntax::PrecisionQualifier) -> Visit314   fn visit_precision_qualifier(&mut self, _: &mut syntax::PrecisionQualifier) -> Visit {
315     Visit::Children
316   }
317 
visit_statement(&mut self, _: &mut syntax::Statement) -> Visit318   fn visit_statement(&mut self, _: &mut syntax::Statement) -> Visit {
319     Visit::Children
320   }
321 
visit_compound_statement(&mut self, _: &mut syntax::CompoundStatement) -> Visit322   fn visit_compound_statement(&mut self, _: &mut syntax::CompoundStatement) -> Visit {
323     Visit::Children
324   }
325 
visit_simple_statement(&mut self, _: &mut syntax::SimpleStatement) -> Visit326   fn visit_simple_statement(&mut self, _: &mut syntax::SimpleStatement) -> Visit {
327     Visit::Children
328   }
329 
visit_storage_qualifier(&mut self, _: &mut syntax::StorageQualifier) -> Visit330   fn visit_storage_qualifier(&mut self, _: &mut syntax::StorageQualifier) -> Visit {
331     Visit::Children
332   }
333 
visit_type_qualifier_spec(&mut self, _: &mut syntax::TypeQualifierSpec) -> Visit334   fn visit_type_qualifier_spec(&mut self, _: &mut syntax::TypeQualifierSpec) -> Visit {
335     Visit::Children
336   }
337 
visit_type_specifier_non_array(&mut self, _: &mut syntax::TypeSpecifierNonArray) -> Visit338   fn visit_type_specifier_non_array(&mut self, _: &mut syntax::TypeSpecifierNonArray) -> Visit {
339     Visit::Children
340   }
341 
visit_unary_op(&mut self, _: &mut syntax::UnaryOp) -> Visit342   fn visit_unary_op(&mut self, _: &mut syntax::UnaryOp) -> Visit {
343     Visit::Children
344   }
345 
visit_expr_statement(&mut self, _: &mut syntax::ExprStatement) -> Visit346   fn visit_expr_statement(&mut self, _: &mut syntax::ExprStatement) -> Visit {
347     Visit::Children
348   }
349 }
350 
351 /// Part of the AST that can be visited.
352 ///
353 /// You shouldn’t have to worry about this type nor how to implement it – it’s completely
354 /// implemented for you. However, it works in a pretty simple way: any implementor of [`Host`] can
355 /// be used with a [`Visitor`].
356 ///
357 /// The idea is that visiting an AST node is a two-step process:
358 ///
359 ///   - First, you *can* get your visitor called once as soon as an interesting node gets visited.
360 ///     For instance, if your visitor has an implementation for visiting expressions, everytime an
361 ///     expression gets visited, your visitor will run.
362 ///   - If your implementation of visiting an AST node returns [`Visit::Children`] and if the given
363 ///     node has children, the visitor will go deeper, invoking other calls if you have defined any.
364 ///     A typical pattern you might want to do is to implement your visitor to gets run on all
365 ///     typenames. Since expressions contains variables, you will get your visitor called once again
366 ///     there.
367 ///   - Notice that since visitors are mutable, you can accumulate a state as you go deeper in the
368 ///     AST to implement various checks and validations.
369 pub trait Host {
370   /// Visit an AST node.
visit<V>(&mut self, visitor: &mut V) where V: Visitor371   fn visit<V>(&mut self, visitor: &mut V)
372   where
373     V: Visitor;
374 }
375 
376 impl<T> Host for Option<T>
377 where
378   T: Host,
379 {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,380   fn visit<V>(&mut self, visitor: &mut V)
381   where
382     V: Visitor,
383   {
384     if let Some(ref mut x) = *self {
385       x.visit(visitor);
386     }
387   }
388 }
389 
390 impl<T> Host for Box<T>
391 where
392   T: Host,
393 {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,394   fn visit<V>(&mut self, visitor: &mut V)
395   where
396     V: Visitor,
397   {
398     (**self).visit(visitor);
399   }
400 }
401 
402 impl Host for syntax::TranslationUnit {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,403   fn visit<V>(&mut self, visitor: &mut V)
404   where
405     V: Visitor,
406   {
407     let visit = visitor.visit_translation_unit(self);
408 
409     if visit == Visit::Children {
410       for ed in &mut (self.0).0 {
411         ed.visit(visitor);
412       }
413     }
414   }
415 }
416 
417 impl Host for syntax::ExternalDeclaration {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,418   fn visit<V>(&mut self, visitor: &mut V)
419   where
420     V: Visitor,
421   {
422     let visit = visitor.visit_external_declaration(self);
423 
424     if visit == Visit::Children {
425       match *self {
426         syntax::ExternalDeclaration::Preprocessor(ref mut p) => p.visit(visitor),
427         syntax::ExternalDeclaration::FunctionDefinition(ref mut fd) => fd.visit(visitor),
428         syntax::ExternalDeclaration::Declaration(ref mut d) => d.visit(visitor),
429       }
430     }
431   }
432 }
433 
434 impl Host for syntax::Preprocessor {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,435   fn visit<V>(&mut self, visitor: &mut V)
436   where
437     V: Visitor,
438   {
439     let visit = visitor.visit_preprocessor(self);
440 
441     if visit == Visit::Children {
442       match *self {
443         syntax::Preprocessor::Define(ref mut pd) => pd.visit(visitor),
444         syntax::Preprocessor::Else => (),
445         syntax::Preprocessor::ElseIf(ref mut pei) => pei.visit(visitor),
446         syntax::Preprocessor::EndIf => (),
447         syntax::Preprocessor::Error(ref mut pe) => pe.visit(visitor),
448         syntax::Preprocessor::If(ref mut pi) => pi.visit(visitor),
449         syntax::Preprocessor::IfDef(ref mut pid) => pid.visit(visitor),
450         syntax::Preprocessor::IfNDef(ref mut pind) => pind.visit(visitor),
451         syntax::Preprocessor::Include(ref mut pi) => pi.visit(visitor),
452         syntax::Preprocessor::Line(ref mut pl) => pl.visit(visitor),
453         syntax::Preprocessor::Pragma(ref mut pp) => pp.visit(visitor),
454         syntax::Preprocessor::Undef(ref mut pu) => pu.visit(visitor),
455         syntax::Preprocessor::Version(ref mut pv) => pv.visit(visitor),
456         syntax::Preprocessor::Extension(ref mut ext) => ext.visit(visitor),
457       }
458     }
459   }
460 }
461 
462 impl Host for syntax::PreprocessorDefine {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,463   fn visit<V>(&mut self, visitor: &mut V)
464   where
465     V: Visitor,
466   {
467     let visit = visitor.visit_preprocessor_define(self);
468 
469     if visit == Visit::Children {
470       match *self {
471         syntax::PreprocessorDefine::ObjectLike { ref mut ident, .. } => {
472           ident.visit(visitor);
473         }
474 
475         syntax::PreprocessorDefine::FunctionLike {
476           ref mut ident,
477           ref mut args,
478           ..
479         } => {
480           ident.visit(visitor);
481 
482           for arg in args {
483             arg.visit(visitor);
484           }
485         }
486       }
487     }
488   }
489 }
490 
491 impl Host for syntax::PreprocessorElseIf {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,492   fn visit<V>(&mut self, visitor: &mut V)
493   where
494     V: Visitor,
495   {
496     let _ = visitor.visit_preprocessor_elseif(self);
497   }
498 }
499 
500 impl Host for syntax::PreprocessorError {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,501   fn visit<V>(&mut self, visitor: &mut V)
502   where
503     V: Visitor,
504   {
505     let _ = visitor.visit_preprocessor_error(self);
506   }
507 }
508 
509 impl Host for syntax::PreprocessorIf {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,510   fn visit<V>(&mut self, visitor: &mut V)
511   where
512     V: Visitor,
513   {
514     let _ = visitor.visit_preprocessor_if(self);
515   }
516 }
517 
518 impl Host for syntax::PreprocessorIfDef {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,519   fn visit<V>(&mut self, visitor: &mut V)
520   where
521     V: Visitor,
522   {
523     let visit = visitor.visit_preprocessor_ifdef(self);
524 
525     if visit == Visit::Children {
526       self.ident.visit(visitor);
527     }
528   }
529 }
530 
531 impl Host for syntax::PreprocessorIfNDef {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,532   fn visit<V>(&mut self, visitor: &mut V)
533   where
534     V: Visitor,
535   {
536     let visit = visitor.visit_preprocessor_ifndef(self);
537 
538     if visit == Visit::Children {
539       self.ident.visit(visitor);
540     }
541   }
542 }
543 
544 impl Host for syntax::PreprocessorInclude {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,545   fn visit<V>(&mut self, visitor: &mut V)
546   where
547     V: Visitor,
548   {
549     let _ = visitor.visit_preprocessor_include(self);
550   }
551 }
552 
553 impl Host for syntax::PreprocessorLine {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,554   fn visit<V>(&mut self, visitor: &mut V)
555   where
556     V: Visitor,
557   {
558     let _ = visitor.visit_preprocessor_line(self);
559   }
560 }
561 
562 impl Host for syntax::PreprocessorPragma {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,563   fn visit<V>(&mut self, visitor: &mut V)
564   where
565     V: Visitor,
566   {
567     let _ = visitor.visit_preprocessor_pragma(self);
568   }
569 }
570 
571 impl Host for syntax::PreprocessorUndef {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,572   fn visit<V>(&mut self, visitor: &mut V)
573   where
574     V: Visitor,
575   {
576     let visit = visitor.visit_preprocessor_undef(self);
577 
578     if visit == Visit::Children {
579       self.name.visit(visitor);
580     }
581   }
582 }
583 
584 impl Host for syntax::PreprocessorVersion {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,585   fn visit<V>(&mut self, visitor: &mut V)
586   where
587     V: Visitor,
588   {
589     let visit = visitor.visit_preprocessor_version(self);
590 
591     if visit == Visit::Children {
592       self.profile.visit(visitor);
593     }
594   }
595 }
596 
597 impl Host for syntax::PreprocessorVersionProfile {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,598   fn visit<V>(&mut self, visitor: &mut V)
599   where
600     V: Visitor,
601   {
602     let _ = visitor.visit_preprocessor_version_profile(self);
603   }
604 }
605 
606 impl Host for syntax::PreprocessorExtension {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,607   fn visit<V>(&mut self, visitor: &mut V)
608   where
609     V: Visitor,
610   {
611     let visit = visitor.visit_preprocessor_extension(self);
612 
613     if visit == Visit::Children {
614       self.name.visit(visitor);
615       self.behavior.visit(visitor);
616     }
617   }
618 }
619 
620 impl Host for syntax::PreprocessorExtensionBehavior {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,621   fn visit<V>(&mut self, visitor: &mut V)
622   where
623     V: Visitor,
624   {
625     let _ = visitor.visit_preprocessor_extension_behavior(self);
626   }
627 }
628 
629 impl Host for syntax::PreprocessorExtensionName {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,630   fn visit<V>(&mut self, visitor: &mut V)
631   where
632     V: Visitor,
633   {
634     let _ = visitor.visit_preprocessor_extension_name(self);
635   }
636 }
637 
638 impl Host for syntax::FunctionPrototype {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,639   fn visit<V>(&mut self, visitor: &mut V)
640   where
641     V: Visitor,
642   {
643     let visit = visitor.visit_function_prototype(self);
644 
645     if visit == Visit::Children {
646       self.ty.visit(visitor);
647       self.name.visit(visitor);
648 
649       for param in &mut self.parameters {
650         param.visit(visitor);
651       }
652     }
653   }
654 }
655 
656 impl Host for syntax::FunctionParameterDeclaration {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,657   fn visit<V>(&mut self, visitor: &mut V)
658   where
659     V: Visitor,
660   {
661     let visit = visitor.visit_function_parameter_declaration(self);
662 
663     if visit == Visit::Children {
664       match *self {
665         syntax::FunctionParameterDeclaration::Named(ref mut tq, ref mut fpd) => {
666           tq.visit(visitor);
667           fpd.visit(visitor);
668         }
669 
670         syntax::FunctionParameterDeclaration::Unnamed(ref mut tq, ref mut ty) => {
671           tq.visit(visitor);
672           ty.visit(visitor);
673         }
674       }
675     }
676   }
677 }
678 
679 impl Host for syntax::FunctionParameterDeclarator {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,680   fn visit<V>(&mut self, visitor: &mut V)
681   where
682     V: Visitor,
683   {
684     let visit = visitor.visit_function_parameter_declarator(self);
685 
686     if visit == Visit::Children {
687       self.ty.visit(visitor);
688       self.ident.visit(visitor);
689     }
690   }
691 }
692 
693 impl Host for syntax::FunctionDefinition {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,694   fn visit<V>(&mut self, visitor: &mut V)
695   where
696     V: Visitor,
697   {
698     let visit = visitor.visit_function_definition(self);
699 
700     if visit == Visit::Children {
701       self.prototype.visit(visitor);
702       self.statement.visit(visitor);
703     }
704   }
705 }
706 
707 impl Host for syntax::Declaration {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,708   fn visit<V>(&mut self, visitor: &mut V)
709   where
710     V: Visitor,
711   {
712     let visit = visitor.visit_declaration(self);
713 
714     if visit == Visit::Children {
715       match *self {
716         syntax::Declaration::FunctionPrototype(ref mut fp) => fp.visit(visitor),
717 
718         syntax::Declaration::InitDeclaratorList(ref mut idl) => idl.visit(visitor),
719 
720         syntax::Declaration::Precision(ref mut pq, ref mut ty) => {
721           pq.visit(visitor);
722           ty.visit(visitor);
723         }
724 
725         syntax::Declaration::Block(ref mut block) => block.visit(visitor),
726 
727         syntax::Declaration::Global(ref mut tq, ref mut idents) => {
728           tq.visit(visitor);
729 
730           for ident in idents {
731             ident.visit(visitor);
732           }
733         }
734       }
735     }
736   }
737 }
738 
739 impl Host for syntax::Block {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,740   fn visit<V>(&mut self, visitor: &mut V)
741   where
742     V: Visitor,
743   {
744     let visit = visitor.visit_block(self);
745 
746     if visit == Visit::Children {
747       self.qualifier.visit(visitor);
748       self.name.visit(visitor);
749 
750       for field in &mut self.fields {
751         field.visit(visitor);
752       }
753 
754       self.identifier.visit(visitor);
755     }
756   }
757 }
758 
759 impl Host for syntax::InitDeclaratorList {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,760   fn visit<V>(&mut self, visitor: &mut V)
761   where
762     V: Visitor,
763   {
764     let visit = visitor.visit_init_declarator_list(self);
765 
766     if visit == Visit::Children {
767       self.head.visit(visitor);
768 
769       for d in &mut self.tail {
770         d.visit(visitor);
771       }
772     }
773   }
774 }
775 
776 impl Host for syntax::SingleDeclaration {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,777   fn visit<V>(&mut self, visitor: &mut V)
778   where
779     V: Visitor,
780   {
781     let visit = visitor.visit_single_declaration(self);
782 
783     if visit == Visit::Children {
784       self.ty.visit(visitor);
785       self.name.visit(visitor);
786       self.array_specifier.visit(visitor);
787       self.initializer.visit(visitor);
788     }
789   }
790 }
791 
792 impl Host for syntax::SingleDeclarationNoType {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,793   fn visit<V>(&mut self, visitor: &mut V)
794   where
795     V: Visitor,
796   {
797     let visit = visitor.visit_single_declaration_no_type(self);
798 
799     if visit == Visit::Children {
800       self.ident.visit(visitor);
801       self.initializer.visit(visitor);
802     }
803   }
804 }
805 
806 impl Host for syntax::FullySpecifiedType {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,807   fn visit<V>(&mut self, visitor: &mut V)
808   where
809     V: Visitor,
810   {
811     let visit = visitor.visit_full_specified_type(self);
812 
813     if visit == Visit::Children {
814       self.qualifier.visit(visitor);
815       self.ty.visit(visitor);
816     }
817   }
818 }
819 
820 impl Host for syntax::TypeSpecifier {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,821   fn visit<V>(&mut self, visitor: &mut V)
822   where
823     V: Visitor,
824   {
825     let visit = visitor.visit_type_specifier(self);
826 
827     if visit == Visit::Children {
828       self.ty.visit(visitor);
829       self.array_specifier.visit(visitor);
830     }
831   }
832 }
833 
834 impl Host for syntax::TypeSpecifierNonArray {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,835   fn visit<V>(&mut self, visitor: &mut V)
836   where
837     V: Visitor,
838   {
839     let visit = visitor.visit_type_specifier_non_array(self);
840 
841     if visit == Visit::Children {
842       match *self {
843         syntax::TypeSpecifierNonArray::Struct(ref mut ss) => ss.visit(visitor),
844         syntax::TypeSpecifierNonArray::TypeName(ref mut tn) => tn.visit(visitor),
845         _ => (),
846       }
847     }
848   }
849 }
850 
851 impl Host for syntax::TypeQualifier {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,852   fn visit<V>(&mut self, visitor: &mut V)
853   where
854     V: Visitor,
855   {
856     let visit = visitor.visit_type_qualifier(self);
857 
858     if visit == Visit::Children {
859       for tqs in &mut self.qualifiers.0 {
860         tqs.visit(visitor);
861       }
862     }
863   }
864 }
865 
866 impl Host for syntax::TypeQualifierSpec {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,867   fn visit<V>(&mut self, visitor: &mut V)
868   where
869     V: Visitor,
870   {
871     let visit = visitor.visit_type_qualifier_spec(self);
872 
873     if visit == Visit::Children {
874       match *self {
875         syntax::TypeQualifierSpec::Storage(ref mut sq) => sq.visit(visitor),
876         syntax::TypeQualifierSpec::Layout(ref mut lq) => lq.visit(visitor),
877         syntax::TypeQualifierSpec::Precision(ref mut pq) => pq.visit(visitor),
878         syntax::TypeQualifierSpec::Interpolation(ref mut iq) => iq.visit(visitor),
879         _ => (),
880       }
881     }
882   }
883 }
884 
885 impl Host for syntax::StorageQualifier {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,886   fn visit<V>(&mut self, visitor: &mut V)
887   where
888     V: Visitor,
889   {
890     let visit = visitor.visit_storage_qualifier(self);
891 
892     if visit == Visit::Children {
893       if let syntax::StorageQualifier::Subroutine(ref mut names) = *self {
894         for name in names {
895           name.visit(visitor);
896         }
897       }
898     }
899   }
900 }
901 
902 impl Host for syntax::LayoutQualifier {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,903   fn visit<V>(&mut self, visitor: &mut V)
904   where
905     V: Visitor,
906   {
907     let visit = visitor.visit_layout_qualifier(self);
908 
909     if visit == Visit::Children {
910       for lqs in &mut self.ids.0 {
911         lqs.visit(visitor);
912       }
913     }
914   }
915 }
916 
917 impl Host for syntax::LayoutQualifierSpec {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,918   fn visit<V>(&mut self, visitor: &mut V)
919   where
920     V: Visitor,
921   {
922     let visit = visitor.visit_layout_qualifier_spec(self);
923 
924     if visit == Visit::Children {
925       if let syntax::LayoutQualifierSpec::Identifier(ref mut ident, ref mut expr) = *self {
926         ident.visit(visitor);
927 
928         if let Some(ref mut e) = *expr {
929           e.visit(visitor);
930         }
931       }
932     }
933   }
934 }
935 
936 impl Host for syntax::PrecisionQualifier {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,937   fn visit<V>(&mut self, visitor: &mut V)
938   where
939     V: Visitor,
940   {
941     let _ = visitor.visit_precision_qualifier(self);
942   }
943 }
944 
945 impl Host for syntax::InterpolationQualifier {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,946   fn visit<V>(&mut self, visitor: &mut V)
947   where
948     V: Visitor,
949   {
950     let _ = visitor.visit_interpolation_qualifier(self);
951   }
952 }
953 
954 impl Host for syntax::TypeName {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,955   fn visit<V>(&mut self, visitor: &mut V)
956   where
957     V: Visitor,
958   {
959     let _ = visitor.visit_type_name(self);
960   }
961 }
962 
963 impl Host for syntax::Identifier {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,964   fn visit<V>(&mut self, visitor: &mut V)
965   where
966     V: Visitor,
967   {
968     let _ = visitor.visit_identifier(self);
969   }
970 }
971 
972 impl Host for syntax::ArrayedIdentifier {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,973   fn visit<V>(&mut self, visitor: &mut V)
974   where
975     V: Visitor,
976   {
977     let visit = visitor.visit_arrayed_identifier(self);
978 
979     if visit == Visit::Children {
980       self.ident.visit(visitor);
981       self.array_spec.visit(visitor);
982     }
983   }
984 }
985 
986 impl Host for syntax::Expr {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,987   fn visit<V>(&mut self, visitor: &mut V)
988   where
989     V: Visitor,
990   {
991     let visit = visitor.visit_expr(self);
992 
993     if visit == Visit::Children {
994       match *self {
995         syntax::Expr::Variable(ref mut ident) => ident.visit(visitor),
996 
997         syntax::Expr::Unary(ref mut op, ref mut e) => {
998           op.visit(visitor);
999           e.visit(visitor);
1000         }
1001 
1002         syntax::Expr::Binary(ref mut op, ref mut a, ref mut b) => {
1003           op.visit(visitor);
1004           a.visit(visitor);
1005           b.visit(visitor);
1006         }
1007 
1008         syntax::Expr::Ternary(ref mut a, ref mut b, ref mut c) => {
1009           a.visit(visitor);
1010           b.visit(visitor);
1011           c.visit(visitor);
1012         }
1013 
1014         syntax::Expr::Assignment(ref mut lhs, ref mut op, ref mut rhs) => {
1015           lhs.visit(visitor);
1016           op.visit(visitor);
1017           rhs.visit(visitor);
1018         }
1019 
1020         syntax::Expr::Bracket(ref mut e, ref mut arr_spec) => {
1021           e.visit(visitor);
1022           arr_spec.visit(visitor);
1023         }
1024 
1025         syntax::Expr::FunCall(ref mut fi, ref mut params) => {
1026           fi.visit(visitor);
1027 
1028           for param in params {
1029             param.visit(visitor);
1030           }
1031         }
1032 
1033         syntax::Expr::Dot(ref mut e, ref mut i) => {
1034           e.visit(visitor);
1035           i.visit(visitor);
1036         }
1037 
1038         syntax::Expr::PostInc(ref mut e) => e.visit(visitor),
1039 
1040         syntax::Expr::PostDec(ref mut e) => e.visit(visitor),
1041 
1042         syntax::Expr::Comma(ref mut a, ref mut b) => {
1043           a.visit(visitor);
1044           b.visit(visitor);
1045         }
1046 
1047         _ => (),
1048       }
1049     }
1050   }
1051 }
1052 
1053 impl Host for syntax::UnaryOp {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,1054   fn visit<V>(&mut self, visitor: &mut V)
1055   where
1056     V: Visitor,
1057   {
1058     let _ = visitor.visit_unary_op(self);
1059   }
1060 }
1061 
1062 impl Host for syntax::BinaryOp {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,1063   fn visit<V>(&mut self, visitor: &mut V)
1064   where
1065     V: Visitor,
1066   {
1067     let _ = visitor.visit_binary_op(self);
1068   }
1069 }
1070 
1071 impl Host for syntax::AssignmentOp {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,1072   fn visit<V>(&mut self, visitor: &mut V)
1073   where
1074     V: Visitor,
1075   {
1076     let _ = visitor.visit_assignment_op(self);
1077   }
1078 }
1079 
1080 impl Host for syntax::ArraySpecifier {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,1081   fn visit<V>(&mut self, visitor: &mut V)
1082   where
1083     V: Visitor,
1084   {
1085     let visit = visitor.visit_array_specifier(self);
1086 
1087     if visit == Visit::Children {
1088       if let syntax::ArraySpecifier::ExplicitlySized(ref mut e) = *self {
1089         e.visit(visitor);
1090       }
1091     }
1092   }
1093 }
1094 
1095 impl Host for syntax::FunIdentifier {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,1096   fn visit<V>(&mut self, visitor: &mut V)
1097   where
1098     V: Visitor,
1099   {
1100     let visit = visitor.visit_fun_identifier(self);
1101 
1102     if visit == Visit::Children {
1103       match *self {
1104         syntax::FunIdentifier::Identifier(ref mut i) => i.visit(visitor),
1105         syntax::FunIdentifier::Expr(ref mut e) => e.visit(visitor),
1106       }
1107     }
1108   }
1109 }
1110 
1111 impl Host for syntax::StructSpecifier {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,1112   fn visit<V>(&mut self, visitor: &mut V)
1113   where
1114     V: Visitor,
1115   {
1116     let visit = visitor.visit_struct_specifier(self);
1117 
1118     if visit == Visit::Children {
1119       self.name.visit(visitor);
1120 
1121       for field in &mut self.fields.0 {
1122         field.visit(visitor);
1123       }
1124     }
1125   }
1126 }
1127 
1128 impl Host for syntax::StructFieldSpecifier {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,1129   fn visit<V>(&mut self, visitor: &mut V)
1130   where
1131     V: Visitor,
1132   {
1133     let visit = visitor.visit_struct_field_specifier(self);
1134 
1135     if visit == Visit::Children {
1136       self.qualifier.visit(visitor);
1137       self.ty.visit(visitor);
1138 
1139       for identifier in &mut self.identifiers.0 {
1140         identifier.visit(visitor);
1141       }
1142     }
1143   }
1144 }
1145 
1146 impl Host for syntax::Statement {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,1147   fn visit<V>(&mut self, visitor: &mut V)
1148   where
1149     V: Visitor,
1150   {
1151     let visit = visitor.visit_statement(self);
1152 
1153     if visit == Visit::Children {
1154       match *self {
1155         syntax::Statement::Compound(ref mut cs) => cs.visit(visitor),
1156         syntax::Statement::Simple(ref mut ss) => ss.visit(visitor),
1157       }
1158     }
1159   }
1160 }
1161 
1162 impl Host for syntax::SimpleStatement {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,1163   fn visit<V>(&mut self, visitor: &mut V)
1164   where
1165     V: Visitor,
1166   {
1167     let visit = visitor.visit_simple_statement(self);
1168 
1169     if visit == Visit::Children {
1170       match *self {
1171         syntax::SimpleStatement::Declaration(ref mut d) => d.visit(visitor),
1172         syntax::SimpleStatement::Expression(ref mut e) => e.visit(visitor),
1173         syntax::SimpleStatement::Selection(ref mut s) => s.visit(visitor),
1174         syntax::SimpleStatement::Switch(ref mut s) => s.visit(visitor),
1175         syntax::SimpleStatement::CaseLabel(ref mut cl) => cl.visit(visitor),
1176         syntax::SimpleStatement::Iteration(ref mut i) => i.visit(visitor),
1177         syntax::SimpleStatement::Jump(ref mut j) => j.visit(visitor),
1178       }
1179     }
1180   }
1181 }
1182 
1183 impl Host for syntax::CompoundStatement {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,1184   fn visit<V>(&mut self, visitor: &mut V)
1185   where
1186     V: Visitor,
1187   {
1188     let visit = visitor.visit_compound_statement(self);
1189 
1190     if visit == Visit::Children {
1191       for stmt in &mut self.statement_list {
1192         stmt.visit(visitor);
1193       }
1194     }
1195   }
1196 }
1197 
1198 impl Host for syntax::SelectionStatement {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,1199   fn visit<V>(&mut self, visitor: &mut V)
1200   where
1201     V: Visitor,
1202   {
1203     let visit = visitor.visit_selection_statement(self);
1204 
1205     if visit == Visit::Children {
1206       self.cond.visit(visitor);
1207       self.rest.visit(visitor);
1208     }
1209   }
1210 }
1211 
1212 impl Host for syntax::SelectionRestStatement {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,1213   fn visit<V>(&mut self, visitor: &mut V)
1214   where
1215     V: Visitor,
1216   {
1217     let visit = visitor.visit_selection_rest_statement(self);
1218 
1219     if visit == Visit::Children {
1220       match *self {
1221         syntax::SelectionRestStatement::Statement(ref mut s) => s.visit(visitor),
1222 
1223         syntax::SelectionRestStatement::Else(ref mut a, ref mut b) => {
1224           a.visit(visitor);
1225           b.visit(visitor);
1226         }
1227       }
1228     }
1229   }
1230 }
1231 
1232 impl Host for syntax::SwitchStatement {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,1233   fn visit<V>(&mut self, visitor: &mut V)
1234   where
1235     V: Visitor,
1236   {
1237     let visit = visitor.visit_switch_statement(self);
1238 
1239     if visit == Visit::Children {
1240       self.head.visit(visitor);
1241 
1242       for s in &mut self.body {
1243         s.visit(visitor);
1244       }
1245     }
1246   }
1247 }
1248 
1249 impl Host for syntax::CaseLabel {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,1250   fn visit<V>(&mut self, visitor: &mut V)
1251   where
1252     V: Visitor,
1253   {
1254     let visit = visitor.visit_case_label(self);
1255 
1256     if visit == Visit::Children {
1257       if let syntax::CaseLabel::Case(ref mut e) = *self {
1258         e.visit(visitor);
1259       }
1260     }
1261   }
1262 }
1263 
1264 impl Host for syntax::IterationStatement {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,1265   fn visit<V>(&mut self, visitor: &mut V)
1266   where
1267     V: Visitor,
1268   {
1269     let visit = visitor.visit_iteration_statement(self);
1270 
1271     if visit == Visit::Children {
1272       match *self {
1273         syntax::IterationStatement::While(ref mut c, ref mut s) => {
1274           c.visit(visitor);
1275           s.visit(visitor);
1276         }
1277 
1278         syntax::IterationStatement::DoWhile(ref mut s, ref mut e) => {
1279           s.visit(visitor);
1280           e.visit(visitor);
1281         }
1282 
1283         syntax::IterationStatement::For(ref mut fis, ref mut frs, ref mut s) => {
1284           fis.visit(visitor);
1285           frs.visit(visitor);
1286           s.visit(visitor);
1287         }
1288       }
1289     }
1290   }
1291 }
1292 
1293 impl Host for syntax::ForInitStatement {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,1294   fn visit<V>(&mut self, visitor: &mut V)
1295   where
1296     V: Visitor,
1297   {
1298     let visit = visitor.visit_for_init_statement(self);
1299 
1300     if visit == Visit::Children {
1301       match *self {
1302         syntax::ForInitStatement::Expression(ref mut e) => e.visit(visitor),
1303         syntax::ForInitStatement::Declaration(ref mut d) => d.visit(visitor),
1304       }
1305     }
1306   }
1307 }
1308 
1309 impl Host for syntax::ForRestStatement {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,1310   fn visit<V>(&mut self, visitor: &mut V)
1311   where
1312     V: Visitor,
1313   {
1314     let visit = visitor.visit_for_rest_statement(self);
1315 
1316     if visit == Visit::Children {
1317       self.condition.visit(visitor);
1318       self.post_expr.visit(visitor);
1319     }
1320   }
1321 }
1322 
1323 impl Host for syntax::JumpStatement {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,1324   fn visit<V>(&mut self, visitor: &mut V)
1325   where
1326     V: Visitor,
1327   {
1328     let visit = visitor.visit_jump_statement(self);
1329 
1330     if visit == Visit::Children {
1331       if let syntax::JumpStatement::Return(ref mut r) = *self {
1332         r.visit(visitor);
1333       }
1334     }
1335   }
1336 }
1337 
1338 impl Host for syntax::Condition {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,1339   fn visit<V>(&mut self, visitor: &mut V)
1340   where
1341     V: Visitor,
1342   {
1343     let visit = visitor.visit_condition(self);
1344 
1345     if visit == Visit::Children {
1346       match *self {
1347         syntax::Condition::Expr(ref mut e) => e.visit(visitor),
1348 
1349         syntax::Condition::Assignment(ref mut fst, ref mut ident, ref mut init) => {
1350           fst.visit(visitor);
1351           ident.visit(visitor);
1352           init.visit(visitor);
1353         }
1354       }
1355     }
1356   }
1357 }
1358 
1359 impl Host for syntax::Initializer {
visit<V>(&mut self, visitor: &mut V) where V: Visitor,1360   fn visit<V>(&mut self, visitor: &mut V)
1361   where
1362     V: Visitor,
1363   {
1364     let visit = visitor.visit_initializer(self);
1365 
1366     if visit == Visit::Children {
1367       match *self {
1368         syntax::Initializer::Simple(ref mut e) => e.visit(visitor),
1369 
1370         syntax::Initializer::List(ref mut i) => {
1371           for i in &mut i.0 {
1372             i.visit(visitor);
1373           }
1374         }
1375       }
1376     }
1377   }
1378 }
1379 
1380 #[cfg(test)]
1381 mod tests {
1382   use std::iter::FromIterator;
1383 
1384   use super::*;
1385   use syntax;
1386 
1387   #[test]
count_variables()1388   fn count_variables() {
1389     let decl0 = syntax::Statement::declare_var(
1390       syntax::TypeSpecifierNonArray::Float,
1391       "x",
1392       None,
1393       Some(syntax::Expr::from(3.14).into()),
1394     );
1395 
1396     let decl1 = syntax::Statement::declare_var(syntax::TypeSpecifierNonArray::Int, "y", None, None);
1397 
1398     let decl2 =
1399       syntax::Statement::declare_var(syntax::TypeSpecifierNonArray::Vec4, "z", None, None);
1400 
1401     let mut compound = syntax::CompoundStatement::from_iter(vec![decl0, decl1, decl2]);
1402 
1403     // our visitor that will count the number of variables it saw
1404     struct Counter {
1405       var_nb: usize,
1406     }
1407 
1408     impl Visitor for Counter {
1409       // we are only interested in single declaration with a name
1410       fn visit_single_declaration(&mut self, declaration: &mut syntax::SingleDeclaration) -> Visit {
1411         if declaration.name.is_some() {
1412           self.var_nb += 1;
1413         }
1414 
1415         // do not go deeper
1416         Visit::Parent
1417       }
1418     }
1419 
1420     let mut counter = Counter { var_nb: 0 };
1421     compound.visit(&mut counter);
1422     assert_eq!(counter.var_nb, 3);
1423   }
1424 }
1425