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