1use crate::Analyzer;
6use crate::err::{Error, ErrorKind};
7use seq_map::SeqMap;
8use std::rc::Rc;
9use swamp_semantic::{
10 ExternalFunctionDefinition, Function, InternalFunctionDefinition, LocalIdentifier,
11 SemanticError, UseItem,
12};
13use swamp_types::TypeVariable;
14use swamp_types::prelude::*;
15use swamp_types::{GenericAwareSignature, ParameterizedTypeBlueprint, ParameterizedTypeKind};
16
17impl Analyzer<'_> {
18 fn general_import(
19 &mut self,
20 path: &[String],
21 import_items: &swamp_ast::ImportItems,
22 node: &swamp_ast::Node,
23 ) -> Result<(), Error> {
24 let found_module = self
25 .shared
26 .get_module(path)
27 .ok_or_else(|| self.create_err(ErrorKind::UnknownModule, node))?
28 .clone();
29
30 match import_items {
31 swamp_ast::ImportItems::Nothing => {
32 let last_name = path.last().unwrap();
33 if self
34 .shared
35 .lookup_table
36 .get_module_link(last_name)
37 .is_none()
38 {
39 self.shared
40 .lookup_table
41 .add_module_link(last_name, found_module.clone())
42 .map_err(|err| self.create_err(ErrorKind::SemanticError(err), node))?;
43 }
44 }
45 swamp_ast::ImportItems::Items(items) => {
46 for ast_items in items {
47 match ast_items {
48 swamp_ast::ImportItem::Identifier(node) => {
49 let ident_resolved_node = self.to_node(&node.0);
50 let ident = UseItem::Identifier(ident_resolved_node.clone());
51 let ident_text =
52 self.get_text_resolved(&ident_resolved_node).to_string();
53 if let Some(found_symbol) =
54 found_module.symbol_table.get_symbol(&ident_text)
55 {
56 self.shared
57 .lookup_table
58 .add_symbol(&ident_text, found_symbol.clone())
59 .map_err(|err| {
60 self.create_err(ErrorKind::SemanticError(err), &node.0)
61 })?;
62 } else {
63 return Err(self.create_err_resolved(
64 ErrorKind::UnknownTypeReference,
65 &ident_resolved_node,
66 ));
67 }
68 ident
69 }
70 swamp_ast::ImportItem::Type(node) => {
71 let ident_resolved_node = self.to_node(&node.0);
72 let ident_text =
73 self.get_text_resolved(&ident_resolved_node).to_string();
74 if let Some(found_symbol) =
75 found_module.symbol_table.get_symbol(&ident_text)
76 {
77 self.shared
78 .lookup_table
79 .add_symbol(&ident_text, found_symbol.clone())
80 .map_err(|err| {
81 self.create_err(ErrorKind::SemanticError(err), &node.0)
82 })?;
83 } else {
84 return Err(self.create_err_resolved(
85 ErrorKind::UnknownTypeReference,
86 &ident_resolved_node,
87 ));
88 }
89 UseItem::TypeIdentifier(self.to_node(&node.0))
90 }
91 };
92 }
93 }
94 swamp_ast::ImportItems::All => {
95 self.shared
96 .lookup_table
97 .extend_from(&found_module.symbol_table)?;
98 }
99 }
100
101 Ok(())
102 }
103
104 fn analyze_mod_definition(&mut self, mod_definition: &swamp_ast::Mod) -> Result<(), Error> {
105 let mut path = Vec::new();
106 for ast_node in &mod_definition.module_path.0 {
107 path.push(self.get_text(ast_node).to_string());
108 }
109
110 let mut nodes_copy = path.clone();
111 nodes_copy.insert(0, "crate".to_string());
112
113 self.general_import(
114 &nodes_copy,
115 &mod_definition.items,
116 &mod_definition.module_path.0[0],
117 )
118 }
119
120 fn analyze_use_definition(&mut self, use_definition: &swamp_ast::Use) -> Result<(), Error> {
121 let mut nodes = Vec::new();
122 for ast_node in &use_definition.module_path.0 {
123 nodes.push(self.to_node(ast_node));
124 }
125
126 let path: Vec<String> = nodes
127 .iter()
128 .map(|node| {
129 let text = self.get_text_resolved(node);
130 text.to_string()
131 })
132 .collect();
133
134 self.general_import(
135 &path,
136 &use_definition.items,
137 &use_definition.module_path.0[0],
138 )
139 }
140
141 fn analyze_enum_type_definition(
142 &mut self,
143 enum_type_name: &swamp_ast::LocalTypeIdentifierWithOptionalTypeVariables,
144 ast_variants: &[swamp_ast::EnumVariantType],
145 ) -> Result<(), Error> {
146 let mut resolved_variants = SeqMap::new();
147
148 let mut new_enum_type = EnumType {
149 name: self.to_node(&enum_type_name.name),
150 assigned_name: self.get_text(&enum_type_name.name).to_string(),
151 module_path: vec![],
152 variants: SeqMap::default(),
153 instantiated_type_parameters: Vec::default(),
154 };
155
156 for (container_index_usize, ast_variant_type) in ast_variants.iter().enumerate() {
157 let variant_name_node = match ast_variant_type {
158 swamp_ast::EnumVariantType::Simple(name) => name,
159 swamp_ast::EnumVariantType::Tuple(name, _) => name,
160 swamp_ast::EnumVariantType::Struct(name, _) => name,
161 };
162
163 let common = EnumVariantCommon {
164 name: self.to_node(variant_name_node),
165 assigned_name: self.get_text(variant_name_node).to_string(),
166 container_index: container_index_usize as u8,
167 };
168
169 let variant_type = match ast_variant_type {
170 swamp_ast::EnumVariantType::Simple(_variant_name_node) => {
171 let simple_ref = EnumVariantSimpleType { common };
172 EnumVariantType::Nothing(EnumVariantSimpleType::from(simple_ref))
173 }
174 swamp_ast::EnumVariantType::Tuple(_variant_name_node, types) => {
175 let mut vec = Vec::new();
176 for tuple_type in types {
177 let resolved_type = self.analyze_type(tuple_type)?;
178 vec.push(resolved_type);
179 }
180
181 let resolved_tuple_type = EnumVariantTupleType {
182 common,
183 fields_in_order: vec,
184 };
185
186 EnumVariantType::Tuple(resolved_tuple_type)
187 }
188 swamp_ast::EnumVariantType::Struct(_variant_name_node, ast_struct_fields) => {
189 let mut fields = SeqMap::new();
190
191 for field_with_type in &ast_struct_fields.fields {
192 let resolved_type = self.analyze_type(&field_with_type.field_type)?;
194 let field_name_str =
195 self.get_text(&field_with_type.field_name.0).to_string();
196
197 let resolved_field = StructTypeField {
198 identifier: Some(self.to_node(&field_with_type.field_name.0)),
199 field_type: resolved_type,
200 };
201
202 fields.insert(field_name_str, resolved_field).map_err(|_| {
203 self.create_err(
204 ErrorKind::DuplicateFieldName,
205 &field_with_type.field_name.0,
206 )
207 })?;
208 }
209
210 let enum_variant_struct_type = EnumVariantStructType {
211 common,
212 anon_struct: AnonymousStructType::new(fields),
213 };
214
215 EnumVariantType::Struct(enum_variant_struct_type)
216 }
217 };
218
219 let variant_name_str = self.get_text(variant_name_node).to_string();
220
221 resolved_variants
222 .insert(variant_name_str, variant_type.into())
223 .map_err(|_| self.create_err(ErrorKind::DuplicateFieldName, variant_name_node))?;
224 }
225
226 new_enum_type.variants = resolved_variants;
227
228 self.shared
229 .definition_table
230 .add_enum_type(new_enum_type.clone())
231 .map_err(|err| self.create_err(ErrorKind::SemanticError(err), &enum_type_name.name))?;
232
233 self.shared
234 .lookup_table
235 .add_enum_type_link(new_enum_type)
236 .map_err(|err| self.create_err(ErrorKind::SemanticError(err), &enum_type_name.name))?;
237
238 Ok(())
239 }
240
241 pub fn analyze_alias_type_definition(
244 &mut self,
245 ast_alias: &swamp_ast::AliasType,
246 ) -> Result<AliasType, Error> {
247 let resolved_type = self.analyze_type(&ast_alias.referenced_type)?;
248
249 let alias_name_str = self.get_text(&ast_alias.identifier.0).to_string();
250 let resolved_alias = AliasType {
251 name: self.to_node(&ast_alias.identifier.0),
252 assigned_name: alias_name_str,
253 referenced_type: resolved_type,
254 };
255
256 let resolved_alias_ref = self
257 .shared
258 .definition_table
259 .add_alias(resolved_alias)
260 .map_err(|err| {
261 self.create_err(ErrorKind::SemanticError(err), &ast_alias.identifier.0)
262 })?;
263 self.shared
264 .lookup_table
265 .add_alias_link(resolved_alias_ref.clone())
266 .map_err(|err| {
267 self.create_err(ErrorKind::SemanticError(err), &ast_alias.identifier.0)
268 })?;
269
270 Ok(resolved_alias_ref)
271 }
272
273 pub fn analyze_anonymous_struct_type(
276 &mut self,
277 ast_struct: &swamp_ast::AnonymousStructType,
278 ) -> Result<AnonymousStructType, Error> {
279 let resolved_fields = self.analyze_anonymous_struct_type_fields(&ast_struct.fields)?;
280
281 let resolved_anon_struct = AnonymousStructType::new_and_sort_fields(&resolved_fields);
282
283 Ok(resolved_anon_struct)
284 }
285
286 pub fn analyze_anonymous_struct_type_fields(
289 &mut self,
290 ast_struct_fields: &[swamp_ast::StructTypeField],
291 ) -> Result<SeqMap<String, StructTypeField>, Error> {
292 let mut resolved_fields = SeqMap::new();
293
294 for field_name_and_type in ast_struct_fields {
295 let resolved_type = self.analyze_type(&field_name_and_type.field_type)?;
296 let name_string = self.get_text(&field_name_and_type.field_name.0).to_string();
297
298 let field_type = StructTypeField {
299 identifier: Some(self.to_node(&field_name_and_type.field_name.0)),
300 field_type: resolved_type,
301 };
302
303 resolved_fields
304 .insert(name_string, field_type)
305 .map_err(|_| {
306 self.create_err(
307 ErrorKind::DuplicateFieldName,
308 &field_name_and_type.field_name.0,
309 )
310 })?;
311 }
312
313 Ok(resolved_fields)
314 }
315
316 pub fn convert_to_type_variables(
317 &mut self,
318 ast_type_variables: &[swamp_ast::TypeVariable],
319 ) -> Vec<String> {
320 let mut types = Vec::new();
321 for ast_type_variable in ast_type_variables {
322 let name = self.get_text(&ast_type_variable.0).to_string();
323 types.push(name);
324 }
325 types
326 }
327
328 pub fn set_type_variables_to_extra_symbol_table(&mut self, type_variables: &[String]) {
331 self.shared
332 .type_variables
333 .push_type_scope_with_variables(type_variables)
334 .unwrap();
335 }
336
337 pub fn analyze_named_struct_type_definition(
340 &mut self,
341 ast_struct_def: &swamp_ast::NamedStructDef,
342 ) -> Result<(), Error> {
343 let has_type_variables = !ast_struct_def.identifier.type_variables.is_empty();
344
345 let type_variables =
346 self.convert_to_type_variables(&ast_struct_def.identifier.type_variables);
347
348 if has_type_variables {
349 self.set_type_variables_to_extra_symbol_table(&type_variables);
350 }
351
352 let struct_name_str = self.get_text(&ast_struct_def.identifier.name).to_string();
353
354 let fields =
355 self.analyze_anonymous_struct_type_fields(&ast_struct_def.struct_type.fields)?;
356
357 let analyzed_anonymous_struct = AnonymousStructType::new(fields); let named_struct_type = NamedStructType {
360 name: self.to_node(&ast_struct_def.identifier.name),
361 anon_struct_type: analyzed_anonymous_struct,
362 assigned_name: struct_name_str,
363 module_path: self.shared.definition_table.module_path(),
364 instantiated_type_parameters: Vec::default(),
365 blueprint_info: None,
366 };
367
368 if has_type_variables {
369 self.shared.type_variables.pop_type_scope();
372
373 let blueprint_ref = self
374 .shared
375 .definition_table
376 .add_blueprint(ParameterizedTypeBlueprint {
377 kind: ParameterizedTypeKind::Struct(named_struct_type),
378 type_variables,
379 defined_in_module_path: self.module_path.clone(),
380 })
381 .map_err(|err| {
382 self.create_err(
383 ErrorKind::SemanticError(err),
384 &ast_struct_def.identifier.name,
385 )
386 })?;
387
388 self.shared
389 .lookup_table
390 .add_blueprint_link(blueprint_ref)
391 .map_err(|err| {
392 self.create_err(
393 ErrorKind::SemanticError(err),
394 &ast_struct_def.identifier.name,
395 )
396 })?;
397
398 return Ok(());
399 }
400
401 let struct_ref = self
402 .shared
403 .definition_table
404 .add_struct(named_struct_type)
405 .map_err(|err| {
406 self.create_err(
407 ErrorKind::SemanticError(err),
408 &ast_struct_def.identifier.name,
409 )
410 })?;
411
412 self.shared
413 .lookup_table
414 .add_struct_link(struct_ref)
415 .map_err(|err| {
416 self.create_err(
417 ErrorKind::SemanticError(err),
418 &ast_struct_def.identifier.name,
419 )
420 })?;
421
422 Ok(())
423 }
424
425 pub(crate) fn analyze_function_definition(
426 &mut self,
427 function: &swamp_ast::Function,
428 ) -> Result<Function, Error> {
429 let func = match function {
430 swamp_ast::Function::Internal(function_data) => {
431 let parameters = self.analyze_parameters(&function_data.declaration.params)?;
432 let return_type = if let Some(found) = &function_data.declaration.return_type {
433 self.analyze_type(found)?
434 } else {
435 Type::Unit
436 };
437
438 for param in ¶meters {
442 self.create_local_variable_resolved(
443 ¶m.node.as_ref().unwrap().name,
444 param.node.as_ref().unwrap().is_mutable.as_ref(),
445 ¶m.resolved_type.clone(),
446 )?;
447 }
448 let function_name = self
449 .get_text(&function_data.declaration.name)
450 .trim()
451 .to_string();
452 let statements =
453 self.analyze_function_body_expression(&function_data.body, &return_type)?;
454 let converted_generic_variables = function_data
457 .declaration
458 .generic_variables
459 .iter()
460 .map(|ast_variable| {
461 let name_str = self.get_text(&ast_variable.0).to_string();
462 TypeVariable(name_str)
463 })
464 .collect();
465
466 let internal = InternalFunctionDefinition {
467 signature: GenericAwareSignature {
468 signature: Signature {
469 parameters,
470 return_type: Box::new(return_type),
471 },
472 generic_type_variables: converted_generic_variables,
473 },
474 body: statements,
475 name: LocalIdentifier(self.to_node(&function_data.declaration.name)),
476 assigned_name: self.get_text(&function_data.declaration.name).to_string(),
477 variable_scopes: self.scope.clone(),
478 function_scope_state: self.function_variables.clone(),
479 program_unique_id: self.shared.state.allocate_internal_function_id(),
480 };
481
482 let function_ref = self
483 .shared
484 .definition_table
485 .add_internal_function(&function_name, internal)
486 .map_err(|err| {
487 self.create_err(
488 ErrorKind::SemanticError(err),
489 &function_data.declaration.name,
490 )
491 })?;
492
493 self.shared
494 .lookup_table
495 .add_internal_function_link(&function_name, function_ref.clone())
496 .map_err(|err| {
497 self.create_err(
498 ErrorKind::SemanticError(err),
499 &function_data.declaration.name,
500 )
501 })?;
502
503 Function::Internal(function_ref)
504 }
505 swamp_ast::Function::External(ast_signature) => {
506 let parameters = self.analyze_parameters(&ast_signature.params)?;
507 let external_return_type = if let Some(found) = &ast_signature.return_type {
508 self.analyze_type(found)?
509 } else {
510 Type::Unit
511 };
512
513 let return_type = external_return_type;
514 let external_function_id = self.shared.state.allocate_external_function_id();
515
516 let external = ExternalFunctionDefinition {
517 assigned_name: self.get_text(&ast_signature.name).to_string(),
518 signature: Signature {
519 parameters,
520 return_type: Box::new(return_type),
521 },
522 name: Some(self.to_node(&ast_signature.name)),
523 id: external_function_id,
524 };
525
526 let function_ref = self
527 .shared
528 .definition_table
529 .add_external_function_declaration(external)
530 .map_err(|err| {
531 self.create_err(ErrorKind::SemanticError(err), &ast_signature.name)
532 })?;
533
534 self.shared
535 .lookup_table
536 .add_external_function_declaration_link(function_ref.clone())
537 .map_err(|err| {
538 self.create_err(ErrorKind::SemanticError(err), &ast_signature.name)
539 })?;
540
541 Function::External(function_ref)
542 }
543 };
544
545 Ok(func)
546 }
547
548 pub fn debug_definition(&self, _definition: &swamp_ast::Definition) {
549 }
561
562 pub fn analyze_definition(&mut self, ast_def: &swamp_ast::Definition) -> Result<(), Error> {
565 match ast_def {
567 swamp_ast::Definition::NamedStructDef(ast_struct) => {
568 self.analyze_named_struct_type_definition(ast_struct)?;
569 }
570 swamp_ast::Definition::AliasDef(alias_def) => {
571 self.analyze_alias_type_definition(alias_def)?;
572 }
573 swamp_ast::Definition::EnumDef(identifier, variants) => {
574 self.analyze_enum_type_definition(identifier, variants)?;
575 }
576 swamp_ast::Definition::FunctionDef(function) => {
577 let resolved_return_type = self.analyze_return_type(function)?;
578 self.start_function();
579 self.analyze_function_definition(function)?;
580
581 self.stop_function();
582 }
583 swamp_ast::Definition::ImplDef(type_identifier, functions) => {
584 self.analyze_impl_definition(type_identifier, functions)?;
585 }
586 swamp_ast::Definition::Mod(mod_info) => self.analyze_mod_definition(mod_info)?,
587 swamp_ast::Definition::Use(use_info) => self.analyze_use_definition(use_info)?,
588 swamp_ast::Definition::Constant(const_info) => {
589 self.analyze_constant_definition(const_info)?;
590 }
591 };
592
593 Ok(())
594 }
595
596 fn analyze_impl_definition(
597 &mut self,
598 attached_to_type: &swamp_ast::LocalTypeIdentifierWithOptionalTypeVariables,
599 functions: &[swamp_ast::Function],
600 ) -> Result<(), Error> {
601 let type_name_text = self.get_text(&attached_to_type.name).to_string();
602
603 let converted_type_variables_to_ast_types = attached_to_type
604 .type_variables
605 .iter()
606 .map(|x| {
607 swamp_ast::Type::Named(swamp_ast::QualifiedTypeIdentifier {
608 name: swamp_ast::LocalTypeIdentifier(x.0.clone()),
609 module_path: None,
610 generic_params: vec![],
611 })
612 })
613 .collect();
614
615 let qualified = swamp_ast::QualifiedTypeIdentifier {
616 name: swamp_ast::LocalTypeIdentifier(attached_to_type.name.clone()),
617 module_path: None,
618 generic_params: converted_type_variables_to_ast_types,
619 };
620
621 let is_parameterized = !qualified.generic_params.is_empty();
622
623 let maybe_type_to_attach_to = if is_parameterized {
624 let type_variables = self.convert_to_type_variables(&attached_to_type.type_variables);
625 self.set_type_variables_to_extra_symbol_table(&type_variables);
626 self.shared
627 .lookup_table
628 .get_blueprint(&type_name_text)
629 .map_or_else(
630 || {
631 panic!("blueprint was missing");
632 },
633 |found_blueprint| Some(Type::Blueprint(found_blueprint.clone())),
634 )
635 } else {
636 Some(self.analyze_named_type(&qualified)?)
637 };
638
639 if let Some(type_to_attach_to) = maybe_type_to_attach_to {
640 let function_refs: Vec<&swamp_ast::Function> = functions.iter().collect();
641
642 self.analyze_impl_functions(&type_to_attach_to, &function_refs)?;
643
644 if is_parameterized {
645 self.shared.type_variables.pop_type_scope();
646 }
647
648 Ok(())
649 } else {
650 Err(self.create_err(
651 ErrorKind::CanNotAttachFunctionsToType,
652 &attached_to_type.name,
653 ))
654 }
655 }
656
657 pub fn analyze_impl_functions(
660 &mut self,
661 attach_to_type: &Type, functions: &[&swamp_ast::Function],
663 ) -> Result<(), Error> {
664 self.shared
665 .state
666 .instantiator
667 .associated_impls
668 .prepare(attach_to_type);
669
670 for function in functions {
671 self.start_function();
673
674 let function_name = match function {
675 swamp_ast::Function::Internal(function_with_body) => {
676 &function_with_body.declaration
677 }
678 swamp_ast::Function::External(external_declaration) => external_declaration,
679 };
680
681 let function_name_str = self.get_text(&function_name.name).to_string();
682
683 let resolved_function = self.analyze_impl_func(function, attach_to_type)?;
684
685 let resolved_function_ref = Rc::new(resolved_function);
686
687 self.stop_function();
688
689 self.shared
690 .state
691 .instantiator
692 .associated_impls
693 .add_member_function(attach_to_type, &function_name_str, resolved_function_ref)
694 .map_err(|err| {
695 self.create_err(ErrorKind::SemanticError(err), &function_name.name)
696 })?;
697 }
698
699 Ok(())
700 }
701
702 pub(crate) fn push_type_scope_with_variables(
703 &mut self,
704 type_variables: &[swamp_ast::TypeVariable],
705 ) -> Result<(), SemanticError> {
706 self.shared.type_variables.push_type_scope();
707
708 for type_var in type_variables {
709 let variable_name_string = self.get_text(&type_var.0).to_string();
710 self.shared
711 .type_variables
712 .declare_type_variable(&variable_name_string)?;
713 }
714
715 Ok(())
716 }
717
718 #[allow(clippy::too_many_lines)]
719 fn analyze_impl_func(
720 &mut self,
721 function: &swamp_ast::Function,
722 self_type: &Type,
723 ) -> Result<Function, Error> {
724 let resolved_fn = match function {
725 swamp_ast::Function::Internal(function_data) => {
726 let has_function_local_generic_type_variables =
727 !function_data.declaration.generic_variables.is_empty();
728 if has_function_local_generic_type_variables {
729 self.push_type_scope_with_variables(
730 &function_data.declaration.generic_variables,
731 )?;
732 }
733
734 let mut parameters = Vec::new();
735
736 if let Some(found_self) = &function_data.declaration.self_parameter {
737 parameters.push(TypeForParameter {
738 name: self.get_text(&found_self.self_node).to_string(),
739 resolved_type: self_type.clone(),
740 is_mutable: found_self.is_mutable.is_some(),
741 node: Option::from(ParameterNode {
742 name: self.to_node(&found_self.self_node),
743 is_mutable: self.to_node_option(Option::from(&found_self.is_mutable)),
744 }),
745 });
746 }
747
748 for param in &function_data.declaration.params {
749 let resolved_type = self.analyze_type(¶m.param_type)?;
750
751 parameters.push(TypeForParameter {
752 name: self.get_text(¶m.variable.name).to_string(),
753 resolved_type,
754 is_mutable: param.variable.is_mutable.is_some(),
755 node: Option::from(ParameterNode {
756 name: self.to_node(¶m.variable.name),
757 is_mutable: self
758 .to_node_option(Option::from(¶m.variable.is_mutable)),
759 }),
760 });
761 }
762
763 let return_type =
764 self.analyze_maybe_type(Option::from(&function_data.declaration.return_type))?;
765
766 for param in ¶meters {
767 self.create_local_variable_resolved(
768 ¶m.node.as_ref().unwrap().name,
769 param.node.as_ref().unwrap().is_mutable.as_ref(),
770 ¶m.resolved_type.clone(),
771 )?;
772 }
773
774 let statements =
775 self.analyze_function_body_expression(&function_data.body, &return_type)?;
776
777 if has_function_local_generic_type_variables {
778 self.shared.type_variables.pop_type_scope();
779 }
780
781 let converted_generic_variables = function_data
782 .declaration
783 .generic_variables
784 .iter()
785 .map(|ast_variable| {
786 let name_str = self.get_text(&ast_variable.0).to_string();
787 TypeVariable(name_str)
788 })
789 .collect();
790
791 let internal = InternalFunctionDefinition {
792 signature: GenericAwareSignature {
793 signature: Signature {
794 parameters,
795 return_type: Box::new(return_type),
796 },
797 generic_type_variables: converted_generic_variables,
798 },
799 body: statements,
800 name: LocalIdentifier(self.to_node(&function_data.declaration.name)),
801 assigned_name: self.get_text(&function_data.declaration.name).to_string(),
802 variable_scopes: self.scope.clone(),
803 function_scope_state: self.function_variables.clone(),
804 program_unique_id: self.shared.state.allocate_internal_function_id(),
805 };
806
807 let internal_ref = Rc::new(internal);
808
809 Function::Internal(internal_ref)
810 }
811
812 swamp_ast::Function::External(signature) => {
813 let mut parameters = Vec::new();
814
815 if let Some(found_self) = &signature.self_parameter {
816 parameters.push(TypeForParameter {
817 name: self.get_text(&found_self.self_node).to_string(),
818 resolved_type: self_type.clone(),
819 is_mutable: found_self.is_mutable.is_some(),
820 node: Option::from(ParameterNode {
821 name: self.to_node(&found_self.self_node),
822 is_mutable: self.to_node_option(Option::from(&found_self.is_mutable)),
823 }),
824 });
825 }
826
827 for param in &signature.params {
829 let resolved_type = self.analyze_type(¶m.param_type)?;
830
831 parameters.push(TypeForParameter {
832 name: self.get_text(¶m.variable.name).to_string(),
833 resolved_type,
834 is_mutable: param.variable.is_mutable.is_some(),
835 node: Option::from(ParameterNode {
836 name: self.to_node(¶m.variable.name),
837 is_mutable: self
838 .to_node_option(Option::from(¶m.variable.is_mutable)),
839 }),
840 });
841 }
842
843 let return_type = self.analyze_maybe_type(Option::from(&signature.return_type))?;
844
845 let external_id = self.shared.state.allocate_external_function_id();
846
847 let external = ExternalFunctionDefinition {
848 assigned_name: self.get_text(&signature.name).to_string(),
849 name: Some(self.to_node(&signature.name)),
850 signature: Signature {
851 parameters,
852 return_type: Box::new(return_type),
853 },
854 id: external_id,
855 };
856
857 let external_ref = Rc::new(external);
858
859 Function::External(external_ref)
860 }
861 };
862 Ok(resolved_fn)
863 }
864}