Skip to main content

code_analyze_mcp/languages/
typescript.rs

1/// Tree-sitter query for extracting TypeScript elements (functions, classes, and TS-specific types).
2pub const ELEMENT_QUERY: &str = r"
3(function_declaration) @function
4(class_declaration) @class
5(method_definition) @function
6(interface_declaration) @class
7(type_alias_declaration) @class
8(enum_declaration) @class
9(abstract_class_declaration) @class
10";
11
12/// Tree-sitter query for extracting function calls.
13pub const CALL_QUERY: &str = r"
14(call_expression
15  function: (identifier) @call)
16(call_expression
17  function: (member_expression property: (property_identifier) @call))
18";
19
20/// Tree-sitter query for extracting type references.
21pub const REFERENCE_QUERY: &str = r"
22(type_identifier) @type_ref
23";
24
25/// Tree-sitter query for extracting TypeScript imports.
26pub const IMPORT_QUERY: &str = r"
27(import_statement) @import_path
28";
29
30use tree_sitter::Node;
31
32/// Extract inheritance information from a TypeScript class node.
33#[must_use]
34pub fn extract_inheritance(node: &Node, source: &str) -> Vec<String> {
35    let mut inherits = Vec::new();
36
37    // Walk children to find class_heritage node
38    for i in 0..node.named_child_count() {
39        if let Some(child) = node.named_child(u32::try_from(i).unwrap_or(u32::MAX))
40            && child.kind() == "class_heritage"
41        {
42            // Walk class_heritage children for extends_clause and implements_clause
43            for j in 0..child.named_child_count() {
44                if let Some(clause) = child.named_child(u32::try_from(j).unwrap_or(u32::MAX)) {
45                    if clause.kind() == "extends_clause" {
46                        // Extract extends type
47                        if let Some(value) = clause.child_by_field_name("value") {
48                            let text = &source[value.start_byte()..value.end_byte()];
49                            inherits.push(format!("extends {text}"));
50                        }
51                    } else if clause.kind() == "implements_clause" {
52                        // Extract implements types
53                        for k in 0..clause.named_child_count() {
54                            if let Some(type_node) =
55                                clause.named_child(u32::try_from(k).unwrap_or(u32::MAX))
56                                && type_node.kind() == "type_identifier"
57                            {
58                                let text = &source[type_node.start_byte()..type_node.end_byte()];
59                                inherits.push(format!("implements {text}"));
60                            }
61                        }
62                    }
63                }
64            }
65        }
66    }
67
68    inherits
69}