1use luau_lexer::lexer::Lexer;
4#[cfg(feature = "cache")]
5use std::collections::HashMap;
6
7use crate::types::Cst;
8
9pub struct Parser<'a> {
11 #[cfg(feature = "cache")]
15 cache: HashMap<String, Cst>,
16
17 lexer: Lexer<'a>,
19}
20
21impl<'a> Parser<'a> {
22 #[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 pub fn with_input(mut self, input: &'a str) -> Self {
34 self.lexer = self.lexer.with_input(input);
35 self
36 }
37
38 pub fn set_input(&mut self, input: &'a str) {
40 self.lexer.set_input(input);
41 }
42
43 pub fn parse(&mut self, uri: &str) -> Cst {
45 let cst = Cst::parse(self.lexer.next_token(), &mut self.lexer, uri);
46
47 #[cfg(feature = "cache")]
48 {
49 self.cache.insert(uri.to_string(), cst);
50
51 self.cache.get(uri).unwrap().to_owned()
52 }
53
54 #[cfg(not(feature = "cache"))]
55 cst
56 }
57
58 #[cfg(feature = "cache")]
62 #[inline]
63 pub fn get_ast(&self, uri: &str) -> &Cst {
64 self.cache.get(uri).unwrap()
65 }
66
67 #[inline]
69 pub fn get_or_create(&mut self, uri: &str, code: &'a str) -> Cst {
70 #[cfg(feature = "cache")]
71 if let Some(cst) = self.maybe_get_ast(uri) {
72 return cst.to_owned();
73 }
74
75 self.lexer.set_input(code);
76 self.parse(uri)
77 }
78
79 #[cfg(feature = "cache")]
83 #[inline]
84 pub fn maybe_get_ast(&self, uri: &str) -> Option<&Cst> {
85 self.cache.get(uri)
86 }
87
88 #[cfg(feature = "cache")]
90 #[inline]
91 pub fn get_all_asts(&self) -> &HashMap<String, Cst> {
92 &self.cache
93 }
94
95 #[cfg(feature = "cache")]
97 #[inline]
98 pub fn clear_cache(&mut self) {
99 self.cache.clear();
100 }
101}