mago_syntax/cst/cst/function_like/
parameter.rs1use mago_span::HasSpan;
2use mago_span::Span;
3
4use crate::cst::cst::attribute::AttributeList;
5use crate::cst::cst::class_like::property::PropertyHookList;
6use crate::cst::cst::expression::Expression;
7use crate::cst::cst::modifier::Modifier;
8use crate::cst::cst::type_hint::Hint;
9use crate::cst::cst::variable::DirectVariable;
10use crate::cst::sequence::Sequence;
11use crate::cst::sequence::TokenSeparatedSequence;
12
13#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
15#[cfg_attr(feature = "serde", derive(serde::Serialize))]
16pub struct FunctionLikeParameterList<'arena> {
17 pub left_parenthesis: Span,
18 pub parameters: TokenSeparatedSequence<'arena, FunctionLikeParameter<'arena>>,
19 pub right_parenthesis: Span,
20}
21
22#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
26#[cfg_attr(feature = "serde", derive(serde::Serialize))]
27pub struct FunctionLikeParameter<'arena> {
28 pub attribute_lists: Sequence<'arena, AttributeList<'arena>>,
29 pub modifiers: Sequence<'arena, Modifier<'arena>>,
30 pub hint: Option<Hint<'arena>>,
31 pub ampersand: Option<Span>,
32 pub ellipsis: Option<Span>,
33 pub variable: DirectVariable<'arena>,
34 pub default_value: Option<FunctionLikeParameterDefaultValue<'arena>>,
35 pub hooks: Option<PropertyHookList<'arena>>,
36}
37
38#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
40#[cfg_attr(feature = "serde", derive(serde::Serialize))]
41pub struct FunctionLikeParameterDefaultValue<'arena> {
42 pub equals: Span,
43 pub value: &'arena Expression<'arena>,
44}
45
46impl FunctionLikeParameter<'_> {
47 #[must_use]
56 pub fn is_promoted_property(&self) -> bool {
57 !self.modifiers.is_empty() || self.hooks.is_some()
58 }
59
60 #[inline]
61 #[must_use]
62 pub const fn is_variadic(&self) -> bool {
63 self.ellipsis.is_some()
64 }
65
66 #[inline]
67 #[must_use]
68 pub const fn is_reference(&self) -> bool {
69 self.ampersand.is_some()
70 }
71}
72
73impl HasSpan for FunctionLikeParameterList<'_> {
74 fn span(&self) -> Span {
75 Span::between(self.left_parenthesis, self.right_parenthesis)
76 }
77}
78
79impl HasSpan for FunctionLikeParameter<'_> {
80 fn span(&self) -> Span {
81 let right = self.hooks.as_ref().map_or_else(
82 || self.default_value.as_ref().map_or_else(|| self.variable.span(), HasSpan::span),
83 HasSpan::span,
84 );
85
86 if let Some(attribute) = self.attribute_lists.first() {
87 return Span::between(attribute.span(), right);
88 }
89
90 if let Some(modifier) = self.modifiers.first() {
91 return Span::between(modifier.span(), right);
92 }
93
94 if let Some(type_hint) = &self.hint {
95 return Span::between(type_hint.span(), right);
96 }
97
98 if let Some(ellipsis) = self.ellipsis {
99 return Span::between(ellipsis, right);
100 }
101
102 if let Some(ampersand) = self.ampersand {
103 return Span::between(ampersand, right);
104 }
105
106 Span::between(self.variable.span(), right)
107 }
108}
109
110impl HasSpan for FunctionLikeParameterDefaultValue<'_> {
111 fn span(&self) -> Span {
112 Span::between(self.equals, self.value.span())
113 }
114}