php_parser_rs/parser/ast/
functions.rs

1use std::slice::Iter;
2
3use schemars::JsonSchema;
4use serde::Deserialize;
5use serde::Serialize;
6
7use crate::lexer::token::Span;
8use crate::node::Node;
9use crate::parser::ast::attributes::AttributeGroup;
10use crate::parser::ast::comments::CommentGroup;
11use crate::parser::ast::data_type::Type;
12use crate::parser::ast::identifiers::SimpleIdentifier;
13use crate::parser::ast::modifiers::MethodModifierGroup;
14use crate::parser::ast::modifiers::PromotedPropertyModifierGroup;
15use crate::parser::ast::utils::CommaSeparated;
16use crate::parser::ast::variables::SimpleVariable;
17use crate::parser::ast::Expression;
18use crate::parser::ast::Statement;
19
20#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
21
22pub struct ReturnType {
23    pub colon: Span,
24    pub data_type: Type,
25}
26
27impl Node for ReturnType {
28    fn children(&mut self) -> Vec<&mut dyn Node> {
29        vec![&mut self.data_type]
30    }
31}
32
33#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
34
35pub struct FunctionParameter {
36    pub comments: CommentGroup,
37    pub name: SimpleVariable,
38    pub attributes: Vec<AttributeGroup>,
39    pub data_type: Option<Type>,
40    pub ellipsis: Option<Span>,
41    pub default: Option<Expression>,
42    pub ampersand: Option<Span>,
43}
44
45impl Node for FunctionParameter {
46    fn children(&mut self) -> Vec<&mut dyn Node> {
47        let mut children: Vec<&mut dyn Node> = vec![&mut self.name];
48        if let Some(data_type) = &mut self.data_type {
49            children.push(data_type);
50        }
51        if let Some(default) = &mut self.default {
52            children.push(default);
53        }
54        children
55    }
56}
57
58#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
59
60pub struct FunctionParameterList {
61    pub comments: CommentGroup,
62    pub left_parenthesis: Span,
63    pub parameters: CommaSeparated<FunctionParameter>,
64    pub right_parenthesis: Span,
65}
66
67impl FunctionParameterList {
68    pub fn iter(&self) -> Iter<'_, FunctionParameter> {
69        self.parameters.iter()
70    }
71}
72
73impl IntoIterator for FunctionParameterList {
74    type Item = FunctionParameter;
75    type IntoIter = std::vec::IntoIter<Self::Item>;
76
77    fn into_iter(self) -> Self::IntoIter {
78        self.parameters.into_iter()
79    }
80}
81
82impl Node for FunctionParameterList {
83    fn children(&mut self) -> Vec<&mut dyn Node> {
84        self.parameters.children()
85    }
86}
87
88#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
89
90pub struct FunctionBody {
91    pub comments: CommentGroup,
92    pub left_brace: Span,
93    pub statements: Vec<Statement>,
94    pub right_brace: Span,
95}
96
97impl Node for FunctionBody {
98    fn children(&mut self) -> Vec<&mut dyn Node> {
99        self.statements
100            .iter_mut()
101            .map(|x| x as &mut dyn Node)
102            .collect()
103    }
104}
105
106#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
107
108pub struct FunctionStatement {
109    pub comments: CommentGroup,
110    pub attributes: Vec<AttributeGroup>,
111    pub function: Span,
112    pub ampersand: Option<Span>,
113    pub name: SimpleIdentifier,
114    pub parameters: FunctionParameterList,
115    pub return_type: Option<ReturnType>,
116    pub body: FunctionBody,
117}
118
119impl Node for FunctionStatement {
120    fn children(&mut self) -> Vec<&mut dyn Node> {
121        let mut children: Vec<&mut dyn Node> =
122            vec![&mut self.name, &mut self.parameters, &mut self.body];
123        if let Some(return_type) = &mut self.return_type {
124            children.push(return_type);
125        }
126        children
127    }
128}
129
130#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
131
132pub struct ClosureUseVariable {
133    pub comments: CommentGroup,
134    pub ampersand: Option<Span>,
135    pub variable: SimpleVariable,
136}
137
138impl Node for ClosureUseVariable {
139    fn children(&mut self) -> Vec<&mut dyn Node> {
140        vec![&mut self.variable]
141    }
142}
143
144#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
145
146pub struct ClosureUse {
147    pub comments: CommentGroup,
148    pub r#use: Span,
149    pub left_parenthesis: Span,
150    pub variables: CommaSeparated<ClosureUseVariable>,
151    pub right_parenthesis: Span,
152}
153
154impl Node for ClosureUse {
155    fn children(&mut self) -> Vec<&mut dyn Node> {
156        self.variables.children()
157    }
158}
159
160#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
161
162pub struct ClosureExpression {
163    pub comments: CommentGroup,
164    pub attributes: Vec<AttributeGroup>,
165    pub r#static: Option<Span>,
166    pub function: Span,
167    pub ampersand: Option<Span>,
168    pub parameters: FunctionParameterList,
169    pub uses: Option<ClosureUse>,
170    pub return_type: Option<ReturnType>,
171    pub body: FunctionBody,
172}
173
174impl Node for ClosureExpression {
175    fn children(&mut self) -> Vec<&mut dyn Node> {
176        let mut children: Vec<&mut dyn Node> = vec![&mut self.parameters];
177        if let Some(uses) = &mut self.uses {
178            children.push(uses);
179        }
180        if let Some(return_type) = &mut self.return_type {
181            children.push(return_type);
182        }
183        children.push(&mut self.body);
184        children
185    }
186}
187
188#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
189
190pub struct ArrowFunctionExpression {
191    pub comments: CommentGroup,
192    pub r#static: Option<Span>,
193    pub ampersand: Option<Span>,
194    pub r#fn: Span,
195    pub attributes: Vec<AttributeGroup>,
196    pub parameters: FunctionParameterList,
197    pub return_type: Option<ReturnType>,
198    pub double_arrow: Span,
199    pub body: Box<Expression>,
200}
201
202impl Node for ArrowFunctionExpression {
203    fn children(&mut self) -> Vec<&mut dyn Node> {
204        let mut children: Vec<&mut dyn Node> = vec![&mut self.parameters];
205        if let Some(return_type) = &mut self.return_type {
206            children.push(return_type);
207        }
208        children.push(self.body.as_mut());
209        children
210    }
211}
212
213#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
214
215pub struct ConstructorParameter {
216    pub attributes: Vec<AttributeGroup>,
217    pub comments: CommentGroup,
218    pub ampersand: Option<Span>,
219    pub name: SimpleVariable,
220    pub data_type: Option<Type>,
221    pub ellipsis: Option<Span>,
222    pub default: Option<Expression>,
223    #[serde(flatten)]
224    pub modifiers: PromotedPropertyModifierGroup,
225}
226
227impl Node for ConstructorParameter {
228    fn children(&mut self) -> Vec<&mut dyn Node> {
229        let mut children: Vec<&mut dyn Node> = vec![&mut self.name];
230        if let Some(data_type) = &mut self.data_type {
231            children.push(data_type);
232        }
233        if let Some(default) = &mut self.default {
234            children.push(default);
235        }
236        children
237    }
238}
239
240#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
241
242pub struct ConstructorParameterList {
243    pub comments: CommentGroup,
244    pub left_parenthesis: Span,
245    pub parameters: CommaSeparated<ConstructorParameter>,
246    pub right_parenthesis: Span,
247}
248
249impl Node for ConstructorParameterList {
250    fn children(&mut self) -> Vec<&mut dyn Node> {
251        self.parameters.children()
252    }
253}
254
255#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
256
257pub struct AbstractConstructor {
258    pub comments: CommentGroup,
259    pub attributes: Vec<AttributeGroup>,
260    #[serde(flatten)]
261    pub modifiers: MethodModifierGroup,
262    pub function: Span,
263    // returning by reference from a constructor doesn't make sense
264    // see: https://chat.stackoverflow.com/transcript/message/55718950#55718950
265    pub ampersand: Option<Span>,
266    pub name: SimpleIdentifier,
267    pub parameters: FunctionParameterList,
268    pub semicolon: Span,
269}
270
271impl Node for AbstractConstructor {
272    fn children(&mut self) -> Vec<&mut dyn Node> {
273        vec![&mut self.name, &mut self.parameters]
274    }
275}
276
277#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
278
279pub struct ConcreteConstructor {
280    pub comments: CommentGroup,
281    pub attributes: Vec<AttributeGroup>,
282    #[serde(flatten)]
283    pub modifiers: MethodModifierGroup,
284    pub function: Span,
285    // returning by reference from a constructor doesn't make sense
286    // see: https://chat.stackoverflow.com/transcript/message/55718950#55718950
287    pub ampersand: Option<Span>,
288    pub name: SimpleIdentifier,
289    pub parameters: ConstructorParameterList,
290    pub body: MethodBody,
291}
292
293impl Node for ConcreteConstructor {
294    fn children(&mut self) -> Vec<&mut dyn Node> {
295        vec![&mut self.name, &mut self.parameters, &mut self.body]
296    }
297}
298
299impl ConcreteConstructor {
300    pub fn first_span(&self) -> Span {
301        self.comments
302            .comments
303            .first()
304            .map(|c| c.span)
305            .unwrap_or_else(|| {
306                self.attributes.first().map(|a| a.start).unwrap_or_else(|| {
307                    self.modifiers
308                        .modifiers
309                        .first()
310                        .map(|m| m.span())
311                        .unwrap_or_else(|| self.function)
312                })
313            })
314    }
315}
316
317#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
318
319pub struct AbstractMethod {
320    pub comments: CommentGroup,
321    pub attributes: Vec<AttributeGroup>,
322    #[serde(flatten)]
323    pub modifiers: MethodModifierGroup,
324    pub function: Span,
325    pub ampersand: Option<Span>,
326    pub name: SimpleIdentifier,
327    pub parameters: FunctionParameterList,
328    pub return_type: Option<ReturnType>,
329    pub semicolon: Span,
330}
331
332impl Node for AbstractMethod {
333    fn children(&mut self) -> Vec<&mut dyn Node> {
334        let mut children: Vec<&mut dyn Node> = vec![&mut self.name, &mut self.parameters];
335        if let Some(return_type) = &mut self.return_type {
336            children.push(return_type);
337        }
338        children
339    }
340}
341
342#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
343
344pub struct ConcreteMethod {
345    pub comments: CommentGroup,
346    pub attributes: Vec<AttributeGroup>,
347    #[serde(flatten)]
348    pub modifiers: MethodModifierGroup,
349    pub function: Span,
350    pub ampersand: Option<Span>,
351    pub name: SimpleIdentifier,
352    pub parameters: FunctionParameterList,
353    pub return_type: Option<ReturnType>,
354    pub body: MethodBody,
355}
356
357impl Node for ConcreteMethod {
358    fn children(&mut self) -> Vec<&mut dyn Node> {
359        let mut children: Vec<&mut dyn Node> = vec![&mut self.name, &mut self.parameters];
360        if let Some(return_type) = &mut self.return_type {
361            children.push(return_type);
362        }
363        children.push(&mut self.body);
364        children
365    }
366}
367
368#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
369
370pub struct MethodBody {
371    pub comments: CommentGroup,
372    pub left_brace: Span, // `{`
373    pub statements: Vec<Statement>,
374    pub right_brace: Span, // `}`
375}
376
377impl Node for MethodBody {
378    fn children(&mut self) -> Vec<&mut dyn Node> {
379        self.statements
380            .iter_mut()
381            .map(|s| s as &mut dyn Node)
382            .collect()
383    }
384}