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