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