mago_ast/ast/function_like/
parameter.rs1use serde::Deserialize;
2use serde::Serialize;
3
4use mago_span::HasSpan;
5use mago_span::Span;
6
7use crate::ast::attribute::AttributeList;
8use crate::ast::class_like::property::PropertyHookList;
9use crate::ast::expression::Expression;
10use crate::ast::modifier::Modifier;
11use crate::ast::type_hint::Hint;
12use crate::ast::variable::DirectVariable;
13use crate::sequence::Sequence;
14use crate::sequence::TokenSeparatedSequence;
15
16#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
18#[repr(C)]
19pub struct FunctionLikeParameterList {
20 pub left_parenthesis: Span,
21 pub parameters: TokenSeparatedSequence<FunctionLikeParameter>,
22 pub right_parenthesis: Span,
23}
24
25#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
29#[repr(C)]
30pub struct FunctionLikeParameter {
31 pub attribute_lists: Sequence<AttributeList>,
32 pub modifiers: Sequence<Modifier>,
33 pub hint: Option<Hint>,
34 pub ampersand: Option<Span>,
35 pub ellipsis: Option<Span>,
36 pub variable: DirectVariable,
37 pub default_value: Option<FunctionLikeParameterDefaultValue>,
38 pub hooks: Option<PropertyHookList>,
39}
40
41#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
43#[repr(C)]
44pub struct FunctionLikeParameterDefaultValue {
45 pub equals: Span,
46 pub value: Expression,
47}
48
49impl FunctionLikeParameter {
50 pub fn is_promoted_property(&self) -> bool {
59 !self.modifiers.is_empty() || self.hooks.is_some()
60 }
61}
62
63impl HasSpan for FunctionLikeParameterList {
64 fn span(&self) -> Span {
65 Span::between(self.left_parenthesis, self.right_parenthesis)
66 }
67}
68
69impl HasSpan for FunctionLikeParameter {
70 fn span(&self) -> Span {
71 let right = self.hooks.as_ref().map(|hooks| hooks.span()).unwrap_or_else(|| {
72 self.default_value.as_ref().map_or_else(|| self.variable.span(), |default_value| default_value.span())
73 });
74
75 if let Some(attribute) = self.attribute_lists.first() {
76 return Span::between(attribute.span(), right);
77 }
78
79 if let Some(modifier) = self.modifiers.first() {
80 return Span::between(modifier.span(), right);
81 }
82
83 if let Some(type_hint) = &self.hint {
84 return Span::between(type_hint.span(), right);
85 }
86
87 if let Some(ellipsis) = self.ellipsis {
88 return Span::between(ellipsis, right);
89 }
90
91 if let Some(ampersand) = self.ampersand {
92 return Span::between(ampersand, right);
93 }
94
95 Span::between(self.variable.span(), right)
96 }
97}
98
99impl HasSpan for FunctionLikeParameterDefaultValue {
100 fn span(&self) -> Span {
101 Span::between(self.equals, self.value.span())
102 }
103}