Source code

Revision control

Copy as Markdown

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use super::*;
use anyhow::bail;
pub fn pass(namespace: &mut Namespace) -> Result<()> {
// UniFFI contract version function. This is used to check that there wasn't a breaking
// change to `uniffi-bindgen`.
namespace.ffi_uniffi_contract_version = RustFfiFunctionName(format!(
"ffi_{}_uniffi_contract_version",
&namespace.crate_name
));
namespace.ffi_definitions.insert(
FfiFunction {
name: RustFfiFunctionName(format!(
"ffi_{}_uniffi_contract_version",
&namespace.crate_name
)),
async_data: None,
arguments: vec![],
return_type: FfiReturnType {
ty: Some(FfiType::UInt32.into()),
},
has_rust_call_status_arg: false,
kind: FfiFunctionKind::UniffiContractVersion,
..FfiFunction::default()
}
.into(),
);
// Checksums, these are used to check that the bindings were built against the same
// exported interface as the loaded library.
let mut checksums = vec![];
// Closure to visit a callable
let mut visit_callable = |callable: &Callable| {
let Some(checksum) = callable.checksum else {
bail!("Checksum not set for {:#?}", callable);
};
let fn_name = match &callable.kind {
CallableKind::Function => {
uniffi_meta::fn_checksum_symbol_name(&namespace.crate_name, &callable.name)
}
CallableKind::Method { self_type } => {
let name = self_type.ty.name().unwrap();
uniffi_meta::method_checksum_symbol_name(
&namespace.crate_name,
name,
&callable.name,
)
}
CallableKind::VTableMethod { self_type } => uniffi_meta::method_checksum_symbol_name(
&namespace.crate_name,
self_type.ty.name().unwrap(),
&callable.name,
),
CallableKind::Constructor { self_type, .. } => {
uniffi_meta::constructor_checksum_symbol_name(
&namespace.crate_name,
self_type.ty.name().unwrap(),
&callable.name,
)
}
};
checksums.push((
FfiFunction {
name: RustFfiFunctionName(fn_name.clone()),
async_data: None,
arguments: vec![],
return_type: FfiReturnType {
ty: Some(FfiType::UInt16.into()),
},
has_rust_call_status_arg: false,
kind: FfiFunctionKind::Checksum,
..FfiFunction::default()
},
checksum,
));
Ok(())
};
// Call `visit_callable` for callables that we have checksums for
// (functions/constructors/methods), but not ones where we don't (VTable methods and UniFFI
// traits).
namespace.try_visit(|function: &Function| function.try_visit(&mut visit_callable))?;
namespace.try_visit(|int: &Interface| {
for cons in int.constructors.iter() {
visit_callable(&cons.callable)?;
}
for meth in int.methods.iter() {
visit_callable(&meth.callable)?;
}
Ok(())
})?;
for (ffi_func, checksum) in checksums {
namespace.checksums.push(Checksum {
fn_name: ffi_func.name.clone(),
checksum,
});
namespace
.ffi_definitions
.insert(FfiDefinition::RustFunction(ffi_func));
}
namespace.correct_contract_version = uniffi_meta::UNIFFI_CONTRACT_VERSION.to_string();
Ok(())
}