darklua_core/nodes/statements/
function.rs

1use crate::nodes::{
2    Block, FunctionBodyTokens, FunctionReturnType, FunctionVariadicType, GenericParameters,
3    Identifier, Token, TypedIdentifier,
4};
5
6#[derive(Clone, Debug, PartialEq, Eq)]
7pub struct FunctionNameTokens {
8    pub periods: Vec<Token>,
9    pub colon: Option<Token>,
10}
11
12impl FunctionNameTokens {
13    super::impl_token_fns!(iter = [periods, colon]);
14}
15
16#[derive(Clone, Debug, PartialEq, Eq)]
17pub struct FunctionName {
18    name: Identifier,
19    field_names: Vec<Identifier>,
20    method: Option<Identifier>,
21    tokens: Option<FunctionNameTokens>,
22}
23
24impl FunctionName {
25    pub fn new(name: Identifier, field_names: Vec<Identifier>, method: Option<Identifier>) -> Self {
26        Self {
27            name,
28            field_names,
29            method,
30            tokens: None,
31        }
32    }
33
34    pub fn from_name<S: Into<Identifier>>(name: S) -> Self {
35        Self {
36            name: name.into(),
37            field_names: Vec::new(),
38            method: None,
39            tokens: None,
40        }
41    }
42
43    pub fn with_tokens(mut self, tokens: FunctionNameTokens) -> Self {
44        self.tokens = Some(tokens);
45        self
46    }
47
48    #[inline]
49    pub fn set_tokens(&mut self, tokens: FunctionNameTokens) {
50        self.tokens = Some(tokens);
51    }
52
53    #[inline]
54    pub fn get_tokens(&self) -> Option<&FunctionNameTokens> {
55        self.tokens.as_ref()
56    }
57
58    pub fn with_field<S: Into<Identifier>>(mut self, field: S) -> Self {
59        self.field_names.push(field.into());
60        self
61    }
62
63    pub fn with_fields(mut self, field_names: Vec<Identifier>) -> Self {
64        self.field_names = field_names;
65        self
66    }
67
68    pub fn with_method<S: Into<Identifier>>(mut self, method: S) -> Self {
69        self.method.replace(method.into());
70        self
71    }
72
73    pub fn push_field<S: Into<Identifier>>(&mut self, field: S) {
74        self.field_names.push(field.into());
75    }
76
77    #[inline]
78    pub fn remove_method(&mut self) -> Option<Identifier> {
79        self.method.take()
80    }
81
82    #[inline]
83    pub fn get_method(&self) -> Option<&Identifier> {
84        self.method.as_ref()
85    }
86
87    #[inline]
88    pub fn has_method(&self) -> bool {
89        self.method.is_some()
90    }
91
92    #[inline]
93    pub fn get_name(&self) -> &Identifier {
94        &self.name
95    }
96
97    #[inline]
98    pub fn set_name(&mut self, name: Identifier) {
99        self.name = name;
100    }
101
102    #[inline]
103    pub fn get_field_names(&self) -> &Vec<Identifier> {
104        &self.field_names
105    }
106
107    #[inline]
108    pub fn mutate_identifier(&mut self) -> &mut Identifier {
109        &mut self.name
110    }
111
112    super::impl_token_fns!(iter = [tokens, field_names, method]);
113}
114
115#[derive(Clone, Debug, PartialEq, Eq)]
116pub struct FunctionStatement {
117    name: FunctionName,
118    block: Block,
119    parameters: Vec<TypedIdentifier>,
120    is_variadic: bool,
121    variadic_type: Option<FunctionVariadicType>,
122    return_type: Option<FunctionReturnType>,
123    generic_parameters: Option<GenericParameters>,
124    tokens: Option<Box<FunctionBodyTokens>>,
125}
126
127impl FunctionStatement {
128    pub fn new(
129        name: FunctionName,
130        block: Block,
131        parameters: Vec<TypedIdentifier>,
132        is_variadic: bool,
133    ) -> Self {
134        Self {
135            name,
136            block,
137            parameters,
138            is_variadic,
139            variadic_type: None,
140            return_type: None,
141            generic_parameters: None,
142            tokens: None,
143        }
144    }
145
146    pub fn from_name<S: Into<String>, B: Into<Block>>(name: S, block: B) -> Self {
147        Self {
148            name: FunctionName::from_name(name),
149            block: block.into(),
150            parameters: Vec::new(),
151            is_variadic: false,
152            variadic_type: None,
153            return_type: None,
154            generic_parameters: None,
155            tokens: None,
156        }
157    }
158
159    pub fn with_tokens(mut self, tokens: FunctionBodyTokens) -> Self {
160        self.tokens = Some(tokens.into());
161        self
162    }
163
164    #[inline]
165    pub fn set_tokens(&mut self, tokens: FunctionBodyTokens) {
166        self.tokens = Some(tokens.into());
167    }
168
169    #[inline]
170    pub fn get_tokens(&self) -> Option<&FunctionBodyTokens> {
171        self.tokens.as_deref()
172    }
173
174    #[inline]
175    pub fn mutate_tokens(&mut self) -> Option<&mut FunctionBodyTokens> {
176        self.tokens.as_deref_mut()
177    }
178
179    pub fn with_parameter(mut self, parameter: impl Into<TypedIdentifier>) -> Self {
180        self.parameters.push(parameter.into());
181        self
182    }
183
184    pub fn variadic(mut self) -> Self {
185        self.is_variadic = true;
186        self
187    }
188
189    pub fn with_variadic_type(mut self, r#type: impl Into<FunctionVariadicType>) -> Self {
190        self.is_variadic = true;
191        self.variadic_type = Some(r#type.into());
192        self
193    }
194
195    pub fn set_variadic_type(&mut self, r#type: impl Into<FunctionVariadicType>) {
196        self.is_variadic = true;
197        self.variadic_type = Some(r#type.into());
198    }
199
200    #[inline]
201    pub fn get_variadic_type(&self) -> Option<&FunctionVariadicType> {
202        self.variadic_type.as_ref()
203    }
204
205    #[inline]
206    pub fn has_variadic_type(&self) -> bool {
207        self.variadic_type.is_some()
208    }
209
210    #[inline]
211    pub fn mutate_variadic_type(&mut self) -> Option<&mut FunctionVariadicType> {
212        self.variadic_type.as_mut()
213    }
214
215    pub fn with_return_type(mut self, return_type: impl Into<FunctionReturnType>) -> Self {
216        self.return_type = Some(return_type.into());
217        self
218    }
219
220    pub fn set_return_type(&mut self, return_type: impl Into<FunctionReturnType>) {
221        self.return_type = Some(return_type.into());
222    }
223
224    #[inline]
225    pub fn get_return_type(&self) -> Option<&FunctionReturnType> {
226        self.return_type.as_ref()
227    }
228
229    #[inline]
230    pub fn has_return_type(&self) -> bool {
231        self.return_type.is_some()
232    }
233
234    #[inline]
235    pub fn mutate_return_type(&mut self) -> Option<&mut FunctionReturnType> {
236        self.return_type.as_mut()
237    }
238
239    pub fn with_generic_parameters(mut self, generic_parameters: GenericParameters) -> Self {
240        self.generic_parameters = Some(generic_parameters);
241        self
242    }
243
244    #[inline]
245    pub fn set_generic_parameters(&mut self, generic_parameters: GenericParameters) {
246        self.generic_parameters = Some(generic_parameters);
247    }
248
249    #[inline]
250    pub fn get_generic_parameters(&self) -> Option<&GenericParameters> {
251        self.generic_parameters.as_ref()
252    }
253
254    #[inline]
255    pub fn get_block(&self) -> &Block {
256        &self.block
257    }
258
259    #[inline]
260    pub fn get_name(&self) -> &FunctionName {
261        &self.name
262    }
263
264    #[inline]
265    pub fn parameters_count(&self) -> usize {
266        self.parameters.len()
267    }
268
269    #[inline]
270    pub fn get_parameters(&self) -> &Vec<TypedIdentifier> {
271        &self.parameters
272    }
273
274    #[inline]
275    pub fn iter_parameters(&self) -> impl Iterator<Item = &TypedIdentifier> {
276        self.parameters.iter()
277    }
278
279    #[inline]
280    pub fn iter_mut_parameters(&mut self) -> impl Iterator<Item = &mut TypedIdentifier> {
281        self.parameters.iter_mut()
282    }
283
284    #[inline]
285    pub fn is_variadic(&self) -> bool {
286        self.is_variadic
287    }
288
289    #[inline]
290    pub fn mutate_block(&mut self) -> &mut Block {
291        &mut self.block
292    }
293
294    #[inline]
295    pub fn mutate_function_name(&mut self) -> &mut FunctionName {
296        &mut self.name
297    }
298
299    #[inline]
300    pub fn mutate_parameters(&mut self) -> &mut Vec<TypedIdentifier> {
301        &mut self.parameters
302    }
303
304    pub fn remove_method(&mut self) {
305        if let Some(method_name) = self.name.remove_method() {
306            self.name.push_field(method_name);
307            self.parameters.insert(0, TypedIdentifier::new("self"));
308        }
309    }
310
311    #[inline]
312    pub fn has_parameters(&self) -> bool {
313        !self.parameters.is_empty()
314    }
315
316    pub fn clear_types(&mut self) {
317        self.return_type.take();
318        self.variadic_type.take();
319        self.generic_parameters.take();
320        for parameter in &mut self.parameters {
321            parameter.remove_type();
322        }
323        if let Some(tokens) = &mut self.tokens {
324            tokens.variable_arguments_colon.take();
325        }
326    }
327
328    super::impl_token_fns!(
329        target = [name]
330        iter = [parameters, generic_parameters, tokens]
331    );
332}