Skip to main content

atomcode_core/semantic/
language.rs

1use std::path::Path;
2use tree_sitter::Language;
3
4/// Supported languages with their tree-sitter grammars.
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6pub enum Lang {
7    Rust,
8    Python,
9    JavaScript,
10    TypeScript,
11    Tsx,
12    Go,
13    Java,
14    C,
15    Cpp,
16    CSharp,
17    Html,
18    Php,
19    /// Vue SFC — dual parser: <script> as TypeScript, <template> as HTML.
20    Vue,
21}
22
23impl Lang {
24    /// Get the tree-sitter Language grammar for this language.
25    pub fn grammar(&self) -> Language {
26        match self {
27            Lang::Rust => tree_sitter_rust::LANGUAGE.into(),
28            Lang::Python => tree_sitter_python::LANGUAGE.into(),
29            Lang::JavaScript => tree_sitter_javascript::LANGUAGE.into(),
30            Lang::TypeScript => tree_sitter_typescript::LANGUAGE_TYPESCRIPT.into(),
31            Lang::Tsx => tree_sitter_typescript::LANGUAGE_TSX.into(),
32            Lang::Go => tree_sitter_go::LANGUAGE.into(),
33            Lang::Java => tree_sitter_java::LANGUAGE.into(),
34            Lang::C => tree_sitter_c::LANGUAGE.into(),
35            Lang::Cpp => tree_sitter_cpp::LANGUAGE.into(),
36            Lang::CSharp => tree_sitter_c_sharp::LANGUAGE.into(),
37            Lang::Html => tree_sitter_html::LANGUAGE.into(),
38            Lang::Php => tree_sitter_php::LANGUAGE_PHP.into(),
39            Lang::Vue => tree_sitter_typescript::LANGUAGE_TYPESCRIPT.into(),
40        }
41    }
42
43    /// The tree-sitter query for extracting function/method definitions.
44    pub fn symbols_query(&self) -> &'static str {
45        match self {
46            Lang::Rust => include_str!("queries/rust.scm"),
47            Lang::Python => include_str!("queries/python.scm"),
48            Lang::JavaScript | Lang::Tsx => include_str!("queries/javascript.scm"),
49            Lang::TypeScript => include_str!("queries/typescript.scm"),
50            Lang::Go => include_str!("queries/go.scm"),
51            Lang::Java => include_str!("queries/java.scm"),
52            Lang::C => include_str!("queries/c.scm"),
53            Lang::Cpp => include_str!("queries/cpp.scm"),
54            Lang::CSharp => include_str!("queries/csharp.scm"),
55            Lang::Html => include_str!("queries/html.scm"),
56            Lang::Php => include_str!("queries/php.scm"),
57            Lang::Vue => include_str!("queries/typescript.scm"),
58        }
59    }
60
61    /// The tree-sitter query for extracting call expressions (callee names).
62    pub fn calls_query(&self) -> Option<&'static str> {
63        match self {
64            Lang::Rust => Some(include_str!("../graph/queries/rust_calls.scm")),
65            Lang::Python => Some(include_str!("../graph/queries/python_calls.scm")),
66            Lang::JavaScript | Lang::TypeScript | Lang::Tsx | Lang::Vue => {
67                Some(include_str!("../graph/queries/javascript_calls.scm"))
68            }
69            Lang::Java => Some(include_str!("../graph/queries/java_calls.scm")),
70            Lang::Go => Some(include_str!("../graph/queries/go_calls.scm")),
71            Lang::C | Lang::Cpp | Lang::CSharp => None,
72            Lang::Html => None,
73            Lang::Php => None,
74        }
75    }
76
77    /// Whether this language is a Vue SFC (needs dual parsing).
78    pub fn is_vue(&self) -> bool {
79        matches!(self, Lang::Vue)
80    }
81
82    /// Get the HTML grammar for parsing Vue <template> sections.
83    pub fn html_grammar() -> Language {
84        tree_sitter_html::LANGUAGE.into()
85    }
86}
87
88/// Registry that maps file extensions to languages.
89pub struct LanguageRegistry;
90
91impl LanguageRegistry {
92    /// Detect language from file path extension.
93    pub fn detect(path: &Path) -> Option<Lang> {
94        let ext = path.extension()?.to_str()?;
95        match ext {
96            "rs" => Some(Lang::Rust),
97            "py" | "pyi" => Some(Lang::Python),
98            "js" | "mjs" | "cjs" => Some(Lang::JavaScript),
99            "ts" | "mts" => Some(Lang::TypeScript),
100            "tsx" | "jsx" => Some(Lang::Tsx),
101            "go" => Some(Lang::Go),
102            "java" => Some(Lang::Java),
103            "c" | "h" => Some(Lang::C),
104            "cc" | "cpp" | "cxx" | "hh" | "hpp" | "hxx" => Some(Lang::Cpp),
105            "cs" => Some(Lang::CSharp),
106            "html" | "htm" => Some(Lang::Html),
107            "php" => Some(Lang::Php),
108            "vue" | "svelte" => Some(Lang::Vue),
109            _ => None,
110        }
111    }
112}