Skip to main content

semtree_parse/
parser.rs

1use semtree_core::Language;
2use tree_sitter::{Node, Parser, Tree};
3
4use crate::ParseError;
5
6pub struct ParsedTree {
7    pub language: Language,
8    pub source: Vec<u8>,
9    pub tree: Tree,
10}
11
12impl ParsedTree {
13    pub fn root(&self) -> Node<'_> {
14        self.tree.root_node()
15    }
16
17    pub fn source_str(&self) -> &str {
18        std::str::from_utf8(&self.source).unwrap_or("")
19    }
20
21    pub fn node_text(&self, node: &Node<'_>) -> &str {
22        node.utf8_text(&self.source).unwrap_or("")
23    }
24}
25
26pub struct SemtreeParser;
27
28impl SemtreeParser {
29    pub fn parse(source: &str, language: Language) -> Result<ParsedTree, ParseError> {
30        let ts_language = ts_language(language)?;
31        let mut parser = Parser::new();
32        parser.set_language(&ts_language).expect("valid language");
33
34        let tree = parser.parse(source, None).ok_or(ParseError::ParseFailed)?;
35
36        Ok(ParsedTree {
37            language,
38            source: source.as_bytes().to_vec(),
39            tree,
40        })
41    }
42
43    pub fn parse_file(path: &std::path::Path) -> Result<ParsedTree, ParseError> {
44        let language = Language::from_path(path);
45        if language == Language::Unknown {
46            return Err(ParseError::UnsupportedLanguage(language));
47        }
48        let source = std::fs::read_to_string(path)?;
49        Self::parse(&source, language)
50    }
51}
52
53fn ts_language(lang: Language) -> Result<tree_sitter::Language, ParseError> {
54    match lang {
55        Language::Rust => Ok(tree_sitter_rust::LANGUAGE.into()),
56        Language::Python => Ok(tree_sitter_python::LANGUAGE.into()),
57        Language::JavaScript => Ok(tree_sitter_javascript::LANGUAGE.into()),
58        Language::TypeScript => Ok(tree_sitter_typescript::LANGUAGE_TYPESCRIPT.into()),
59        Language::Go => Ok(tree_sitter_go::LANGUAGE.into()),
60        Language::Java => Ok(tree_sitter_java::LANGUAGE.into()),
61        Language::C => Ok(tree_sitter_c::LANGUAGE.into()),
62        Language::Cpp => Ok(tree_sitter_cpp::LANGUAGE.into()),
63        Language::CSharp => Ok(tree_sitter_c_sharp::LANGUAGE.into()),
64        Language::Ruby => Ok(tree_sitter_ruby::LANGUAGE.into()),
65        Language::Php => Ok(tree_sitter_php::LANGUAGE_PHP.into()),
66        Language::Tsx => Ok(tree_sitter_typescript::LANGUAGE_TSX.into()),
67        Language::Kotlin => Ok(tree_sitter_kotlin_ng::LANGUAGE.into()),
68        Language::Scala => Ok(tree_sitter_scala::LANGUAGE.into()),
69        Language::Swift => Ok(tree_sitter_swift::LANGUAGE.into()),
70        Language::OCaml => Ok(tree_sitter_ocaml::LANGUAGE_OCAML.into()),
71        Language::Solidity => Ok(tree_sitter_solidity::LANGUAGE.into()),
72        Language::Lua => Ok(tree_sitter_lua::LANGUAGE.into()),
73        Language::Zig => Ok(tree_sitter_zig::LANGUAGE.into()),
74        Language::Elisp => Ok(tree_sitter_elisp::LANGUAGE.into()),
75        Language::Unknown => Err(ParseError::UnsupportedLanguage(lang)),
76    }
77}