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