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,
12 SemanticError, UseItem,
13};
14use swamp_script_types::prelude::*;
15use swamp_script_types::{
16 GenericAwareSignature, ParameterizedTypeBlueprint, ParameterizedTypeKind,
17};
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 self.shared
343 .type_variables
344 .push_type_scope_with_variables(type_variables);
345 }
346
347 pub fn analyze_named_struct_type_definition(
350 &mut self,
351 ast_struct_def: &swamp_script_ast::NamedStructDef,
352 ) -> Result<(), Error> {
353 let has_type_variables = !ast_struct_def.identifier.type_variables.is_empty();
354
355 let type_variables =
356 self.convert_to_type_variables(&ast_struct_def.identifier.type_variables);
357
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 instantiated_type_parameters: Vec::default(),
375 blueprint_info: None,
376 };
377
378 if has_type_variables {
379 self.shared.type_variables.pop_type_scope();
382
383 let blueprint_ref = self
384 .shared
385 .definition_table
386 .add_blueprint(ParameterizedTypeBlueprint {
387 kind: ParameterizedTypeKind::Struct(named_struct_type),
388 type_variables,
389 defined_in_module_path: self.module_path.clone(),
390 })
391 .map_err(|err| {
392 self.create_err(
393 ErrorKind::SemanticError(err),
394 &ast_struct_def.identifier.name,
395 )
396 })?;
397
398 self.shared
399 .lookup_table
400 .add_blueprint_link(blueprint_ref)
401 .map_err(|err| {
402 self.create_err(
403 ErrorKind::SemanticError(err),
404 &ast_struct_def.identifier.name,
405 )
406 })?;
407
408 return Ok(());
409 }
410
411 let struct_ref = self
412 .shared
413 .definition_table
414 .add_struct(named_struct_type)
415 .map_err(|err| {
416 self.create_err(
417 ErrorKind::SemanticError(err),
418 &ast_struct_def.identifier.name,
419 )
420 })?;
421
422 self.shared
423 .lookup_table
424 .add_struct_link(struct_ref)
425 .map_err(|err| {
426 self.create_err(
427 ErrorKind::SemanticError(err),
428 &ast_struct_def.identifier.name,
429 )
430 })?;
431
432 Ok(())
433 }
434
435 pub(crate) fn analyze_function_definition(
436 &mut self,
437 function: &swamp_script_ast::Function,
438 ) -> Result<Function, Error> {
439 let func = match function {
440 swamp_script_ast::Function::Internal(function_data) => {
441 let parameters = self.analyze_parameters(&function_data.declaration.params)?;
442 let return_type = if let Some(found) = &function_data.declaration.return_type {
443 self.analyze_type(found)?
444 } else {
445 Type::Unit
446 };
447
448 self.scope.return_type = return_type.clone();
449
450 for param in ¶meters {
452 self.create_local_variable_resolved(
453 ¶m.node.as_ref().unwrap().name,
454 param.node.as_ref().unwrap().is_mutable.as_ref(),
455 ¶m.resolved_type.clone(),
456 )?;
457 }
458 let function_name = self
459 .get_text(&function_data.declaration.name)
460 .trim()
461 .to_string();
462 let statements =
463 self.analyze_function_body_expression(&function_data.body, &return_type)?;
464 self.scope.return_type = Type::Unit;
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: vec![],
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_script_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_script_ast::Definition) {
549 }
561
562 pub fn analyze_definition(
565 &mut self,
566 ast_def: &swamp_script_ast::Definition,
567 ) -> Result<(), Error> {
568 self.debug_definition(ast_def);
569 match ast_def {
570 swamp_script_ast::Definition::NamedStructDef(ast_struct) => {
571 self.analyze_named_struct_type_definition(ast_struct)?;
572 }
573 swamp_script_ast::Definition::AliasDef(alias_def) => {
574 self.analyze_alias_type_definition(alias_def)?;
575 }
576 swamp_script_ast::Definition::EnumDef(identifier, variants) => {
577 self.analyze_enum_type_definition(identifier, variants)?;
578 }
579 swamp_script_ast::Definition::FunctionDef(function) => {
580 let resolved_return_type = self.analyze_return_type(function)?;
581 self.start_function(resolved_return_type);
582 self.analyze_function_definition(function)?;
583
584 self.stop_function();
585 }
586 swamp_script_ast::Definition::ImplDef(type_identifier, functions) => {
587 self.analyze_impl_definition(type_identifier, functions)?;
588 }
589 swamp_script_ast::Definition::Mod(mod_info) => self.analyze_mod_definition(mod_info)?,
590 swamp_script_ast::Definition::Use(use_info) => self.analyze_use_definition(use_info)?,
591 swamp_script_ast::Definition::Constant(const_info) => {
592 self.analyze_constant_definition(const_info)?;
593 }
594 };
595
596 Ok(())
597 }
598
599 fn analyze_impl_definition(
600 &mut self,
601 attached_to_type: &swamp_script_ast::LocalTypeIdentifierWithOptionalTypeVariables,
602 functions: &[swamp_script_ast::Function],
603 ) -> Result<(), Error> {
604 let type_name_text = self.get_text(&attached_to_type.name).to_string();
605
606 let converted_type_variables_to_ast_types = attached_to_type
607 .type_variables
608 .iter()
609 .map(|x| {
610 swamp_script_ast::Type::Named(swamp_script_ast::QualifiedTypeIdentifier {
611 name: swamp_script_ast::LocalTypeIdentifier(x.0.clone()),
612 module_path: None,
613 generic_params: vec![],
614 })
615 })
616 .collect();
617
618 let qualified = swamp_script_ast::QualifiedTypeIdentifier {
619 name: swamp_script_ast::LocalTypeIdentifier(attached_to_type.name.clone()),
620 module_path: None,
621 generic_params: converted_type_variables_to_ast_types,
622 };
623
624 let is_parameterized = !qualified.generic_params.is_empty();
625
626 let maybe_type_to_attach_to = if is_parameterized {
627 let type_variables = self.convert_to_type_variables(&attached_to_type.type_variables);
628 self.set_type_variables_to_extra_symbol_table(&type_variables);
629 if let Some(found_blueprint) = self.shared.lookup_table.get_blueprint(&type_name_text) {
630 Some(Type::Blueprint(found_blueprint.clone()))
631 } else {
632 panic!("must be something");
633 }
634 } else {
635 Some(self.analyze_named_type(&qualified)?)
636 };
637
638 if let Some(type_to_attach_to) = maybe_type_to_attach_to {
639 let function_refs: Vec<&swamp_script_ast::Function> = functions.iter().collect();
640
641 self.analyze_impl_functions(type_to_attach_to, &function_refs)?;
642
643 if is_parameterized {
644 self.shared.type_variables.pop_type_scope();
645 }
646
647 Ok(())
648 } else {
649 Err(self.create_err(
650 ErrorKind::CanNotAttachFunctionsToType,
651 &attached_to_type.name,
652 ))
653 }
654 }
655
656 pub fn analyze_impl_functions(
659 &mut self,
660 attach_to_type: Type, functions: &[&swamp_script_ast::Function],
662 ) -> Result<(), Error> {
663 self.shared
664 .state
665 .instantiator
666 .associated_impls
667 .prepare(&attach_to_type);
668
669 for function in functions {
670 let new_return_type = self.analyze_return_type(function)?;
671 self.start_function(new_return_type);
672
673 let function_name = match function {
674 swamp_script_ast::Function::Internal(function_with_body) => {
675 &function_with_body.declaration
676 }
677 swamp_script_ast::Function::External(external_declaration) => external_declaration,
678 };
679
680 let function_name_str = self.get_text(&function_name.name).to_string();
681
682 let resolved_function = self.analyze_impl_func(function, &attach_to_type)?;
683
684 let resolved_function_ref = Rc::new(resolved_function);
685
686 self.stop_function();
687
688 self.shared
689 .state
690 .instantiator
691 .associated_impls
692 .add_member_function(&attach_to_type, &function_name_str, resolved_function_ref)
693 .map_err(|err| {
694 self.create_err(ErrorKind::SemanticError(err), &function_name.name)
695 })?;
696 }
697
698 Ok(())
699 }
700
701 pub(crate) fn push_type_scope_with_variables(
702 &mut self,
703 type_variables: &[swamp_script_ast::TypeVariable],
704 ) -> Result<(), SemanticError> {
705 self.shared.type_variables.push_type_scope();
706
707 for type_var in type_variables {
708 let variable_name_string = self.get_text(&type_var.0).to_string();
709 self.shared
710 .type_variables
711 .declare_type_variable(&variable_name_string)?;
712 }
713
714 Ok(())
715 }
716
717 #[allow(clippy::too_many_lines)]
718 fn analyze_impl_func(
719 &mut self,
720 function: &swamp_script_ast::Function,
721 self_type: &Type,
722 ) -> Result<Function, Error> {
723 let resolved_fn = match function {
724 swamp_script_ast::Function::Internal(function_data) => {
725 let has_function_local_generic_type_variables =
726 !function_data.declaration.generic_variables.is_empty();
727 if has_function_local_generic_type_variables {
728 self.push_type_scope_with_variables(
729 &function_data.declaration.generic_variables,
730 )?;
731 }
732
733 let mut parameters = Vec::new();
734
735 if let Some(found_self) = &function_data.declaration.self_parameter {
736 parameters.push(TypeForParameter {
737 name: self.get_text(&found_self.self_node).to_string(),
738 resolved_type: self_type.clone(),
739 is_mutable: found_self.is_mutable.is_some(),
740 node: Option::from(ParameterNode {
741 name: self.to_node(&found_self.self_node),
742 is_mutable: self.to_node_option(Option::from(&found_self.is_mutable)),
743 }),
744 });
745 }
746
747 for param in &function_data.declaration.params {
748 let resolved_type = self.analyze_type(¶m.param_type)?;
749
750 parameters.push(TypeForParameter {
751 name: self.get_text(¶m.variable.name).to_string(),
752 resolved_type,
753 is_mutable: param.variable.is_mutable.is_some(),
754 node: Option::from(ParameterNode {
755 name: self.to_node(¶m.variable.name),
756 is_mutable: self
757 .to_node_option(Option::from(¶m.variable.is_mutable)),
758 }),
759 });
760 }
761
762 let return_type =
763 self.analyze_maybe_type(Option::from(&function_data.declaration.return_type))?;
764
765 for param in ¶meters {
766 self.create_local_variable_resolved(
767 ¶m.node.as_ref().unwrap().name,
768 param.node.as_ref().unwrap().is_mutable.as_ref(),
769 ¶m.resolved_type.clone(),
770 )?;
771 }
772
773 let statements =
774 self.analyze_function_body_expression(&function_data.body, &return_type)?;
775
776 if has_function_local_generic_type_variables {
777 self.shared.type_variables.pop_type_scope();
778 }
779
780 let internal = InternalFunctionDefinition {
781 signature: GenericAwareSignature {
782 signature: Signature {
783 parameters,
784 return_type: Box::new(return_type),
785 },
786 generic_type_variables: vec![],
787 },
788 body: statements,
789 name: LocalIdentifier(self.to_node(&function_data.declaration.name)),
790 assigned_name: self.get_text(&function_data.declaration.name).to_string(),
791 variable_scopes: self.scope.clone(),
792 function_scope_state: self.function_variables.clone(),
793 program_unique_id: self.shared.state.allocate_internal_function_id(),
794 };
795
796 let internal_ref = Rc::new(internal);
797
798 Function::Internal(internal_ref)
799 }
800
801 swamp_script_ast::Function::External(signature) => {
802 let mut parameters = Vec::new();
803
804 if let Some(found_self) = &signature.self_parameter {
805 parameters.push(TypeForParameter {
806 name: self.get_text(&found_self.self_node).to_string(),
807 resolved_type: self_type.clone(),
808 is_mutable: found_self.is_mutable.is_some(),
809 node: Option::from(ParameterNode {
810 name: self.to_node(&found_self.self_node),
811 is_mutable: self.to_node_option(Option::from(&found_self.is_mutable)),
812 }),
813 });
814 }
815
816 for param in &signature.params {
818 let resolved_type = self.analyze_type(¶m.param_type)?;
819
820 parameters.push(TypeForParameter {
821 name: self.get_text(¶m.variable.name).to_string(),
822 resolved_type,
823 is_mutable: param.variable.is_mutable.is_some(),
824 node: Option::from(ParameterNode {
825 name: self.to_node(¶m.variable.name),
826 is_mutable: self
827 .to_node_option(Option::from(¶m.variable.is_mutable)),
828 }),
829 });
830 }
831
832 let return_type = self.analyze_maybe_type(Option::from(&signature.return_type))?;
833
834 let external_id = self.shared.state.allocate_external_function_id();
835
836 let external = ExternalFunctionDefinition {
837 assigned_name: self.get_text(&signature.name).to_string(),
838 name: Some(self.to_node(&signature.name)),
839 signature: Signature {
840 parameters,
841 return_type: Box::new(return_type),
842 },
843 id: external_id,
844 };
845
846 let external_ref = Rc::new(external);
847
848 Function::External(external_ref)
849 }
850 };
851 Ok(resolved_fn)
852 }
853}