use crate::lang::FunctionId;
use crate::lang::functions::{Argument, Function, FunctionKind, Signature};
use crate::lang::meta::{Emission, Visibility};
use crate::pass::Outcome::Unchanged;
use crate::pass::{ModelResult, PassInfo, model};
use crate::try_resolve;
use interoptopus::inventory::Functions;
use std::collections::HashMap;
#[derive(Default)]
pub struct Config {}
pub struct Pass {
info: PassInfo,
functions: HashMap<FunctionId, Function>,
}
impl Pass {
#[must_use]
pub fn new(_: Config) -> Self {
Self { info: PassInfo { name: file!() }, functions: HashMap::default() }
}
pub fn process(
&mut self,
pass_meta: &mut crate::pass::PassMeta,
id_map: &model::common::id_map::Pass,
all: &mut model::common::fns::all::Pass,
rs_functions: &Functions,
) -> ModelResult {
let mut outcome = Unchanged;
for (rust_id, rust_fn) in rs_functions {
let Some(cs_id) = id_map.fns(*rust_id) else { continue };
if self.functions.contains_key(&cs_id) {
continue;
}
let cs_rval = try_resolve!(id_map.ty(rust_fn.signature.rval), pass_meta, self.info, crate::pass::MissingItem::RustType(rust_fn.signature.rval));
let mut cs_arguments = Vec::new();
let mut all_args_available = true;
for rust_arg in &rust_fn.signature.arguments {
let Some(cs_arg_type) = id_map.ty(rust_arg.ty) else {
pass_meta.lost_found.missing(self.info, crate::pass::MissingItem::RustType(rust_arg.ty));
all_args_available = false;
break;
};
cs_arguments.push(Argument { name: rust_arg.name.clone(), ty: cs_arg_type });
}
if !all_args_available {
continue;
}
let cs_signature = Signature { arguments: cs_arguments, rval: cs_rval };
let cs_function = Function {
emission: rust_fn.emission.clone(),
name: rust_fn.name.clone(),
visibility: Visibility::Public,
docs: rust_fn.docs.lines.clone(),
signature: cs_signature,
kind: FunctionKind::Original,
};
all.register(cs_id, cs_function.clone());
self.functions.insert(cs_id, cs_function);
outcome.changed();
}
Ok(outcome)
}
}