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 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}