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