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