1use crate::err::{Error, ErrorKind};
6use crate::{Analyzer, TypeContext};
7use source_map_node::Node;
8use swamp_semantic::ExpressionKind;
9use swamp_semantic::{ArgumentExpressionOrLocation, EnumLiteralData, Expression, Fp, Literal};
10use swamp_types::prelude::*;
11
12impl Analyzer<'_> {
13 #[allow(clippy::too_many_lines)]
18 pub fn analyze_complex_literal_to_expression(
19 &mut self,
20 ast_node: &swamp_ast::Node,
21 ast_literal_kind: &swamp_ast::LiteralKind,
22 context: &TypeContext,
23 ) -> Result<Expression, Error> {
24 let expression = match &ast_literal_kind {
25 swamp_ast::LiteralKind::Slice(items) => {
26 let (encountered_element_type, resolved_items) =
27 self.analyze_slice_type_helper(ast_node, items)?;
28
29 let slice_type = Type::Slice(Box::new(encountered_element_type.clone()));
30
31 let found_expected_type = if let Some(inner_type) = context.expected_type {
32 inner_type.clone()
33 } else {
34 let vec_blueprint = self
35 .shared
36 .core_symbol_table
37 .get_blueprint("Vec")
38 .unwrap()
39 .clone();
40 self.shared
41 .state
42 .instantiator
43 .instantiate_blueprint_and_members(
44 &vec_blueprint,
45 &[encountered_element_type],
46 )?
47 };
48
49 if let Some(found) = self
50 .shared
51 .state
52 .instantiator
53 .associated_impls
54 .get_internal_member_function(&found_expected_type, "new_from_slice")
55 {
56 let required_type = &found.signature.signature.parameters[0].resolved_type;
57 if resolved_items.is_empty() || slice_type.compatible_with(required_type) {
58 let slice_literal = Literal::Slice(slice_type.clone(), resolved_items);
59
60 let expr = self.create_expr(
61 ExpressionKind::Literal(slice_literal),
62 slice_type,
63 ast_node,
64 );
65 let return_type = *found.signature.signature.return_type.clone();
66 let arg = ArgumentExpressionOrLocation::Expression(expr);
67 let call_kind = self.create_static_call(
68 "new_from_slice",
69 &[arg],
70 ast_node,
71 &found_expected_type.clone(),
72 )?;
73
74 self.create_expr(call_kind, return_type, ast_node)
75 } else {
76 return Err(self.create_err(
77 ErrorKind::IncompatibleTypes {
78 expected: required_type.clone(),
79 found: slice_type,
80 },
81 ast_node,
82 ));
83 }
84 } else {
85 return Err(self.create_err(
86 ErrorKind::MissingMemberFunction("new_from_slice".to_string()),
87 ast_node,
88 ));
89 }
90 }
91
92 swamp_ast::LiteralKind::SlicePair(entries) => {
93 let (resolved_items, encountered_key_type, encountered_value_type) =
94 self.analyze_slice_pair_literal(ast_node, entries)?;
95
96 let slice_pair_type = Type::SlicePair(
97 Box::new(encountered_key_type.clone()),
98 Box::new(encountered_value_type.clone()),
99 );
100
101 let found_expected_type = if let Some(inner_type) = context.expected_type {
102 inner_type.clone()
103 } else {
104 let map_blueprint = self
105 .shared
106 .core_symbol_table
107 .get_blueprint("Map")
108 .unwrap()
109 .clone();
110 self.shared
111 .state
112 .instantiator
113 .instantiate_blueprint_and_members(
114 &map_blueprint,
115 &[encountered_key_type, encountered_value_type],
116 )?
117 };
118
119 if let Some(found) = self
120 .shared
121 .state
122 .instantiator
123 .associated_impls
124 .get_internal_member_function(&found_expected_type, "new_from_slice_pair")
125 {
126 let required_type = &found.signature.signature.parameters[0].resolved_type;
127 if resolved_items.is_empty() || slice_pair_type.compatible_with(required_type) {
128 let slice_literal =
129 Literal::SlicePair(slice_pair_type.clone(), resolved_items);
130
131 let expr = self.create_expr(
132 ExpressionKind::Literal(slice_literal),
133 slice_pair_type,
134 ast_node,
135 );
136 let return_type = *found.signature.signature.return_type.clone();
137 let arg = ArgumentExpressionOrLocation::Expression(expr);
138 let call_kind = self.create_static_call(
139 "new_from_slice_pair",
140 &[arg],
141 ast_node,
142 &found_expected_type.clone(),
143 )?;
144
145 self.create_expr(call_kind, return_type, ast_node)
146 } else {
147 return Err(self.create_err(
148 ErrorKind::IncompatibleTypes {
149 expected: required_type.clone(),
150 found: slice_pair_type,
151 },
152 ast_node,
153 ));
154 }
155 } else {
156 return Err(self.create_err(
157 ErrorKind::MissingMemberFunction("new_from_slice_pair".to_string()),
158 ast_node,
159 ));
160 }
161 }
162
163 _ => {
164 let (lit_kind, literal_type) =
165 self.analyze_literal(ast_node, ast_literal_kind, context)?;
166 self.create_expr(ExpressionKind::Literal(lit_kind), literal_type, ast_node)
167 }
168 };
169
170 Ok(expression)
171 }
172
173 #[allow(clippy::too_many_lines)]
174 pub(crate) fn analyze_literal(
175 &mut self,
176 ast_node: &swamp_ast::Node,
177 ast_literal_kind: &swamp_ast::LiteralKind,
178 context: &TypeContext,
179 ) -> Result<(Literal, Type), Error> {
180 let node_text = self.get_text(ast_node);
181 let resolved_literal = match &ast_literal_kind {
182 swamp_ast::LiteralKind::Int => (
183 Literal::IntLiteral(Self::str_to_int(node_text).map_err(|int_conversion_err| {
184 self.create_err(ErrorKind::IntConversionError(int_conversion_err), ast_node)
185 })?),
186 Type::Int,
187 ),
188 swamp_ast::LiteralKind::Float => {
189 let float = Self::str_to_float(node_text).map_err(|float_conversion_err| {
190 self.create_err(
191 ErrorKind::FloatConversionError(float_conversion_err),
192 ast_node,
193 )
194 })?;
195 (Literal::FloatLiteral(Fp::from(float)), Type::Float)
196 }
197 swamp_ast::LiteralKind::String(processed_string) => (
198 Literal::StringLiteral(processed_string.to_string()),
199 Type::String,
200 ),
201 swamp_ast::LiteralKind::Bool => {
202 let bool_val = if node_text == "false" {
203 false
204 } else if node_text == "true" {
205 true
206 } else {
207 return Err(self.create_err(ErrorKind::BoolConversionError, ast_node));
208 };
209 (Literal::BoolLiteral(bool_val), Type::Bool)
210 }
211 swamp_ast::LiteralKind::EnumVariant(enum_literal) => {
212 let (enum_name, variant_name) = match enum_literal {
213 swamp_ast::EnumVariantLiteral::Simple(enum_name, variant_name) => {
214 (enum_name, variant_name)
215 }
216 swamp_ast::EnumVariantLiteral::Tuple(enum_name, variant_name, _) => {
217 (enum_name, variant_name)
218 }
219 swamp_ast::EnumVariantLiteral::Struct(enum_name, variant_name, _, _) => {
220 (enum_name, variant_name)
221 }
222 };
223
224 let (symbol_table, name) = self.get_symbol_table_and_name(enum_name)?;
225 if let Some(enum_type_ref) = symbol_table.get_enum(&name) {
226 let enum_type_clone = enum_type_ref.clone();
227 let enum_type = Type::Enum(enum_type_ref.clone());
228
229 let variant_ref = self.analyze_enum_variant_ref(enum_name, variant_name)?;
231
232 let resolved_data = match enum_literal {
233 swamp_ast::EnumVariantLiteral::Simple(_, _) => EnumLiteralData::Nothing,
234 swamp_ast::EnumVariantLiteral::Tuple(_node, _variant, ast_expressions) => {
235 let EnumVariantType::Tuple(tuple_data) = &variant_ref else {
236 return Err(self.create_err(
237 ErrorKind::WrongEnumVariantContainer(variant_ref),
238 ast_node,
239 ));
240 };
241
242 let resolved = self.analyze_tuple_type(
243 enum_literal.node(),
244 &tuple_data.fields_in_order,
245 ast_expressions,
246 )?;
247 EnumLiteralData::Tuple(resolved)
248 }
249 swamp_ast::EnumVariantLiteral::Struct(
250 _qualified_type_identifier,
251 variant,
252 anonym_struct_field_and_expressions,
253 detected_rest,
254 ) => {
255 if let EnumVariantType::Struct(ref resolved_variant_struct_ref) =
256 variant_ref
257 {
258 if anonym_struct_field_and_expressions.len()
259 != resolved_variant_struct_ref
260 .anon_struct
261 .field_name_sorted_fields
262 .len()
263 {
264 return Err(self.create_err(
265 ErrorKind::WrongNumberOfArguments(
266 anonym_struct_field_and_expressions.len(),
267 resolved_variant_struct_ref
268 .anon_struct
269 .field_name_sorted_fields
270 .len(),
271 ),
272 &variant.0,
273 ));
274 }
275
276 let resolved = self.analyze_anon_struct_instantiation(
277 &variant.0.clone(),
278 &resolved_variant_struct_ref.anon_struct,
279 anonym_struct_field_and_expressions,
280 *detected_rest,
281 )?;
282
283 EnumLiteralData::Struct(resolved)
284 } else {
285 return Err(self.create_err(
286 ErrorKind::WrongEnumVariantContainer(variant_ref.clone()),
287 &variant.0,
288 ));
289 }
290 }
291 };
292
293 return Ok((
294 Literal::EnumVariantLiteral(enum_type_clone, variant_ref, resolved_data),
295 enum_type,
296 ));
297 }
298 return Err(self.create_err(ErrorKind::UnknownEnumType, ast_node));
299 }
300
301 swamp_ast::LiteralKind::Tuple(expressions) => {
302 let (tuple_type_ref, resolved_items) = self.analyze_tuple_literal(expressions)?;
303 (
304 Literal::TupleLiteral(tuple_type_ref.clone(), resolved_items),
305 Type::Tuple(tuple_type_ref),
306 )
307 }
308 swamp_ast::LiteralKind::None => {
309 if let Some(found_expected_type) = context.expected_type {
310 if let Type::Optional(_some_type) = found_expected_type {
311 return Ok((Literal::NoneLiteral, found_expected_type.clone()));
312 }
313 }
314 return Err(self.create_err(ErrorKind::NoneNeedsExpectedTypeHint, ast_node));
315 }
316 &&swamp_ast::LiteralKind::Slice(_) | &swamp_ast::LiteralKind::SlicePair(_) => todo!(),
317 };
318
319 Ok(resolved_literal)
320 }
321
322 fn analyze_tuple_literal(
323 &mut self,
324 items: &[swamp_ast::Expression],
325 ) -> Result<(Vec<Type>, Vec<Expression>), Error> {
326 let expressions = self.analyze_argument_expressions(None, items)?;
327 let mut tuple_types = Vec::new();
328 for expr in &expressions {
329 let item_type = expr.ty.clone();
330 tuple_types.push(item_type);
331 }
332
333 Ok((tuple_types, expressions))
334 }
335
336 fn analyze_tuple_type(
337 &mut self,
338 node: &swamp_ast::Node,
339 expected_types: &[Type],
340 ast_expressions: &Vec<swamp_ast::Expression>,
341 ) -> Result<Vec<Expression>, Error> {
342 if ast_expressions.len() != expected_types.len() {
343 return Err(self.create_err(ErrorKind::WrongNumberOfArguments(0, 0), node));
344 }
345
346 let mut expressions = Vec::new();
347 for (expected_type, expr) in expected_types.iter().zip(ast_expressions) {
348 let context = TypeContext::new_argument(expected_type);
349 let resolved_expr = self.analyze_expression(expr, &context)?;
350 expressions.push(resolved_expr);
351 }
352
353 Ok(expressions)
354 }
355
356 fn analyze_slice_pair_literal(
357 &mut self,
358 node: &swamp_ast::Node,
359 entries: &[(swamp_ast::Expression, swamp_ast::Expression)],
360 ) -> Result<(Vec<(Expression, Expression)>, Type, Type), Error> {
361 if entries.is_empty() {
362 return Ok((vec![], Type::Unit, Type::Unit));
363 }
364
365 let (first_key, first_value) = &entries[0];
367 let anything_context = TypeContext::new_anything_argument();
368 let resolved_first_key = self.analyze_expression(first_key, &anything_context)?;
369 let resolved_first_value = self.analyze_expression(first_value, &anything_context)?;
370 let key_type = resolved_first_key.ty.clone();
371 let value_type = resolved_first_value.ty.clone();
372
373 let key_context = TypeContext::new_argument(&key_type);
374 let value_context = TypeContext::new_argument(&value_type);
375
376 let mut resolved_entries = Vec::new();
378 resolved_entries.push((resolved_first_key, resolved_first_value));
379
380 for (key, value) in entries.iter().skip(1) {
381 let resolved_key = self.analyze_expression(key, &key_context)?;
382 let resolved_value = self.analyze_expression(value, &value_context)?;
383
384 if !resolved_key.ty.compatible_with(&key_type) {
385 return Err(self.create_err(
386 ErrorKind::MapKeyTypeMismatch {
387 expected: key_type,
388 found: resolved_key.ty,
389 },
390 node,
391 ));
392 }
393
394 if !resolved_value.ty.compatible_with(&value_type) {
395 return Err(self.create_err(
396 ErrorKind::MapValueTypeMismatch {
397 expected: value_type,
398 found: resolved_value.ty,
399 },
400 node,
401 ));
402 }
403
404 resolved_entries.push((resolved_key, resolved_value));
405 }
406
407 Ok((resolved_entries, key_type, value_type))
408 }
409
410 #[must_use]
411 pub const fn create_err(&self, kind: ErrorKind, ast_node: &swamp_ast::Node) -> Error {
412 Error {
413 node: self.to_node(ast_node),
414 kind,
415 }
416 }
417
418 #[must_use]
419 pub fn create_err_resolved(&self, kind: ErrorKind, resolved_node: &Node) -> Error {
420 Error {
421 node: resolved_node.clone(),
422 kind,
423 }
424 }
425}