probe_code/language/
javascript.rs

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