luau_parser/impl/expression/
function.rs1use luau_lexer::prelude::{Keyword, Lexer, Literal, ParseError, Symbol, Token, TokenType};
10
11use crate::{
12 force_parse_bracketed, parse_bracketed,
13 types::{
14 Block, BracketedList, Closure, Expression, FunctionArgument, FunctionArguments,
15 FunctionCall, FunctionCallInvoked, Parse, ParseWithArgs, Pointer, PrefixExp, Table,
16 TableAccessPrefix, TryParse, TryParseWithArgs, TypeValue,
17 },
18 utils::{get_token_type_display, get_token_type_display_extended},
19};
20
21impl Parse for FunctionCallInvoked {
22 fn parse(token: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
23 let prefix_exp = Pointer::new(PrefixExp::parse(token, lexer, errors)?);
24
25 maybe_next_token!(lexer, colon, TokenType::Symbol(Symbol::Colon));
26 let Some(colon) = colon else {
27 return Some(Self::Function(prefix_exp));
28 };
29
30 next_token_recoverable!(
31 lexer,
32 method,
33 TokenType::Identifier(_) | TokenType::PartialKeyword(_),
34 TokenType::Identifier("*error*".into(),),
35 errors,
36 "Expected ".to_string() + get_token_type_display(&TokenType::Identifier("".into(),))
37 );
38
39 Some(Self::TableMethod {
40 table: prefix_exp,
41 colon: Pointer::new(colon),
42 method: Pointer::new(method),
43 })
44 }
45}
46impl TryParse for FunctionCallInvoked {}
47
48impl Parse for FunctionCall {
49 fn parse(token: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
50 let invoked = FunctionCallInvoked::parse(token, lexer, errors)?;
51 let arguments = FunctionArguments::try_parse(lexer, errors);
52
53 if let Some(arguments) = arguments {
54 return Some(FunctionCall { invoked, arguments });
55 }
56 if let FunctionCallInvoked::Function(pointer) = invoked {
57 if let PrefixExp::FunctionCall(call) = (*pointer).clone() {
58 return Some(call);
59 }
60 }
61
62 None
63 }
64}
65impl TryParse for FunctionCall {
66 fn try_parse(lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
67 Some(Self {
68 invoked: FunctionCallInvoked::try_parse(lexer, errors)?,
69 arguments: FunctionArguments::try_parse(lexer, errors)?,
70 })
71 }
72}
73
74impl Parse<PrefixExp> for FunctionCall {
75 fn parse(token: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<PrefixExp> {
76 Self::parse(token, lexer, errors).map(PrefixExp::FunctionCall)
77 }
78}
79impl Parse<TableAccessPrefix> for FunctionCall {
80 fn parse(
81 token: Token,
82 lexer: &mut Lexer,
83 errors: &mut Vec<ParseError>,
84 ) -> Option<TableAccessPrefix> {
85 Pointer::<Self>::parse(token, lexer, errors).map(TableAccessPrefix::FunctionCall)
86 }
87}
88
89impl Parse for FunctionArguments {
90 fn parse(token: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
91 if matches!(token.token_type, TokenType::Literal(Literal::String(_))) {
92 return Some(Self::String(token));
93 }
94 if token.token_type == TokenType::Symbol(Symbol::OpeningParenthesis) {
95 return BracketedList::parse_with(
96 token,
97 lexer,
98 errors,
99 ("Expected <expr>", Symbol::ClosingParenthesis),
100 )
101 .map(Self::List);
102 }
103
104 Table::parse(token.clone(), lexer, errors)
105 }
106}
107impl TryParse for FunctionArguments {}
108
109impl Parse for FunctionArgument {
110 fn parse(token: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
111 if matches!(token.token_type, TokenType::Symbol(Symbol::Ellipses)) {
112 Some(Self::VariadicValues(token))
113 } else {
114 Expression::parse(token, lexer, errors).map(Self::Expression)
115 }
116 }
117}
118impl TryParse for FunctionArgument {}
119
120impl Parse for Closure {
121 fn parse(token: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
122 let attributes;
123 let function_keyword;
124
125 match token.token_type {
126 TokenType::Keyword(Keyword::Function) => {
127 attributes = Vec::new();
128 function_keyword = token;
129 }
130 TokenType::Symbol(Symbol::At) => {
131 attributes = safe_unwrap!(
132 lexer,
133 errors,
134 "Expected <attribute>",
135 Vec::parse(token, lexer, errors)
136 );
137 function_keyword = lexer.next_token();
138 }
139 _ => return None,
140 }
141
142 parse_function!(attributes, function_keyword, lexer, errors)
143 }
144}