1#[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
118fn 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}