luau_parser/impl/block/
if_statement.rs

1//! All `impl` blocks for:
2//!
3//! * [`IfStatement`]
4//! * [`ElseStatement`]
5//! * [`ElseIfStatement`]
6
7use luau_lexer::prelude::{Error, Keyword, Lexer, Token, TokenType};
8
9use crate::{
10    safe_unwrap,
11    types::{
12        Block, ElseIfStatement, ElseStatement, Expression, IfStatement, Parse, Pointer, TryParse,
13        TryParseWithArgs,
14    },
15};
16
17/// All type of tokens that can end if/else/elseif blocks.
18const END_TOKENS: [TokenType; 3] = [
19    TokenType::Keyword(Keyword::End),
20    TokenType::Keyword(Keyword::Elseif),
21    TokenType::Keyword(Keyword::Else),
22];
23
24impl Parse for IfStatement {
25    fn parse(if_keyword: Token, lexer: &mut Lexer, errors: &mut Vec<Error>) -> Option<Self> {
26        if if_keyword != TokenType::Keyword(Keyword::If) {
27            return None;
28        }
29
30        let condition = safe_unwrap!(
31            lexer,
32            errors,
33            "Expected <expr>",
34            Pointer::<Expression>::try_parse(lexer, errors)
35        );
36
37        next_token_recoverable!(
38            lexer,
39            then_keyword,
40            TokenType::Keyword(Keyword::Then),
41            TokenType::Keyword(Keyword::Then),
42            errors,
43            "Expected `then`"
44        );
45
46        let body = Block::try_parse_with(lexer, errors, END_TOKENS).unwrap_or_default();
47
48        let else_if_statements =
49            Vec::<ElseIfStatement>::try_parse(lexer, errors).unwrap_or_default();
50
51        let else_statement = ElseStatement::try_parse(lexer, errors);
52        next_token_recoverable!(
53            lexer,
54            end_keyword,
55            TokenType::Keyword(Keyword::End),
56            TokenType::Keyword(Keyword::End),
57            errors,
58            "Expected `end`"
59        );
60
61        Some(Self {
62            if_keyword,
63            condition,
64            then_keyword,
65            body,
66            else_if_statements,
67            else_statement,
68            end_keyword,
69        })
70    }
71}
72impl TryParse for IfStatement {}
73
74impl Parse for ElseIfStatement {
75    fn parse(elseif_keyword: Token, lexer: &mut Lexer, errors: &mut Vec<Error>) -> Option<Self> {
76        if elseif_keyword != TokenType::Keyword(Keyword::Elseif) {
77            return None;
78        }
79
80        let condition = safe_unwrap!(
81            lexer,
82            errors,
83            "Expected <expr>",
84            Pointer::<Expression>::try_parse(lexer, errors)
85        );
86
87        next_token_recoverable!(
88            lexer,
89            then_keyword,
90            TokenType::Keyword(Keyword::Then),
91            TokenType::Keyword(Keyword::Then),
92            errors,
93            "Expected `then`"
94        );
95
96        let body = Block::try_parse_with(lexer, errors, END_TOKENS).unwrap_or_default();
97
98        Some(Self {
99            elseif_keyword,
100            condition,
101            then_keyword,
102            body,
103        })
104    }
105}
106impl TryParse for ElseIfStatement {}
107
108impl Parse for ElseStatement {
109    fn parse(else_keyword: Token, lexer: &mut Lexer, errors: &mut Vec<Error>) -> Option<Self> {
110        if else_keyword != TokenType::Keyword(Keyword::Else) {
111            return None;
112        }
113
114        Some(Self {
115            else_keyword,
116            body: Block::try_parse_with(lexer, errors, TokenType::Keyword(Keyword::End))
117                .unwrap_or_default(),
118        })
119    }
120}
121impl TryParse for ElseStatement {}