1pub mod prelude;
6
7use fmt::{Debug, Display};
8use seq_fmt::comma;
9use seq_map::SeqMap;
10use source_map_node::Node;
11use std::cmp::PartialEq;
12use std::fmt;
13use std::hash::Hash;
14
15#[derive(Eq, PartialEq, Hash, Clone)]
16pub enum Type {
17 Int,
19 Float,
20 String,
21 Bool,
22
23 Unit, Never, Slice(Box<Type>),
27 SlicePair(Box<Type>, Box<Type>),
28
29 Tuple(Vec<Type>),
31 NamedStruct(NamedStructType),
32 AnonymousStruct(AnonymousStructType),
33
34 Enum(EnumType),
35
36 Function(Signature),
37
38 Optional(Box<Type>),
39
40 Generic(ParameterizedTypeBlueprint, Vec<Type>),
41 Blueprint(ParameterizedTypeBlueprint),
42 Variable(String),
43
44 MutableReference(Box<Type>),
45
46 External(ExternalType),
47}
48
49impl Type {
50 pub fn inner_optional_mut_or_immutable(&self) -> Option<&Type> {
51 if let Self::Optional(normal) = self {
52 Some(normal)
53 } else if let Self::MutableReference(mutable_reference) = self {
54 mutable_reference.inner_optional_mut_or_immutable()
55 } else {
56 None
57 }
58 }
59}
60
61#[derive(Debug, Clone, PartialEq, Eq, Hash)]
62pub enum ParameterizedTypeKind {
63 Struct(NamedStructType),
64 Enum(EnumType),
65}
66
67impl ParameterizedTypeKind {
68 pub fn name(&self) -> String {
69 match self {
70 Self::Struct(struct_type_ref) => struct_type_ref.assigned_name.clone(),
71 Self::Enum(enum_type_ref) => enum_type_ref.assigned_name.clone(),
72 }
73 }
74}
75
76#[derive(Debug, Clone, PartialEq, Eq, Hash)]
77pub struct ParameterizedTypeBlueprintInfo {
78 pub name: String,
79 pub defined_in_module_path: Vec<String>,
80}
81
82#[derive(Debug, PartialEq, Eq, Hash, Clone)]
83pub struct ParameterizedTypeBlueprint {
84 pub kind: ParameterizedTypeKind,
85 pub type_variables: Vec<String>,
86
87 pub defined_in_module_path: Vec<String>,
88}
89
90impl ParameterizedTypeBlueprint {
91 pub fn info(&self) -> ParameterizedTypeBlueprintInfo {
92 ParameterizedTypeBlueprintInfo {
93 name: self.name(),
94 defined_in_module_path: self.defined_in_module_path.clone(),
95 }
96 }
97 pub fn name(&self) -> String {
98 self.kind.name()
99 }
100}
101
102#[derive(Clone, Eq, PartialEq, Hash)]
103pub struct ParameterNode {
104 pub name: Node,
105 pub is_mutable: Option<Node>,
106}
107
108impl Debug for ParameterNode {
109 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110 write!(f, "Parameter")
111 }
112}
113
114impl ParameterNode {
115 #[inline]
116 #[must_use]
117 pub const fn is_mutable(&self) -> bool {
118 self.is_mutable.is_some()
119 }
120}
121
122#[derive(Debug, Clone, Eq, PartialEq, Hash)]
123pub struct ExternalType {
124 pub type_name: String, pub number: u32, }
127
128#[derive(Debug, Eq, PartialEq, Clone, Hash)]
129pub struct TypeForParameter {
130 pub name: String,
131 pub resolved_type: Type,
132 pub is_mutable: bool,
133 pub node: Option<ParameterNode>,
134}
135
136impl Display for TypeForParameter {
137 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
138 write!(
139 f,
140 "{}{}: {:?}",
141 if self.is_mutable { "mut " } else { "" },
142 self.name,
143 self.resolved_type
144 )
145 }
146}
147
148#[derive(Debug, Eq, PartialEq, Clone, Hash)]
149pub struct TypeVariable(pub String);
150
151#[derive(Debug, Eq, PartialEq, Clone, Hash)]
152pub struct GenericAwareSignature {
153 pub signature: Signature,
154 pub generic_type_variables: Vec<TypeVariable>,
155}
156
157#[derive(Debug, Eq, PartialEq, Clone, Hash)]
158pub struct Signature {
159 pub parameters: Vec<TypeForParameter>,
160 pub return_type: Box<Type>,
161}
162
163impl Display for Signature {
164 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
165 write!(f, "({})->{}", comma(&self.parameters), self.return_type)
166 }
167}
168
169impl Signature {
170 #[must_use]
171 pub fn same_type(&self, other: &Self) -> bool {
172 if self.parameters.len() != other.parameters.len()
173 || !self.return_type.compatible_with(&other.return_type)
174 {
175 return false;
176 }
177
178 for (param, other_param) in self.parameters.iter().zip(other.parameters.clone()) {
179 if !¶m
180 .resolved_type
181 .compatible_with(&other_param.resolved_type)
182 {
183 return false;
184 }
185
186 if param.is_mutable != other_param.is_mutable {
187 return false;
188 }
189 }
190
191 true
192 }
193}
194
195impl Type {
196 #[must_use]
197 pub const fn is_concrete(&self) -> bool {
198 !matches!(
199 self,
200 Self::Unit | Self::Never | Self::Variable(_) | Self::Generic(_, _) | Self::Blueprint(_)
201 )
202 }
203}
204
205impl Debug for Type {
206 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207 match self {
208 Self::Int => write!(f, "Int"),
209 Self::Float => write!(f, "Float"),
210 Self::String => write!(f, "String"),
211 Self::Bool => write!(f, "Bool"),
212 Self::Unit => write!(f, "()"),
213 Self::Never => write!(f, "!"),
214 Self::Tuple(tuple_type_ref) => write!(f, "( {tuple_type_ref:?} )"),
215 Self::NamedStruct(struct_type_ref) => {
216 write!(f, "{}", struct_type_ref.assigned_name)
217 }
218 Self::AnonymousStruct(anonymous_struct_type) => {
219 write!(f, "{anonymous_struct_type:?}")
220 }
221 Self::Enum(enum_type_ref) => write!(f, "{:?}", enum_type_ref.assigned_name),
222 Self::Function(function_type_signature) => {
223 write!(f, "{function_type_signature:?}")
224 }
225 Self::Optional(base_type) => write!(f, "{base_type:?}?"),
226 Self::MutableReference(base_type) => write!(f, "mut ref {base_type:?}?"),
227 Self::External(rust_type) => write!(f, "{:?}?", rust_type.type_name),
228 Self::Variable(variable_name) => write!(f, "<|{variable_name}|>"),
229 Self::Generic(blueprint, non_concrete_arguments) => {
230 write!(f, "{blueprint:?}<{non_concrete_arguments:?}>")
231 }
232 Self::Slice(value_type) => {
233 write!(f, "Slice<{value_type:?}>")
234 }
235 Self::SlicePair(key_type, value_type) => {
236 write!(f, "SlicePair<{key_type:?}, {value_type:?}>")
237 }
238 Self::Blueprint(blueprint) => {
239 write!(f, "{blueprint:?}")
240 }
241 }
242 }
243}
244
245impl Display for Type {
246 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
247 match self {
248 Self::Int => write!(f, "Int"),
249 Self::Float => write!(f, "Float"),
250 Self::String => write!(f, "String"),
251 Self::Bool => write!(f, "Bool"),
252 Self::Unit => write!(f, "()"),
253 Self::Never => write!(f, "!"),
254 Self::Tuple(tuple) => write!(f, "({})", comma(tuple)),
255 Self::NamedStruct(struct_ref) => write!(f, "{}", struct_ref.assigned_name),
256 Self::AnonymousStruct(struct_ref) => write!(f, "{struct_ref:?}"),
257 Self::Enum(enum_type) => write!(f, "{}", enum_type.assigned_name),
258 Self::Function(signature) => write!(f, "function {signature}"),
259 Self::Optional(base_type) => write!(f, "{base_type}?"),
260 Self::MutableReference(base_type) => write!(f, "mut ref {base_type:?}?"),
261 Self::External(rust_type) => write!(f, "RustType {}", rust_type.type_name),
262 Self::Variable(variable_name) => write!(f, "<|{variable_name}|>"),
263
264 Self::Generic(blueprint, non_concrete_arguments) => {
265 write!(f, "{blueprint:?}<{non_concrete_arguments:?}>")
266 }
267 Self::Slice(value_type) => {
268 write!(f, "Slice<{value_type:?}>")
269 }
270 Self::SlicePair(key_type, value_type) => {
271 write!(f, "SlicePair<{key_type:?}, {value_type:?}>")
272 }
273 Self::Blueprint(blueprint) => {
274 write!(f, "{blueprint:?}")
275 }
276 }
277 }
278}
279
280impl Type {
281 #[must_use]
282 pub fn assignable_type(&self, other: &Self) -> bool {
283 if self.compatible_with(other) {
284 true
285 } else if let Self::Optional(inner_type) = self {
286 inner_type.compatible_with(other)
287 } else {
288 false
289 }
290 }
291
292 pub fn compatible_ignore_mutability_of(&self, other: &Self) -> bool {
293 if let Self::MutableReference(other_reference) = other {
294 self.compatible_with(other_reference)
295 } else {
296 self.compatible_with(other)
297 }
298 }
299
300 #[must_use]
301 pub fn compatible_with(&self, other: &Self) -> bool {
302 match (self, other) {
303 (Self::Function(a), Self::Function(b)) => a.same_type(b),
304
305 (_, Self::Never)
306 | (Self::Never, _)
307 | (Self::Int, Self::Int)
308 | (Self::Float, Self::Float)
309 | (Self::String, Self::String)
310 | (Self::Bool, Self::Bool)
311 | (Self::Unit, Self::Unit) => true,
312
313 (Self::Enum(a), Self::Enum(b)) => a == b,
314
315 (Self::NamedStruct(a), Self::NamedStruct(b)) => compare_struct_types(a, b),
316
317 (Self::AnonymousStruct(a), Self::AnonymousStruct(b)) => {
318 compare_anonymous_struct_types(a, b)
319 }
320 (Self::MutableReference(a), Self::MutableReference(b)) => a.compatible_with(b),
321
322 (Self::Tuple(a), Self::Tuple(b)) => {
323 if a.len() != b.len() {
324 return false;
325 }
326 a.iter().zip(b.iter()).all(|(a, b)| a.compatible_with(b))
327 }
328
329 (Self::Optional(inner_type_a), Self::Optional(inner_type_b)) => {
330 inner_type_a.compatible_with(inner_type_b)
331 }
332
333 (Self::Generic(blueprint_a, args_a), Self::Generic(blueprint_b, args_b)) => {
334 blueprint_a == blueprint_b && (args_a == args_b)
335 }
336
337 (
338 Self::SlicePair(a_key_type, a_value_type),
339 Self::SlicePair(b_key_type, b_value_type),
340 ) => a_key_type == b_key_type && (a_value_type == b_value_type),
341 (Self::Slice(inner_type_a), Self::Slice(inner_type_b)) => {
342 inner_type_a.compatible_with(inner_type_b)
343 }
344
345 (Self::Blueprint(a), Self::Blueprint(b)) => a == b,
346
347 (Self::Variable(a), Self::Variable(b)) => a == b,
348
349 (Self::External(type_ref_a), Self::External(type_ref_b)) => {
350 type_ref_a.number == type_ref_b.number
351 }
352
353 _ => false,
354 }
355 }
356}
357
358fn compare_struct_types(a: &NamedStructType, b: &NamedStructType) -> bool {
359 let a_borrow = a;
360 let b_borrow = b;
361
362 if a_borrow.assigned_name != b_borrow.assigned_name {
363 return false;
364 }
365
366 compare_anonymous_struct_types(&a_borrow.anon_struct_type, &b_borrow.anon_struct_type)
367}
368
369#[must_use]
370pub fn same_anon_struct_ref(a: &AnonymousStructType, b: &AnonymousStructType) -> bool {
371 compare_anonymous_struct_types(a, b)
372}
373
374pub fn same_named_struct_ref(a: &NamedStructType, b: &NamedStructType) -> bool {
375 if a.assigned_name != b.assigned_name {
376 return false;
377 }
378
379 compare_anonymous_struct_types(&a.anon_struct_type, &b.anon_struct_type)
380}
381
382#[must_use]
383pub fn compare_anonymous_struct_types(a: &AnonymousStructType, b: &AnonymousStructType) -> bool {
384 if a.field_name_sorted_fields.len() != b.field_name_sorted_fields.len() {
385 return false;
386 }
387
388 for ((a_name, a_type), (b_name, b_type)) in a
389 .field_name_sorted_fields
390 .iter()
391 .zip(b.field_name_sorted_fields.clone())
392 {
393 if *a_name != b_name {
394 return false;
395 }
396
397 if !a_type.field_type.compatible_with(&b_type.field_type) {
398 return false;
399 }
400 }
401
402 true
403}
404
405#[must_use]
406pub fn check_assignable_anonymous_struct_types(
407 a: &AnonymousStructType,
408 b: &AnonymousStructType,
409) -> bool {
410 if a.field_name_sorted_fields.len() != b.field_name_sorted_fields.len() {
411 return false;
412 }
413
414 for (name, field) in &a.field_name_sorted_fields {
415 if let Some(found_field) = b.field_name_sorted_fields.get(name) {
416 if !found_field.field_type.compatible_with(&field.field_type) {
417 return false;
418 }
419 } else {
420 return false;
421 }
422 }
423
424 true
425}
426
427#[must_use]
428pub fn comma_seq<K: Clone + Hash + Eq + Display, V: Display>(values: &SeqMap<K, V>) -> String {
429 let mut result = String::new();
430 for (i, (key, value)) in values.iter().enumerate() {
431 if i > 0 {
432 result.push_str(", ");
433 }
434 result.push_str(format!("{key}: {value}").as_str());
435 }
436 result
437}
438
439#[must_use]
440pub fn comma_seq_nl<K: Clone + Hash + Eq + Display, V: Display>(
441 values: &SeqMap<K, V>,
442 prefix: &str,
443) -> String {
444 let mut result = String::new();
445 for (key, value) in values.iter() {
446 result.push_str(format!("{prefix}{key}: {value}\n").as_str());
447 }
448 result
449}
450
451#[derive(Clone, Eq, PartialEq, Hash)]
452pub struct StructTypeField {
453 pub identifier: Option<Node>,
454 pub field_type: Type,
455}
456
457impl Display for StructTypeField {
458 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
459 write!(f, "{:?}:{}", self.identifier, self.field_type)
460 }
461}
462
463#[derive(Clone, Eq, PartialEq, Hash)]
464pub struct AnonymousStructType {
465 pub field_name_sorted_fields: SeqMap<String, StructTypeField>,
467}
468
469impl Debug for AnonymousStructType {
470 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
471 write!(f, "{}", comma_seq(&self.field_name_sorted_fields))
472 }
473}
474
475#[must_use]
476pub fn sort_struct_fields2(
477 unordered_seq_map: &SeqMap<String, StructTypeField>,
478) -> SeqMap<String, StructTypeField> {
479 let mut sorted_pairs: Vec<(&String, &StructTypeField)> = unordered_seq_map.iter().collect();
480 sorted_pairs.sort_by(|a, b| a.0.cmp(b.0));
481
482 sorted_pairs
483 .into_iter()
484 .map(|(name, field)| (name.clone(), field.clone()))
485 .collect()
486}
487
488impl AnonymousStructType {
489 #[must_use]
490 pub fn new_and_sort_fields(source_ordered_fields: &SeqMap<String, StructTypeField>) -> Self {
491 Self {
492 field_name_sorted_fields: sort_struct_fields2(source_ordered_fields),
493 }
494 }
495
496 #[must_use]
497 pub const fn new(defined_order: SeqMap<String, StructTypeField>) -> Self {
498 Self {
499 field_name_sorted_fields: defined_order,
500 }
501 }
502}
503
504#[derive(Clone, Debug, Eq, PartialEq, Hash)]
505pub struct EnumVariantStructType {
506 pub common: EnumVariantCommon,
507 pub anon_struct: AnonymousStructType,
508}
509
510#[derive(Clone, Debug, Eq, PartialEq, Hash)]
511pub struct EnumVariantTupleType {
512 pub common: EnumVariantCommon,
513 pub fields_in_order: Vec<Type>,
514}
515
516#[derive(Clone, Eq, PartialEq, Hash)]
517pub struct EnumType {
518 pub name: Node,
519 pub assigned_name: String,
520 pub module_path: Vec<String>,
521 pub variants: SeqMap<String, EnumVariantType>,
522 pub instantiated_type_parameters: Vec<Type>,
523}
524
525impl Debug for EnumType {
526 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
527 write!(f, "{}", self.assigned_name)?;
528 let s = comma(
529 &self
530 .variants
531 .iter()
532 .map(|(name, _variant)| name)
533 .collect::<Vec<&String>>(),
534 );
535 write!(f, "{{ {s} }}")
536 }
537}
538
539impl EnumType {
540 #[must_use]
541 pub fn new(name: Node, assigned_name: &str, module_path: Vec<String>) -> Self {
542 Self {
543 name,
544 assigned_name: assigned_name.to_string(),
545 module_path,
546 variants: SeqMap::new(),
547 instantiated_type_parameters: Vec::default(),
548 }
549 }
550
551 #[must_use]
552 pub const fn name(&self) -> &Node {
553 &self.name
554 }
555
556 #[must_use]
557 pub fn get_variant(&self, name: &str) -> Option<&EnumVariantType> {
558 self.variants.get(&name.to_string())
559 }
560
561 #[must_use]
562 pub fn get_variant_from_index(&self, index: usize) -> Option<&EnumVariantType> {
563 Some(self.variants.values().collect::<Vec<_>>()[index])
564 }
565}
566
567#[derive(Clone, Eq, PartialEq, Hash)]
568pub struct EnumVariantCommon {
569 pub name: Node,
570 pub assigned_name: String,
571 pub container_index: u8,
572}
573
574impl Debug for EnumVariantCommon {
575 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
576 write!(f, "{}::{}", self.assigned_name, self.assigned_name)
577 }
578}
579
580#[derive(Debug)]
581pub struct EnumVariantStructFieldType {
582 pub name: Node,
583 pub enum_variant: EnumVariantType,
584 pub resolved_type: Type,
585
586 pub field_index: usize,
587}
588
589#[derive(Debug, Eq, PartialEq)]
590pub struct EnumVariantTupleFieldType {
591 pub name: Node,
592 pub enum_variant: EnumVariantType,
593 pub resolved_type: Type,
594
595 pub field_index: usize,
596}
597
598#[derive(Clone, Debug, Eq, PartialEq, Hash)]
599pub struct EnumVariantSimpleType {
600 pub common: EnumVariantCommon,
601}
602
603#[derive(Clone, Eq, PartialEq, Hash)]
604pub enum EnumVariantType {
605 Struct(EnumVariantStructType),
606 Tuple(EnumVariantTupleType),
607 Nothing(EnumVariantSimpleType),
608}
609impl EnumVariantType {
610 #[must_use]
611 pub const fn common(&self) -> &EnumVariantCommon {
612 match self {
613 Self::Tuple(tuple) => &tuple.common,
614 Self::Struct(c) => &c.common,
615 Self::Nothing(c) => &c.common,
616 }
617 }
618}
619
620impl Debug for EnumVariantType {
621 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
622 match self {
623 Self::Struct(x) => write!(f, "{{ {x:?} }}"),
624 Self::Tuple(x) => write!(f, "({x:?})"),
625 Self::Nothing(_x) => Ok(()),
626 }
627 }
628}
629
630#[derive(Debug, Clone)]
631pub struct AliasType {
632 pub name: Node,
633 pub assigned_name: String,
634 pub referenced_type: Type,
635}
636
637#[derive(Clone, PartialEq, Eq, Hash)]
638pub struct NamedStructType {
639 pub name: Node,
640 pub module_path: Vec<String>,
641 pub assigned_name: String,
642 pub anon_struct_type: AnonymousStructType,
643 pub instantiated_type_parameters: Vec<Type>,
644 pub blueprint_info: Option<ParameterizedTypeBlueprintInfo>,
645}
646
647impl Debug for NamedStructType {
648 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
649 write!(
650 f,
651 "struct {} anon: {:?}",
652 self.assigned_name, self.anon_struct_type
653 )
654 }
655}
656
657impl NamedStructType {
658 #[must_use]
659 pub fn new(
660 name: Node,
661 assigned_name: &str,
662 anon_struct_type: AnonymousStructType,
663 module_path: &[String],
664 blueprint_info: Option<ParameterizedTypeBlueprintInfo>,
665 ) -> Self {
666 Self {
667 anon_struct_type,
669 name,
670 module_path: module_path.to_vec(),
671 assigned_name: assigned_name.to_string(),
672 instantiated_type_parameters: Vec::default(),
673 blueprint_info,
674 }
675 }
676
677 #[must_use]
678 pub fn field_index(&self, field_name: &str) -> Option<usize> {
679 self.anon_struct_type
680 .field_name_sorted_fields
681 .get_index(&field_name.to_string())
682 }
683
684 #[must_use]
685 pub const fn name(&self) -> &Node {
686 &self.name
687 }
688}
689
690pub fn all_types_are_concrete(types: &[Type]) -> bool {
691 for ty in types {
692 if !ty.is_concrete() {
693 return false;
694 }
695 }
696 true
697}
698
699pub fn all_types_are_concrete_or_unit(types: &[Type]) -> bool {
700 for ty in types {
701 if !ty.is_concrete() && *ty != Type::Unit {
702 return false;
703 }
704 }
705 true
706}
707
708pub fn all_types_are_variables(types: &[Type]) -> bool {
709 for ty in types {
710 if let Type::Variable(_) = ty {
711 } else {
712 return false;
713 }
714 }
715 true
716}