1use crate::err::{Error, ErrorKind};
6use crate::{Analyzer, TypeContext};
7use swamp_script_node::Node;
8use swamp_script_semantic::{EnumLiteralData, Expression, Fp, Literal};
9use swamp_script_types::prelude::*;
10use tracing::error;
11
12impl Analyzer<'_> {
13 #[allow(clippy::too_many_lines)]
14 pub(crate) fn analyze_literal(
15 &mut self,
16 ast_node: &swamp_script_ast::Node,
17 ast_literal_kind: &swamp_script_ast::LiteralKind,
18 context: &TypeContext,
19 ) -> Result<(Literal, Type), Error> {
20 let node_text = self.get_text(ast_node);
21 let resolved_literal = match &ast_literal_kind {
22 swamp_script_ast::LiteralKind::Int => (
23 Literal::IntLiteral(Self::str_to_int(node_text).map_err(|int_conversion_err| {
24 self.create_err(ErrorKind::IntConversionError(int_conversion_err), ast_node)
25 })?),
26 Type::Int,
27 ),
28 swamp_script_ast::LiteralKind::Float => {
29 let float = Self::str_to_float(node_text).map_err(|float_conversion_err| {
30 self.create_err(
31 ErrorKind::FloatConversionError(float_conversion_err),
32 ast_node,
33 )
34 })?;
35 (Literal::FloatLiteral(Fp::from(float)), Type::Float)
36 }
37 swamp_script_ast::LiteralKind::String(processed_string) => (
38 Literal::StringLiteral(processed_string.to_string()),
39 Type::String,
40 ),
41 swamp_script_ast::LiteralKind::Bool => {
42 let bool_val = if node_text == "false" {
43 false
44 } else if node_text == "true" {
45 true
46 } else {
47 return Err(self.create_err(ErrorKind::BoolConversionError, ast_node));
48 };
49 (Literal::BoolLiteral(bool_val), Type::Bool)
50 }
51 swamp_script_ast::LiteralKind::EnumVariant(enum_literal) => {
52 let (enum_name, variant_name) = match enum_literal {
53 swamp_script_ast::EnumVariantLiteral::Simple(enum_name, variant_name) => {
54 (enum_name, variant_name)
55 }
56 swamp_script_ast::EnumVariantLiteral::Tuple(enum_name, variant_name, _) => {
57 (enum_name, variant_name)
58 }
59 swamp_script_ast::EnumVariantLiteral::Struct(enum_name, variant_name, _, _) => {
60 (enum_name, variant_name)
61 }
62 };
63
64 let (symbol_table, name) = self.get_symbol_table_and_name(enum_name)?;
65 if let Some(enum_type_ref) = symbol_table.get_enum(&name) {
66 let enum_type = Type::Enum(enum_type_ref.clone());
67
68 let variant_ref = self.analyze_enum_variant_ref(enum_name, variant_name)?;
70
71 let resolved_data = match enum_literal {
72 swamp_script_ast::EnumVariantLiteral::Simple(_, _) => {
73 EnumLiteralData::Nothing
74 }
75 swamp_script_ast::EnumVariantLiteral::Tuple(
76 _node,
77 _variant,
78 expressions,
79 ) => {
80 let resolved = self.analyze_argument_expressions(None, expressions)?;
81 EnumLiteralData::Tuple(resolved)
82 }
83 swamp_script_ast::EnumVariantLiteral::Struct(
84 _qualified_type_identifier,
85 variant,
86 anonym_struct_field_and_expressions,
87 detected_rest,
88 ) => {
89 if let EnumVariantType::Struct(resolved_variant_struct_ref) =
90 &*variant_ref
91 {
92 if anonym_struct_field_and_expressions.len()
93 != resolved_variant_struct_ref
94 .anon_struct
95 .field_name_sorted_fields
96 .len()
97 {
98 return Err(self.create_err(
99 ErrorKind::WrongNumberOfArguments(
100 anonym_struct_field_and_expressions.len(),
101 resolved_variant_struct_ref
102 .anon_struct
103 .field_name_sorted_fields
104 .len(),
105 ),
106 &variant.0,
107 ));
108 }
109
110 let resolved = self.analyze_anon_struct_instantiation(
111 &variant.0.clone(),
112 &resolved_variant_struct_ref.anon_struct,
113 anonym_struct_field_and_expressions,
114 *detected_rest,
115 )?;
116
117 EnumLiteralData::Struct(resolved)
118 } else {
119 return Err(self.create_err(
120 ErrorKind::WrongEnumVariantContainer(variant_ref.clone()),
121 &variant.0,
122 ));
123 }
124 }
125 };
126
127 return Ok((
128 Literal::EnumVariantLiteral(variant_ref, resolved_data),
129 enum_type,
130 ));
131 }
132 return Err(self.create_err(ErrorKind::UnknownEnumType, ast_node));
133 }
134
135 swamp_script_ast::LiteralKind::Slice(items) => {
136 if items.is_empty() {
137 if let Some(found_expected_type) = context.expected_type {
138 match found_expected_type {
139 Type::Map(key, value) => (
140 Literal::Map(*key.clone(), *value.clone(), vec![]),
141 found_expected_type.clone(),
142 ),
143 Type::Vec(element_type) => (
144 Literal::Vec(*element_type.clone(), vec![]),
145 found_expected_type.clone(),
146 ),
147 _ => {
148 return Err(self.create_err(
149 ErrorKind::EmptySliceCanOnlyBeMapOrArray,
150 ast_node,
151 ));
152 }
153 }
154 } else {
155 return Err(
156 self.create_err(ErrorKind::EmptySliceCanOnlyBeMapOrArray, ast_node)
157 );
158 }
159 } else {
160 let (encountered_element_type, resolved_items) =
161 self.analyze_slice_type_helper(ast_node, items, context.expected_type)?;
162 if let Some(found_expected_type) = context.expected_type {
163 match found_expected_type {
164 Type::Vec(required_element_type) => {
165 if !encountered_element_type.compatible_with(required_element_type)
166 {
167 return Err(self.create_err(
168 ErrorKind::IncompatibleTypes(
169 *required_element_type.clone(),
170 encountered_element_type,
171 ),
172 ast_node,
173 ));
174 }
175
176 (
177 Literal::Vec(encountered_element_type.clone(), resolved_items),
178 Type::Vec(Box::from(encountered_element_type)),
179 )
180 }
181 _ => (
182 Literal::Slice(encountered_element_type.clone(), resolved_items),
183 Type::Slice(Box::from(encountered_element_type)),
184 ),
185 }
186 } else {
187 (
189 Literal::Vec(encountered_element_type.clone(), resolved_items),
190 Type::Vec(Box::from(encountered_element_type)),
191 )
192 }
193 }
194 }
195
196 swamp_script_ast::LiteralKind::SlicePair(entries) => {
197 let (expressions_tuple, encountered_key_type, encountered_value_type) =
198 self.analyze_slice_pair_literal(ast_node, &entries)?;
199
200 if let Some(found_expected_type) = context.expected_type {
201 match found_expected_type {
202 Type::Map(required_key_type, required_value_type) => {
203 if !required_key_type.compatible_with(&encountered_key_type) {
204 return Err(self.create_err(
205 ErrorKind::IncompatibleTypes(
206 *required_key_type.clone(),
207 encountered_key_type,
208 ),
209 ast_node,
210 ));
211 }
212
213 if !required_value_type.compatible_with(&encountered_value_type) {
214 return Err(self.create_err(
215 ErrorKind::IncompatibleTypes(
216 *required_key_type.clone(),
217 encountered_key_type,
218 ),
219 ast_node,
220 ));
221 }
222
223 (
224 Literal::Map(
225 encountered_key_type.clone(),
226 encountered_value_type.clone(),
227 expressions_tuple,
228 ),
229 Type::Map(
230 Box::from(encountered_key_type),
231 Box::from(encountered_value_type),
232 ),
233 )
234 }
235 _ => (
236 Literal::SlicePair(
237 encountered_key_type.clone(),
238 encountered_value_type.clone(),
239 expressions_tuple,
240 ),
241 Type::SlicePair(
242 Box::from(encountered_key_type),
243 Box::from(encountered_value_type),
244 ),
245 ),
246 }
247 } else {
248 (
250 Literal::Map(
251 encountered_key_type.clone(),
252 encountered_value_type.clone(),
253 expressions_tuple,
254 ),
255 Type::Map(
256 Box::from(encountered_key_type),
257 Box::from(encountered_value_type),
258 ),
259 )
260 }
261 }
262
263 swamp_script_ast::LiteralKind::Tuple(expressions) => {
264 let (tuple_type_ref, resolved_items) = self.analyze_tuple_literal(&expressions)?;
265 (
266 Literal::TupleLiteral(tuple_type_ref.clone(), resolved_items),
267 Type::Tuple(tuple_type_ref),
268 )
269 }
270 swamp_script_ast::LiteralKind::None => {
271 if let Some(found_expected_type) = context.expected_type {
272 if let Type::Optional(_some_type) = found_expected_type {
273 return Ok((Literal::NoneLiteral, found_expected_type.clone()));
274 }
275 }
276 return Err(self.create_err(ErrorKind::NoneNeedsExpectedTypeHint, &ast_node));
277 }
278 };
279
280 Ok(resolved_literal)
281 }
282
283 fn analyze_tuple_literal(
284 &mut self,
285 items: &[swamp_script_ast::Expression],
286 ) -> Result<(Vec<Type>, Vec<Expression>), Error> {
287 let expressions = self.analyze_argument_expressions(None, items)?;
288 let mut tuple_types = Vec::new();
289 for expr in &expressions {
290 let item_type = expr.ty.clone();
291 tuple_types.push(item_type);
292 }
293
294 Ok((tuple_types, expressions))
295 }
296
297 fn analyze_slice_pair_literal(
298 &mut self,
299 node: &swamp_script_ast::Node,
300 entries: &[(swamp_script_ast::Expression, swamp_script_ast::Expression)],
301 ) -> Result<(Vec<(Expression, Expression)>, Type, Type), Error> {
302 if entries.is_empty() {
303 return Err(self.create_err(ErrorKind::EmptyMapLiteral, node));
304 }
305
306 let (first_key, first_value) = &entries[0];
308 let anything_context = TypeContext::new_anything_argument();
309 let resolved_first_key = self.analyze_expression(first_key, &anything_context)?;
310 let resolved_first_value = self.analyze_expression(first_value, &anything_context)?;
311 let key_type = resolved_first_key.ty.clone();
312 let value_type = resolved_first_value.ty.clone();
313
314 let key_context = TypeContext::new_argument(&key_type);
315 let value_context = TypeContext::new_argument(&value_type);
316
317 let mut resolved_entries = Vec::new();
319 resolved_entries.push((resolved_first_key, resolved_first_value));
320
321 for (key, value) in entries.iter().skip(1) {
322 let resolved_key = self.analyze_expression(key, &key_context)?;
323 let resolved_value = self.analyze_expression(value, &value_context)?;
324
325 if !resolved_key.ty.compatible_with(&key_type) {
326 return Err(self.create_err(
327 ErrorKind::MapKeyTypeMismatch {
328 expected: key_type,
329 found: resolved_key.ty,
330 },
331 node,
332 ));
333 }
334
335 if !resolved_value.ty.compatible_with(&value_type) {
336 return Err(self.create_err(
337 ErrorKind::MapValueTypeMismatch {
338 expected: value_type,
339 found: resolved_value.ty,
340 },
341 node,
342 ));
343 }
344
345 resolved_entries.push((resolved_key, resolved_value));
346 }
347
348 Ok((resolved_entries, key_type, value_type))
349 }
350
351 #[must_use]
352 pub fn create_err(&self, kind: ErrorKind, ast_node: &swamp_script_ast::Node) -> Error {
353 error!(?kind, "error created");
354 Error {
355 node: self.to_node(ast_node),
356 kind,
357 }
358 }
359
360 #[must_use]
361 pub fn create_err_resolved(&self, kind: ErrorKind, resolved_node: &Node) -> Error {
362 Error {
363 node: resolved_node.clone(),
364 kind,
365 }
366 }
367}