1use crate::flags::TypeFlags;
7use crate::prelude::StructTypeField;
8use crate::supporting_types::{AnonymousStructType, EnumType, NamedStructType, Signature};
9use crate::type_kind::{TypeKind, TypeRef};
10use crate::{Type, TypeId};
11use seq_map::SeqMap;
12use std::rc::Rc;
13use swamp_symbol::TopLevelSymbolId;
14
15#[derive(Debug, Clone)]
17pub struct TypeCache {
18 pub(crate) type_id_to_type: SeqMap<TypeId, Rc<Type>>,
19 pub(crate) kind_to_type_id: SeqMap<TypeKind, TypeId>,
20 pub(crate) compatible_cache: SeqMap<(TypeId, TypeId), bool>,
21 pub(crate) next_id: u32,
22}
23
24impl TypeCache {}
25
26impl TypeCache {}
27
28impl Default for TypeCache {
29 fn default() -> Self {
30 Self::new()
31 }
32}
33
34impl TypeCache {
35 #[must_use]
37 pub fn new() -> Self {
38 Self {
39 type_id_to_type: SeqMap::new(),
40 kind_to_type_id: SeqMap::new(),
41 compatible_cache: SeqMap::new(),
42 next_id: 0,
43 }
44 }
45
46 #[must_use]
47 pub const fn type_id_to_type(&self) -> &SeqMap<TypeId, Rc<Type>> {
48 &self.type_id_to_type
49 }
50
51 #[must_use]
52 pub const fn compatible_cache(&self) -> &SeqMap<(TypeId, TypeId), bool> {
53 &self.compatible_cache
54 }
55
56 const fn next_type_id(&mut self) -> TypeId {
57 let id = TypeId(self.next_id);
58 self.next_id += 1;
59 id
60 }
61
62 fn create_type(&mut self, kind: TypeKind) -> Rc<Type> {
64 let id = self.next_type_id();
65
66 let flags = TypeFlags::compute_for_type_kind(&kind);
67
68 let type_instance = Type {
69 id,
70 flags,
71 kind: Rc::new(kind),
72 };
73
74 let rc_type = Rc::new(type_instance);
75 self.type_id_to_type
76 .insert(id, Rc::clone(&rc_type))
77 .unwrap();
78
79 rc_type
80 }
81
82 #[inline]
84 fn find_type(&self, kind: &TypeKind) -> Option<Rc<Type>> {
85 self.kind_to_type_id
86 .get(kind)
87 .map(|id| self.type_id_to_type[id].clone())
88 }
89
90 #[inline]
92 fn add_type_to_cache(&mut self, type_: &Rc<Type>) {
93 self.kind_to_type_id
94 .insert((*type_.kind).clone(), type_.id)
95 .unwrap();
96 }
97
98 #[inline]
100 #[must_use]
101 pub fn get_by_id(&self, id: TypeId) -> Option<Rc<Type>> {
102 self.type_id_to_type.get(&id).cloned()
103 }
104
105 #[allow(clippy::too_many_lines)]
107 pub fn compatible_with(&mut self, a: &Type, b: &Type) -> bool {
108 if a.id == b.id {
109 return true;
110 }
111
112 let key = (a.id, b.id);
113
114 if let Some(&result) = self.compatible_cache.get(&key) {
115 return result;
116 }
117
118 self.compatible_cache
120 .insert(key, false)
121 .expect("should work");
122
123 let base_compatible = a.do_compatible_with(b, self);
125
126 if !base_compatible {
128 self.compatible_cache.remove(&key);
129 self.compatible_cache
130 .insert(key, false)
131 .expect("should work to insert again");
132 return false;
133 }
134
135 let result = match (&*a.kind, &*b.kind) {
137 (TypeKind::Optional(inner_a), TypeKind::Optional(inner_b)) => {
138 self.compatible_with(inner_a, inner_b)
139 }
140
141 (TypeKind::VecStorage(elem_a, _), TypeKind::VecStorage(elem_b, _)) => {
142 self.compatible_with(elem_a, elem_b)
143 }
144
145 (TypeKind::SparseStorage(elem_a, _), TypeKind::SparseStorage(elem_b, _)) => {
146 self.compatible_with(elem_a, elem_b)
147 }
148
149 (TypeKind::QueueStorage(elem_a, _), TypeKind::QueueStorage(elem_b, _)) => {
150 self.compatible_with(elem_a, elem_b)
151 }
152
153 (TypeKind::StackStorage(elem_a, _), TypeKind::StackStorage(elem_b, _)) => {
154 self.compatible_with(elem_a, elem_b)
155 }
156
157 (TypeKind::SliceView(elem_a), TypeKind::SliceView(elem_b)) => {
158 self.compatible_with(elem_a, elem_b)
159 }
160
161 (TypeKind::SparseView(elem_a), TypeKind::SparseView(elem_b)) => {
162 self.compatible_with(elem_a, elem_b)
163 }
164
165 (TypeKind::QueueView(elem_a), TypeKind::QueueView(elem_b)) => {
166 self.compatible_with(elem_a, elem_b)
167 }
168
169 (TypeKind::StackView(elem_a), TypeKind::StackView(elem_b)) => {
170 self.compatible_with(elem_a, elem_b)
171 }
172
173 (TypeKind::DynamicLengthVecView(elem_a), TypeKind::DynamicLengthVecView(elem_b)) => {
174 self.compatible_with(elem_a, elem_b)
175 }
176
177 (TypeKind::MapStorage(key_a, val_a, _), TypeKind::MapStorage(key_b, val_b, _)) => {
178 self.compatible_with(key_a, key_b) && self.compatible_with(val_a, val_b)
179 }
180
181 (
182 TypeKind::DynamicLengthMapView(key_a, val_a),
183 TypeKind::DynamicLengthMapView(key_b, val_b),
184 ) => self.compatible_with(key_a, key_b) && self.compatible_with(val_a, val_b),
185
186 (TypeKind::GridStorage(elem_a, _, _), TypeKind::GridStorage(elem_b, _, _)) => {
187 self.compatible_with(elem_a, elem_b)
188 }
189
190 (TypeKind::GridView(elem_a), TypeKind::GridView(elem_b)) => {
191 self.compatible_with(elem_a, elem_b)
192 }
193
194 (TypeKind::Tuple(elems_a), TypeKind::Tuple(elems_b)) => {
195 if elems_a.len() == elems_b.len() {
196 elems_a
197 .iter()
198 .zip(elems_b.iter())
199 .all(|(a, b)| self.compatible_with(a, b))
200 } else {
201 false
202 }
203 }
204
205 (
206 TypeKind::FixedCapacityAndLengthArray(elem_a, size_a),
207 TypeKind::FixedCapacityAndLengthArray(elem_b, size_b),
208 ) => size_a == size_b && self.compatible_with(elem_a, elem_b),
209
210 (TypeKind::AnonymousStruct(anon_a), TypeKind::AnonymousStruct(anon_b)) => {
211 anon_a.field_name_sorted_fields.len() == anon_b.field_name_sorted_fields.len()
213 && anon_a.field_name_sorted_fields.keys().all(|key| {
214 anon_b.field_name_sorted_fields.contains_key(key)
215 && self.compatible_with(
216 &anon_a.field_name_sorted_fields[key].field_type,
217 &anon_b.field_name_sorted_fields[key].field_type,
218 )
219 })
220 }
221
222 (TypeKind::Range(range_a), TypeKind::Range(range_b)) => {
223 let named_a = match &*range_a.kind {
225 TypeKind::NamedStruct(named_struct) => named_struct,
226 _ => return false,
227 };
228 let named_b = match &*range_b.kind {
229 TypeKind::NamedStruct(named_struct) => named_struct,
230 _ => return false,
231 };
232
233 let anon_a = match &*named_a.anon_struct_type.kind {
234 TypeKind::AnonymousStruct(anon_struct) => anon_struct,
235 _ => return false,
236 };
237 let anon_b = match &*named_b.anon_struct_type.kind {
238 TypeKind::AnonymousStruct(anon_struct) => anon_struct,
239 _ => return false,
240 };
241
242 anon_a.field_name_sorted_fields.len() == anon_b.field_name_sorted_fields.len()
244 && anon_a.field_name_sorted_fields.keys().all(|key| {
245 anon_b.field_name_sorted_fields.contains_key(key)
246 && self.compatible_with(
247 &anon_a.field_name_sorted_fields[key].field_type,
248 &anon_b.field_name_sorted_fields[key].field_type,
249 )
250 })
251 }
252
253 (TypeKind::NamedStruct(named_a), TypeKind::NamedStruct(named_b)) => {
254 if named_a.assigned_name == named_b.assigned_name {
256 self.compatible_with(&named_a.anon_struct_type, &named_b.anon_struct_type)
257 } else {
258 false
259 }
260 }
261
262 (TypeKind::Enum(enum_a), TypeKind::Enum(enum_b)) => {
263 if enum_a.assigned_name != enum_b.assigned_name
265 || enum_a.instantiated_type_parameters.len()
266 != enum_b.instantiated_type_parameters.len()
267 {
268 false
269 } else {
270 enum_a
272 .instantiated_type_parameters
273 .iter()
274 .zip(enum_b.instantiated_type_parameters.iter())
275 .all(|(a, b)| self.compatible_with(a, b))
276 }
277 }
278
279 (TypeKind::Function(sig_a), TypeKind::Function(sig_b)) => {
280 if sig_a.parameters.len() == sig_b.parameters.len() {
282 let params_match = sig_a
284 .parameters
285 .iter()
286 .zip(sig_b.parameters.iter())
287 .all(|(a, b)| self.compatible_with(&a.resolved_type, &b.resolved_type));
288
289 params_match && self.compatible_with(&sig_a.return_type, &sig_b.return_type)
290 } else {
291 false
292 }
293 }
294
295 _ => true,
296 };
297
298 self.compatible_cache.remove(&key);
299 self.compatible_cache
300 .insert(key, result)
301 .unwrap_or_else(|_| panic!("should be able to insert into cache {key:?}"));
302
303 result
304 }
305
306 pub fn clear_compatibility_cache(&mut self) {
308 self.compatible_cache.clear();
309 }
310
311 pub fn never(&mut self) -> Rc<Type> {
312 let never_kind = TypeKind::Never;
313
314 if let Some(existing) = self.find_type(&never_kind) {
315 return existing;
316 }
317
318 let never_type = self.create_type(never_kind);
319 self.add_type_to_cache(&never_type);
320 never_type
321 }
322
323 pub fn byte(&mut self) -> Rc<Type> {
329 let byte_kind = TypeKind::Byte;
330
331 if let Some(existing) = self.find_type(&byte_kind) {
332 return existing;
333 }
334
335 let byte_type = self.create_type(byte_kind);
336 self.add_type_to_cache(&byte_type);
337 byte_type
338 }
339
340 pub fn int(&mut self) -> Rc<Type> {
341 let int_kind = TypeKind::Int;
342
343 if let Some(existing) = self.find_type(&int_kind) {
344 return existing;
345 }
346
347 let int_type = self.create_type(int_kind);
348 self.add_type_to_cache(&int_type);
349 int_type
350 }
351
352 pub fn codepoint(&mut self) -> Rc<Type> {
353 let char_kind = TypeKind::Codepoint;
354
355 if let Some(existing) = self.find_type(&char_kind) {
356 return existing;
357 }
358
359 let char_type = self.create_type(char_kind);
360 self.add_type_to_cache(&char_type);
361 char_type
362 }
363
364 pub fn float(&mut self) -> Rc<Type> {
365 let float_kind = TypeKind::Float;
366
367 if let Some(existing) = self.find_type(&float_kind) {
368 return existing;
369 }
370
371 let float_type = self.create_type(float_kind);
372 self.add_type_to_cache(&float_type);
373 float_type
374 }
375
376 pub fn bool(&mut self) -> Rc<Type> {
377 let bool_kind = TypeKind::Bool;
378
379 if let Some(existing) = self.find_type(&bool_kind) {
380 return existing;
381 }
382
383 let bool_type = self.create_type(bool_kind);
384 self.add_type_to_cache(&bool_type);
385 bool_type
386 }
387
388 pub fn unit(&mut self) -> Rc<Type> {
389 let unit_kind = TypeKind::Unit;
390
391 if let Some(existing) = self.find_type(&unit_kind) {
392 return existing;
393 }
394
395 let unit_type = self.create_type(unit_kind);
396 self.add_type_to_cache(&unit_type);
397 unit_type
398 }
399
400 pub fn optional(&mut self, inner_type: &Rc<Type>) -> Rc<Type> {
405 let optional_kind = TypeKind::Optional(Rc::clone(inner_type));
406
407 if let Some(existing) = self.find_type(&optional_kind) {
408 return existing;
409 }
410
411 let optional_type = self.create_type(optional_kind);
412 self.add_type_to_cache(&optional_type);
413 optional_type
414 }
415
416 pub fn tuple(&mut self, element_types: Vec<Rc<Type>>) -> Rc<Type> {
417 let tuple_kind = TypeKind::Tuple(element_types);
418
419 if let Some(existing) = self.find_type(&tuple_kind) {
420 return existing;
421 }
422
423 let tuple_type = self.create_type(tuple_kind);
424 self.add_type_to_cache(&tuple_type);
425 tuple_type
426 }
427
428 pub fn string_storage(&mut self, capacity: usize) -> Rc<Type> {
429 let string_kind = TypeKind::StringStorage(self.byte(), self.codepoint(), capacity);
430
431 if let Some(existing) = self.find_type(&string_kind) {
432 return existing;
433 }
434
435 let string_type = self.create_type(string_kind);
436 self.add_type_to_cache(&string_type);
437 string_type
438 }
439
440 pub fn string(&mut self) -> Rc<Type> {
441 let string_kind = TypeKind::String(self.byte(), self.codepoint());
442
443 if let Some(existing) = self.find_type(&string_kind) {
444 return existing;
445 }
446
447 let string_type = self.create_type(string_kind);
448 self.add_type_to_cache(&string_type);
449 string_type
450 }
451
452 pub fn vec_storage(&mut self, element_type: &Rc<Type>, capacity: usize) -> Rc<Type> {
454 let vec_kind = TypeKind::VecStorage(Rc::clone(element_type), capacity);
455
456 if let Some(existing) = self.find_type(&vec_kind) {
457 return existing;
458 }
459
460 let vec_type = self.create_type(vec_kind);
461 self.add_type_to_cache(&vec_type);
462 vec_type
463 }
464
465 pub fn sparse_storage(&mut self, element_type: &Rc<Type>, capacity: usize) -> Rc<Type> {
466 let sparse_kind = TypeKind::SparseStorage(Rc::clone(element_type), capacity);
467
468 if let Some(existing) = self.find_type(&sparse_kind) {
469 return existing;
470 }
471
472 let sparse_type = self.create_type(sparse_kind);
473 self.add_type_to_cache(&sparse_type);
474 sparse_type
475 }
476
477 pub fn queue_storage(&mut self, element_type: &Rc<Type>, capacity: usize) -> Rc<Type> {
478 let queue_kind = TypeKind::QueueStorage(Rc::clone(element_type), capacity);
479
480 if let Some(existing) = self.find_type(&queue_kind) {
481 return existing;
482 }
483
484 let queue_type = self.create_type(queue_kind);
485 self.add_type_to_cache(&queue_type);
486 queue_type
487 }
488
489 pub fn stack_storage(&mut self, element_type: &Rc<Type>, capacity: usize) -> Rc<Type> {
490 let stack_kind = TypeKind::StackStorage(Rc::clone(element_type), capacity);
491
492 if let Some(existing) = self.find_type(&stack_kind) {
493 return existing;
494 }
495
496 let stack_type = self.create_type(stack_kind);
497 self.add_type_to_cache(&stack_type);
498 stack_type
499 }
500
501 pub fn map_storage(
502 &mut self,
503 key_type: &Rc<Type>,
504 value_type: &Rc<Type>,
505 capacity: usize,
506 ) -> Rc<Type> {
507 let map_kind = TypeKind::MapStorage(Rc::clone(key_type), Rc::clone(value_type), capacity);
508
509 if let Some(existing) = self.find_type(&map_kind) {
510 return existing;
511 }
512
513 let map_type = self.create_type(map_kind);
514 self.add_type_to_cache(&map_type);
515 map_type
516 }
517
518 pub fn grid_storage(&mut self, element_type: &Rc<Type>, rows: usize, cols: usize) -> Rc<Type> {
519 let grid_kind = TypeKind::GridStorage(Rc::clone(element_type), rows, cols);
520
521 if let Some(existing) = self.find_type(&grid_kind) {
522 return existing;
523 }
524
525 let grid_type = self.create_type(grid_kind);
526 self.add_type_to_cache(&grid_type);
527 grid_type
528 }
529
530 pub fn fixed_array(&mut self, element_type: &Rc<Type>, size: usize) -> Rc<Type> {
531 let array_kind = TypeKind::FixedCapacityAndLengthArray(Rc::clone(element_type), size);
532
533 if let Some(existing) = self.find_type(&array_kind) {
534 return existing;
535 }
536
537 let array_type = self.create_type(array_kind);
538 self.add_type_to_cache(&array_type);
539 array_type
540 }
541
542 pub fn slice_view(&mut self, element_type: &Rc<Type>) -> Rc<Type> {
543 let slice_kind = TypeKind::SliceView(Rc::clone(element_type));
544
545 if let Some(existing) = self.find_type(&slice_kind) {
546 return existing;
547 }
548
549 let slice_type = self.create_type(slice_kind);
550 self.add_type_to_cache(&slice_type);
551 slice_type
552 }
553
554 pub fn sparse_view(&mut self, element_type: &Rc<Type>) -> Rc<Type> {
555 let sparse_kind = TypeKind::SparseView(Rc::clone(element_type));
556
557 if let Some(existing) = self.find_type(&sparse_kind) {
558 return existing;
559 }
560
561 let sparse_type = self.create_type(sparse_kind);
562 self.add_type_to_cache(&sparse_type);
563 sparse_type
564 }
565
566 pub fn queue_view(&mut self, element_type: &Rc<Type>) -> Rc<Type> {
567 let queue_kind = TypeKind::QueueView(Rc::clone(element_type));
568
569 if let Some(existing) = self.find_type(&queue_kind) {
570 return existing;
571 }
572
573 let queue_type = self.create_type(queue_kind);
574 self.add_type_to_cache(&queue_type);
575 queue_type
576 }
577
578 pub fn stack_view(&mut self, element_type: &Rc<Type>) -> Rc<Type> {
579 let stack_kind = TypeKind::StackView(Rc::clone(element_type));
580
581 if let Some(existing) = self.find_type(&stack_kind) {
582 return existing;
583 }
584
585 let stack_type = self.create_type(stack_kind);
586 self.add_type_to_cache(&stack_type);
587 stack_type
588 }
589
590 pub fn any(&mut self) -> Rc<Type> {
591 let any_kind = TypeKind::Any;
592
593 if let Some(existing) = self.find_type(&any_kind) {
594 return existing;
595 }
596
597 let any_type = self.create_type(any_kind);
598 self.add_type_to_cache(&any_type);
599 any_type
600 }
601
602 pub fn dynamic_vec_view(&mut self, element_type: &Rc<Type>) -> Rc<Type> {
603 let vec_view_kind = TypeKind::DynamicLengthVecView(Rc::clone(element_type));
604
605 if let Some(existing) = self.find_type(&vec_view_kind) {
606 return existing;
607 }
608
609 let vec_view_type = self.create_type(vec_view_kind);
610 self.add_type_to_cache(&vec_view_type);
611 vec_view_type
612 }
613
614 pub fn dynamic_map_view(&mut self, key_type: &Rc<Type>, value_type: &Rc<Type>) -> Rc<Type> {
615 let map_view_kind =
616 TypeKind::DynamicLengthMapView(Rc::clone(key_type), Rc::clone(value_type));
617
618 if let Some(existing) = self.find_type(&map_view_kind) {
619 return existing;
620 }
621
622 let map_view_type = self.create_type(map_view_kind);
623 self.add_type_to_cache(&map_view_type);
624 map_view_type
625 }
626
627 pub fn grid_view(&mut self, element_type: &Rc<Type>) -> Rc<Type> {
628 let grid_view_kind = TypeKind::GridView(Rc::clone(element_type));
629
630 if let Some(existing) = self.find_type(&grid_view_kind) {
631 return existing;
632 }
633
634 let grid_view_type = self.create_type(grid_view_kind);
635 self.add_type_to_cache(&grid_view_type);
636 grid_view_type
637 }
638
639 pub fn anonymous_struct(&mut self, anon_struct: AnonymousStructType) -> Rc<Type> {
645 let struct_kind = TypeKind::AnonymousStruct(anon_struct);
646
647 if let Some(existing) = self.find_type(&struct_kind) {
648 return existing;
649 }
650
651 let struct_type = self.create_type(struct_kind);
652 self.add_type_to_cache(&struct_type);
653 struct_type
654 }
655
656 pub fn range(&mut self, range_struct_ref: TypeRef) -> Rc<Type> {
657 let range_kind = TypeKind::Range(range_struct_ref);
658
659 if let Some(existing) = self.find_type(&range_kind) {
660 return existing;
661 }
662
663 let range_type = self.create_type(range_kind);
664 self.add_type_to_cache(&range_type);
665 range_type
666 }
667
668 pub fn range_int(&mut self) -> Rc<Type> {
669 let int_type = self.int();
670 let bool_type = self.bool();
671
672 let mut range_fields = SeqMap::new();
674 let _ = range_fields.insert(
675 "start".to_string(),
676 StructTypeField {
677 symbol_id: TopLevelSymbolId::new_illegal(),
678 identifier: None,
679 field_type: int_type.clone(),
680 },
681 );
682 let _ = range_fields.insert(
683 "end".to_string(),
684 StructTypeField {
685 symbol_id: TopLevelSymbolId::new_illegal(),
686 identifier: None,
687 field_type: int_type,
688 },
689 );
690 let _ = range_fields.insert(
691 "is_inclusive".to_string(),
692 StructTypeField {
693 symbol_id: TopLevelSymbolId::new_illegal(),
694 identifier: None,
695 field_type: bool_type,
696 },
697 );
698
699 let anon_struct = AnonymousStructType::new(range_fields);
700 let anon_struct_ref = self.anonymous_struct(anon_struct);
701 self.range(anon_struct_ref)
715 }
716
717 pub fn named_struct(&mut self, named_struct: NamedStructType) -> Rc<Type> {
718 let struct_kind = TypeKind::NamedStruct(named_struct);
719
720 if let Some(existing) = self.find_type(&struct_kind) {
721 return existing;
722 }
723
724 let struct_type = self.create_type(struct_kind);
725 self.add_type_to_cache(&struct_type);
726 struct_type
727 }
728
729 pub fn enum_type(&mut self, enum_type: EnumType) -> Rc<Type> {
730 let enum_kind = TypeKind::Enum(enum_type);
731
732 if let Some(existing) = self.find_type(&enum_kind) {
733 return existing;
734 }
735
736 let enum_type = self.create_type(enum_kind);
737 self.add_type_to_cache(&enum_type);
738 enum_type
739 }
740
741 pub fn function(&mut self, signature: Signature) -> Rc<Type> {
742 let function_kind = TypeKind::Function(signature);
743
744 if let Some(existing) = self.find_type(&function_kind) {
745 return existing;
746 }
747
748 let function_type = self.create_type(function_kind);
749 self.add_type_to_cache(&function_type);
750 function_type
751 }
752}