luau_parser/impl/
bracketed.rs

1//! All `impl` blocks for [`Bracketed`].
2
3use luau_lexer::prelude::{Lexer, ParseError, State, Symbol, Token, TokenType};
4use std::ops::{Deref, DerefMut};
5
6use crate::{
7    types::{Bracketed, List, Parse, ParseWithArgs, Print, TryParse, TryParseWithArgs},
8    utils::get_token_type_display_extended,
9};
10
11/// A private trait that indicates whether or not the current item is empty.
12/// It's only implemented for a limited set of types.
13trait IsEmpty {
14    /// Whether or not this item is empty.
15    fn is_empty(&self) -> bool {
16        false
17    }
18}
19impl<T> IsEmpty for List<T> {
20    fn is_empty(&self) -> bool {
21        (**self).is_empty()
22    }
23}
24
25/// Implements [`IsEmpty`] for the passed type and for
26/// [`Pointer`](crate::types::Pointer) of that type
27macro_rules! __sealed_impl {
28    ($($ty:ident $(<$generic:ident>)?),* $(,)?) => {
29        $( impl $(<$generic>)? IsEmpty for $crate::types::$ty $(<$generic>)? {})*
30        $( impl $(<$generic>)? IsEmpty for $crate::types::Pointer<$crate::types::$ty $(<$generic>)?> {})*
31    };
32}
33__sealed_impl!(Bracketed<T>, TypeValue, Expression);
34
35#[allow(private_bounds)]
36impl<T: IsEmpty> Bracketed<T> {
37    /// The actual parsing logic.
38    fn parse(
39        previous_state: State,
40        maybe_parsed_item: Option<T>,
41        opening_bracket: Token,
42        lexer: &mut Lexer,
43        errors: &mut Vec<ParseError>,
44        (error_message, stop_at): (&str, Symbol),
45    ) -> Option<Self> {
46        let Some(item) = maybe_parsed_item else {
47            let state = lexer.save_state();
48            errors.push(ParseError::new(
49                state.lexer_position(),
50                error_message.to_string(),
51                Some(state.lexer_position()),
52            ));
53
54            return None;
55        };
56
57        if item.is_empty() {
58            lexer.set_state(previous_state);
59        }
60
61        next_token_recoverable_with_condition!(
62            lexer,
63            closing_bracket,
64            closing_bracket.token_type == TokenType::Symbol(stop_at),
65            TokenType::Symbol(stop_at),
66            errors,
67            format!(
68                "Expected {}",
69                get_token_type_display_extended(&TokenType::Symbol(stop_at))
70            )
71        );
72
73        Some(Self {
74            opening_bracket,
75            item,
76            closing_bracket,
77        })
78    }
79}
80
81impl<T: Parse + TryParse + IsEmpty> ParseWithArgs<(&str, Symbol)> for Bracketed<T> {
82    #[inline]
83    fn parse_with(
84        opening_bracket: Token,
85        lexer: &mut Lexer,
86        errors: &mut Vec<ParseError>,
87        (error_message, stop_at): (&str, Symbol),
88    ) -> Option<Self> {
89        Self::parse(
90            lexer.save_state(),
91            T::parse(lexer.next_token(), lexer, errors),
92            opening_bracket,
93            lexer,
94            errors,
95            (error_message, stop_at),
96        )
97    }
98}
99impl<A, T> ParseWithArgs<(&str, Symbol, A)> for Bracketed<T>
100where
101    T: ParseWithArgs<A> + TryParseWithArgs<A> + IsEmpty,
102{
103    #[inline]
104    fn parse_with(
105        opening_bracket: Token,
106        lexer: &mut Lexer,
107        errors: &mut Vec<ParseError>,
108        (error_message, stop_at, args): (&str, Symbol, A),
109    ) -> Option<Self> {
110        Self::parse(
111            lexer.save_state(),
112            T::parse_with(lexer.next_token(), lexer, errors, args),
113            opening_bracket,
114            lexer,
115            errors,
116            (error_message, stop_at),
117        )
118    }
119}
120
121impl<T> Deref for Bracketed<T> {
122    type Target = T;
123
124    fn deref(&self) -> &Self::Target {
125        &self.item
126    }
127}
128
129impl<T> DerefMut for Bracketed<T> {
130    fn deref_mut(&mut self) -> &mut Self::Target {
131        &mut self.item
132    }
133}
134
135impl<T: Print> Print for Bracketed<T> {
136    fn print_final_trivia(&self) -> String {
137        self.closing_bracket.print_final_trivia()
138    }
139
140    fn print_without_final_trivia(&self) -> String {
141        self.opening_bracket.print_without_final_trivia()
142            + &self.item.print_without_final_trivia()
143            + &self.closing_bracket.print_without_final_trivia()
144    }
145}