///|
fn render_function(
function : CFunction,
aliases : Map[String, String],
opaque_types : Map[String, Bool],
enums : Map[String, Bool],
config : GenerateConfig,
) -> (String?, String) {
ignore(function.source.line)
if function.c_signature.contains("...") {
return (None, "variadic function")
}
let return_m = match
resolve_configured_type(
function.return_type,
function.canonical_return_type,
aliases,
opaque_types,
enums,
config,
utf8_input=false,
result=true,
) {
Some(value) => value.moon_type
None => return (None, "unsupported return type: " + function.return_type)
}
let params : Array[String] = []
let borrowed : Array[String] = []
let parameter_names : Map[String, Int] = Map([])
for parameter in function.parameters {
let resolved = match
resolve_configured_type(
parameter.c_type,
parameter.canonical_type,
aliases,
opaque_types,
enums,
config,
utf8_input=config.is_utf8_input(function.name, parameter.name),
result=false,
) {
Some(value) => value
None => return (None, "unsupported parameter type: " + parameter.c_type)
}
let base_name = moonbit_value_name(parameter.name)
let count = parameter_names.get(base_name).unwrap_or(0) + 1
parameter_names[base_name] = count
let name = if count == 1 {
base_name
} else {
base_name + "_" + count.to_string()
}
if resolved.borrowed {
borrowed.push(name)
}
params.push(name + " : " + resolved.moon_type)
}
let attributes = if borrowed.length() == 0 {
""
} else {
"#borrow(" + borrowed.join(", ") + ")\n"
}
let declaration = "pub extern \"C\" fn " +
function.moon_name +
"(" +
params.join(", ") +
") -> " +
return_m +
" = \"" +
function.symbol +
"\"\n"
let multiline_v2 = config.schema_version == 2 && declaration.length() > 112
let multiline_v1 = config.schema_version == 1 && declaration.length() > 110
if params.length() > 2 || multiline_v1 || multiline_v2 {
let body = params.map(param => " " + param + ",").join("\n")
let multiline = "///|\n" +
attributes +
"pub extern \"C\" fn " +
function.moon_name +
"(\n" +
body +
"\n) -> " +
return_m +
" = \"" +
function.symbol +
"\"\n"
(Some(multiline), "")
} else {
(Some("///|\n" + attributes + declaration), "")
}
}