(&mut self, node: Node<'t>)
| 530 | // --- the dispatcher (visitNode, PHP-relevant branches) ------------------------ |
| 531 | |
| 532 | fn visit_node(&mut self, node: Node<'t>) { |
| 533 | if self.try_visit_hook(node) { |
| 534 | self.scan_fn_ref_subtree(node, 0); |
| 535 | return; |
| 536 | } |
| 537 | |
| 538 | let kind = node.kind(); |
| 539 | let mut skip_children = false; |
| 540 | |
| 541 | self.maybe_capture_fn_refs(node); |
| 542 | |
| 543 | if kind == "function_definition" { |
| 544 | // functionTypes; method_declaration is not in it, so this is |
| 545 | // always extractFunction (php functions can't be class members). |
| 546 | self.extract_function(node); |
| 547 | skip_children = true; |
| 548 | } else if kind == "class_declaration" { |
| 549 | self.extract_class(node, "class"); |
| 550 | skip_children = true; |
| 551 | } else if kind == "trait_declaration" { |
| 552 | // classifyClassNode → 'trait'. |
| 553 | self.extract_class(node, "trait"); |
| 554 | skip_children = true; |
| 555 | } else if kind == "method_declaration" { |
| 556 | // Inside a class-like → method; outside (an anonymous class's |
| 557 | // members at TOP level — grammar-bump delta #1) the 1747 gate |
| 558 | // bounces to extractFunction: a file-level `function` node. |
| 559 | if self.inside_class_like() { |
| 560 | self.extract_method(node); |
| 561 | } else { |
| 562 | self.extract_function(node); |
| 563 | } |
| 564 | skip_children = true; |
| 565 | } else if kind == "interface_declaration" { |
| 566 | self.extract_interface(node); |
| 567 | skip_children = true; |
| 568 | } else if kind == "enum_declaration" { |
| 569 | self.extract_enum(node); |
| 570 | skip_children = true; |
| 571 | } else if kind == "property_declaration" && self.inside_class_like() { |
| 572 | self.extract_field(node); |
| 573 | self.scan_fn_ref_subtree(node, 0); |
| 574 | skip_children = true; |
| 575 | } else if matches!( |
| 576 | kind, |
| 577 | "namespace_use_declaration" | "include_expression" | "include_once_expression" |
| 578 | | "require_expression" | "require_once_expression" |
| 579 | ) { |
| 580 | self.extract_import(node); |
| 581 | // children still visited (importTypes sets no skipChildren) |
| 582 | } else if matches!( |
| 583 | kind, |
| 584 | "function_call_expression" | "member_call_expression" | "scoped_call_expression" |
| 585 | ) { |
| 586 | self.extract_call(node); |
| 587 | } else if kind == "object_creation_expression" { |
| 588 | self.extract_instantiation(node); |
| 589 | if let Some(anon_body) = find_anonymous_class_body(node) { |
no test coverage detected