Walk the AST and extract entities. `in_type` tracks the enclosing type name (class, struct, enum, protocol, or extension) so that nested `function_declaration` nodes are emitted as `Method` rather than `Function`.
(
&self,
node: &Node,
source: &str,
file_path: &str,
entities: &mut Vec<Entity>,
in_type: Option<&str>,
)
| 56 | /// or extension) so that nested `function_declaration` nodes are emitted as |
| 57 | /// `Method` rather than `Function`. |
| 58 | fn walk_tree( |
| 59 | &self, |
| 60 | node: &Node, |
| 61 | source: &str, |
| 62 | file_path: &str, |
| 63 | entities: &mut Vec<Entity>, |
| 64 | in_type: Option<&str>, |
| 65 | ) { |
| 66 | match node.kind() { |
| 67 | "function_declaration" | "protocol_function_declaration" => { |
| 68 | if let Some(entity) = self.extract_function(node, source, file_path, in_type) { |
| 69 | entities.push(entity); |
| 70 | } |
| 71 | } |
| 72 | // tree-sitter-swift uses `class_declaration` for class, struct, |
| 73 | // AND enum — differentiated by the keyword child node. |
| 74 | "class_declaration" => { |
| 75 | let kind = self.detect_type_kind(node); |
| 76 | if let Some(entity) = self.extract_type_declaration(node, source, file_path, kind) { |
| 77 | let type_name = entity.name.clone(); |
| 78 | entities.push(entity); |
| 79 | |
| 80 | // Walk the body for methods. The body node kind varies: |
| 81 | // class/struct → class_body |
| 82 | // enum → enum_class_body |
| 83 | if let Some(body) = self.find_type_body(node) { |
| 84 | let mut cursor = body.walk(); |
| 85 | for child in body.children(&mut cursor) { |
| 86 | self.walk_tree(&child, source, file_path, entities, Some(&type_name)); |
| 87 | } |
| 88 | } |
| 89 | return; |
| 90 | } |
| 91 | } |
| 92 | "protocol_declaration" => { |
| 93 | if let Some(entity) = |
| 94 | self.extract_type_declaration(node, source, file_path, EntityKind::Interface) |
| 95 | { |
| 96 | let type_name = entity.name.clone(); |
| 97 | entities.push(entity); |
| 98 | |
| 99 | if let Some(body) = self.find_type_body(node) { |
| 100 | let mut cursor = body.walk(); |
| 101 | for child in body.children(&mut cursor) { |
| 102 | self.walk_tree(&child, source, file_path, entities, Some(&type_name)); |
| 103 | } |
| 104 | } |
| 105 | return; |
| 106 | } |
| 107 | } |
| 108 | "extension_declaration" => { |
| 109 | // Extensions don't produce their own entity, but functions |
| 110 | // inside them become Method with the extended type as context. |
| 111 | let type_name = self.find_type_identifier(node, source); |
| 112 | |
| 113 | if let Some(body) = self.find_type_body(node) { |
| 114 | let mut cursor = body.walk(); |
| 115 | for child in body.children(&mut cursor) { |
no test coverage detected