1use crate::{Analyzer, TypeContext};
6use source_map_node::Node;
7use swamp_ast::FieldExpression;
8use swamp_semantic::err::ErrorKind;
9use swamp_semantic::prelude::Error;
10use swamp_semantic::{EnumLiteralExpressions, ExpressionKind};
11use swamp_semantic::{Expression, Fp};
12use swamp_types::prelude::*;
13use tracing::{error, warn};
14
15impl Analyzer<'_> {
16 pub fn analyze_enum_variant_struct_literal(
17 &mut self,
18 variant_ref: &EnumVariantType,
19 found_enum_type: &TypeRef,
20 anonym_struct_field_and_expressions: &[FieldExpression],
22 detected_rest: bool,
23 node: &swamp_ast::Node,
24 ) -> Expression {
25 if let TypeKind::AnonymousStruct(anon_payload) = &*variant_ref.payload_type.kind {
26 if anonym_struct_field_and_expressions.len()
27 != anon_payload.field_name_sorted_fields.len()
28 {
29 return self.create_err(
30 ErrorKind::WrongNumberOfArguments(
31 anonym_struct_field_and_expressions.len(),
32 anon_payload.field_name_sorted_fields.len(),
33 ),
34 node,
35 );
36 }
37
38 let resolved_fields = self.analyze_anon_struct_instantiation(
39 node,
40 anon_payload,
41 &anonym_struct_field_and_expressions.to_vec(),
42 detected_rest,
43 );
44
45 let data = EnumLiteralExpressions::Struct(resolved_fields);
46
47 self.create_expr(
48 ExpressionKind::EnumVariantLiteral(variant_ref.clone(), data),
49 found_enum_type.clone(),
50 node,
51 )
52 } else {
53 panic!("strange")
54 }
55 }
56
57 #[allow(clippy::too_many_lines)]
62 pub fn analyze_complex_literal_to_expression(
63 &mut self,
64 ast_expression: &swamp_ast::Expression,
65 ast_literal_kind: &swamp_ast::LiteralKind,
66 parent_context: &TypeContext,
67 ) -> Expression {
68 let literal_context = parent_context.expected_type_or_optional_inner();
72
73 let ast_node = &ast_expression.node;
74 let (lit_kind, literal_type) = match &ast_literal_kind {
75 swamp_ast::LiteralKind::InternalInitializerList(items) => {
76 let (collection_type, resolved_items) =
77 self.analyze_internal_initializer_list(ast_node, items, &literal_context);
78
79 (
80 ExpressionKind::InitializerList(collection_type.clone(), resolved_items),
81 collection_type,
82 )
83 }
84
85 swamp_ast::LiteralKind::InternalInitializerPairList(entries) => {
86 let (collection_type, resolved_items) = self
87 .analyze_internal_initializer_pair_list(ast_node, entries, &literal_context);
88
89 (
90 ExpressionKind::InitializerPairList(collection_type.clone(), resolved_items),
91 collection_type,
92 )
93 }
94
95 _ => {
96 return self.analyze_literal(
97 ast_node,
98 ast_literal_kind,
99 parent_context,
100 &literal_context,
101 );
102 }
103 };
104
105 self.create_expr(lit_kind, literal_type, ast_node)
106 }
107
108 #[allow(clippy::too_many_lines)]
109 pub(crate) fn analyze_literal(
110 &mut self,
111 ast_node: &swamp_ast::Node,
112 ast_literal_kind: &swamp_ast::LiteralKind,
113 parent_context: &TypeContext,
114 context: &TypeContext,
115 ) -> Expression {
116 let node_text = self.get_text(ast_node);
117 let (expression_kind, ty) = match &ast_literal_kind {
118 swamp_ast::LiteralKind::Int => match Self::str_to_int(node_text) {
119 Err(int_err) => {
120 return self.create_err(ErrorKind::IntConversionError(int_err), ast_node);
121 }
122 Ok(int_value) => (
123 ExpressionKind::IntLiteral(int_value),
124 self.shared.state.types.int(),
125 ),
126 },
127 swamp_ast::LiteralKind::Byte => match Self::str_to_byte(node_text) {
128 Err(byte_err) => {
129 return self.create_err(
130 ErrorKind::ByteConversionError(format!("{byte_err:?}")),
131 ast_node,
132 );
133 }
134 Ok(byte_value) => (
135 ExpressionKind::ByteLiteral(byte_value),
136 self.shared.state.types.byte(),
137 ),
138 },
139 swamp_ast::LiteralKind::Float => match Self::str_to_float(node_text) {
140 Err(float_err) => {
141 return self.create_err(ErrorKind::FloatConversionError(float_err), ast_node);
142 }
143 Ok(float_value) => (
144 ExpressionKind::FloatLiteral(Fp::from(float_value)),
145 self.shared.state.types.float(),
146 ),
147 },
148 swamp_ast::LiteralKind::String(processed_string) => (
149 ExpressionKind::StringLiteral(processed_string.to_string()),
150 self.shared.state.types.string(),
151 ),
152 swamp_ast::LiteralKind::Bool => match Self::str_to_bool(node_text) {
153 Err(_bool_err) => return self.create_err(ErrorKind::BoolConversionError, ast_node),
154 Ok(bool_value) => (
155 ExpressionKind::BoolLiteral(bool_value),
156 self.shared.state.types.bool(),
157 ),
158 },
159 swamp_ast::LiteralKind::EnumVariant(enum_variant_literal) => {
160 let variant_name_text = self.get_text(&enum_variant_literal.name.0).to_string();
161
162 let found_enum_type = if let Some(enum_type_name_node) =
163 &enum_variant_literal.qualified_enum_type_name
164 {
165 let Some((symbol_table, name)) =
166 self.get_symbol_table_and_name(enum_type_name_node)
167 else {
168 self.add_err(ErrorKind::UnknownModule, &enum_type_name_node.name.0);
169 return self.create_err(ErrorKind::UnknownEnumVariantType, ast_node);
170 };
171 let Some(found_enum_type) = symbol_table.get_type(&name) else {
172 return self.create_err(ErrorKind::UnknownEnumType, ast_node);
173 };
174 found_enum_type.clone()
175 } else if let Some(expected_type) = context.expected_type {
176 if let TypeKind::Enum(_enum_type) = &*expected_type.kind {
177 expected_type.clone()
178 } else {
179 return self.create_err(ErrorKind::EnumTypeWasntExpectedHere, ast_node);
180 }
181 } else {
182 return self.create_err(ErrorKind::CanNotInferEnumType, ast_node);
183 };
184
185 let TypeKind::Enum(enum_type) = &*found_enum_type.kind else {
186 return self.create_err(ErrorKind::UnknownEnumType, ast_node);
187 };
188
189 let variant_name = &variant_name_text;
190 let Some(variant_ref) = enum_type.get_variant(variant_name) else {
192 return self.create_err(
193 ErrorKind::UnknownEnumVariantType,
194 &enum_variant_literal.name.0,
195 );
196 };
197
198 let variant_reference_name_node = self.to_node(&enum_variant_literal.name.0);
199 self.shared.state.refs.add(
200 variant_ref.common.symbol_id.into(),
201 variant_reference_name_node.clone(),
202 );
203 self.shared.definition_table.refs.add(
204 variant_ref.common.symbol_id.into(),
205 variant_reference_name_node,
206 );
207
208 let resolved_data = match &enum_variant_literal.kind {
209 swamp_ast::EnumVariantLiteralKind::Simple => EnumLiteralExpressions::Nothing,
210 swamp_ast::EnumVariantLiteralKind::Tuple(ast_expressions) => {
211 if let TypeKind::Tuple(tuple_field_types) = &*variant_ref.payload_type.kind
212 {
213 if tuple_field_types.len() != ast_expressions.len() {
215 return self.create_err(
216 ErrorKind::WrongNumberOfArguments(
217 tuple_field_types.len(),
218 ast_expressions.len(),
219 ),
220 ast_node,
221 );
222 }
223
224 let resolved_expression = tuple_field_types
225 .iter()
226 .zip(ast_expressions)
227 .map(|(expected_type, ast_expression)| {
228 let ctx = context.argument(expected_type);
229 self.analyze_expression(ast_expression, &ctx)
230 })
231 .collect();
232
233 EnumLiteralExpressions::Tuple(resolved_expression)
234 } else {
235 if ast_expressions.len() != 1 {
237 return self.create_err(
238 ErrorKind::WrongNumberOfArguments(1, ast_expressions.len()),
239 ast_node,
240 );
241 }
242
243 let ctx = context.argument(&variant_ref.payload_type);
244 let resolved_expression =
245 self.analyze_expression(&ast_expressions[0], &ctx);
246
247 EnumLiteralExpressions::Tuple(vec![resolved_expression])
248 }
249 }
250 swamp_ast::EnumVariantLiteralKind::Struct(
251 anonym_struct_field_and_expressions,
252 detected_rest,
253 ) => {
254 let TypeKind::AnonymousStruct(anon_payload) =
255 &*variant_ref.payload_type.kind
256 else {
257 return self.create_err(
258 ErrorKind::WrongEnumVariantContainer(variant_ref.clone()),
259 ast_node,
260 );
261 };
262
263 if anonym_struct_field_and_expressions.len()
264 != anon_payload.field_name_sorted_fields.len()
265 {
266 return self.create_err(
267 ErrorKind::WrongNumberOfArguments(
268 anonym_struct_field_and_expressions.len(),
269 anon_payload.field_name_sorted_fields.len(),
270 ),
271 &enum_variant_literal.name.0,
272 );
273 }
274
275 let resolved_fields = self.analyze_anon_struct_instantiation(
276 &enum_variant_literal.name.0,
277 anon_payload,
278 anonym_struct_field_and_expressions,
279 *detected_rest,
280 );
281
282 EnumLiteralExpressions::Struct(resolved_fields)
283 }
284 };
285
286 (
287 ExpressionKind::EnumVariantLiteral(variant_ref.clone(), resolved_data),
288 found_enum_type.clone(),
289 )
290 }
291
292 swamp_ast::LiteralKind::Tuple(expressions) => {
293 let (tuple_type_ref, resolved_items) =
294 self.analyze_tuple_literal(expressions, context);
295
296 let tuple_type = self.shared.state.types.tuple(tuple_type_ref);
297
298 self.ensure_default_functions_for_type(&tuple_type, &expressions[0].node);
299 (ExpressionKind::TupleLiteral(resolved_items), tuple_type)
300 }
301 swamp_ast::LiteralKind::None => {
302 if let Some(found_expected_type) = parent_context.expected_type {
303 let underlying = found_expected_type;
304 if let TypeKind::Optional(_some_type) = &*underlying.kind {
305 (ExpressionKind::NoneLiteral, underlying.clone())
306 } else {
307 return self.create_err(ErrorKind::NoneNeedsExpectedTypeHint, ast_node);
308 }
309 } else {
310 return self.create_err(ErrorKind::NoneNeedsExpectedTypeHint, ast_node);
311 }
312 }
313 &&swamp_ast::LiteralKind::InternalInitializerList(_)
314 | &swamp_ast::LiteralKind::InternalInitializerPairList(_) => {
315 panic!("initializer lists are not basic literals")
316 }
317 };
318
319 self.create_expr(expression_kind, ty, ast_node)
320 }
321
322 fn analyze_tuple_literal(
323 &mut self,
324 items: &[swamp_ast::Expression],
325 context: &TypeContext,
326 ) -> (Vec<TypeRef>, Vec<Expression>) {
327 let expressions = self.analyze_argument_expressions(None, context, items);
328 let mut tuple_types = Vec::new();
329 for expr in &expressions {
330 let item_type = expr.ty.clone();
331 tuple_types.push(item_type);
332 }
333
334 (tuple_types, expressions)
335 }
336
337 fn analyze_tuple_type(
338 &mut self,
339 node: &swamp_ast::Node,
340 expected_types: &[TypeRef],
341 ast_expressions: &Vec<swamp_ast::Expression>,
342 ) -> Vec<Expression> {
343 if ast_expressions.len() != expected_types.len() {
344 return vec![self.create_err(
345 ErrorKind::WrongNumberOfArguments(expected_types.len(), ast_expressions.len()),
346 node,
347 )];
348 }
349
350 let mut expressions = Vec::new();
351 for (expected_type, expr) in expected_types.iter().zip(ast_expressions) {
352 let context = TypeContext::new_argument(
353 expected_type,
354 expected_type.collection_view_that_needs_explicit_storage(),
355 );
356 let resolved_expr = self.analyze_expression(expr, &context);
357 expressions.push(resolved_expr);
358 }
359
360 expressions
361 }
362
363 pub fn add_err(&mut self, kind: ErrorKind, ast_node: &swamp_ast::Node) {
364 self.add_err_resolved(kind, &self.to_node(ast_node));
365 }
366 pub(crate) fn add_hint(&mut self, kind: ErrorKind, ast_node: &swamp_ast::Node) {
367 self.add_hint_resolved(kind, &self.to_node(ast_node));
368 }
369
370 pub(crate) fn add_hint_resolved(&mut self, kind: ErrorKind, node: &Node) {
371 warn!(?kind, "add error");
372 let err = Error {
373 node: node.clone(),
374 kind,
375 };
376
377 self.shared.state.hints.push(err);
378 }
379
380 pub(crate) fn add_err_resolved(&mut self, kind: ErrorKind, node: &Node) {
381 error!(?kind, "add error");
382 let err = Error {
383 node: node.clone(),
384 kind,
385 };
386 self.shared.state.errors.push(err);
387 }
388
389 #[must_use]
390 pub fn create_err_vec(
391 &mut self,
392 kind: ErrorKind,
393 ast_node: &swamp_ast::Node,
394 ) -> Vec<Expression> {
395 vec![self.create_err(kind, ast_node)]
396 }
397
398 #[must_use]
399 pub fn create_err(&mut self, kind: ErrorKind, ast_node: &swamp_ast::Node) -> Expression {
400 self.add_err(kind.clone(), ast_node);
401
402 Expression {
403 ty: self.types().unit(),
404 node: self.to_node(ast_node),
405 kind: ExpressionKind::Error(kind),
406 }
407 }
408 #[must_use]
409 pub fn create_err_resolved(&mut self, kind: ErrorKind, resolved_node: &Node) -> Expression {
410 self.add_err_resolved(kind.clone(), resolved_node);
411
412 Expression {
413 ty: self.types().unit(),
414 node: resolved_node.clone(),
415 kind: ExpressionKind::Error(kind),
416 }
417 }
418}