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