luau_parser/impl/
mod.rs

1//! All `impl` blocks for CST-related types.
2
3#[macro_use]
4mod macros;
5
6mod block;
7mod bracketed;
8mod cst;
9mod expression;
10mod list;
11mod literals;
12mod name;
13mod range;
14mod value;
15
16use luau_lexer::prelude::{Comment, Lexer, ParseError, Token, Trivia};
17
18use crate::types::{
19    GetRange, GetRangeError, Parse, ParseWithArgs, Pointer, Print, Range, TryParse,
20    TryParseWithArgs,
21};
22
23impl<T: Parse> Parse for Pointer<T> {
24    #[inline]
25    fn parse(token: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
26        T::parse(token, lexer, errors).map(Self::new)
27    }
28}
29impl<T: TryParse + Parse> TryParse for Pointer<T> {
30    #[inline]
31    fn try_parse(lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
32        T::try_parse(lexer, errors).map(Self::new)
33    }
34}
35
36impl<T: Parse> Parse for Vec<T> {
37    #[inline]
38    fn parse(mut token: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
39        let mut values = Vec::new();
40        let mut state = lexer.save_state();
41
42        while let Some(value) = T::parse(token, lexer, errors) {
43            values.push(value);
44            state = lexer.save_state();
45            token = lexer.next_token();
46        }
47
48        lexer.set_state(state);
49
50        (!values.is_empty()).then_some(values)
51    }
52}
53impl<T: TryParse + Parse> TryParse for Vec<T> {}
54
55impl<T: ParseWithArgs<A>, A: Clone> ParseWithArgs<A> for Vec<T> {
56    #[inline]
57    fn parse_with(
58        mut token: Token,
59        lexer: &mut Lexer,
60        errors: &mut Vec<ParseError>,
61        args: A,
62    ) -> Option<Self> {
63        let mut values = Vec::new();
64        let mut state = lexer.save_state();
65
66        while let Some(value) = T::parse_with(token, lexer, errors, args.clone()) {
67            values.push(value);
68            state = lexer.save_state();
69            token = lexer.next_token();
70        }
71
72        lexer.set_state(state);
73
74        (!values.is_empty()).then_some(values)
75    }
76}
77impl<T: ParseWithArgs<A>, A: Clone> TryParseWithArgs<A> for T {}
78
79impl GetRange for Token {
80    #[inline]
81    fn get_range(&self) -> Result<Range, GetRangeError> {
82        Ok(Range::new(self.start, self.end))
83    }
84}
85
86impl Print for Comment {
87    #[inline]
88    fn print(&self) -> String {
89        match self {
90            Comment::SingleLine(smol_str) | Comment::MultiLine(smol_str) => smol_str.to_string(),
91        }
92    }
93
94    fn print_final_trivia(&self) -> String {
95        unreachable!()
96    }
97    fn print_without_final_trivia(&self) -> String {
98        unreachable!()
99    }
100}
101impl Print for Trivia {
102    #[inline]
103    fn print(&self) -> String {
104        match self {
105            Trivia::Spaces(smol_str) => smol_str.to_string(),
106            Trivia::Comment(comment) => comment.print(),
107        }
108    }
109
110    fn print_final_trivia(&self) -> String {
111        unreachable!()
112    }
113    fn print_without_final_trivia(&self) -> String {
114        unreachable!()
115    }
116}
117
118/// [`Print`] implementation for [`Vec<Trivia>`] as the default one won't work.
119/// It takes `&[Trivia]` so we don't need to `.clone()`.
120fn print_trivia(trivia: &[Trivia]) -> String {
121    trivia
122        .iter()
123        .fold("".to_string(), |str, item| str + &item.print())
124}
125
126impl Print for Token {
127    #[inline]
128    fn print_final_trivia(&self) -> String {
129        print_trivia(&self.trailing_trivia)
130    }
131
132    #[inline]
133    fn print_without_final_trivia(&self) -> String {
134        self.token_type
135            .try_as_string()
136            .map(|token_type| print_trivia(&self.leading_trivia) + &token_type)
137            .unwrap_or_default()
138    }
139
140    #[inline]
141    fn print(&self) -> String {
142        self.token_type
143            .try_as_string()
144            .map(|token_type| {
145                print_trivia(&self.leading_trivia)
146                    + &token_type
147                    + &print_trivia(&self.trailing_trivia)
148            })
149            .unwrap_or_default()
150    }
151}
152
153impl<T: GetRange> GetRange for Pointer<T> {
154    #[inline]
155    fn get_range(&self) -> Result<Range, GetRangeError> {
156        (**self).get_range()
157    }
158}
159impl<T: Print> Print for Pointer<T> {
160    #[inline]
161    fn print(&self) -> String {
162        (**self).print()
163    }
164
165    #[inline]
166    fn print_final_trivia(&self) -> String {
167        (**self).print_final_trivia()
168    }
169
170    #[inline]
171    fn print_without_final_trivia(&self) -> String {
172        (**self).print_without_final_trivia()
173    }
174}
175
176impl<T: Print> Print for Option<T> {
177    #[inline]
178    fn print(&self) -> String {
179        match self {
180            Some(item) => item.print(),
181            None => "".to_string(),
182        }
183    }
184
185    fn print_final_trivia(&self) -> String {
186        match self {
187            Some(item) => item.print_final_trivia(),
188            None => "".to_string(),
189        }
190    }
191
192    fn print_without_final_trivia(&self) -> String {
193        match self {
194            Some(item) => item.print_without_final_trivia(),
195            None => "".to_string(),
196        }
197    }
198}
199
200impl<T: GetRange> GetRange for Vec<T> {
201    #[inline]
202    fn get_range(&self) -> Result<Range, GetRangeError> {
203        if self.is_empty() {
204            Err(GetRangeError::EmptyList)
205        } else if self.len() == 1 {
206            self[0].get_range()
207        } else {
208            Ok(Range::new(
209                self[0].get_range()?.start,
210                self.last().unwrap().get_range()?.end,
211            ))
212        }
213    }
214}
215impl<T: Print> Print for Vec<T> {
216    #[inline]
217    fn print_final_trivia(&self) -> String {
218        self.last()
219            .map(|item| item.print_final_trivia())
220            .unwrap_or_default()
221    }
222
223    #[inline]
224    fn print_without_final_trivia(&self) -> String {
225        self.iter().fold("".to_string(), |str, item| {
226            str + &item.print_without_final_trivia()
227        })
228    }
229}
230
231impl<T: Print, U: Print> Print for (T, U) {
232    #[inline]
233    fn print(&self) -> String {
234        let end = self.1.print();
235
236        if end.is_empty() {
237            self.0.print()
238        } else {
239            self.0.print_without_final_trivia() + &end
240        }
241    }
242
243    #[inline]
244    fn print_final_trivia(&self) -> String {
245        let maybe_final_trivia = self.1.print_final_trivia();
246        if maybe_final_trivia.is_empty() {
247            self.0.print_final_trivia()
248        } else {
249            maybe_final_trivia
250        }
251    }
252
253    #[inline]
254    fn print_without_final_trivia(&self) -> String {
255        self.0.print_without_final_trivia() + &self.1.print_without_final_trivia()
256    }
257}