1use lsp_types::Range;
9use luau_lexer::prelude::{Lexer, ParseError, Symbol, Token, TokenType};
10use std::cell::Cell;
11
12use crate::{
13 safe_unwrap,
14 types::{
15 Bracketed, BracketedList, Expression, FunctionArguments, GetRange, GetRangeError, Parse,
16 ParseWithArgs, Pointer, Print, Table, TableAccessKey, TableField, TableFieldValue,
17 TableKey, TryParse, TryParseWithArgs, TypeValue,
18 },
19};
20
21#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
23struct ParseArgs {
24 is_type: bool,
26
27 inferred_keys: Cell<u32>,
29}
30impl ParseArgs {
31 #[inline]
33 fn new(is_type: bool, inferred_keys: u32) -> Self {
34 Self {
35 is_type,
36 inferred_keys: Cell::new(inferred_keys),
37 }
38 }
39}
40
41impl TableKey {
42 #[inline]
44 fn undefined_number(parse_args: &ParseArgs) -> Self {
45 Self::UndefinedNumber(
46 parse_args
47 .inferred_keys
48 .replace(parse_args.inferred_keys.get() + 1),
49 )
50 }
51
52 #[inline]
54 fn undefined_string() -> Self {
55 Self::UndefinedString("number".into())
56 }
57}
58
59impl ParseWithArgs<bool> for TableKey {
60 fn parse_with(
61 token: Token,
62 lexer: &mut Lexer,
63 errors: &mut Vec<ParseError>,
64 is_type: bool,
65 ) -> Option<Self> {
66 match token.token_type {
67 TokenType::Identifier(_) | TokenType::PartialKeyword(_) => Some(Self::Simple(token)),
68 TokenType::Symbol(Symbol::OpeningBrackets) => {
69 if is_type {
70 Bracketed::<_>::parse_with(
71 token,
72 lexer,
73 errors,
74 ("Expected <type>", Symbol::ClosingBrackets),
75 )
76 .map(Self::Type)
77 } else {
78 Bracketed::<_>::parse_with(
79 token,
80 lexer,
81 errors,
82 ("Expected <expr>", Symbol::ClosingBrackets),
83 )
84 .map(Self::Expression)
85 }
86 }
87 _ => None,
88 }
89 }
90}
91
92impl ParseWithArgs<&ParseArgs> for TableField {
93 fn parse_with(
94 token: Token,
95 lexer: &mut Lexer,
96 errors: &mut Vec<ParseError>,
97 parse_args: &ParseArgs,
98 ) -> Option<Self> {
99 if token == TokenType::Symbol(Symbol::ClosingCurlyBrackets) {
100 return None;
103 }
104
105 let state = lexer.save_state();
106
107 let (key, equal_or_colon) = if let Some(key) =
108 TableKey::parse_with(token.clone(), lexer, errors, parse_args.is_type)
109 {
110 let equal_or_colon = if parse_args.is_type {
111 maybe_next_token!(lexer, temp, TokenType::Symbol(Symbol::Colon));
112
113 temp
114 } else {
115 maybe_next_token!(lexer, temp, TokenType::Symbol(Symbol::Equal));
116
117 temp
118 };
119
120 (Some(Pointer::new(key)), equal_or_colon)
121 } else {
122 (None, None)
123 };
124
125 if key.is_none() || equal_or_colon.is_none() {
126 lexer.set_state(state);
127
128 return Some(Self {
129 key: if parse_args.is_type {
130 Pointer::new(TableKey::undefined_string())
131 } else {
132 Pointer::new(TableKey::undefined_number(parse_args))
133 },
134 equal_or_colon: None,
135 value: safe_unwrap!(
136 lexer,
137 errors,
138 "Expected <type>",
139 TableFieldValue::parse_with(token.clone(), lexer, errors, parse_args.is_type)
140 .map(Pointer::new)
141 ),
142 });
143 }
144
145 let key = key.unwrap();
146
147 let value = Pointer::new(TableFieldValue::try_parse_with(
148 lexer,
149 errors,
150 parse_args.is_type,
151 )?);
152
153 Some(Self {
154 key,
155 equal_or_colon,
156 value,
157 })
158 }
159}
160
161impl ParseWithArgs<bool> for TableFieldValue {
162 #[inline]
163 fn parse_with(
164 token: Token,
165 lexer: &mut Lexer,
166 errors: &mut Vec<ParseError>,
167 is_type: bool,
168 ) -> Option<Self> {
169 if is_type {
170 TypeValue::parse(token, lexer, errors).map(Self::Type)
171 } else if token == TokenType::Symbol(Symbol::Ellipses) {
172 Some(Self::VariadicValues(token))
173 } else {
174 Expression::parse(token, lexer, errors).map(Self::Expression)
175 }
176 }
177}
178
179impl ParseWithArgs<bool> for Table {
180 fn parse_with(
181 token: Token,
182 lexer: &mut Lexer,
183 errors: &mut Vec<ParseError>,
184 is_type: bool,
185 ) -> Option<Self> {
186 if !matches!(
187 token.token_type,
188 TokenType::Symbol(Symbol::OpeningCurlyBrackets)
189 ) {
190 return None;
191 }
192
193 BracketedList::<TableField>::parse_with(
194 token,
195 lexer,
196 errors,
197 (
198 "Expected <table-field>",
199 Symbol::ClosingCurlyBrackets,
200 &ParseArgs::new(is_type, 1),
201 ),
202 )
203 .map(Self)
204 }
205}
206
207impl Parse<FunctionArguments> for Table {
208 #[inline]
209 fn parse(
210 token: Token,
211 lexer: &mut Lexer,
212 errors: &mut Vec<ParseError>,
213 ) -> Option<FunctionArguments> {
214 Self::parse_with(token, lexer, errors, false).map(FunctionArguments::Table)
215 }
216}
217impl TryParse<FunctionArguments> for Table {}
218
219impl Parse<TableAccessKey> for TableKey {
220 #[inline]
221 fn parse(
222 token: Token,
223 lexer: &mut Lexer,
224 errors: &mut Vec<ParseError>,
225 ) -> Option<TableAccessKey> {
226 Self::parse_with(token, lexer, errors, false)
227 .map(Pointer::new)
228 .map(TableAccessKey::Expression)
229 }
230}
231impl TryParse<TableAccessKey> for TableKey {}
232
233impl GetRange for TableKey {
234 #[inline]
235 fn get_range(&self) -> Result<Range, GetRangeError> {
236 match self {
237 TableKey::ERROR => Err(GetRangeError::ErrorVariant),
238 TableKey::UndefinedNumber(_) | TableKey::UndefinedString(_) => {
239 Err(GetRangeError::UndefinedKey)
240 }
241 TableKey::Simple(token) => token.get_range(),
242 TableKey::Expression(bracketed) => bracketed.get_range(),
243 TableKey::Type(bracketed) => bracketed.get_range(),
244 }
245 }
246}
247
248impl GetRange for TableField {
249 #[inline]
250 fn get_range(&self) -> Result<Range, GetRangeError> {
251 let value_range = self.value.get_range();
252
253 if let Ok(key_range) = self.key.get_range() {
254 Ok(Range::new(key_range.start, value_range?.end))
255 } else {
256 value_range
257 }
258 }
259}
260
261impl Print for TableKey {
262 #[inline]
263 fn print(&self) -> String {
264 match self {
265 TableKey::Simple(token) => token.print(),
266 TableKey::Expression(bracketed) => bracketed.print(),
267 TableKey::Type(bracketed) => bracketed.print(),
268 _ => "".to_string(),
269 }
270 }
271
272 #[inline]
273 fn print_final_trivia(&self) -> String {
274 match self {
275 TableKey::Simple(token) => token.print_final_trivia(),
276 TableKey::Expression(bracketed) => bracketed.print_final_trivia(),
277 TableKey::Type(bracketed) => bracketed.print_final_trivia(),
278 _ => "".to_string(),
279 }
280 }
281
282 #[inline]
283 fn print_without_final_trivia(&self) -> String {
284 match self {
285 TableKey::Simple(token) => token.print_without_final_trivia(),
286 TableKey::Expression(bracketed) => bracketed.print_without_final_trivia(),
287 TableKey::Type(bracketed) => bracketed.print_without_final_trivia(),
288 _ => "".to_string(),
289 }
290 }
291}
292
293impl Print for TableField {
294 #[inline]
295 fn print_without_final_trivia(&self) -> String {
296 self.key.print_without_final_trivia()
297 + &self.equal_or_colon.print_without_final_trivia()
298 + &self.value.print_without_final_trivia()
299 }
300
301 #[inline]
302 fn print_final_trivia(&self) -> String {
303 self.value.print_final_trivia()
304 }
305}