probe_code/language/
typescript.rs

1use super::language_trait::LanguageImpl;
2use tree_sitter::{Language as TSLanguage, Node};
3
4/// Implementation of LanguageImpl for TypeScript
5pub struct TypeScriptLanguage {
6    tsx: bool,
7}
8
9impl TypeScriptLanguage {
10    pub fn new_typescript() -> Self {
11        TypeScriptLanguage { tsx: false }
12    }
13
14    pub fn new_tsx() -> Self {
15        TypeScriptLanguage { tsx: true }
16    }
17}
18
19impl LanguageImpl for TypeScriptLanguage {
20    fn get_tree_sitter_language(&self) -> TSLanguage {
21        if self.tsx {
22            tree_sitter_typescript::LANGUAGE_TSX.into()
23        } else {
24            tree_sitter_typescript::LANGUAGE_TYPESCRIPT.into()
25        }
26    }
27
28    fn get_extension(&self) -> &'static str {
29        if self.tsx {
30            "tsx"
31        } else {
32            "ts"
33        }
34    }
35
36    fn is_acceptable_parent(&self, node: &Node) -> bool {
37        matches!(
38            node.kind(),
39            "function_declaration"
40                | "method_definition"
41                | "class_declaration"
42                | "arrow_function"
43                | "function"
44                | "export_statement"
45                | "variable_declaration"
46                | "lexical_declaration"
47                | "interface_declaration"  // TypeScript specific
48                | "type_alias_declaration" // TypeScript specific
49                | "enum_declaration" // TypeScript specific
50        )
51    }
52
53    fn is_test_node(&self, node: &Node, source: &[u8]) -> bool {
54        // TypeScript test detection is the same as JavaScript
55        let debug_mode = std::env::var("DEBUG").unwrap_or_default() == "1";
56        let node_type = node.kind();
57
58        // TypeScript: Check for describe/it/test blocks
59        if node_type == "function_declaration"
60            || node_type == "method_definition"
61            || node_type == "arrow_function"
62        {
63            let mut cursor = node.walk();
64
65            // Try to find the function/method name
66            for child in node.children(&mut cursor) {
67                if child.kind() == "identifier" {
68                    let name = child.utf8_text(source).unwrap_or("");
69                    if name.contains("test") || name.contains("Test") {
70                        if debug_mode {
71                            println!(
72                                "DEBUG: Test node detected (TypeScript): test function/method"
73                            );
74                        }
75                        return true;
76                    }
77                }
78            }
79        }
80
81        // Check for call expressions like describe(), it(), test()
82        if node_type == "call_expression" {
83            let mut cursor = node.walk();
84            for child in node.children(&mut cursor) {
85                if child.kind() == "identifier" {
86                    let name = child.utf8_text(source).unwrap_or("");
87                    if name == "describe" || name == "it" || name == "test" || name == "expect" {
88                        if debug_mode {
89                            println!("DEBUG: Test node detected (TypeScript): {name} call");
90                        }
91                        return true;
92                    }
93                }
94            }
95        }
96
97        false
98    }
99}