luau_parser/impl/block/
statement.rs

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