factorio_codegen/generator/
function.rs1use factorio_ir::{function::Function, module::Module, scope::Scope};
2
3use crate::{LuaGenerator, LuaGeneratorError, LuaGeneratorResult};
4
5impl LuaGenerator {
6 pub(crate) fn generate_function(
8 &mut self,
9 func: &Function,
10 module: Option<&Module>,
11 scope: Scope,
12 module_name: Option<&str>,
13 ) -> LuaGeneratorResult<()> {
14 if scope == Scope::Private && module_name.is_some() {
16 return Err(LuaGeneratorError::FunctionLocalAndExported(
17 func.name.clone(),
18 ));
19 }
20
21 let prefix = match scope {
22 Scope::Private => "local ",
23 Scope::Public => "",
24 };
25
26 let function_uses_self = func
27 .params
28 .first()
29 .is_some_and(|parameter| parameter.name == "self");
30
31 let params = if function_uses_self && module_name.is_some() {
33 func.params
34 .iter()
35 .skip(1)
36 .map(|parameter| self.format_parameter(parameter))
37 .collect::<Vec<_>>()
38 .join(", ")
39 } else {
40 func.params
41 .iter()
42 .map(|parameter| self.format_parameter(parameter))
43 .collect::<Vec<_>>()
44 .join(", ")
45 };
46
47 let return_comment = self.function_return_comment(
48 func.debug
49 .as_ref()
50 .and_then(|debug| debug.return_type.as_deref()),
51 );
52
53 let function_name = match module_name {
54 Some(module_name) if function_uses_self => {
55 format!("{module_name}:{}", func.name)
56 }
57 Some(module_name) => format!("{module_name}.{}", func.name),
58 None => func.name.clone(),
59 };
60
61 self.write_doc_comments(func.doc.as_deref());
62
63 if self.debug_level_at_least(0)
64 && let Some(debug) = &func.debug
65 {
66 self.write_line(&format!("-- {}", debug.header_comment));
67 }
68
69 self.write_line(&format!(
70 "{prefix}function {function_name}({params}){return_comment}"
71 ));
72
73 self.indent_level += 1;
74 self.generate_block(&func.body, module)?;
75 self.indent_level -= 1;
76
77 self.write_line("end");
78
79 Ok(())
80 }
81}