darklua_core/nodes/
function_body.rs

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}