1use crate::{Analyzer, TypeContext};
6use source_map_node::Node;
7use std::env::current_dir;
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 #[allow(clippy::too_many_lines)]
21 pub fn analyze_complex_literal_to_expression(
22 &mut self,
23 ast_expression: &swamp_ast::Expression,
24 ast_literal_kind: &swamp_ast::LiteralKind,
25 parent_context: &TypeContext,
26 ) -> Expression {
27 let literal_context = parent_context.expected_type_or_optional_inner();
31
32 let ast_node = &ast_expression.node;
33 let (lit_kind, literal_type) = match &ast_literal_kind {
34 swamp_ast::LiteralKind::InternalInitializerList(items) => {
35 let (collection_type, resolved_items) =
36 self.analyze_internal_initializer_list(ast_node, items, &literal_context);
37
38 (
39 ExpressionKind::InitializerList(collection_type.clone(), resolved_items),
40 collection_type,
41 )
42 }
43
44 swamp_ast::LiteralKind::InternalInitializerPairList(entries) => {
45 let (collection_type, resolved_items) = self
46 .analyze_internal_initializer_pair_list(ast_node, entries, &literal_context);
47
48 (
49 ExpressionKind::InitializerPairList(collection_type.clone(), resolved_items),
50 collection_type,
51 )
52 }
53
54 _ => {
55 return self.analyze_literal(
56 ast_node,
57 ast_literal_kind,
58 parent_context,
59 &literal_context,
60 );
61 }
62 };
63
64 self.create_expr(lit_kind, literal_type, ast_node)
65 }
66
67 #[allow(clippy::too_many_lines)]
68 pub(crate) fn analyze_literal(
69 &mut self,
70 ast_node: &swamp_ast::Node,
71 ast_literal_kind: &swamp_ast::LiteralKind,
72 parent_context: &TypeContext,
73 context: &TypeContext,
74 ) -> Expression {
75 let node_text = self.get_text(ast_node);
76 let (expression_kind, ty) = match &ast_literal_kind {
77 swamp_ast::LiteralKind::Int => match Self::str_to_int(node_text) {
78 Err(int_err) => {
79 return self.create_err(ErrorKind::IntConversionError(int_err), ast_node);
80 }
81 Ok(int_value) => (
82 ExpressionKind::IntLiteral(int_value),
83 self.shared.state.types.int(),
84 ),
85 },
86 swamp_ast::LiteralKind::Float => match Self::str_to_float(node_text) {
87 Err(float_err) => {
88 return self.create_err(ErrorKind::FloatConversionError(float_err), ast_node);
89 }
90 Ok(float_value) => (
91 ExpressionKind::FloatLiteral(Fp::from(float_value)),
92 self.shared.state.types.float(),
93 ),
94 },
95 swamp_ast::LiteralKind::String(processed_string) => (
96 ExpressionKind::StringLiteral(processed_string.to_string()),
97 self.shared.state.types.string(),
98 ),
99 swamp_ast::LiteralKind::Bool => match Self::str_to_bool(node_text) {
100 Err(_bool_err) => return self.create_err(ErrorKind::BoolConversionError, ast_node),
101 Ok(bool_value) => (
102 ExpressionKind::BoolLiteral(bool_value),
103 self.shared.state.types.bool(),
104 ),
105 },
106 swamp_ast::LiteralKind::EnumVariant(enum_literal) => {
107 let (enum_name, variant_name_node) = match enum_literal {
108 swamp_ast::EnumVariantLiteral::Simple(enum_name, variant_name) => {
109 (enum_name, variant_name)
110 }
111 swamp_ast::EnumVariantLiteral::Tuple(enum_name, variant_name, _) => {
112 (enum_name, variant_name)
113 }
114 swamp_ast::EnumVariantLiteral::Struct(enum_name, variant_name, _, _) => {
115 (enum_name, variant_name)
116 }
117 };
118
119 let variant_name_text = self.get_text(&variant_name_node.0).to_string();
121
122 let found_enum_type = {
124 let Some((symbol_table, name)) = self.get_symbol_table_and_name(enum_name)
125 else {
126 self.add_err(ErrorKind::UnknownModule, &enum_name.name.0);
127 return self.create_err(ErrorKind::UnknownEnumVariantType, ast_node);
128 };
129 let Some(found_enum_type) = symbol_table.get_type(&name) else {
130 return self.create_err(ErrorKind::UnknownEnumType, ast_node);
131 };
132 found_enum_type.clone()
133 };
134
135 let TypeKind::Enum(enum_type) = &*found_enum_type.kind else {
136 return self.create_err(ErrorKind::UnknownEnumType, ast_node);
137 };
138 let variant_name = &variant_name_text;
139 let Some(variant_ref) = enum_type.get_variant(variant_name) else {
141 return self
142 .create_err(ErrorKind::UnknownEnumVariantType, &variant_name_node.0);
143 };
144
145 let resolved_data = match enum_literal {
146 swamp_ast::EnumVariantLiteral::Simple(_, _) => EnumLiteralExpressions::Nothing,
147 swamp_ast::EnumVariantLiteral::Tuple(_node, _variant, ast_expressions) => {
148 if let TypeKind::Tuple(tuple_field_types) = &*variant_ref.payload_type.kind
149 {
150 if tuple_field_types.len() != ast_expressions.len() {
152 return self.create_err(
153 ErrorKind::WrongNumberOfArguments(
154 tuple_field_types.len(),
155 ast_expressions.len(),
156 ),
157 ast_node,
158 );
159 }
160
161 let resolved_expression = tuple_field_types
162 .iter()
163 .zip(ast_expressions)
164 .map(|(expected_type, ast_expression)| {
165 let ctx = context.argument(expected_type);
166 self.analyze_expression(ast_expression, &ctx)
167 })
168 .collect();
169
170 EnumLiteralExpressions::Tuple(resolved_expression)
171 } else {
172 if ast_expressions.len() != 1 {
174 return self.create_err(
175 ErrorKind::WrongNumberOfArguments(1, ast_expressions.len()),
176 ast_node,
177 );
178 }
179
180 let ctx = context.argument(&variant_ref.payload_type);
181 let resolved_expression =
182 self.analyze_expression(&ast_expressions[0], &ctx);
183
184 EnumLiteralExpressions::Tuple(vec![resolved_expression])
185 }
186 }
187 swamp_ast::EnumVariantLiteral::Struct(
188 _qualified_type_identifier,
189 variant,
190 anonym_struct_field_and_expressions,
191 detected_rest,
192 ) => {
193 let TypeKind::AnonymousStruct(anon_payload) =
194 &*variant_ref.payload_type.kind
195 else {
196 return self.create_err(
197 ErrorKind::WrongEnumVariantContainer(variant_ref.clone()),
198 ast_node,
199 );
200 };
201
202 if anonym_struct_field_and_expressions.len()
203 != anon_payload.field_name_sorted_fields.len()
204 {
205 return self.create_err(
206 ErrorKind::WrongNumberOfArguments(
207 anonym_struct_field_and_expressions.len(),
208 anon_payload.field_name_sorted_fields.len(),
209 ),
210 &variant.0,
211 );
212 }
213
214 let resolved_fields = self.analyze_anon_struct_instantiation(
215 &variant.0.clone(),
216 anon_payload,
217 anonym_struct_field_and_expressions,
218 *detected_rest,
219 );
220
221 EnumLiteralExpressions::Struct(resolved_fields)
222 }
223 };
224
225 (
226 ExpressionKind::EnumVariantLiteral(variant_ref.clone(), resolved_data),
227 found_enum_type.clone(),
228 )
229 }
230
231 swamp_ast::LiteralKind::Tuple(expressions) => {
232 let (tuple_type_ref, resolved_items) =
233 self.analyze_tuple_literal(expressions, context);
234 let tuple_type = self.shared.state.types.tuple(tuple_type_ref);
235 (ExpressionKind::TupleLiteral(resolved_items), tuple_type)
236 }
237 swamp_ast::LiteralKind::None => {
238 if let Some(found_expected_type) = parent_context.expected_type {
239 let underlying = found_expected_type;
240 if let TypeKind::Optional(_some_type) = &*underlying.kind {
241 (ExpressionKind::NoneLiteral, underlying.clone())
242 } else {
243 return self.create_err(ErrorKind::NoneNeedsExpectedTypeHint, ast_node);
244 }
245 } else {
246 return self.create_err(ErrorKind::NoneNeedsExpectedTypeHint, ast_node);
247 }
248 }
249 &&swamp_ast::LiteralKind::InternalInitializerList(_)
250 | &swamp_ast::LiteralKind::InternalInitializerPairList(_) => {
251 panic!("initializer lists are not basic literals")
252 }
253 };
254
255 self.create_expr(expression_kind, ty, ast_node)
256 }
257
258 fn analyze_tuple_literal(
259 &mut self,
260 items: &[swamp_ast::Expression],
261 context: &TypeContext,
262 ) -> (Vec<TypeRef>, Vec<Expression>) {
263 let expressions = self.analyze_argument_expressions(None, context, items);
264 let mut tuple_types = Vec::new();
265 for expr in &expressions {
266 let item_type = expr.ty.clone();
267 tuple_types.push(item_type);
268 }
269
270 (tuple_types, expressions)
271 }
272
273 fn analyze_tuple_type(
274 &mut self,
275 node: &swamp_ast::Node,
276 expected_types: &[TypeRef],
277 ast_expressions: &Vec<swamp_ast::Expression>,
278 ) -> Vec<Expression> {
279 if ast_expressions.len() != expected_types.len() {
280 return vec![self.create_err(
281 ErrorKind::WrongNumberOfArguments(expected_types.len(), ast_expressions.len()),
282 node,
283 )];
284 }
285
286 let mut expressions = Vec::new();
287 for (expected_type, expr) in expected_types.iter().zip(ast_expressions) {
288 let context = TypeContext::new_argument(
289 expected_type,
290 expected_type.collection_view_that_needs_explicit_storage(),
291 );
292 let resolved_expr = self.analyze_expression(expr, &context);
293 expressions.push(resolved_expr);
294 }
295
296 expressions
297 }
298
299 pub fn add_err(&mut self, kind: ErrorKind, ast_node: &swamp_ast::Node) {
300 self.add_err_resolved(kind, &self.to_node(ast_node));
301 }
302 pub(crate) fn add_hint(&mut self, kind: ErrorKind, ast_node: &swamp_ast::Node) {
303 self.add_hint_resolved(kind, &self.to_node(ast_node));
304 }
305
306 pub(crate) fn add_hint_resolved(&mut self, kind: ErrorKind, node: &Node) {
307 warn!(?kind, "add error");
308 let err = Error {
309 node: node.clone(),
310 kind,
311 };
312 let line_info = self
313 .shared
314 .source_map
315 .get_line(&node.span, ¤t_dir().unwrap());
316
317 eprintln!("{}:{} {}", line_info.row, line_info.col, line_info.line);
318 self.shared.state.hints.push(err);
319 }
320
321 pub(crate) fn add_err_resolved(&mut self, kind: ErrorKind, node: &Node) {
322 error!(?kind, "add error");
323 let err = Error {
324 node: node.clone(),
325 kind,
326 };
327 let line_info = self
328 .shared
329 .source_map
330 .get_line(&node.span, ¤t_dir().unwrap());
331
332 eprintln!("{}:{} {}", line_info.row, line_info.col, line_info.line);
333 self.shared.state.errors.push(err);
334 }
335
336 #[must_use]
337 pub fn create_err_vec(
338 &mut self,
339 kind: ErrorKind,
340 ast_node: &swamp_ast::Node,
341 ) -> Vec<Expression> {
342 vec![self.create_err(kind, ast_node)]
343 }
344
345 #[must_use]
346 pub fn create_err(&mut self, kind: ErrorKind, ast_node: &swamp_ast::Node) -> Expression {
347 self.add_err(kind.clone(), ast_node);
348
349 Expression {
350 ty: self.types().unit(),
351 node: self.to_node(ast_node),
352 kind: ExpressionKind::Error(kind),
353 }
354 }
355 #[must_use]
356 pub fn create_err_resolved(&mut self, kind: ErrorKind, resolved_node: &Node) -> Expression {
357 self.add_err_resolved(kind.clone(), resolved_node);
358
359 Expression {
360 ty: self.types().unit(),
361 node: resolved_node.clone(),
362 kind: ExpressionKind::Error(kind),
363 }
364 }
365}