luau_parser/impl/block/
statement.rs

1//! All `impl` blocks for [`Statement`] and [`TerminationStatement`].
2
3use luau_lexer::prelude::{Error, Keyword, Lexer, PartialKeyword, Token, TokenType};
4
5use crate::{
6    handle_error_token,
7    types::{Expression, List, Parse, Pointer, Print, Statement, TerminationStatement, TryParse},
8};
9
10impl Parse for Statement {
11    fn parse(token: Token, lexer: &mut Lexer, errors: &mut Vec<Error>) -> Option<Self> {
12        match token.token_type {
13            TokenType::Error(error) => handle_error_token!(errors, error),
14            _ => Self::__parse(token, lexer, errors),
15        }
16    }
17}
18
19impl Parse for TerminationStatement {
20    fn parse(keyword: Token, lexer: &mut Lexer, errors: &mut Vec<Error>) -> Option<Self> {
21        if !matches!(
22            keyword.token_type,
23            TokenType::Keyword(Keyword::Break)
24                | TokenType::Keyword(Keyword::Return)
25                | TokenType::PartialKeyword(PartialKeyword::Continue)
26        ) {
27            return None;
28        }
29        if matches!(keyword.token_type, TokenType::Keyword(Keyword::Break)) {
30            return Some(Self::Break(keyword));
31        }
32
33        if matches!(
34            keyword.token_type,
35            TokenType::PartialKeyword(PartialKeyword::Continue)
36        ) {
37            return Some(Self::Continue(keyword));
38        }
39
40        if matches!(keyword.token_type, TokenType::Keyword(Keyword::Return)) {
41            let state = lexer.save_state();
42            let mut expressions = List::<Pointer<Expression>>::try_parse(lexer, errors);
43            if expressions
44                .as_ref()
45                .map(|expressions| expressions.is_empty())
46                .unwrap_or(false)
47            {
48                expressions = None;
49                lexer.set_state(state);
50            }
51
52            return Some(Self::Return {
53                return_keyword: keyword,
54                expressions,
55            });
56        }
57
58        None
59    }
60}
61
62impl Print for TerminationStatement {
63    fn print_final_trivia(&self) -> String {
64        match self {
65            Self::Break(token) | Self::Continue(token) => token.print_final_trivia(),
66            Self::Return {
67                return_keyword,
68                expressions,
69            } => expressions.as_ref().map_or_else(
70                || return_keyword.print_final_trivia(),
71                |expressions| expressions.print_final_trivia(),
72            ),
73        }
74    }
75
76    fn print_without_final_trivia(&self) -> String {
77        match self {
78            Self::Break(token) | Self::Continue(token) => token.print_without_final_trivia(),
79            Self::Return {
80                return_keyword,
81                expressions,
82            } => {
83                return_keyword.print_without_final_trivia()
84                    + &expressions.print_without_final_trivia()
85            }
86        }
87    }
88}