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 FunctionCall {
49 pub fn try_parse_with_invoked(
56 lexer: &mut Lexer,
57 errors: &mut Vec<ParseError>,
58 mut invoked: FunctionCallInvoked,
59 ) -> Option<Self> {
60 while let Some(arguments) = FunctionArguments::try_parse(lexer, errors) {
61 invoked = FunctionCallInvoked::Function(Pointer::new(PrefixExp::FunctionCall(Self {
62 invoked,
63 arguments,
64 })));
65 }
66
67 if let FunctionCallInvoked::Function(pointer) = invoked {
68 if let PrefixExp::FunctionCall(function_call) = (*pointer).clone() {
69 return Some(function_call);
70 }
71 }
72
73 None
74 }
75}
76
77impl Parse for FunctionCall {
78 fn parse(token: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
79 let invoked = FunctionCallInvoked::parse(token, lexer, errors)?;
80 let arguments = FunctionArguments::try_parse(lexer, errors);
81
82 if let Some(arguments) = arguments {
83 return Some(FunctionCall { invoked, arguments });
84 }
85 if let FunctionCallInvoked::Function(pointer) = invoked {
86 if let PrefixExp::FunctionCall(call) = (*pointer).clone() {
87 return Some(call);
88 }
89 }
90
91 None
92 }
93}
94impl TryParse for FunctionCall {
95 fn try_parse(lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
96 Some(Self {
97 invoked: FunctionCallInvoked::try_parse(lexer, errors)?,
98 arguments: FunctionArguments::try_parse(lexer, errors)?,
99 })
100 }
101}
102
103impl Parse<PrefixExp> for FunctionCall {
104 fn parse(token: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<PrefixExp> {
105 Self::parse(token, lexer, errors).map(PrefixExp::FunctionCall)
106 }
107}
108impl Parse<TableAccessPrefix> for FunctionCall {
109 fn parse(
110 token: Token,
111 lexer: &mut Lexer,
112 errors: &mut Vec<ParseError>,
113 ) -> Option<TableAccessPrefix> {
114 Pointer::<Self>::parse(token, lexer, errors).map(TableAccessPrefix::FunctionCall)
115 }
116}
117
118impl Parse for FunctionArguments {
119 fn parse(token: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
120 if matches!(token.token_type, TokenType::Literal(Literal::String(_))) {
121 return Some(Self::String(token));
122 }
123 if token.token_type == TokenType::Symbol(Symbol::OpeningParenthesis) {
124 return BracketedList::parse_with(
125 token,
126 lexer,
127 errors,
128 ("Expected <expr>", Symbol::ClosingParenthesis),
129 )
130 .map(Self::List);
131 }
132
133 Table::parse(token.clone(), lexer, errors)
134 }
135}
136impl TryParse for FunctionArguments {}
137
138impl Parse for FunctionArgument {
139 fn parse(token: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
140 if matches!(token.token_type, TokenType::Symbol(Symbol::Ellipses)) {
141 Some(Self::VariadicValues(token))
142 } else {
143 Expression::parse(token, lexer, errors).map(Self::Expression)
144 }
145 }
146}
147impl TryParse for FunctionArgument {}
148
149impl Parse for Closure {
150 fn parse(token: Token, lexer: &mut Lexer, errors: &mut Vec<ParseError>) -> Option<Self> {
151 let attributes;
152 let function_keyword;
153
154 match token.token_type {
155 TokenType::Keyword(Keyword::Function) => {
156 attributes = Vec::new();
157 function_keyword = token;
158 }
159 TokenType::Symbol(Symbol::At) => {
160 attributes = safe_unwrap!(
161 lexer,
162 errors,
163 "Expected <attribute>",
164 Vec::parse(token, lexer, errors)
165 );
166 function_keyword = lexer.next_token();
167 }
168 _ => return None,
169 }
170
171 parse_function!(
172 let attributes = attributes;
173 function_keyword,
174 lexer,
175 errors,
176 { attributes }
177 )
178 }
179}