mago_codex/metadata/parameter.rs
1use serde::Deserialize;
2use serde::Serialize;
3
4use mago_span::HasSpan;
5use mago_span::Span;
6
7use crate::metadata::attribute::AttributeMetadata;
8use crate::metadata::flags::MetadataFlags;
9use crate::metadata::ttype::TypeMetadata;
10use crate::misc::VariableIdentifier;
11
12/// Contains metadata associated with a single parameter within a function, method, or closure signature.
13///
14/// This captures details like the parameter's name, type hint, attributes, default value,
15/// pass-by-reference status, variadic nature, and other PHP features like property promotion.
16#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
17#[non_exhaustive]
18pub struct FunctionLikeParameterMetadata {
19 /// Attributes attached to the parameter declaration.
20 pub attributes: Vec<AttributeMetadata>,
21
22 /// The identifier (name) of the parameter, including the leading '$'.
23 pub name: VariableIdentifier,
24
25 /// The native type declaration from the function signature.
26 ///
27 /// This is the type hint specified in the code (e.g., `string $name`), not from docblocks.
28 /// Can be `None` if no type hint is specified in the signature.
29 pub type_declaration_metadata: Option<TypeMetadata>,
30
31 /// The explicit type declaration (type hint) or docblock type (`@param`).
32 ///
33 /// If there's a docblock `@param` annotation, this will contain that type (with `from_docblock=true`).
34 /// Otherwise, this will be the same as `type_declaration_metadata`.
35 /// Can be `None` if no type is specified.
36 pub type_metadata: Option<TypeMetadata>,
37
38 /// The type specified by a `@param-out` docblock tag.
39 ///
40 /// This indicates the expected type of a pass-by-reference parameter *after* the function executes.
41 pub out_type: Option<TypeMetadata>,
42
43 /// The inferred type of the parameter's default value, if `has_default` is true and the
44 /// type could be determined.
45 ///
46 /// `None` if there is no default or the default value's type couldn't be inferred.
47 pub default_type: Option<TypeMetadata>,
48
49 /// The source code location (span) covering the entire parameter declaration.
50 pub span: Span,
51
52 /// The specific source code location (span) of the parameter's name identifier.
53 pub name_span: Span,
54
55 /// Flags indicating various properties of the parameter.
56 pub flags: MetadataFlags,
57}
58
59/// Contains metadata associated with a single parameter within a function, method, or closure signature.
60///
61/// This captures details like the parameter's name, type hint, attributes, default value,
62/// pass-by-reference status, variadic nature, and other PHP features like property promotion.
63impl FunctionLikeParameterMetadata {
64 /// Creates new `FunctionLikeParameterMetadata` for a basic parameter.
65 /// Initializes most flags to false and optional fields to None.
66 ///
67 /// # Arguments
68 ///
69 /// * `name`: The identifier (name) of the parameter (e.g., `$userId`).
70 /// * `span`: The source code location covering the entire parameter declaration.
71 /// * `name_span`: The source code location of the parameter's name identifier (`$userId`).
72 #[must_use]
73 pub fn new(name: VariableIdentifier, span: Span, name_span: Span, flags: MetadataFlags) -> Self {
74 Self {
75 attributes: Vec::new(),
76 name,
77 flags,
78 span,
79 name_span,
80 type_declaration_metadata: None,
81 type_metadata: None,
82 out_type: None,
83 default_type: None,
84 }
85 }
86
87 /// Returns a reference to the parameter's name identifier (e.g., `$userId`).
88 #[inline]
89 #[must_use]
90 pub fn get_name(&self) -> &VariableIdentifier {
91 &self.name
92 }
93
94 /// Returns the span covering the entire parameter declaration.
95 #[inline]
96 #[must_use]
97 pub fn get_span(&self) -> Span {
98 self.span
99 }
100
101 /// Returns the span covering the parameter's name identifier.
102 #[inline]
103 #[must_use]
104 pub fn get_name_span(&self) -> Span {
105 self.name_span
106 }
107
108 /// Returns a reference to the parameter's type metadata (effective type with docblock).
109 #[inline]
110 #[must_use]
111 pub fn get_type_metadata(&self) -> Option<&TypeMetadata> {
112 self.type_metadata.as_ref()
113 }
114
115 /// Returns a reference to the parameter's native type declaration metadata.
116 #[inline]
117 #[must_use]
118 pub fn get_type_declaration_metadata(&self) -> Option<&TypeMetadata> {
119 self.type_declaration_metadata.as_ref()
120 }
121
122 /// Returns a reference to the inferred type of the default value, if known.
123 #[inline]
124 #[must_use]
125 pub fn get_default_type(&self) -> Option<&TypeMetadata> {
126 self.default_type.as_ref()
127 }
128
129 /// Sets the attributes, replacing any existing ones.
130 pub fn set_attributes(&mut self, attributes: impl IntoIterator<Item = AttributeMetadata>) {
131 self.attributes = attributes.into_iter().collect();
132 }
133
134 /// Returns a new instance with the attributes replaced.
135 pub fn with_attributes(mut self, attributes: impl IntoIterator<Item = AttributeMetadata>) -> Self {
136 self.set_attributes(attributes);
137 self
138 }
139
140 /// Sets the parameter's type metadata (effective type with docblock).
141 #[inline]
142 pub fn set_type_metadata(&mut self, type_metadata: Option<TypeMetadata>) {
143 self.type_metadata = type_metadata;
144 }
145
146 /// Sets the parameter's native type declaration metadata.
147 ///
148 /// If `type_metadata` is not set, it will be initialized with the same value.
149 #[inline]
150 pub fn set_type_declaration_metadata(&mut self, type_declaration: Option<TypeMetadata>) {
151 if self.type_metadata.is_none() {
152 self.type_metadata.clone_from(&type_declaration);
153 }
154
155 self.type_declaration_metadata = type_declaration;
156 }
157}
158
159impl HasSpan for FunctionLikeParameterMetadata {
160 fn span(&self) -> Span {
161 self.span
162 }
163}