luau_parser/impl/value/
table.rs

1//! All `impl` blocks for table-related types:
2//!
3//! * [`TableKey`]
4//! * [`TableField`]
5//! * [`TableFieldValue`]
6//! * [`Table`]
7
8use 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/// A simple struct holding arguments needed for parsing tables.
22#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
23struct ParseArgs {
24    /// Whether or not it's currently parsing a type.
25    is_type: bool,
26
27    /// The number of keys it inferred. Only for expressions.
28    inferred_keys: Cell<u32>,
29}
30impl ParseArgs {
31    /// Create new [`ParseArgs`].
32    #[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    /// Crate a new [`TableKey::UndefinedNumber`] from the passed [`ParseArgs`].
43    #[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    /// Crate a new [`TableKey::UndefinedString`] from the passed [`ParseArgs`].
53    #[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            // Sometimes causes issues when the last item in the table is trailing
101            // this just ensures it never happens.
102            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}