1use crate::nodes::Attributes;
2
3use super::{
4 Block, FunctionExpression, FunctionName, FunctionReturnType, FunctionStatement,
5 FunctionVariadicType, GenericParameters, Identifier, LocalFunctionStatement,
6 LocalFunctionTokens, Token, TypeFunctionStatement, TypeFunctionStatementTokens,
7 TypedIdentifier,
8};
9
10pub(crate) struct FunctionBuilder {
11 block: Block,
12 parameters: Vec<TypedIdentifier>,
13 is_variadic: bool,
14 variadic_type: Option<FunctionVariadicType>,
15 return_type: Option<FunctionReturnType>,
16
17 function: Option<Token>,
18 opening_parenthese: Option<Token>,
19 closing_parenthese: Option<Token>,
20 end: Option<Token>,
21 parameter_commas: Vec<Token>,
22
23 variable_arguments: Option<Token>,
24 variable_arguments_colon: Option<Token>,
25 return_type_colon: Option<Token>,
26 generic_parameters: Option<GenericParameters>,
27
28 attributes: Attributes,
29}
30
31impl FunctionBuilder {
32 pub fn from_block(block: impl Into<Block>) -> Self {
33 Self {
34 block: block.into(),
35 parameters: Vec::new(),
36 is_variadic: false,
37 variadic_type: None,
38 return_type: None,
39
40 function: None,
41 opening_parenthese: None,
42 closing_parenthese: None,
43 end: None,
44 parameter_commas: Vec::new(),
45
46 variable_arguments: None,
47 variable_arguments_colon: None,
48 return_type_colon: None,
49 generic_parameters: None,
50
51 attributes: Attributes::new(),
52 }
53 }
54
55 pub(crate) fn into_function_expression(self) -> FunctionExpression {
56 let mut expression = FunctionExpression::new(self.block, self.parameters, self.is_variadic)
57 .with_attributes(self.attributes);
58
59 if let Some(variadic_type) = self.variadic_type {
60 expression.set_variadic_type(variadic_type);
61 }
62
63 if let Some(return_type) = self.return_type {
64 expression.set_return_type(return_type);
65 }
66
67 if let Some(generic_parameters) = self.generic_parameters {
68 expression.set_generic_parameters(generic_parameters);
69 }
70
71 if let (Some(function), Some(opening_parenthese), Some(closing_parenthese), Some(end)) = (
72 self.function,
73 self.opening_parenthese,
74 self.closing_parenthese,
75 self.end,
76 ) {
77 expression.set_tokens(FunctionBodyTokens {
78 function,
79 opening_parenthese,
80 closing_parenthese,
81 end,
82 parameter_commas: self.parameter_commas,
83 variable_arguments: self.variable_arguments,
84 variable_arguments_colon: self.variable_arguments_colon,
85 return_type_colon: self.return_type_colon,
86 });
87 }
88
89 expression
90 }
91
92 pub(crate) fn into_function_statement(self, name: FunctionName) -> FunctionStatement {
93 let mut statement =
94 FunctionStatement::new(name, self.block, self.parameters, self.is_variadic)
95 .with_attributes(self.attributes);
96
97 if let Some(variadic_type) = self.variadic_type {
98 statement.set_variadic_type(variadic_type);
99 }
100
101 if let Some(return_type) = self.return_type {
102 statement.set_return_type(return_type);
103 }
104
105 if let Some(generic_parameters) = self.generic_parameters {
106 statement.set_generic_parameters(generic_parameters);
107 }
108
109 if let (Some(function), Some(opening_parenthese), Some(closing_parenthese), Some(end)) = (
110 self.function,
111 self.opening_parenthese,
112 self.closing_parenthese,
113 self.end,
114 ) {
115 statement.set_tokens(FunctionBodyTokens {
116 function,
117 opening_parenthese,
118 closing_parenthese,
119 end,
120 parameter_commas: self.parameter_commas,
121 variable_arguments: self.variable_arguments,
122 variable_arguments_colon: self.variable_arguments_colon,
123 return_type_colon: self.return_type_colon,
124 });
125 }
126
127 statement
128 }
129
130 pub(crate) fn into_local_function_statement(
131 self,
132 name: Identifier,
133 local_token: Option<Token>,
134 ) -> LocalFunctionStatement {
135 let mut statement =
136 LocalFunctionStatement::new(name, self.block, self.parameters, self.is_variadic)
137 .with_attributes(self.attributes);
138
139 if let Some(variadic_type) = self.variadic_type {
140 statement.set_variadic_type(variadic_type);
141 }
142
143 if let Some(return_type) = self.return_type {
144 statement.set_return_type(return_type);
145 }
146
147 if let Some(generic_parameters) = self.generic_parameters {
148 statement.set_generic_parameters(generic_parameters);
149 }
150
151 if let (
152 Some(local),
153 Some(function),
154 Some(opening_parenthese),
155 Some(closing_parenthese),
156 Some(end),
157 ) = (
158 local_token,
159 self.function,
160 self.opening_parenthese,
161 self.closing_parenthese,
162 self.end,
163 ) {
164 statement.set_tokens(LocalFunctionTokens {
165 local,
166 function_body: FunctionBodyTokens {
167 function,
168 opening_parenthese,
169 closing_parenthese,
170 end,
171 parameter_commas: self.parameter_commas,
172 variable_arguments: self.variable_arguments,
173 variable_arguments_colon: self.variable_arguments_colon,
174 return_type_colon: self.return_type_colon,
175 },
176 });
177 }
178
179 statement
180 }
181
182 pub(crate) fn into_type_function_statement(
183 self,
184 name: Identifier,
185 type_token: Option<Token>,
186 export_token: Option<Token>,
187 ) -> TypeFunctionStatement {
188 let mut statement =
189 TypeFunctionStatement::new(name, self.block, self.parameters, self.is_variadic);
190
191 if let Some(variadic_type) = self.variadic_type {
192 statement.set_variadic_type(variadic_type);
193 }
194
195 if let Some(return_type) = self.return_type {
196 statement.set_return_type(return_type);
197 }
198
199 if let Some(generic_parameters) = self.generic_parameters {
200 statement.set_generic_parameters(generic_parameters);
201 }
202
203 if let (
204 Some(type_token),
205 Some(function),
206 Some(opening_parenthese),
207 Some(closing_parenthese),
208 Some(end),
209 ) = (
210 type_token,
211 self.function,
212 self.opening_parenthese,
213 self.closing_parenthese,
214 self.end,
215 ) {
216 statement.set_tokens(TypeFunctionStatementTokens {
217 r#type: type_token,
218 export: export_token,
219 function_body: FunctionBodyTokens {
220 function,
221 opening_parenthese,
222 closing_parenthese,
223 end,
224 parameter_commas: self.parameter_commas,
225 variable_arguments: self.variable_arguments,
226 variable_arguments_colon: self.variable_arguments_colon,
227 return_type_colon: self.return_type_colon,
228 },
229 });
230 }
231
232 statement
233 }
234
235 pub(crate) fn is_variadic(&self) -> bool {
236 self.is_variadic
237 }
238
239 pub(crate) fn set_return_type_colon(&mut self, token: Token) {
240 self.return_type_colon = Some(token);
241 }
242
243 pub(crate) fn set_return_type(&mut self, r#type: FunctionReturnType) {
244 self.return_type = Some(r#type);
245 }
246
247 pub(crate) fn set_variable_arguments_token(&mut self, token: Token) {
248 self.variable_arguments = Some(token);
249 }
250
251 pub(crate) fn set_variadic(&mut self) {
252 self.is_variadic = true;
253 }
254
255 pub(crate) fn set_variadic_type(&mut self, r#type: FunctionVariadicType) {
256 self.is_variadic = true;
257 self.variadic_type = Some(r#type);
258 }
259
260 pub(crate) fn set_variable_arguments_colon(&mut self, token: Token) {
261 self.variable_arguments_colon = Some(token);
262 }
263
264 pub(crate) fn push_parameter(&mut self, typed_identifier: TypedIdentifier) {
265 self.parameters.push(typed_identifier);
266 }
267
268 pub(crate) fn set_parentheses_tokens(&mut self, open: Token, close: Token) {
269 self.opening_parenthese = Some(open);
270 self.closing_parenthese = Some(close);
271 }
272
273 pub(crate) fn set_parameter_commas(&mut self, commas: Vec<Token>) {
274 self.parameter_commas = commas;
275 }
276
277 pub(crate) fn set_function_token(&mut self, token: Token) {
278 self.function = Some(token);
279 }
280
281 pub(crate) fn set_end_token(&mut self, token: Token) {
282 self.end = Some(token);
283 }
284
285 pub(crate) fn set_generic_parameters(&mut self, generic_parameters: GenericParameters) {
286 self.generic_parameters = Some(generic_parameters);
287 }
288
289 pub(crate) fn set_attributes(&mut self, attributes: Attributes) {
290 self.attributes = attributes;
291 }
292}
293
294#[derive(Clone, Debug, PartialEq, Eq)]
296pub struct FunctionBodyTokens {
297 pub function: Token,
299 pub opening_parenthese: Token,
301 pub closing_parenthese: Token,
303 pub end: Token,
305 pub parameter_commas: Vec<Token>,
307 pub variable_arguments: Option<Token>,
309 pub variable_arguments_colon: Option<Token>,
311 pub return_type_colon: Option<Token>,
313}
314
315impl FunctionBodyTokens {
316 super::impl_token_fns!(
317 target = [function, opening_parenthese, closing_parenthese, end]
318 iter = [
319 variable_arguments,
320 variable_arguments_colon,
321 return_type_colon,
322 parameter_commas,
323 ]
324 );
325}