1use crate::Analyzer;
6use swamp_types::TypeRef;
7use swamp_types::prelude::{Signature, TypeForParameter};
8
9#[derive(Default)]
10pub(crate) struct TypeAnalyzeContext {
11 pub is_analyzing_type_in_parameter_context: bool,
12}
13
14impl TypeAnalyzeContext {
15 pub(crate) const fn new_parameter_context() -> Self {
16 Self {
17 is_analyzing_type_in_parameter_context: true,
18 }
19 }
20
21 pub const fn is_analyzing_a_parameter_type(&self) -> bool {
22 self.is_analyzing_type_in_parameter_context
23 }
24}
25
26impl Analyzer<'_> {
27 pub fn analyze_map_type(
30 &mut self,
31 ast_key_type: &swamp_ast::Type,
32 ast_value_type: &swamp_ast::Type,
33 ) -> (TypeRef, TypeRef) {
34 let key_type = self.analyze_type(ast_key_type, &TypeAnalyzeContext::default());
35 let value_type = self.analyze_type(ast_value_type, &TypeAnalyzeContext::default());
36
37 (key_type, value_type)
39 }
40
41 pub fn analyze_key_and_value_type(
44 &mut self,
45 ast_key_type: &swamp_ast::Type,
46 ast_value_type: &swamp_ast::Type,
47 ) -> (TypeRef, TypeRef) {
48 let key_type = self.analyze_type(ast_key_type, &TypeAnalyzeContext::default());
49 let value_type = self.analyze_type(ast_value_type, &TypeAnalyzeContext::default());
50
51 (key_type, value_type)
53 }
54
55 pub fn analyze_type(
59 &mut self,
60 ast_type: &swamp_ast::Type,
61 ctx: &TypeAnalyzeContext,
62 ) -> TypeRef {
63 match ast_type {
64 swamp_ast::Type::AnonymousStruct(ast_struct) => {
65 let struct_ref = self.analyze_anonymous_struct_type(ast_struct, ctx);
66 let anon_struct_type = self.shared.state.types.anonymous_struct(struct_ref);
68
69 let default_node = swamp_ast::Node::default();
71 self.add_default_functions(&anon_struct_type, &default_node);
72
73 anon_struct_type
74 }
75 swamp_ast::Type::FixedCapacityArray(ast_type, fixed_size) => {
76 let element_type = self.analyze_type(ast_type, &TypeAnalyzeContext::default());
77 let int_str = self.get_text(fixed_size);
78 let int_value = Self::str_to_unsigned_int(int_str).unwrap() as usize;
79
80 let array_type = self
82 .shared
83 .state
84 .types
85 .fixed_array(&element_type, int_value);
86
87 self.add_default_functions(&array_type, fixed_size);
89
90 array_type
91 }
92 swamp_ast::Type::Slice(ast_type) => {
93 let element_type = self.analyze_type(ast_type, &TypeAnalyzeContext::default());
94 let slice_type = self.shared.state.types.slice_view(&element_type);
96
97 let default_node = swamp_ast::Node::default();
99 self.add_default_functions(&slice_type, &default_node);
100
101 slice_type
102 }
103
104 swamp_ast::Type::FixedCapacityMap(ast_key_type, ast_value_type, fixed_size) => {
105 let (key_type, value_type) =
106 self.analyze_key_and_value_type(ast_key_type, ast_value_type);
107
108 let int_str = self.get_text(fixed_size);
109 let int_value = Self::str_to_unsigned_int(int_str).unwrap() as usize;
110
111 let map_type =
113 self.shared
114 .state
115 .types
116 .map_storage(&key_type, &value_type, int_value);
117
118 self.add_default_functions(&map_type, fixed_size);
120
121 map_type
122 }
123 swamp_ast::Type::DynamicLengthMap(ast_key_type, ast_value_type) => {
124 let (key_type, value_type) =
125 self.analyze_key_and_value_type(ast_key_type, ast_value_type);
126
127 let map_view_type = self
129 .shared
130 .state
131 .types
132 .dynamic_map_view(&key_type, &value_type);
133
134 let default_node = swamp_ast::Node::default();
136 self.add_default_functions(&map_view_type, &default_node);
137
138 map_view_type
139 }
140
141 swamp_ast::Type::Tuple(types) => {
142 let analyzed_types = self.analyze_types(types, &TypeAnalyzeContext::default());
143 let tuple_type = self.shared.state.types.tuple(analyzed_types);
145
146 let default_node = swamp_ast::Node::default();
148 self.add_default_functions(&tuple_type, &default_node);
149
150 tuple_type
151 }
152 swamp_ast::Type::Named(ast_type_reference) => {
153 self.analyze_named_type(ast_type_reference)
155 }
156 swamp_ast::Type::Unit => self.shared.state.types.unit(),
157 swamp_ast::Type::Never => self.shared.state.types.never(),
158 swamp_ast::Type::Optional(inner_type_ast, _node) => {
159 let inner_resolved_type =
160 self.analyze_type(inner_type_ast, &TypeAnalyzeContext::default());
161 let optional_type = self.shared.state.types.optional(&inner_resolved_type);
163
164 let default_node = swamp_ast::Node::default();
166 self.add_default_functions(&optional_type, &default_node);
167
168 optional_type
169 }
170 swamp_ast::Type::Function(parameters, return_type) => {
171 let parameter_types = self.analyze_param_types(parameters);
172
173 let resolved_return_type = self.analyze_type(return_type, ctx);
174 let signature = Signature {
175 parameters: parameter_types,
176 return_type: resolved_return_type,
177 };
178 self.shared.state.types.function(signature)
180 }
181 }
182 }
183
184 pub(crate) fn analyze_types(
185 &mut self,
186 types: &[swamp_ast::Type],
187 ctx: &TypeAnalyzeContext,
188 ) -> Vec<TypeRef> {
189 let mut resolved_types = Vec::new();
190 for some_type in types {
191 resolved_types.push(self.analyze_type(some_type, ctx));
192 }
193 resolved_types
194 }
195
196 fn analyze_param_types(
197 &mut self,
198 type_for_parameters: &Vec<swamp_ast::TypeForParameter>,
199 ) -> Vec<TypeForParameter> {
200 let mut vec = Vec::new();
201 for x in type_for_parameters {
202 vec.push(TypeForParameter {
203 name: String::new(),
204 resolved_type: self.analyze_type(&x.ast_type, &TypeAnalyzeContext::default()),
206 is_mutable: x.is_mutable,
207 node: None,
208 });
209 }
210
211 vec
212 }
213}