1use crate::err::{Error, ErrorKind};
6use crate::{Analyzer, TypeContext};
7use seq_map::SeqMap;
8use seq_set::SeqSet;
9use swamp_script_node::Node;
10use swamp_script_semantic::{
11 AnonymousStructLiteral, ArgumentExpressionOrLocation, Expression, ExpressionKind, FunctionRef,
12 LocationAccess, LocationAccessKind, MutOrImmutableExpression, SingleLocationExpression,
13 SingleLocationExpressionKind, SingleMutLocationExpression, StructInstantiation,
14};
15use swamp_script_types::prelude::*;
16
17impl Analyzer<'_> {
18 fn analyze_struct_init_calling_default(
19 &mut self,
20 function: &FunctionRef,
21 struct_to_instantiate: &NamedStructTypeRef,
22 source_order_expressions: Vec<(usize, Node, Expression)>,
23 node: &swamp_script_ast::Node,
24 ) -> Result<Expression, Error> {
25 let mut expressions = Vec::new();
26
27 self.push_block_scope("struct_instantiation");
28
29 let temp_var = self.create_local_variable_generated(
30 "__generated",
31 true,
32 &Type::NamedStruct(struct_to_instantiate.clone()),
33 )?;
34
35 let return_type = *function.signature().return_type.clone();
37
38 let default_call_kind = self
39 .create_default_static_call(node, &Type::NamedStruct(struct_to_instantiate.clone()))?;
40
41 let static_call = self.create_expr(default_call_kind, return_type, node);
42
43 let expr = self.create_expr(
44 ExpressionKind::VariableDefinition(
45 temp_var.clone(),
46 Box::new(MutOrImmutableExpression {
47 expression_or_location: ArgumentExpressionOrLocation::Expression(static_call),
48 is_mutable: None,
49 }),
50 ),
51 Type::Unit,
52 node,
53 );
54 expressions.push(expr);
55
56 for (field_target_index, resolved_field_name_node, field_source_expression) in
58 source_order_expressions
59 {
60 let node = field_source_expression.node.clone();
61
62 let field_expression_type = field_source_expression.ty.clone();
63
64 let kind = LocationAccessKind::FieldIndex(
65 struct_to_instantiate.borrow().anon_struct_type.clone(),
66 field_target_index,
67 );
68
69 let single_chain = vec![LocationAccess {
70 node: resolved_field_name_node,
71 ty: field_expression_type.clone(),
72 kind,
73 }];
74
75 let created_location = SingleLocationExpression {
76 kind: SingleLocationExpressionKind::MutStructFieldRef(
77 struct_to_instantiate.clone(),
78 field_target_index,
79 ),
80 node: node.clone(),
81 ty: field_expression_type,
82 starting_variable: temp_var.clone(),
83 access_chain: single_chain,
84 };
85
86 let created_mut_location = SingleMutLocationExpression(created_location);
87
88 let overwrite_expression = self.create_expr_resolved(
89 ExpressionKind::Assignment(
90 Box::from(created_mut_location),
91 Box::new(field_source_expression),
92 ),
93 Type::Unit,
94 &node,
95 );
96
97 expressions.push(overwrite_expression);
98 }
99
100 let ty = temp_var.resolved_type.clone();
101 let access_variable =
102 self.create_expr(ExpressionKind::VariableAccess(temp_var), ty.clone(), &node);
103
104 expressions.push(access_variable); self.pop_block_scope("struct instantiation");
107
108 let block = self.create_expr(ExpressionKind::Block(expressions), ty, &node);
109 Ok(block)
110 }
111
112 fn analyze_struct_init_field_by_field(
113 &mut self,
114 struct_to_instantiate: NamedStructTypeRef,
115 mut source_order_expressions: Vec<(usize, Expression)>,
116 missing_fields: SeqSet<String>,
117 node: &swamp_script_ast::Node,
118 ) -> Result<Expression, Error> {
119 {
120 let borrowed_anon_type = &struct_to_instantiate.borrow().anon_struct_type;
121
122 for missing_field_name in missing_fields {
123 let field = borrowed_anon_type
124 .field_name_sorted_fields
125 .get(&missing_field_name)
126 .expect("should have been verified by helper function");
127 let field_index = borrowed_anon_type
128 .field_name_sorted_fields
129 .get_index(&missing_field_name)
130 .expect("should have been verified earlier");
131
132 let expression = self.create_default_value_for_type(&node, &field.field_type)?; source_order_expressions.push((field_index, expression));
135 }
136 }
137
138 let ty = Type::NamedStruct(struct_to_instantiate.clone());
139
140 Ok(self.create_expr(
141 ExpressionKind::StructInstantiation(StructInstantiation {
142 source_order_expressions,
143 struct_type_ref: struct_to_instantiate,
144 }),
145 ty,
146 &node,
147 ))
148 }
149
150 pub fn analyze_anonymous_struct_literal(
155 &mut self,
156 node: &swamp_script_ast::Node,
157 ast_fields: &Vec<swamp_script_ast::FieldExpression>,
158 rest_was_specified: bool,
159 context: &TypeContext,
160 ) -> Result<Expression, Error> {
161 let mut maybe_named_struct: Option<NamedStructTypeRef> = None;
162
163 let struct_to_instantiate = if let Some(expected_type) = context.expected_type {
164 match expected_type {
165 Type::NamedStruct(named_struct) => {
166 maybe_named_struct = Some(named_struct.clone());
167 named_struct.borrow().anon_struct_type.clone()
168 }
169 Type::AnonymousStruct(anonymous_struct) => anonymous_struct.clone(),
170 _ => {
171 return Err(
172 self.create_err(ErrorKind::CouldNotCoerceTo(expected_type.clone()), node)
173 );
174 }
175 }
176 } else {
177 let mut map_for_creating_type = SeqMap::new();
179
180 for field in ast_fields {
181 let field_name = self.get_text(&field.field_name.0).to_string();
182 let resolved_node = self.to_node(&field.field_name.0);
183
184 let field_type_context = TypeContext::new_anything_argument();
185 let resolved_expression =
186 self.analyze_expression(&field.expression, &field_type_context)?;
187
188 let expression_type = resolved_expression.ty.clone();
189 let field = StructTypeField {
191 identifier: Some(resolved_node),
192 field_type: expression_type,
193 };
194
195 map_for_creating_type
196 .insert(field_name.clone(), field)
197 .expect("TODO: panic message");
198 }
199
200 AnonymousStructType::new_and_sort_fields(&map_for_creating_type)
201 };
202
203 let mapped = self.analyze_anon_struct_instantiation(
204 node,
205 &struct_to_instantiate,
206 ast_fields,
207 rest_was_specified,
208 )?;
209
210 let (kind, ty) = if let Some(named_struct) = maybe_named_struct {
211 (
212 ExpressionKind::StructInstantiation(StructInstantiation {
213 source_order_expressions: mapped,
214 struct_type_ref: named_struct.clone(),
215 }),
216 Type::NamedStruct(named_struct),
217 )
218 } else {
219 (
220 ExpressionKind::AnonymousStructLiteral(AnonymousStructLiteral {
221 source_order_expressions: mapped,
222 anonymous_struct_type: struct_to_instantiate.clone(),
223 }),
224 Type::AnonymousStruct(struct_to_instantiate),
225 )
226 };
227
228 Ok(self.create_expr(kind, ty, &node))
229 }
230
231 pub(crate) fn analyze_struct_instantiation(
232 &mut self,
233 qualified_type_identifier: &swamp_script_ast::QualifiedTypeIdentifier,
234 ast_fields: &Vec<swamp_script_ast::FieldExpression>,
235 has_rest: bool,
236 ) -> Result<Expression, Error> {
237 let struct_to_instantiate = self.get_struct_type(qualified_type_identifier)?;
238
239 let (source_order_expressions, missing_fields) = self
240 .analyze_anon_struct_instantiation_helper(
241 &struct_to_instantiate.borrow().anon_struct_type,
242 ast_fields,
243 )?;
244
245 if has_rest {
246 let maybe_default = {
247 self.shared
248 .state
249 .associated_impls
250 .get_member_function(
251 &Type::NamedStruct(struct_to_instantiate.clone()),
252 "default",
253 )
254 .cloned()
255 };
256
257 if let Some(function) = maybe_default {
258 self.analyze_struct_init_calling_default(
259 &function,
260 &struct_to_instantiate,
261 source_order_expressions,
262 &qualified_type_identifier.name.0,
263 )
264 } else {
265 let mapped: Vec<(usize, Expression)> = source_order_expressions
266 .into_iter()
267 .map(|(a, _b, c)| (a, c))
268 .collect::<Vec<_>>();
269 self.analyze_struct_init_field_by_field(
270 struct_to_instantiate,
271 mapped,
272 missing_fields,
273 &qualified_type_identifier.name.0,
274 )
275 }
276 } else if missing_fields.is_empty() {
277 let ty = Type::NamedStruct(struct_to_instantiate.clone());
278 let node = qualified_type_identifier.name.0.clone();
279 let mapped: Vec<(usize, Expression)> = source_order_expressions
280 .into_iter()
281 .map(|(a, _b, c)| (a, c))
282 .collect::<Vec<_>>();
283 Ok(self.create_expr(
284 ExpressionKind::StructInstantiation(StructInstantiation {
285 source_order_expressions: mapped,
286 struct_type_ref: struct_to_instantiate,
287 }),
288 ty,
289 &node,
290 ))
291 } else {
292 let node = qualified_type_identifier.name.0.clone();
293 Err(self.create_err(
294 ErrorKind::MissingFieldInStructInstantiation(
295 missing_fields.to_vec(),
296 struct_to_instantiate.borrow().anon_struct_type.clone(),
297 ),
298 &node,
299 ))
300 }
301 }
302
303 fn analyze_anon_struct_instantiation_helper(
304 &mut self,
305 struct_to_instantiate: &AnonymousStructType,
306 ast_fields: &Vec<swamp_script_ast::FieldExpression>,
307 ) -> Result<(Vec<(usize, Node, Expression)>, SeqSet<String>), Error> {
308 let mut missing_fields: SeqSet<String> = struct_to_instantiate
309 .field_name_sorted_fields
310 .keys()
311 .cloned()
312 .collect();
313
314 let mut source_order_expressions = Vec::new();
315
316 for field in ast_fields {
317 let field_name = self.get_text(&field.field_name.0).to_string();
318 let resolved_node = self.to_node(&field.field_name.0);
319
320 if !missing_fields.remove(&field_name) {
322 return if struct_to_instantiate
323 .field_name_sorted_fields
324 .contains_key(&field_name)
325 {
326 Err(self.create_err(
327 ErrorKind::DuplicateFieldInStructInstantiation(field_name),
328 &field.field_name.0,
329 ))
330 } else {
331 Err(self.create_err(ErrorKind::UnknownStructField, &field.field_name.0))
332 };
333 }
334
335 let looked_up_field = struct_to_instantiate
336 .field_name_sorted_fields
337 .get(&field_name)
338 .expect("field existence checked above");
339
340 let field_index_in_definition = struct_to_instantiate
341 .field_name_sorted_fields
342 .get_index(&field_name)
343 .expect("field_name is checked earlier");
344
345 let field_type_context = TypeContext::new_argument(&looked_up_field.field_type);
346 let resolved_expression =
347 self.analyze_expression(&field.expression, &field_type_context)?;
348
349 source_order_expressions.push((
350 field_index_in_definition,
351 resolved_node,
352 resolved_expression,
353 ));
354 }
355
356 Ok((source_order_expressions, missing_fields))
357 }
358
359 pub(crate) fn analyze_anon_struct_instantiation(
360 &mut self,
361 node: &swamp_script_ast::Node,
362 struct_to_instantiate: &AnonymousStructType,
363 ast_fields: &Vec<swamp_script_ast::FieldExpression>,
364 allow_rest: bool,
365 ) -> Result<Vec<(usize, Expression)>, Error> {
366 let (source_order_expressions, missing_fields) =
367 self.analyze_anon_struct_instantiation_helper(struct_to_instantiate, ast_fields)?;
368
369 let mut mapped: Vec<(usize, Expression)> = source_order_expressions
370 .into_iter()
371 .map(|(a, _b, c)| (a, c))
372 .collect::<Vec<_>>();
373
374 if allow_rest {
375 for missing_field_name in missing_fields {
377 let field = struct_to_instantiate
378 .field_name_sorted_fields
379 .get(&missing_field_name)
380 .expect("field must exist in struct definition");
381
382 let field_index = struct_to_instantiate
383 .field_name_sorted_fields
384 .get_index(&missing_field_name)
385 .expect("field must exist in struct definition");
386
387 let default_expression =
389 self.create_default_value_for_type(node, &field.field_type)?;
390
391 mapped.push((field_index, default_expression));
392 }
393 } else if !missing_fields.is_empty() {
394 return Err(self.create_err(
395 ErrorKind::MissingFieldInStructInstantiation(
396 missing_fields.to_vec(),
397 struct_to_instantiate.clone(),
398 ),
399 node,
400 ));
401 }
402
403 Ok(mapped)
404 }
405}