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