luau_parser/impl/block/
statement.rs1use 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 _ => Self::__parse(token, lexer, errors),
15 }
16 }
17}
18
19impl Parse for TerminationStatement {
20 fn parse(keyword: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> 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 TerminationStatement::Break(token) | TerminationStatement::Continue(token) => {
66 token.print_final_trivia()
67 }
68 TerminationStatement::Return {
69 return_keyword,
70 expressions,
71 } => {
72 if let Some(expressions) = expressions {
73 expressions.print_final_trivia()
74 } else {
75 return_keyword.print_final_trivia()
76 }
77 }
78 }
79 }
80
81 fn print_without_final_trivia(&self) -> String {
82 match self {
83 TerminationStatement::Break(token) | TerminationStatement::Continue(token) => {
84 token.print_without_final_trivia()
85 }
86 TerminationStatement::Return {
87 return_keyword,
88 expressions,
89 } => {
90 return_keyword.print_without_final_trivia()
91 + &expressions.print_without_final_trivia()
92 }
93 }
94 }
95}