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