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