blob: 65d6c67710f941a8b8db61700cbf87b1fc7cabe1 [file] [log] [blame]
// Functionality that is shared between the cxx_build::bridge entry point and
// the cxxbridge CLI command.
mod error;
mod find;
pub(super) mod include;
pub(super) mod out;
mod write;
use self::error::{format_err, Error, Result};
use crate::syntax::namespace::Namespace;
use crate::syntax::report::Errors;
use crate::syntax::{self, check, Types};
use std::fs;
use std::path::Path;
use syn::Item;
struct Input {
namespace: Namespace,
module: Vec<Item>,
}
#[derive(Default)]
pub(super) struct Opt {
/// Any additional headers to #include
pub include: Vec<String>,
/// Whether to set __attribute__((visibility("default")))
/// or similar annotations on function implementations.
pub cxx_impl_annotations: Option<String>,
}
pub(super) fn do_generate_bridge(path: &Path, opt: Opt) -> Vec<u8> {
let header = false;
generate(path, opt, header)
}
pub(super) fn do_generate_header(path: &Path, opt: Opt) -> Vec<u8> {
let header = true;
generate(path, opt, header)
}
fn generate(path: &Path, opt: Opt, header: bool) -> Vec<u8> {
let source = match fs::read_to_string(path) {
Ok(source) => source,
Err(err) => format_err(path, "", Error::Io(err)),
};
match (|| -> Result<_> {
proc_macro2::fallback::force();
let ref mut errors = Errors::new();
let syntax = syn::parse_file(&source)?;
let bridge = find::find_bridge_mod(syntax)?;
let ref namespace = bridge.namespace;
let ref apis = syntax::parse_items(errors, bridge.module);
let ref types = Types::collect(errors, apis);
errors.propagate()?;
check::typecheck(errors, namespace, apis, types);
errors.propagate()?;
let out = write::gen(namespace, apis, types, opt, header);
Ok(out)
})() {
Ok(out) => out.content(),
Err(err) => format_err(path, &source, err),
}
}