blob: fa69cb5bae8c21742eda8b82f5d3036dd8a3182e [file] [log] [blame]
David Tolnay7db73692019-10-20 14:51:12 -04001// Functionality that is shared between the cxx::generate_bridge entry point and
2// the cmd.
3
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 Tolnay52509842020-04-25 19:38:59 -070010use self::error::{format_err, Error, Result};
David Tolnay08419302020-04-19 20:38:20 -070011use crate::syntax::namespace::Namespace;
David Tolnay0dd85ff2020-05-03 23:43:33 -070012use crate::syntax::report::Errors;
David Tolnayb6cf3142020-04-19 20:56:09 -070013use crate::syntax::{self, check, Types};
David Tolnay7db73692019-10-20 14:51:12 -040014use std::fs;
David Tolnay7db73692019-10-20 14:51:12 -040015use std::path::Path;
David Tolnay2967b662020-05-11 00:53:06 -070016use syn::Item;
David Tolnay7db73692019-10-20 14:51:12 -040017
18struct Input {
David Tolnay754e21c2020-03-29 20:58:46 -070019 namespace: Namespace,
David Tolnay7db73692019-10-20 14:51:12 -040020 module: Vec<Item>,
21}
22
David Tolnay33d30292020-03-18 18:02:02 -070023#[derive(Default)]
24pub(super) struct Opt {
25 /// Any additional headers to #include
26 pub include: Vec<String>,
27}
28
David Tolnay7ece56f2020-03-29 21:21:38 -070029pub(super) fn do_generate_bridge(path: &Path, opt: Opt) -> Vec<u8> {
David Tolnay7db73692019-10-20 14:51:12 -040030 let header = false;
David Tolnay33d30292020-03-18 18:02:02 -070031 generate(path, opt, header)
David Tolnay7db73692019-10-20 14:51:12 -040032}
33
David Tolnay7ece56f2020-03-29 21:21:38 -070034pub(super) fn do_generate_header(path: &Path, opt: Opt) -> Vec<u8> {
David Tolnay7db73692019-10-20 14:51:12 -040035 let header = true;
David Tolnay33d30292020-03-18 18:02:02 -070036 generate(path, opt, header)
David Tolnay7db73692019-10-20 14:51:12 -040037}
38
David Tolnay7ece56f2020-03-29 21:21:38 -070039fn generate(path: &Path, opt: Opt, header: bool) -> Vec<u8> {
David Tolnay7db73692019-10-20 14:51:12 -040040 let source = match fs::read_to_string(path) {
41 Ok(source) => source,
42 Err(err) => format_err(path, "", Error::Io(err)),
43 };
44 match (|| -> Result<_> {
David Tolnay761a5fc2020-05-01 16:02:02 -070045 proc_macro2::fallback::force();
David Tolnay0dd85ff2020-05-03 23:43:33 -070046 let ref mut errors = Errors::new();
David Tolnay7db73692019-10-20 14:51:12 -040047 let syntax = syn::parse_file(&source)?;
David Tolnay2967b662020-05-11 00:53:06 -070048 let bridge = find::find_bridge_mod(syntax)?;
David Tolnay2ec14632020-05-04 00:47:10 -070049 let ref namespace = bridge.namespace;
David Tolnay52759782020-05-03 23:59:40 -070050 let ref apis = syntax::parse_items(errors, bridge.module);
51 let ref types = Types::collect(errors, apis);
52 errors.propagate()?;
David Tolnay0dd85ff2020-05-03 23:43:33 -070053 check::typecheck(errors, namespace, apis, types);
54 errors.propagate()?;
David Tolnay2ec14632020-05-04 00:47:10 -070055 let out = write::gen(namespace, apis, types, opt, header);
David Tolnay7db73692019-10-20 14:51:12 -040056 Ok(out)
57 })() {
David Tolnay7ece56f2020-03-29 21:21:38 -070058 Ok(out) => out.content(),
David Tolnay7db73692019-10-20 14:51:12 -040059 Err(err) => format_err(path, &source, err),
60 }
61}