swamp_analyzer/
types.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/swamp
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5use crate::Analyzer;
6use swamp_types::TypeRef;
7use swamp_types::prelude::{Signature, TypeForParameter};
8
9impl Analyzer<'_> {
10    /// # Errors
11    ///
12    pub fn analyze_map_type(
13        &mut self,
14        ast_key_type: &swamp_ast::Type,
15        ast_value_type: &swamp_ast::Type,
16    ) -> (TypeRef, TypeRef) {
17        let key_type = self.analyze_type(ast_key_type);
18        let value_type = self.analyze_type(ast_value_type);
19
20        // Using TypeCache to ensure proper type comparison and creation
21        (key_type, value_type)
22    }
23
24    /// # Errors
25    ///
26    pub fn analyze_key_and_value_type(
27        &mut self,
28        ast_key_type: &swamp_ast::Type,
29        ast_value_type: &swamp_ast::Type,
30    ) -> (TypeRef, TypeRef) {
31        let key_type = self.analyze_type(ast_key_type);
32        let value_type = self.analyze_type(ast_value_type);
33
34        // Using TypeCache to ensure proper type comparison and creation
35        (key_type, value_type)
36    }
37
38    /// # Errors
39    ///
40    /// # Panics
41    pub fn analyze_type(&mut self, ast_type: &swamp_ast::Type) -> TypeRef {
42        match ast_type {
43            swamp_ast::Type::AnonymousStruct(ast_struct) => {
44                let struct_ref = self.analyze_anonymous_struct_type(ast_struct);
45                // Use TypeCache to create the anonymous struct type
46                let anon_struct_type = self.shared.state.types.anonymous_struct(struct_ref);
47
48                // Generate default functions for the new anonymous struct type
49                let default_node = swamp_ast::Node::default();
50                self.add_default_functions(&anon_struct_type, &default_node);
51
52                anon_struct_type
53            }
54            swamp_ast::Type::FixedCapacityArray(ast_type, fixed_size) => {
55                let element_type = self.analyze_type(ast_type);
56                let int_str = self.get_text(fixed_size);
57                let int_value = Self::str_to_unsigned_int(int_str).unwrap() as usize;
58
59                // Use TypeCache for fixed array creation
60                let array_type = self
61                    .shared
62                    .state
63                    .types
64                    .fixed_array(&element_type, int_value);
65
66                // Generate default functions for the new array type
67                self.add_default_functions(&array_type, fixed_size);
68
69                array_type
70            }
71            swamp_ast::Type::Slice(ast_type) => {
72                let element_type = self.analyze_type(ast_type);
73                // Use TypeCache for slice view creation
74                let slice_type = self.shared.state.types.slice_view(&element_type);
75
76                // Generate default functions for the new slice type
77                let default_node = swamp_ast::Node::default();
78                self.add_default_functions(&slice_type, &default_node);
79
80                slice_type
81            }
82
83            swamp_ast::Type::FixedCapacityMap(ast_key_type, ast_value_type, fixed_size) => {
84                let (key_type, value_type) =
85                    self.analyze_key_and_value_type(ast_key_type, ast_value_type);
86
87                let int_str = self.get_text(fixed_size);
88                let int_value = Self::str_to_unsigned_int(int_str).unwrap() as usize;
89
90                // Use TypeCache for map storage creation
91                let map_type =
92                    self.shared
93                        .state
94                        .types
95                        .map_storage(&key_type, &value_type, int_value);
96
97                // Generate default functions for the new map type
98                self.add_default_functions(&map_type, fixed_size);
99
100                map_type
101            }
102            swamp_ast::Type::DynamicLengthMap(ast_key_type, ast_value_type) => {
103                let (key_type, value_type) =
104                    self.analyze_key_and_value_type(ast_key_type, ast_value_type);
105
106                // Use TypeCache for dynamic map view creation
107                let map_view_type = self
108                    .shared
109                    .state
110                    .types
111                    .dynamic_map_view(&key_type, &value_type);
112
113                // Generate default functions for the new map view type
114                let default_node = swamp_ast::Node::default();
115                self.add_default_functions(&map_view_type, &default_node);
116
117                map_view_type
118            }
119
120            swamp_ast::Type::Tuple(types) => {
121                let analyzed_types = self.analyze_types(types);
122                // Use TypeCache for tuple creation
123                let tuple_type = self.shared.state.types.tuple(analyzed_types);
124
125                // Generate default functions for the new tuple type
126                let default_node = swamp_ast::Node::default();
127                self.add_default_functions(&tuple_type, &default_node);
128
129                tuple_type
130            }
131            swamp_ast::Type::Named(ast_type_reference) => {
132                // Named types need to be analyzed through the TypeCache as well
133                self.analyze_named_type(ast_type_reference)
134            }
135            swamp_ast::Type::Unit => self.shared.state.types.unit(),
136            swamp_ast::Type::Optional(inner_type_ast, _node) => {
137                let inner_resolved_type = self.analyze_type(inner_type_ast);
138                // Use TypeCache for optional type creation
139                let optional_type = self.shared.state.types.optional(&inner_resolved_type);
140
141                // Generate default functions for the new optional type
142                let default_node = swamp_ast::Node::default();
143                self.add_default_functions(&optional_type, &default_node);
144
145                optional_type
146            }
147            swamp_ast::Type::Function(parameters, return_type) => {
148                let parameter_types = self.analyze_param_types(parameters);
149
150                let resolved_return_type = self.analyze_type(return_type);
151                let signature = Signature {
152                    parameters: parameter_types,
153                    return_type: resolved_return_type,
154                };
155                // Use TypeCache for function type creation
156                self.shared.state.types.function(signature)
157            }
158        }
159    }
160
161    pub(crate) fn analyze_types(&mut self, types: &[swamp_ast::Type]) -> Vec<TypeRef> {
162        let mut resolved_types = Vec::new();
163        for some_type in types {
164            resolved_types.push(self.analyze_type(some_type));
165        }
166        resolved_types
167    }
168
169    fn analyze_param_types(
170        &mut self,
171        type_for_parameters: &Vec<swamp_ast::TypeForParameter>,
172    ) -> Vec<TypeForParameter> {
173        let mut vec = Vec::new();
174        for x in type_for_parameters {
175            vec.push(TypeForParameter {
176                name: String::new(),
177                // Use TypeCache to ensure the resolved type is properly created
178                resolved_type: self.analyze_type(&x.ast_type),
179                is_mutable: x.is_mutable,
180                node: None,
181            });
182        }
183
184        vec
185    }
186}