luau_parser/
parser.rs

1//! The main item of this crate, the actual [`parser`](Parser).
2
3use luau_lexer::lexer::Lexer;
4#[cfg(feature = "cache")]
5use std::collections::HashMap;
6
7use crate::types::Cst;
8
9/// A Luau parser.
10pub struct Parser<'a> {
11    /// Cache, only works with the `cache` feature, this is useful when you need
12    /// to use the [`CST`](Cst) more than once in 2 different places without
13    /// re-parsing.
14    #[cfg(feature = "cache")]
15    cache: HashMap<String, Cst>,
16
17    /// The `tree-sitter` parser.
18    lexer: Lexer<'a>,
19}
20
21impl<'a> Parser<'a> {
22    /// Create a new [`parser`](Parser).
23    #[inline]
24    pub fn new(input: &'a str) -> Self {
25        Self {
26            #[cfg(feature = "cache")]
27            cache: HashMap::new(),
28            lexer: Lexer::new(input),
29        }
30    }
31
32    /// Parse Luau code into an [`CST`](Cst).
33    pub fn parse(&mut self, uri: &str) -> Cst {
34        let cst = Cst::parse(self.lexer.next_token(), &mut self.lexer, uri);
35
36        #[cfg(feature = "cache")]
37        {
38            self.cache.insert(uri.to_string(), cst);
39
40            self.cache.get(uri).unwrap().to_owned()
41        }
42
43        #[cfg(not(feature = "cache"))]
44        cst
45    }
46
47    /// Get a specific [`CST`](Cst) from the cache, this function assumes the
48    /// cst does exist. If it may or may not exist, use
49    /// [`maybe_get_ast`](Self::maybe_get_ast).
50    #[cfg(feature = "cache")]
51    #[inline]
52    pub fn get_ast(&self, uri: &str) -> &Cst {
53        self.cache.get(uri).unwrap()
54    }
55
56    /// Get a specific [`CST`](Cst) from the cache, or parse `code` and return the
57    #[inline]
58    pub fn get_or_create(&mut self, uri: &str, code: &'a str) -> Cst {
59        #[cfg(feature = "cache")]
60        if let Some(cst) = self.maybe_get_ast(uri) {
61            return cst.to_owned();
62        }
63
64        self.lexer.set_input(code);
65        self.parse(uri)
66    }
67
68    /// Get a specific [`CST`](Cst) from the cache, this function, unlike
69    /// [`get_ast`](Self::get_ast), doesn't error when the [`CST`](Cst) isn't
70    /// there.
71    #[cfg(feature = "cache")]
72    #[inline]
73    pub fn maybe_get_ast(&self, uri: &str) -> Option<&Cst> {
74        self.cache.get(uri)
75    }
76
77    /// Get all cached [`CST`](Cst)s.
78    #[cfg(feature = "cache")]
79    #[inline]
80    pub fn get_all_asts(&self) -> &HashMap<String, Cst> {
81        &self.cache
82    }
83
84    /// Clear the cache.
85    #[cfg(feature = "cache")]
86    #[inline]
87    pub fn clear_cache(&mut self) {
88        self.cache.clear();
89    }
90}