(&mut self, node: Node<'t>)
| 607 | // --- the dispatcher (visitNode) -------------------------------------------- |
| 608 | |
| 609 | fn visit_node(&mut self, node: Node<'t>) { |
| 610 | let kind = node.kind(); |
| 611 | let mut skip_children = false; |
| 612 | |
| 613 | // Function-as-value capture — independent of the dispatch ladder. |
| 614 | self.maybe_capture_fn_refs(node); |
| 615 | |
| 616 | if is_function_type(kind) { |
| 617 | // (the isInsideClassLike + methodTypes overlap is Python/Ruby-only) |
| 618 | self.extract_function(node, None); |
| 619 | skip_children = true; |
| 620 | } else if is_class_type(self.variant, kind) { |
| 621 | self.extract_class(node); |
| 622 | skip_children = true; |
| 623 | } else if is_method_type(self.variant, kind) { |
| 624 | if classify_ts_class_member(node) == Member::Property { |
| 625 | let prop = self.extract_property(node); |
| 626 | if let (Some((row, name)), Some(value)) = (prop, node.child_by_field_name("value")) { |
| 627 | self.stack.push(Scope { row, kind: "property", name }); |
| 628 | self.visit_function_body(value); |
| 629 | self.stack.pop(); |
| 630 | } |
| 631 | self.scan_fn_ref_subtree(node, 0); |
| 632 | } else { |
| 633 | self.extract_method(node); |
| 634 | } |
| 635 | skip_children = true; |
| 636 | } else if self.variant.is_ts() && kind == "interface_declaration" { |
| 637 | self.extract_interface(node); |
| 638 | skip_children = true; |
| 639 | } else if self.variant.is_ts() && kind == "enum_declaration" { |
| 640 | self.extract_enum(node); |
| 641 | skip_children = true; |
| 642 | } else if self.variant.is_ts() && kind == "type_alias_declaration" { |
| 643 | skip_children = self.extract_type_alias(node); |
| 644 | } else if is_variable_type(kind) && !self.inside_class_like() { |
| 645 | self.extract_variable(node); |
| 646 | self.scan_fn_ref_subtree(node, 0); |
| 647 | skip_children = true; |
| 648 | } else if kind == "import_statement" { |
| 649 | self.extract_import(node); |
| 650 | } else if kind == "export_statement" && node.child_by_field_name("source").is_some() { |
| 651 | // Re-export: `export { X } from './y'`. |
| 652 | self.emit_re_export_refs(node); |
| 653 | } else if kind == "export_statement" && self.looks_like_vue_store_file() { |
| 654 | // Vuex MODULE default export (`export default { actions: {…} }`). |
| 655 | if let Some(exported) = node.child_by_field_name("value") { |
| 656 | if matches!(exported.kind(), "object" | "object_expression") { |
| 657 | self.extract_store_collection_methods(exported); |
| 658 | skip_children = true; |
| 659 | } |
| 660 | } |
| 661 | } else if kind == "call_expression" { |
| 662 | self.extract_call(node); |
| 663 | } else if kind == "new_expression" { |
| 664 | self.extract_instantiation(node); |
| 665 | } else if self.variant.is_ts() |
| 666 | && matches!(kind, "property_signature" | "method_signature") |
no test coverage detected