1use crate::{Analyzer, TypeContext};
6use seq_map::SeqMap;
7use seq_set::SeqSet;
8use source_map_node::Node;
9use std::collections::HashSet;
10use swamp_semantic::err::ErrorKind;
11use swamp_semantic::{
12 AnonymousStructLiteral, Expression, ExpressionKind, FunctionRef, Postfix, PostfixKind,
13 StartOfChain, StartOfChainKind,
14};
15use swamp_symbol::{Symbol, SymbolKind};
16use swamp_types::prelude::*;
17
18impl Analyzer<'_> {
19 fn analyze_struct_init_calling_default(
20 &mut self,
21 function: &FunctionRef,
22 super_type: &TypeRef,
23 anon_struct_type: &AnonymousStructType,
24 mut source_order_expressions: Vec<(usize, Option<Node>, Expression)>,
25 node: &swamp_ast::Node,
26 ) -> Expression {
27 let mut provided_field_indices = HashSet::new();
35 for (field_index, _, _) in &source_order_expressions {
36 provided_field_indices.insert(*field_index);
37 }
38
39 let default_call = self.create_default_static_call(node, super_type);
41 let default_struct_expr = self.create_expr(default_call, super_type.clone(), node);
42
43 for (field_index, (_field_name, field_info)) in
45 anon_struct_type.field_name_sorted_fields.iter().enumerate()
46 {
47 if !provided_field_indices.contains(&field_index) {
48 let start_of_chain = StartOfChain {
50 kind: StartOfChainKind::Expression(Box::new(default_struct_expr.clone())),
51 node: self.to_node(node),
52 };
53 let postfixes = vec![Postfix {
54 kind: PostfixKind::StructField(super_type.clone(), field_index),
55 ty: field_info.field_type.clone(),
56 node: self.to_node(node),
57 }];
58
59 let field_access_expr = self.create_expr(
60 ExpressionKind::PostfixChain(start_of_chain, postfixes),
61 field_info.field_type.clone(),
62 node,
63 );
64
65 source_order_expressions.push((
66 field_index,
67 field_info.identifier.clone(),
68 field_access_expr,
69 ));
70 }
71 }
72
73 self.create_expr(
75 ExpressionKind::AnonymousStructLiteral(AnonymousStructLiteral {
76 struct_like_type: Self::get_struct_like_type(super_type),
77 source_order_expressions,
78 }),
79 super_type.clone(),
80 node,
81 )
82 }
83
84 fn get_struct_like_type(ty: &TypeRef) -> TypeRef {
85 ty.clone()
86 }
87
88 fn analyze_struct_init_field_by_field(
89 &mut self,
90 borrowed_anon_type: &AnonymousStructType,
91 mut source_order_expressions: Vec<(usize, Option<Node>, Expression)>,
92 missing_fields: SeqSet<String>,
93 result_type: &TypeRef,
94 node: &swamp_ast::Node,
95 ) -> Expression {
96 {
97 for missing_field_name in missing_fields {
98 let field = borrowed_anon_type
99 .field_name_sorted_fields
100 .get(&missing_field_name)
101 .expect("verified");
102 let field_index = borrowed_anon_type
103 .field_name_sorted_fields
104 .get_index(&missing_field_name)
105 .expect("verified");
106
107 if let Some(expression) =
109 self.create_default_value_for_type(node, &field.field_type)
110 {
111 source_order_expressions.push((
112 field_index,
113 field.identifier.clone(),
114 expression,
115 ));
116 }
117 }
119 }
120
121 self.create_expr(
122 ExpressionKind::AnonymousStructLiteral(AnonymousStructLiteral {
123 struct_like_type: Self::get_struct_like_type(result_type),
124 source_order_expressions: source_order_expressions.clone(),
125 }),
126 result_type.clone(),
127 node,
128 )
129 }
130
131 pub fn deduce_the_anon_struct_type(
132 &mut self,
133 ast_fields: &Vec<swamp_ast::FieldExpression>,
134 context: &TypeContext,
135 ) -> AnonymousStructType {
136 let mut map_for_creating_type = SeqMap::new();
137
138 for field in ast_fields {
139 let field_name = self.get_text(&field.field_name.0).to_string();
140 let resolved_node = self.to_node(&field.field_name.0);
141
142 let field_type_context = TypeContext::new_anything_argument(true);
143 let resolved_expression =
144 self.analyze_expression(&field.expression, &field_type_context);
145
146 let expression_type = resolved_expression.ty.clone();
147
148 let symbol_id = self.shared.state.symbol_id_allocator.alloc_top_level();
149 self.shared.state.symbols.insert_top(
150 symbol_id,
151 Symbol {
152 id: symbol_id.into(),
153 kind: SymbolKind::AnonStructField,
154 source_map_node: Default::default(),
155 name: Default::default(),
156 },
157 );
158
159 let field = StructTypeField {
160 symbol_id,
161 identifier: Some(resolved_node),
162 field_type: expression_type,
163 };
164
165 map_for_creating_type
166 .insert(field_name.clone(), field)
167 .expect("insert");
168 }
169
170 AnonymousStructType::new_and_sort_fields(&map_for_creating_type)
173 }
174
175 pub fn analyze_anonymous_struct_literal(
180 &mut self,
181 node: &swamp_ast::Node,
182 ast_fields: &Vec<swamp_ast::FieldExpression>,
183 rest_was_specified: bool,
184 context: &TypeContext,
185 ) -> Expression {
186 let (super_type, anon_struct_type) = if let Some(expected_type) = context.expected_type {
189 match &*expected_type.kind {
190 TypeKind::NamedStruct(named_struct_type) => {
191 if let TypeKind::AnonymousStruct(anon_struct) =
193 &*named_struct_type.anon_struct_type.kind
194 {
195 (expected_type, anon_struct)
196 } else {
197 return self
198 .create_err(ErrorKind::CouldNotCoerceTo(expected_type.clone()), node);
199 }
200 }
201 TypeKind::AnonymousStruct(anonymous_struct_type) => {
202 (expected_type, anonymous_struct_type)
203 }
204 _ => {
205 return self
206 .create_err(ErrorKind::CouldNotCoerceTo(expected_type.clone()), node);
207 }
208 }
209 } else {
210 let deduced_anon_struct_type = self.deduce_the_anon_struct_type(ast_fields, context);
211 let anon_struct_type_ref = self
212 .shared
213 .state
214 .types
215 .anonymous_struct(deduced_anon_struct_type.clone());
216
217 self.add_default_functions(&anon_struct_type_ref, node);
219
220 return self.analyze_struct_init(
222 node,
223 &anon_struct_type_ref,
224 &deduced_anon_struct_type,
225 ast_fields,
226 rest_was_specified,
227 );
228 };
229
230 self.analyze_struct_init(
232 node,
233 super_type,
234 anon_struct_type,
235 ast_fields,
236 rest_was_specified,
237 )
238 }
239
240 pub(crate) fn analyze_named_struct_literal(
241 &mut self,
242 qualified_type_identifier: &swamp_ast::QualifiedTypeIdentifier,
243 ast_fields: &Vec<swamp_ast::FieldExpression>,
244 rest_was_specified: bool,
245 context: &TypeContext,
246 ) -> Expression {
247 if qualified_type_identifier.module_path.is_none()
248 && let Some(expected_type) = context.expected_type
249 && let TypeKind::Enum(found_enum_type) = &*expected_type.kind
250 {
251 let named_struct_or_variant = self.get_text(&qualified_type_identifier.name.0);
252 if let Some(found_variant) = found_enum_type.get_variant(named_struct_or_variant)
253 && matches!(
254 *found_variant.payload_type.kind,
255 TypeKind::AnonymousStruct(_)
256 )
257 {
258 return self.analyze_enum_variant_struct_literal(
259 found_variant,
260 expected_type,
261 ast_fields,
262 rest_was_specified,
263 &qualified_type_identifier.name.0,
264 );
265 }
266 }
267
268 let named_struct_type = self.get_struct_type(qualified_type_identifier);
269 let sem_node = self.to_node(&qualified_type_identifier.name.0);
270
271 self.shared
272 .state
273 .refs
274 .add(named_struct_type.symbol_id.into(), sem_node);
275
276 let super_type = self
277 .shared
278 .state
279 .types
280 .named_struct(named_struct_type.clone());
281
282 if let TypeKind::AnonymousStruct(anon_struct) = &*named_struct_type.anon_struct_type.kind {
283 let anon_expr = self.analyze_struct_init(
284 &qualified_type_identifier.name.0,
285 &super_type,
286 anon_struct,
287 ast_fields,
288 rest_was_specified,
289 );
290 let ty = anon_expr.ty.clone();
291
292 self.create_expr(
293 ExpressionKind::NamedStructLiteral(Box::from(anon_expr)),
294 ty,
295 &qualified_type_identifier.name.0,
296 )
297 } else {
298 self.create_err(
299 ErrorKind::UnknownStructTypeReference,
300 &qualified_type_identifier.name.0,
301 )
302 }
303 }
304
305 fn analyze_struct_init(
306 &mut self,
307 node: &swamp_ast::Node,
308 super_type: &TypeRef,
309 anon_struct_type: &AnonymousStructType,
310 ast_fields: &Vec<swamp_ast::FieldExpression>,
311 rest_was_specified: bool,
312 ) -> Expression {
313 let (source_order_expressions, missing_fields) = self
314 .place_anon_struct_fields_that_exist_and_return_missing(anon_struct_type, ast_fields);
315
316 if missing_fields.is_empty() {
317 self.create_expr(
319 ExpressionKind::AnonymousStructLiteral(AnonymousStructLiteral {
320 struct_like_type: Self::get_struct_like_type(super_type),
321 source_order_expressions,
322 }),
323 super_type.clone(),
324 node,
325 )
326 } else {
327 if rest_was_specified {
329 self.make_solution_for_missing_fields(
330 node,
331 super_type,
332 anon_struct_type,
333 source_order_expressions,
334 missing_fields,
335 )
336 } else {
337 self.create_err(
338 ErrorKind::MissingFieldInStructInstantiation(
339 missing_fields.to_vec(),
340 anon_struct_type.clone(),
341 ),
342 node,
343 )
344 }
345 }
346 }
347
348 fn make_solution_for_missing_fields(
391 &mut self,
392 node: &swamp_ast::Node,
393 super_type: &TypeRef,
394 anon_struct_type: &AnonymousStructType,
395 source_order_expressions: Vec<(usize, Option<Node>, Expression)>,
396 missing_fields: SeqSet<String>,
397 ) -> Expression {
398 let maybe_default = {
400 self.shared
401 .state
402 .associated_impls
403 .get_member_function(super_type, "default")
404 .cloned()
405 };
406
407 if let Some(function) = maybe_default {
410 self.analyze_struct_init_calling_default(
411 &function,
412 super_type,
413 anon_struct_type,
414 source_order_expressions,
415 node,
416 )
417 } else {
418 self.analyze_struct_init_field_by_field(
426 anon_struct_type,
427 source_order_expressions,
428 missing_fields,
429 super_type,
430 node,
431 )
432 }
433
434 }
455
456 fn place_anon_struct_fields_that_exist_and_return_missing(
457 &mut self,
458 target_anon_struct_type: &AnonymousStructType,
459 ast_fields: &Vec<swamp_ast::FieldExpression>,
460 ) -> (Vec<(usize, Option<Node>, Expression)>, SeqSet<String>) {
461 let mut missing_fields: SeqSet<String> = target_anon_struct_type
462 .field_name_sorted_fields
463 .keys()
464 .cloned()
465 .collect();
466
467 let mut source_order_expressions = Vec::new();
468
469 for field in ast_fields {
470 let field_name = self.get_text(&field.field_name.0).to_string();
471 let resolved_node = self.to_node(&field.field_name.0);
472
473 if !missing_fields.remove(&field_name) {
475 return if target_anon_struct_type
476 .field_name_sorted_fields
477 .contains_key(&field_name)
478 {
479 self.add_err(
480 ErrorKind::DuplicateFieldInStructInstantiation(field_name),
481 &field.field_name.0,
482 );
483 (vec![], SeqSet::new())
484 } else {
485 self.add_err(ErrorKind::UnknownStructField, &field.field_name.0);
486 (vec![], SeqSet::new())
487 };
488 }
489
490 let looked_up_field = target_anon_struct_type
491 .field_name_sorted_fields
492 .get(&field_name)
493 .expect("field existence checked above");
494
495 self.shared
496 .state
497 .refs
498 .add(looked_up_field.symbol_id.into(), resolved_node.clone());
499 self.shared
500 .definition_table
501 .refs
502 .add(looked_up_field.symbol_id.into(), resolved_node.clone());
503
504 let field_index_in_definition = target_anon_struct_type
505 .field_name_sorted_fields
506 .get_index(&field_name)
507 .expect("field_name is checked earlier");
508
509 let field_type_context = TypeContext::new_argument(
510 &looked_up_field.field_type,
511 looked_up_field
512 .field_type
513 .collection_view_that_needs_explicit_storage(),
514 );
515 let resolved_expression =
516 self.analyze_expression(&field.expression, &field_type_context);
517
518 source_order_expressions.push((
519 field_index_in_definition,
520 Some(resolved_node),
521 resolved_expression,
522 ));
523 }
524
525 (source_order_expressions, missing_fields)
526 }
527
528 pub(crate) fn analyze_anon_struct_instantiation(
529 &mut self,
530 node: &swamp_ast::Node,
531 struct_to_instantiate: &AnonymousStructType,
532 ast_fields: &Vec<swamp_ast::FieldExpression>,
533 allow_rest: bool,
534 ) -> Vec<(usize, Option<Node>, Expression)> {
535 let (source_order_expressions, missing_fields) = self
536 .place_anon_struct_fields_that_exist_and_return_missing(
537 struct_to_instantiate,
538 ast_fields,
539 );
540
541 let mut mapped: Vec<(usize, Option<Node>, Expression)> = source_order_expressions;
542
543 if allow_rest {
544 for missing_field_name in missing_fields {
546 let field = struct_to_instantiate
547 .field_name_sorted_fields
548 .get(&missing_field_name)
549 .expect("field must exist in struct definition");
550
551 let field_index = struct_to_instantiate
552 .field_name_sorted_fields
553 .get_index(&missing_field_name)
554 .expect("field must exist in struct definition");
555
556 if let Some(default_expression) =
558 self.create_default_value_for_type(node, &field.field_type)
559 {
560 mapped.push((field_index, None, default_expression));
561 }
562 }
564 } else if !missing_fields.is_empty() {
565 self.add_err(
566 ErrorKind::MissingFieldInStructInstantiation(
567 missing_fields.to_vec(),
568 struct_to_instantiate.clone(),
569 ),
570 node,
571 );
572 return vec![];
573 }
574
575 mapped
576 }
577}