blob: 8df3404fbfb781c3e8d504d86ef84c7d61632736 [file] [log] [blame]
David Tolnayb4dba232020-05-11 00:55:29 -07001// Functionality that is shared between the cxx_build::bridge entry point and
2// the cxxbridge CLI command.
David Tolnay7db73692019-10-20 14:51:12 -04003
4mod error;
David Tolnayfcd8f462020-08-29 12:13:09 -07005mod file;
David Tolnay2967b662020-05-11 00:53:06 -07006mod find;
David Tolnay7db73692019-10-20 14:51:12 -04007pub(super) mod include;
8pub(super) mod out;
9mod write;
10
David Tolnay0d47a532020-07-30 19:39:04 -070011#[cfg(test)]
12mod tests;
13
David Tolnay52509842020-04-25 19:38:59 -070014use self::error::{format_err, Error, Result};
David Tolnayfcd8f462020-08-29 12:13:09 -070015use self::file::File;
David Tolnay08419302020-04-19 20:38:20 -070016use crate::syntax::namespace::Namespace;
David Tolnay0dd85ff2020-05-03 23:43:33 -070017use crate::syntax::report::Errors;
David Tolnayb6cf3142020-04-19 20:56:09 -070018use crate::syntax::{self, check, Types};
David Tolnay7db73692019-10-20 14:51:12 -040019use std::fs;
David Tolnay7db73692019-10-20 14:51:12 -040020use std::path::Path;
David Tolnay2967b662020-05-11 00:53:06 -070021use syn::Item;
David Tolnay7db73692019-10-20 14:51:12 -040022
23struct Input {
David Tolnay754e21c2020-03-29 20:58:46 -070024 namespace: Namespace,
David Tolnay7db73692019-10-20 14:51:12 -040025 module: Vec<Item>,
26}
27
David Tolnay33d30292020-03-18 18:02:02 -070028#[derive(Default)]
29pub(super) struct Opt {
30 /// Any additional headers to #include
31 pub include: Vec<String>,
Adrian Taylor21f0ff02020-07-21 16:21:48 -070032 /// Whether to set __attribute__((visibility("default")))
33 /// or similar annotations on function implementations.
34 pub cxx_impl_annotations: Option<String>,
David Tolnay33d30292020-03-18 18:02:02 -070035}
36
David Tolnay7ece56f2020-03-29 21:21:38 -070037pub(super) fn do_generate_bridge(path: &Path, opt: Opt) -> Vec<u8> {
David Tolnay7db73692019-10-20 14:51:12 -040038 let header = false;
Adrian Taylor8205e622020-07-21 21:53:59 -070039 generate_from_path(path, opt, header)
David Tolnay7db73692019-10-20 14:51:12 -040040}
41
David Tolnay7ece56f2020-03-29 21:21:38 -070042pub(super) fn do_generate_header(path: &Path, opt: Opt) -> Vec<u8> {
David Tolnay7db73692019-10-20 14:51:12 -040043 let header = true;
Adrian Taylor8205e622020-07-21 21:53:59 -070044 generate_from_path(path, opt, header)
David Tolnay7db73692019-10-20 14:51:12 -040045}
46
Adrian Taylor8205e622020-07-21 21:53:59 -070047fn generate_from_path(path: &Path, opt: Opt, header: bool) -> Vec<u8> {
David Tolnay7db73692019-10-20 14:51:12 -040048 let source = match fs::read_to_string(path) {
49 Ok(source) => source,
50 Err(err) => format_err(path, "", Error::Io(err)),
51 };
Adrian Taylor8205e622020-07-21 21:53:59 -070052 match generate(&source, opt, header) {
53 Ok(out) => out,
David Tolnay7db73692019-10-20 14:51:12 -040054 Err(err) => format_err(path, &source, err),
55 }
56}
Adrian Taylor8205e622020-07-21 21:53:59 -070057
58fn generate(source: &str, opt: Opt, header: bool) -> Result<Vec<u8>> {
59 proc_macro2::fallback::force();
60 let ref mut errors = Errors::new();
David Tolnayfcd8f462020-08-29 12:13:09 -070061 let syntax: File = syn::parse_str(source)?;
Adrian Taylor8205e622020-07-21 21:53:59 -070062 let bridge = find::find_bridge_mod(syntax)?;
63 let ref namespace = bridge.namespace;
64 let ref apis = syntax::parse_items(errors, bridge.module);
65 let ref types = Types::collect(errors, apis);
66 errors.propagate()?;
67 check::typecheck(errors, namespace, apis, types);
68 errors.propagate()?;
69 let out = write::gen(namespace, apis, types, opt, header);
70 Ok(out.content())
71}