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