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_types::prelude::*;
16
17impl Analyzer<'_> {
18 fn analyze_struct_init_calling_default(
19 &mut self,
20 function: &FunctionRef,
21 super_type: &TypeRef,
22 anon_struct_type: &AnonymousStructType,
23 mut source_order_expressions: Vec<(usize, Option<Node>, Expression)>,
24 node: &swamp_ast::Node,
25 ) -> Expression {
26 let mut provided_field_indices = HashSet::new();
34 for (field_index, _, _) in &source_order_expressions {
35 provided_field_indices.insert(*field_index);
36 }
37
38 let default_call = self.create_default_static_call(node, super_type);
40 let default_struct_expr = self.create_expr(default_call, super_type.clone(), node);
41
42 for (field_index, (_field_name, field_info)) in
44 anon_struct_type.field_name_sorted_fields.iter().enumerate()
45 {
46 if !provided_field_indices.contains(&field_index) {
47 let start_of_chain = StartOfChain {
49 kind: StartOfChainKind::Expression(Box::new(default_struct_expr.clone())),
50 node: self.to_node(node),
51 };
52 let postfixes = vec![Postfix {
53 kind: PostfixKind::StructField(super_type.clone(), field_index),
54 ty: field_info.field_type.clone(),
55 node: self.to_node(node),
56 }];
57
58 let field_access_expr = self.create_expr(
59 ExpressionKind::PostfixChain(start_of_chain, postfixes),
60 field_info.field_type.clone(),
61 node,
62 );
63
64 source_order_expressions.push((
65 field_index,
66 field_info.identifier.clone(),
67 field_access_expr,
68 ));
69 }
70 }
71
72 self.create_expr(
74 ExpressionKind::AnonymousStructLiteral(AnonymousStructLiteral {
75 struct_like_type: Self::get_struct_like_type(super_type),
76 source_order_expressions,
77 }),
78 super_type.clone(),
79 node,
80 )
81 }
82
83 fn get_struct_like_type(ty: &TypeRef) -> TypeRef {
84 ty.clone()
85 }
86
87 fn analyze_struct_init_field_by_field(
88 &mut self,
89 borrowed_anon_type: &AnonymousStructType,
90 mut source_order_expressions: Vec<(usize, Option<Node>, Expression)>,
91 missing_fields: SeqSet<String>,
92 result_type: &TypeRef,
93 node: &swamp_ast::Node,
94 ) -> Expression {
95 {
96 for missing_field_name in missing_fields {
97 let field = borrowed_anon_type
98 .field_name_sorted_fields
99 .get(&missing_field_name)
100 .expect("verified");
101 let field_index = borrowed_anon_type
102 .field_name_sorted_fields
103 .get_index(&missing_field_name)
104 .expect("verified");
105
106 if let Some(expression) =
108 self.create_default_value_for_type(node, &field.field_type)
109 {
110 source_order_expressions.push((
111 field_index,
112 field.identifier.clone(),
113 expression,
114 ));
115 }
116 }
118 }
119
120 self.create_expr(
121 ExpressionKind::AnonymousStructLiteral(AnonymousStructLiteral {
122 struct_like_type: Self::get_struct_like_type(result_type),
123 source_order_expressions: source_order_expressions.clone(),
124 }),
125 result_type.clone(),
126 node,
127 )
128 }
129
130 pub fn deduce_the_anon_struct_type(
131 &mut self,
132 ast_fields: &Vec<swamp_ast::FieldExpression>,
133 context: &TypeContext,
134 ) -> AnonymousStructType {
135 let mut map_for_creating_type = SeqMap::new();
136
137 for field in ast_fields {
138 let field_name = self.get_text(&field.field_name.0).to_string();
139 let resolved_node = self.to_node(&field.field_name.0);
140
141 let field_type_context = TypeContext::new_anything_argument(true);
142 let resolved_expression =
143 self.analyze_expression(&field.expression, &field_type_context);
144
145 let expression_type = resolved_expression.ty.clone();
146
147 let field = StructTypeField {
148 identifier: Some(resolved_node),
149 field_type: expression_type,
150 };
151
152 map_for_creating_type
153 .insert(field_name.clone(), field)
154 .expect("insert");
155 }
156
157 AnonymousStructType::new_and_sort_fields(&map_for_creating_type)
160 }
161
162 pub fn analyze_anonymous_struct_literal(
167 &mut self,
168 node: &swamp_ast::Node,
169 ast_fields: &Vec<swamp_ast::FieldExpression>,
170 rest_was_specified: bool,
171 context: &TypeContext,
172 ) -> Expression {
173 let (super_type, anon_struct_type) = if let Some(expected_type) = context.expected_type {
176 match &*expected_type.kind {
177 TypeKind::NamedStruct(named_struct_type) => {
178 if let TypeKind::AnonymousStruct(anon_struct) =
180 &*named_struct_type.anon_struct_type.kind
181 {
182 (expected_type, anon_struct)
183 } else {
184 return self
185 .create_err(ErrorKind::CouldNotCoerceTo(expected_type.clone()), node);
186 }
187 }
188 TypeKind::AnonymousStruct(anonymous_struct_type) => {
189 (expected_type, anonymous_struct_type)
190 }
191 _ => {
192 return self
193 .create_err(ErrorKind::CouldNotCoerceTo(expected_type.clone()), node);
194 }
195 }
196 } else {
197 let deduced_anon_struct_type = self.deduce_the_anon_struct_type(ast_fields, context);
198 let anon_struct_type_ref = self
199 .shared
200 .state
201 .types
202 .anonymous_struct(deduced_anon_struct_type.clone());
203
204 self.add_default_functions(&anon_struct_type_ref, node);
206
207 return self.analyze_struct_init(
209 node,
210 &anon_struct_type_ref,
211 &deduced_anon_struct_type,
212 ast_fields,
213 rest_was_specified,
214 );
215 };
216
217 self.analyze_struct_init(
219 node,
220 super_type,
221 anon_struct_type,
222 ast_fields,
223 rest_was_specified,
224 )
225 }
226
227 pub(crate) fn analyze_named_struct_literal(
228 &mut self,
229 qualified_type_identifier: &swamp_ast::QualifiedTypeIdentifier,
230 ast_fields: &Vec<swamp_ast::FieldExpression>,
231 rest_was_specified: bool,
232 ) -> Expression {
233 let named_struct_type = self.get_struct_type(qualified_type_identifier);
234
235 let super_type = self
236 .shared
237 .state
238 .types
239 .named_struct(named_struct_type.clone());
240
241 if let TypeKind::AnonymousStruct(anon_struct) = &*named_struct_type.anon_struct_type.kind {
242 self.analyze_struct_init(
243 &qualified_type_identifier.name.0,
244 &super_type,
245 anon_struct,
246 ast_fields,
247 rest_was_specified,
248 )
249 } else {
250 self.create_err(
251 ErrorKind::UnknownStructTypeReference,
252 &qualified_type_identifier.name.0,
253 )
254 }
255 }
256
257 fn analyze_struct_init(
258 &mut self,
259 node: &swamp_ast::Node,
260 super_type: &TypeRef,
261 anon_struct_type: &AnonymousStructType,
262 ast_fields: &Vec<swamp_ast::FieldExpression>,
263 rest_was_specified: bool,
264 ) -> Expression {
265 let (source_order_expressions, missing_fields) = self
266 .place_anon_struct_fields_that_exist_and_return_missing(anon_struct_type, ast_fields);
267
268 if missing_fields.is_empty() {
269 self.create_expr(
271 ExpressionKind::AnonymousStructLiteral(AnonymousStructLiteral {
272 struct_like_type: Self::get_struct_like_type(super_type),
273 source_order_expressions,
274 }),
275 super_type.clone(),
276 node,
277 )
278 } else {
279 if rest_was_specified {
281 self.make_solution_for_missing_fields(
282 node,
283 super_type,
284 anon_struct_type,
285 source_order_expressions,
286 missing_fields,
287 )
288 } else {
289 self.create_err(
290 ErrorKind::MissingFieldInStructInstantiation(
291 missing_fields.to_vec(),
292 anon_struct_type.clone(),
293 ),
294 node,
295 )
296 }
297 }
298 }
299
300 fn make_solution_for_missing_fields(
343 &mut self,
344 node: &swamp_ast::Node,
345 super_type: &TypeRef,
346 anon_struct_type: &AnonymousStructType,
347 source_order_expressions: Vec<(usize, Option<Node>, Expression)>,
348 missing_fields: SeqSet<String>,
349 ) -> Expression {
350 let maybe_default = {
352 self.shared
353 .state
354 .associated_impls
355 .get_member_function(super_type, "default")
356 .cloned()
357 };
358
359 if let Some(function) = maybe_default {
362 self.analyze_struct_init_calling_default(
363 &function,
364 super_type,
365 anon_struct_type,
366 source_order_expressions,
367 node,
368 )
369 } else {
370 self.analyze_struct_init_field_by_field(
378 anon_struct_type,
379 source_order_expressions,
380 missing_fields,
381 super_type,
382 node,
383 )
384 }
385
386 }
407
408 fn place_anon_struct_fields_that_exist_and_return_missing(
409 &mut self,
410 target_anon_struct_type: &AnonymousStructType,
411 ast_fields: &Vec<swamp_ast::FieldExpression>,
412 ) -> (Vec<(usize, Option<Node>, Expression)>, SeqSet<String>) {
413 let mut missing_fields: SeqSet<String> = target_anon_struct_type
414 .field_name_sorted_fields
415 .keys()
416 .cloned()
417 .collect();
418
419 let mut source_order_expressions = Vec::new();
420
421 for field in ast_fields {
422 let field_name = self.get_text(&field.field_name.0).to_string();
423 let resolved_node = self.to_node(&field.field_name.0);
424
425 if !missing_fields.remove(&field_name) {
427 return if target_anon_struct_type
428 .field_name_sorted_fields
429 .contains_key(&field_name)
430 {
431 self.add_err(
432 ErrorKind::DuplicateFieldInStructInstantiation(field_name),
433 &field.field_name.0,
434 );
435 (vec![], SeqSet::new())
436 } else {
437 self.add_err(ErrorKind::UnknownStructField, &field.field_name.0);
438 (vec![], SeqSet::new())
439 };
440 }
441
442 let looked_up_field = target_anon_struct_type
443 .field_name_sorted_fields
444 .get(&field_name)
445 .expect("field existence checked above");
446
447 let field_index_in_definition = target_anon_struct_type
448 .field_name_sorted_fields
449 .get_index(&field_name)
450 .expect("field_name is checked earlier");
451
452 let field_type_context = TypeContext::new_argument(
453 &looked_up_field.field_type,
454 looked_up_field
455 .field_type
456 .collection_view_that_needs_explicit_storage(),
457 );
458 let resolved_expression =
459 self.analyze_expression(&field.expression, &field_type_context);
460
461 source_order_expressions.push((
462 field_index_in_definition,
463 Some(resolved_node),
464 resolved_expression,
465 ));
466 }
467
468 (source_order_expressions, missing_fields)
469 }
470
471 pub(crate) fn analyze_anon_struct_instantiation(
472 &mut self,
473 node: &swamp_ast::Node,
474 struct_to_instantiate: &AnonymousStructType,
475 ast_fields: &Vec<swamp_ast::FieldExpression>,
476 allow_rest: bool,
477 ) -> Vec<(usize, Option<Node>, Expression)> {
478 let (source_order_expressions, missing_fields) = self
479 .place_anon_struct_fields_that_exist_and_return_missing(
480 struct_to_instantiate,
481 ast_fields,
482 );
483
484 let mut mapped: Vec<(usize, Option<Node>, Expression)> = source_order_expressions;
485
486 if allow_rest {
487 for missing_field_name in missing_fields {
489 let field = struct_to_instantiate
490 .field_name_sorted_fields
491 .get(&missing_field_name)
492 .expect("field must exist in struct definition");
493
494 let field_index = struct_to_instantiate
495 .field_name_sorted_fields
496 .get_index(&missing_field_name)
497 .expect("field must exist in struct definition");
498
499 if let Some(default_expression) =
501 self.create_default_value_for_type(node, &field.field_type)
502 {
503 mapped.push((field_index, None, default_expression));
504 }
505 }
507 } else if !missing_fields.is_empty() {
508 self.add_err(
509 ErrorKind::MissingFieldInStructInstantiation(
510 missing_fields.to_vec(),
511 struct_to_instantiate.clone(),
512 ),
513 node,
514 );
515 return vec![];
516 }
517
518 mapped
519 }
520}