blob: 710bca224218e8265b287dd900259022686b7c64 [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 Tolnay2967b662020-05-11 00:53:06 -07005mod find;
David Tolnay7db73692019-10-20 14:51:12 -04006pub(super) mod include;
7pub(super) mod out;
8mod write;
9
David Tolnay0d47a532020-07-30 19:39:04 -070010#[cfg(test)]
11mod tests;
12
David Tolnay52509842020-04-25 19:38:59 -070013use self::error::{format_err, Error, Result};
David Tolnay08419302020-04-19 20:38:20 -070014use crate::syntax::namespace::Namespace;
David Tolnay0dd85ff2020-05-03 23:43:33 -070015use crate::syntax::report::Errors;
David Tolnayb6cf3142020-04-19 20:56:09 -070016use crate::syntax::{self, check, Types};
David Tolnay7db73692019-10-20 14:51:12 -040017use std::fs;
David Tolnay7db73692019-10-20 14:51:12 -040018use std::path::Path;
David Tolnay2967b662020-05-11 00:53:06 -070019use syn::Item;
David Tolnay7db73692019-10-20 14:51:12 -040020
21struct Input {
David Tolnay754e21c2020-03-29 20:58:46 -070022 namespace: Namespace,
David Tolnay7db73692019-10-20 14:51:12 -040023 module: Vec<Item>,
24}
25
David Tolnay33d30292020-03-18 18:02:02 -070026#[derive(Default)]
27pub(super) struct Opt {
28 /// Any additional headers to #include
29 pub include: Vec<String>,
Adrian Taylor21f0ff02020-07-21 16:21:48 -070030 /// Whether to set __attribute__((visibility("default")))
31 /// or similar annotations on function implementations.
32 pub cxx_impl_annotations: Option<String>,
David Tolnay33d30292020-03-18 18:02:02 -070033}
34
David Tolnay7ece56f2020-03-29 21:21:38 -070035pub(super) fn do_generate_bridge(path: &Path, opt: Opt) -> Vec<u8> {
David Tolnay7db73692019-10-20 14:51:12 -040036 let header = false;
Adrian Taylor8205e622020-07-21 21:53:59 -070037 generate_from_path(path, opt, header)
David Tolnay7db73692019-10-20 14:51:12 -040038}
39
David Tolnay7ece56f2020-03-29 21:21:38 -070040pub(super) fn do_generate_header(path: &Path, opt: Opt) -> Vec<u8> {
David Tolnay7db73692019-10-20 14:51:12 -040041 let header = true;
Adrian Taylor8205e622020-07-21 21:53:59 -070042 generate_from_path(path, opt, header)
David Tolnay7db73692019-10-20 14:51:12 -040043}
44
Adrian Taylor8205e622020-07-21 21:53:59 -070045fn generate_from_path(path: &Path, opt: Opt, header: bool) -> Vec<u8> {
David Tolnay7db73692019-10-20 14:51:12 -040046 let source = match fs::read_to_string(path) {
47 Ok(source) => source,
48 Err(err) => format_err(path, "", Error::Io(err)),
49 };
Adrian Taylor8205e622020-07-21 21:53:59 -070050 match generate(&source, opt, header) {
51 Ok(out) => out,
David Tolnay7db73692019-10-20 14:51:12 -040052 Err(err) => format_err(path, &source, err),
53 }
54}
Adrian Taylor8205e622020-07-21 21:53:59 -070055
56fn generate(source: &str, opt: Opt, header: bool) -> Result<Vec<u8>> {
57 proc_macro2::fallback::force();
58 let ref mut errors = Errors::new();
59 let syntax = syn::parse_file(&source)?;
60 let bridge = find::find_bridge_mod(syntax)?;
61 let ref namespace = bridge.namespace;
62 let ref apis = syntax::parse_items(errors, bridge.module);
63 let ref types = Types::collect(errors, apis);
64 errors.propagate()?;
65 check::typecheck(errors, namespace, apis, types);
66 errors.propagate()?;
67 let out = write::gen(namespace, apis, types, opt, header);
68 Ok(out.content())
69}