1use crate::{Type, TypeRef};
7use seq_map::SeqMap;
8use source_map_node::Node;
9use std::fmt::{Debug, Display};
10use std::hash::{Hash, Hasher};
11
12#[derive(Debug, Clone, PartialEq, Eq)]
13pub struct NamedStructType {
14 pub name: Node,
15 pub module_path: Vec<String>,
16 pub assigned_name: String,
17 pub anon_struct_type: TypeRef,
18 pub instantiated_type_parameters: Vec<Type>,
19}
20
21impl Hash for NamedStructType {
22 fn hash<H: Hasher>(&self, state: &mut H) {
23 self.module_path.hash(state);
24 state.write(self.assigned_name.as_ref());
25 self.instantiated_type_parameters.hash(state);
26 }
27}
28
29impl NamedStructType {
30 #[must_use]
31 pub fn new(
32 name: Node,
33 assigned_name: &str,
34 anon_struct_type: TypeRef,
35 module_path: &[String],
36 ) -> Self {
37 Self {
38 anon_struct_type,
39 name,
40 module_path: module_path.to_vec(),
41 assigned_name: assigned_name.to_string(),
42 instantiated_type_parameters: Vec::default(),
43 }
44 }
45
46 #[must_use]
47 pub fn field_index(&self, field_name: &str) -> Option<usize> {
48 if let crate::TypeKind::AnonymousStruct(anon_struct) = &*self.anon_struct_type.kind {
49 anon_struct
50 .field_name_sorted_fields
51 .get_index(&field_name.to_string())
52 } else {
53 None
54 }
55 }
56
57 #[must_use]
58 pub const fn name(&self) -> &Node {
59 &self.name
60 }
61}
62
63#[derive(Debug, Clone, Eq, PartialEq)]
64pub struct AnonymousStructType {
65 pub field_name_sorted_fields: SeqMap<String, StructTypeField>,
66}
67impl Hash for AnonymousStructType {
68 fn hash<H: Hasher>(&self, state: &mut H) {
69 for (name, field) in &self.field_name_sorted_fields {
70 name.hash(state);
71 field.field_type.id.0.hash(state);
72 }
73 }
74}
75
76impl AnonymousStructType {
77 #[must_use]
78 pub fn new_and_sort_fields(source_ordered_fields: &SeqMap<String, StructTypeField>) -> Self {
79 Self {
80 field_name_sorted_fields: sort_struct_fields2(source_ordered_fields),
81 }
82 }
83
84 #[must_use]
85 pub const fn new(defined_order: SeqMap<String, StructTypeField>) -> Self {
86 Self {
87 field_name_sorted_fields: defined_order,
88 }
89 }
90}
91
92#[derive(Debug, Clone, Eq, PartialEq, Hash)]
93pub struct StructTypeField {
94 pub identifier: Option<Node>,
95 pub field_type: TypeRef,
96}
97
98impl Display for StructTypeField {
99 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
100 write!(f, "{:?}", self.field_type)
101 }
102}
103
104#[derive(Debug, Eq, PartialEq, Clone, Hash)]
105pub struct Signature {
106 pub parameters: Vec<TypeForParameter>,
107 pub return_type: TypeRef,
108}
109
110impl Signature {
111 #[must_use]
112 pub fn same_type(&self, other: &Self) -> bool {
113 if !self.return_type.do_compatible_with(&other.return_type) {
114 return false;
115 }
116
117 if self.parameters.len() != other.parameters.len() {
118 return false;
119 }
120
121 for (i, self_param) in self.parameters.iter().enumerate() {
122 let other_param = &other.parameters[i];
123
124 if !self_param
125 .resolved_type
126 .do_compatible_with(&other_param.resolved_type)
127 {
128 return false;
129 }
130
131 if self_param.is_mutable != other_param.is_mutable {
132 return false;
133 }
134 }
135
136 true
137 }
138
139 #[must_use]
140 pub fn is_self_mutable(&self) -> bool {
141 self.parameters
142 .first()
143 .is_some_and(|x| x.name == "self" && x.is_mutable)
144 }
145}
146
147#[derive(Debug, Eq, Clone)]
148pub struct TypeForParameter {
149 pub name: String,
150 pub resolved_type: TypeRef,
151 pub is_mutable: bool,
152 pub node: Option<ParameterNode>,
153}
154
155impl PartialEq for TypeForParameter {
156 fn eq(&self, other: &Self) -> bool {
157 self.resolved_type == other.resolved_type && self.is_mutable == other.is_mutable
158 }
159}
160
161impl std::hash::Hash for TypeForParameter {
162 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
163 self.resolved_type.hash(state);
164 self.is_mutable.hash(state);
165 }
166}
167
168impl Display for TypeForParameter {
169 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
170 write!(
171 f,
172 "{}{}: {:?}",
173 if self.is_mutable { "mut " } else { "" },
174 self.name,
175 self.resolved_type
176 )
177 }
178}
179
180#[derive(Clone, Eq, PartialEq, Hash)]
181pub struct ParameterNode {
182 pub name: Node,
183 pub is_mutable: Option<Node>,
184}
185
186impl Debug for ParameterNode {
187 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
188 write!(f, "Parameter")
189 }
190}
191
192impl ParameterNode {
193 #[inline]
194 #[must_use]
195 pub const fn is_mutable(&self) -> bool {
196 self.is_mutable.is_some()
197 }
198}
199
200#[derive(Debug, Clone, Eq, PartialEq, Hash)]
201pub struct EnumType {
202 pub name: Node,
203 pub assigned_name: String,
204 pub module_path: Vec<String>,
205 pub variants: SeqMap<String, EnumVariantType>,
206 pub instantiated_type_parameters: Vec<Type>,
207}
208
209impl EnumType {}
210
211impl EnumType {
212 #[must_use]
213 pub fn new(name: Node, assigned_name: &str, module_path: Vec<String>) -> Self {
214 Self {
215 name,
216 assigned_name: assigned_name.to_string(),
217 module_path,
218 variants: SeqMap::new(),
219 instantiated_type_parameters: Vec::default(),
220 }
221 }
222
223 #[must_use]
224 pub const fn name(&self) -> &Node {
225 &self.name
226 }
227
228 #[must_use]
229 pub fn get_variant(&self, name: &str) -> Option<&EnumVariantType> {
230 self.variants.get(&name.to_string())
231 }
232
233 #[must_use]
234 pub fn are_all_variants_with_blittable_payload(&self) -> bool {
235 self.variants.iter().all(|(_name, variant)| {
236 assert!(
237 variant.payload_type.is_blittable(),
238 "what is wrong with this variant {variant}"
239 );
240 variant.payload_type.is_blittable()
241 })
242 }
243
244 pub(crate) fn are_all_variants_with_storage_payload(&self) -> bool {
245 self.variants.iter().all(|(_name, variant)| {
246 if !variant.payload_type.is_storage() {
247 eprintln!("this variant can not be stored, please verify why {self}::{variant}");
248 }
249 variant.payload_type.is_storage()
250 })
251 }
252
253 #[must_use]
254 pub fn get_variant_from_index(&self, index: usize) -> Option<&EnumVariantType> {
255 Some(self.variants.values().collect::<Vec<_>>()[index])
256 }
257}
258
259#[derive(Debug, Clone, Eq, PartialEq, Hash)]
260pub struct EnumVariantType {
261 pub common: EnumVariantCommon,
262 pub payload_type: TypeRef, }
264
265impl EnumVariantType {
266 #[must_use]
267 pub const fn common(&self) -> &EnumVariantCommon {
268 &self.common
269 }
270}
271
272#[derive(Clone, Eq, PartialEq, Hash, Debug)]
273pub struct EnumVariantCommon {
274 pub name: Node,
275 pub assigned_name: String,
276 pub container_index: u8,
277}
278
279impl EnumVariantCommon {
280 #[must_use]
281 pub const fn index(&self) -> u8 {
282 self.container_index
283 }
284}
285
286#[must_use]
287pub fn sort_struct_fields2(
288 unordered_seq_map: &SeqMap<String, StructTypeField>,
289) -> SeqMap<String, StructTypeField> {
290 let mut sorted_pairs: Vec<(&String, &StructTypeField)> = unordered_seq_map.iter().collect();
291 sorted_pairs.sort_by(|a, b| a.0.cmp(b.0));
292
293 sorted_pairs
294 .into_iter()
295 .map(|(name, field)| (name.clone(), field.clone()))
296 .collect()
297}
298
299impl Display for NamedStructType {
300 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
301 if self.instantiated_type_parameters.is_empty() {
302 write!(f, "{}", self.assigned_name)
303 } else {
304 write!(
305 f,
306 "{}<{}>",
307 self.assigned_name,
308 seq_fmt::comma(&self.instantiated_type_parameters)
309 )
310 }
311 }
312}
313
314impl Display for AnonymousStructType {
315 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
316 write!(
317 f,
318 "{{ {} }}",
319 seq_fmt::comma(
320 &self
321 .field_name_sorted_fields
322 .iter()
323 .map(|(name, field)| format!("{}: {}", name, field.field_type))
324 .collect::<Vec<_>>()
325 )
326 )
327 }
328}
329
330impl Display for Signature {
331 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
332 write!(
333 f,
334 "({}) -> {}",
335 seq_fmt::comma(&self.parameters),
336 self.return_type
337 )
338 }
339}
340
341impl Display for EnumType {
342 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
343 if self.instantiated_type_parameters.is_empty() {
344 write!(f, "{}", self.assigned_name)
345 } else {
346 write!(
347 f,
348 "{}<{}>",
349 self.assigned_name,
350 seq_fmt::comma(&self.instantiated_type_parameters)
351 )
352 }
353 }
354}
355
356impl Display for EnumVariantType {
357 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
358 write!(f, "{}", self.payload_type)
359 }
360}