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 return self.analyze_struct_init(
206 node,
207 &anon_struct_type_ref,
208 &deduced_anon_struct_type,
209 ast_fields,
210 rest_was_specified,
211 );
212 };
213
214 self.analyze_struct_init(
216 node,
217 super_type,
218 anon_struct_type,
219 ast_fields,
220 rest_was_specified,
221 )
222 }
223
224 pub(crate) fn analyze_named_struct_literal(
225 &mut self,
226 qualified_type_identifier: &swamp_ast::QualifiedTypeIdentifier,
227 ast_fields: &Vec<swamp_ast::FieldExpression>,
228 rest_was_specified: bool,
229 ) -> Expression {
230 let named_struct_type = self.get_struct_type(qualified_type_identifier);
231
232 let super_type = self
233 .shared
234 .state
235 .types
236 .named_struct(named_struct_type.clone());
237
238 if let TypeKind::AnonymousStruct(anon_struct) = &*named_struct_type.anon_struct_type.kind {
239 self.analyze_struct_init(
240 &qualified_type_identifier.name.0,
241 &super_type,
242 anon_struct,
243 ast_fields,
244 rest_was_specified,
245 )
246 } else {
247 self.create_err(
248 ErrorKind::UnknownStructTypeReference,
249 &qualified_type_identifier.name.0,
250 )
251 }
252 }
253
254 fn analyze_struct_init(
255 &mut self,
256 node: &swamp_ast::Node,
257 super_type: &TypeRef,
258 anon_struct_type: &AnonymousStructType,
259 ast_fields: &Vec<swamp_ast::FieldExpression>,
260 rest_was_specified: bool,
261 ) -> Expression {
262 let (source_order_expressions, missing_fields) = self
263 .place_anon_struct_fields_that_exist_and_return_missing(anon_struct_type, ast_fields);
264
265 if missing_fields.is_empty() {
266 self.create_expr(
268 ExpressionKind::AnonymousStructLiteral(AnonymousStructLiteral {
269 struct_like_type: Self::get_struct_like_type(super_type),
270 source_order_expressions,
271 }),
272 super_type.clone(),
273 node,
274 )
275 } else {
276 if rest_was_specified {
278 self.make_solution_for_missing_fields(
279 node,
280 super_type,
281 anon_struct_type,
282 source_order_expressions,
283 missing_fields,
284 )
285 } else {
286 self.create_err(
287 ErrorKind::MissingFieldInStructInstantiation(
288 missing_fields.to_vec(),
289 anon_struct_type.clone(),
290 ),
291 node,
292 )
293 }
294 }
295 }
296
297 fn make_solution_for_missing_fields(
340 &mut self,
341 node: &swamp_ast::Node,
342 super_type: &TypeRef,
343 anon_struct_type: &AnonymousStructType,
344 source_order_expressions: Vec<(usize, Option<Node>, Expression)>,
345 missing_fields: SeqSet<String>,
346 ) -> Expression {
347 let maybe_default = {
349 self.shared
350 .state
351 .associated_impls
352 .get_member_function(super_type, "default")
353 .cloned()
354 };
355
356 if let Some(function) = maybe_default {
359 self.analyze_struct_init_calling_default(
360 &function,
361 super_type,
362 anon_struct_type,
363 source_order_expressions,
364 node,
365 )
366 } else {
367 self.analyze_struct_init_field_by_field(
375 anon_struct_type,
376 source_order_expressions,
377 missing_fields,
378 super_type,
379 node,
380 )
381 }
382
383 }
404
405 fn place_anon_struct_fields_that_exist_and_return_missing(
406 &mut self,
407 target_anon_struct_type: &AnonymousStructType,
408 ast_fields: &Vec<swamp_ast::FieldExpression>,
409 ) -> (Vec<(usize, Option<Node>, Expression)>, SeqSet<String>) {
410 let mut missing_fields: SeqSet<String> = target_anon_struct_type
411 .field_name_sorted_fields
412 .keys()
413 .cloned()
414 .collect();
415
416 let mut source_order_expressions = Vec::new();
417
418 for field in ast_fields {
419 let field_name = self.get_text(&field.field_name.0).to_string();
420 let resolved_node = self.to_node(&field.field_name.0);
421
422 if !missing_fields.remove(&field_name) {
424 return if target_anon_struct_type
425 .field_name_sorted_fields
426 .contains_key(&field_name)
427 {
428 self.add_err(
429 ErrorKind::DuplicateFieldInStructInstantiation(field_name),
430 &field.field_name.0,
431 );
432 (vec![], SeqSet::new())
433 } else {
434 self.add_err(ErrorKind::UnknownStructField, &field.field_name.0);
435 (vec![], SeqSet::new())
436 };
437 }
438
439 let looked_up_field = target_anon_struct_type
440 .field_name_sorted_fields
441 .get(&field_name)
442 .expect("field existence checked above");
443
444 let field_index_in_definition = target_anon_struct_type
445 .field_name_sorted_fields
446 .get_index(&field_name)
447 .expect("field_name is checked earlier");
448
449 let field_type_context = TypeContext::new_argument(
450 &looked_up_field.field_type,
451 looked_up_field
452 .field_type
453 .collection_view_that_needs_explicit_storage(),
454 );
455 let resolved_expression =
456 self.analyze_expression(&field.expression, &field_type_context);
457
458 source_order_expressions.push((
459 field_index_in_definition,
460 Some(resolved_node),
461 resolved_expression,
462 ));
463 }
464
465 (source_order_expressions, missing_fields)
466 }
467
468 pub(crate) fn analyze_anon_struct_instantiation(
469 &mut self,
470 node: &swamp_ast::Node,
471 struct_to_instantiate: &AnonymousStructType,
472 ast_fields: &Vec<swamp_ast::FieldExpression>,
473 allow_rest: bool,
474 ) -> Vec<(usize, Option<Node>, Expression)> {
475 let (source_order_expressions, missing_fields) = self
476 .place_anon_struct_fields_that_exist_and_return_missing(
477 struct_to_instantiate,
478 ast_fields,
479 );
480
481 let mut mapped: Vec<(usize, Option<Node>, Expression)> = source_order_expressions;
482
483 if allow_rest {
484 for missing_field_name in missing_fields {
486 let field = struct_to_instantiate
487 .field_name_sorted_fields
488 .get(&missing_field_name)
489 .expect("field must exist in struct definition");
490
491 let field_index = struct_to_instantiate
492 .field_name_sorted_fields
493 .get_index(&missing_field_name)
494 .expect("field must exist in struct definition");
495
496 if let Some(default_expression) =
498 self.create_default_value_for_type(node, &field.field_type)
499 {
500 mapped.push((field_index, None, default_expression));
501 }
502 }
504 } else if !missing_fields.is_empty() {
505 self.add_err(
506 ErrorKind::MissingFieldInStructInstantiation(
507 missing_fields.to_vec(),
508 struct_to_instantiate.clone(),
509 ),
510 node,
511 );
512 return vec![];
513 }
514
515 mapped
516 }
517}