blob: 710bca224218e8265b287dd900259022686b7c64 [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;
#[cfg(test)]
mod tests;
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_from_path(path, opt, header)
}
pub(super) fn do_generate_header(path: &Path, opt: Opt) -> Vec<u8> {
let header = true;
generate_from_path(path, opt, header)
}
fn generate_from_path(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 generate(&source, opt, header) {
Ok(out) => out,
Err(err) => format_err(path, &source, err),
}
}
fn generate(source: &str, opt: Opt, header: bool) -> Result<Vec<u8>> {
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.content())
}