luau_parser/impl/block/
if_statement.rs

1//! All `impl` blocks for:
2//!
3//! * [`IfStatement`]
4//! * [`ElseStatement`]
5//! * [`ElseIfStatement`]
6
7use luau_lexer::prelude::{Keyword, Lexer, ParseError, 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<ParseError>) -> 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(
76        elseif_keyword: Token,
77        lexer: &mut Lexer,
78        errors: &mut Vec<ParseError>,
79    ) -> Option<Self> {
80        if elseif_keyword != TokenType::Keyword(Keyword::Elseif) {
81            return None;
82        }
83
84        let condition = safe_unwrap!(
85            lexer,
86            errors,
87            "Expected <expr>",
88            Pointer::<Expression>::try_parse(lexer, errors)
89        );
90
91        next_token_recoverable!(
92            lexer,
93            then_keyword,
94            TokenType::Keyword(Keyword::Then),
95            TokenType::Keyword(Keyword::Then),
96            errors,
97            "Expected `then`"
98        );
99
100        let body = Block::try_parse_with(lexer, errors, END_TOKENS).unwrap_or_default();
101
102        Some(Self {
103            elseif_keyword,
104            condition,
105            then_keyword,
106            body,
107        })
108    }
109}
110impl TryParse for ElseIfStatement {}
111
112impl Parse for ElseStatement {
113    fn parse(else_keyword: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
114        if else_keyword != TokenType::Keyword(Keyword::Else) {
115            return None;
116        }
117
118        Some(Self {
119            else_keyword,
120            body: Block::try_parse_with(lexer, errors, TokenType::Keyword(Keyword::End))
121                .unwrap_or_default(),
122        })
123    }
124}
125impl TryParse for ElseStatement {}