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