darklua_core/nodes/statements/
function.rs1use crate::nodes::{
2 Block, FunctionBodyTokens, FunctionReturnType, FunctionVariadicType, GenericParameters,
3 Identifier, Token, TypedIdentifier,
4};
5
6#[derive(Clone, Debug, PartialEq, Eq)]
8pub struct FunctionNameTokens {
9 pub periods: Vec<Token>,
11 pub colon: Option<Token>,
13}
14
15impl FunctionNameTokens {
16 super::impl_token_fns!(iter = [periods, colon]);
17}
18
19#[derive(Clone, Debug, PartialEq, Eq)]
24pub struct FunctionName {
25 name: Identifier,
26 field_names: Vec<Identifier>,
27 method: Option<Identifier>,
28 tokens: Option<FunctionNameTokens>,
29}
30
31impl FunctionName {
32 pub fn new(name: Identifier, field_names: Vec<Identifier>, method: Option<Identifier>) -> Self {
34 Self {
35 name,
36 field_names,
37 method,
38 tokens: None,
39 }
40 }
41
42 pub fn from_name<S: Into<Identifier>>(name: S) -> Self {
44 Self {
45 name: name.into(),
46 field_names: Vec::new(),
47 method: None,
48 tokens: None,
49 }
50 }
51
52 pub fn with_tokens(mut self, tokens: FunctionNameTokens) -> Self {
54 self.tokens = Some(tokens);
55 self
56 }
57
58 #[inline]
60 pub fn set_tokens(&mut self, tokens: FunctionNameTokens) {
61 self.tokens = Some(tokens);
62 }
63
64 #[inline]
66 pub fn get_tokens(&self) -> Option<&FunctionNameTokens> {
67 self.tokens.as_ref()
68 }
69
70 pub fn with_field<S: Into<Identifier>>(mut self, field: S) -> Self {
72 self.field_names.push(field.into());
73 self
74 }
75
76 pub fn with_fields(mut self, field_names: Vec<Identifier>) -> Self {
78 self.field_names = field_names;
79 self
80 }
81
82 pub fn with_method<S: Into<Identifier>>(mut self, method: S) -> Self {
84 self.method.replace(method.into());
85 self
86 }
87
88 pub fn push_field<S: Into<Identifier>>(&mut self, field: S) {
90 self.field_names.push(field.into());
91 }
92
93 #[inline]
95 pub fn remove_method(&mut self) -> Option<Identifier> {
96 self.method.take()
97 }
98
99 #[inline]
101 pub fn get_method(&self) -> Option<&Identifier> {
102 self.method.as_ref()
103 }
104
105 #[inline]
107 pub fn has_method(&self) -> bool {
108 self.method.is_some()
109 }
110
111 #[inline]
113 pub fn get_name(&self) -> &Identifier {
114 &self.name
115 }
116
117 #[inline]
119 pub fn set_name(&mut self, name: Identifier) {
120 self.name = name;
121 }
122
123 #[inline]
125 pub fn get_field_names(&self) -> &Vec<Identifier> {
126 &self.field_names
127 }
128
129 #[inline]
131 pub fn mutate_identifier(&mut self) -> &mut Identifier {
132 &mut self.name
133 }
134
135 super::impl_token_fns!(iter = [tokens, field_names, method]);
136}
137
138#[derive(Clone, Debug, PartialEq, Eq)]
140pub struct FunctionStatement {
141 name: FunctionName,
142 block: Block,
143 parameters: Vec<TypedIdentifier>,
144 is_variadic: bool,
145 variadic_type: Option<FunctionVariadicType>,
146 return_type: Option<FunctionReturnType>,
147 generic_parameters: Option<GenericParameters>,
148 tokens: Option<Box<FunctionBodyTokens>>,
149}
150
151impl FunctionStatement {
152 pub fn new(
154 name: FunctionName,
155 block: Block,
156 parameters: Vec<TypedIdentifier>,
157 is_variadic: bool,
158 ) -> Self {
159 Self {
160 name,
161 block,
162 parameters,
163 is_variadic,
164 variadic_type: None,
165 return_type: None,
166 generic_parameters: None,
167 tokens: None,
168 }
169 }
170
171 pub fn from_name<S: Into<String>, B: Into<Block>>(name: S, block: B) -> Self {
173 Self {
174 name: FunctionName::from_name(name),
175 block: block.into(),
176 parameters: Vec::new(),
177 is_variadic: false,
178 variadic_type: None,
179 return_type: None,
180 generic_parameters: None,
181 tokens: None,
182 }
183 }
184
185 pub fn with_tokens(mut self, tokens: FunctionBodyTokens) -> Self {
187 self.tokens = Some(tokens.into());
188 self
189 }
190
191 #[inline]
193 pub fn set_tokens(&mut self, tokens: FunctionBodyTokens) {
194 self.tokens = Some(tokens.into());
195 }
196
197 #[inline]
199 pub fn get_tokens(&self) -> Option<&FunctionBodyTokens> {
200 self.tokens.as_deref()
201 }
202
203 #[inline]
205 pub fn mutate_tokens(&mut self) -> Option<&mut FunctionBodyTokens> {
206 self.tokens.as_deref_mut()
207 }
208
209 pub fn with_parameter(mut self, parameter: impl Into<TypedIdentifier>) -> Self {
211 self.parameters.push(parameter.into());
212 self
213 }
214
215 pub fn variadic(mut self) -> Self {
217 self.is_variadic = true;
218 self
219 }
220
221 pub fn with_variadic_type(mut self, r#type: impl Into<FunctionVariadicType>) -> Self {
223 self.is_variadic = true;
224 self.variadic_type = Some(r#type.into());
225 self
226 }
227
228 pub fn set_variadic_type(&mut self, r#type: impl Into<FunctionVariadicType>) {
230 self.is_variadic = true;
231 self.variadic_type = Some(r#type.into());
232 }
233
234 #[inline]
236 pub fn get_variadic_type(&self) -> Option<&FunctionVariadicType> {
237 self.variadic_type.as_ref()
238 }
239
240 #[inline]
242 pub fn has_variadic_type(&self) -> bool {
243 self.variadic_type.is_some()
244 }
245
246 #[inline]
248 pub fn mutate_variadic_type(&mut self) -> Option<&mut FunctionVariadicType> {
249 self.variadic_type.as_mut()
250 }
251
252 pub fn with_return_type(mut self, return_type: impl Into<FunctionReturnType>) -> Self {
254 self.return_type = Some(return_type.into());
255 self
256 }
257
258 pub fn set_return_type(&mut self, return_type: impl Into<FunctionReturnType>) {
260 self.return_type = Some(return_type.into());
261 }
262
263 #[inline]
265 pub fn get_return_type(&self) -> Option<&FunctionReturnType> {
266 self.return_type.as_ref()
267 }
268
269 #[inline]
271 pub fn has_return_type(&self) -> bool {
272 self.return_type.is_some()
273 }
274
275 #[inline]
277 pub fn mutate_return_type(&mut self) -> Option<&mut FunctionReturnType> {
278 self.return_type.as_mut()
279 }
280
281 pub fn with_generic_parameters(mut self, generic_parameters: GenericParameters) -> Self {
283 self.generic_parameters = Some(generic_parameters);
284 self
285 }
286
287 #[inline]
289 pub fn set_generic_parameters(&mut self, generic_parameters: GenericParameters) {
290 self.generic_parameters = Some(generic_parameters);
291 }
292
293 #[inline]
295 pub fn get_generic_parameters(&self) -> Option<&GenericParameters> {
296 self.generic_parameters.as_ref()
297 }
298
299 #[inline]
301 pub fn get_block(&self) -> &Block {
302 &self.block
303 }
304
305 #[inline]
307 pub fn get_name(&self) -> &FunctionName {
308 &self.name
309 }
310
311 #[inline]
313 pub fn parameters_count(&self) -> usize {
314 self.parameters.len()
315 }
316
317 #[inline]
319 pub fn get_parameters(&self) -> &Vec<TypedIdentifier> {
320 &self.parameters
321 }
322
323 #[inline]
325 pub fn iter_parameters(&self) -> impl Iterator<Item = &TypedIdentifier> {
326 self.parameters.iter()
327 }
328
329 #[inline]
331 pub fn iter_mut_parameters(&mut self) -> impl Iterator<Item = &mut TypedIdentifier> {
332 self.parameters.iter_mut()
333 }
334
335 #[inline]
337 pub fn is_variadic(&self) -> bool {
338 self.is_variadic
339 }
340
341 #[inline]
343 pub fn mutate_block(&mut self) -> &mut Block {
344 &mut self.block
345 }
346
347 #[inline]
349 pub fn mutate_function_name(&mut self) -> &mut FunctionName {
350 &mut self.name
351 }
352
353 #[inline]
355 pub fn mutate_parameters(&mut self) -> &mut Vec<TypedIdentifier> {
356 &mut self.parameters
357 }
358
359 pub fn remove_method(&mut self) {
364 if let Some(method_name) = self.name.remove_method() {
365 self.name.push_field(method_name);
366 self.parameters.insert(0, TypedIdentifier::new("self"));
367 }
368 }
369
370 #[inline]
372 pub fn has_parameters(&self) -> bool {
373 !self.parameters.is_empty()
374 }
375
376 pub fn clear_types(&mut self) {
379 self.return_type.take();
380 self.variadic_type.take();
381 self.generic_parameters.take();
382 for parameter in &mut self.parameters {
383 parameter.remove_type();
384 }
385 if let Some(tokens) = &mut self.tokens {
386 tokens.variable_arguments_colon.take();
387 }
388 }
389
390 pub fn mutate_first_token(&mut self) -> &mut Token {
392 self.set_default_tokens();
393 &mut self.tokens.as_deref_mut().unwrap().function
394 }
395
396 pub fn mutate_last_token(&mut self) -> &mut Token {
399 self.set_default_tokens();
400 &mut self.tokens.as_deref_mut().unwrap().end
401 }
402
403 fn set_default_tokens(&mut self) {
404 if self.tokens.is_none() {
405 self.tokens = Some(
406 FunctionBodyTokens {
407 function: Token::from_content("function"),
408 opening_parenthese: Token::from_content("("),
409 closing_parenthese: Token::from_content(")"),
410 end: Token::from_content("end"),
411 parameter_commas: Vec::new(),
412 variable_arguments: None,
413 variable_arguments_colon: None,
414 return_type_colon: None,
415 }
416 .into(),
417 );
418 }
419 }
420
421 super::impl_token_fns!(
422 target = [name]
423 iter = [parameters, generic_parameters, tokens]
424 );
425}