xref: /third_party/rust/crates/cxx/gen/src/file.rs (revision 33d722a9)
133d722a9Sopenharmony_ciuse crate::syntax::file::Module;
233d722a9Sopenharmony_ciuse crate::syntax::namespace::Namespace;
333d722a9Sopenharmony_ciuse syn::parse::discouraged::Speculative;
433d722a9Sopenharmony_ciuse syn::parse::{Error, Parse, ParseStream, Result};
533d722a9Sopenharmony_ciuse syn::{braced, Attribute, Ident, Item, Meta, Token, Visibility};
633d722a9Sopenharmony_ci
733d722a9Sopenharmony_cipub struct File {
833d722a9Sopenharmony_ci    pub modules: Vec<Module>,
933d722a9Sopenharmony_ci}
1033d722a9Sopenharmony_ci
1133d722a9Sopenharmony_ciimpl Parse for File {
1233d722a9Sopenharmony_ci    fn parse(input: ParseStream) -> Result<Self> {
1333d722a9Sopenharmony_ci        let mut modules = Vec::new();
1433d722a9Sopenharmony_ci        input.call(Attribute::parse_inner)?;
1533d722a9Sopenharmony_ci        parse(input, &mut modules)?;
1633d722a9Sopenharmony_ci        Ok(File { modules })
1733d722a9Sopenharmony_ci    }
1833d722a9Sopenharmony_ci}
1933d722a9Sopenharmony_ci
2033d722a9Sopenharmony_cifn parse(input: ParseStream, modules: &mut Vec<Module>) -> Result<()> {
2133d722a9Sopenharmony_ci    while !input.is_empty() {
2233d722a9Sopenharmony_ci        let mut cxx_bridge = false;
2333d722a9Sopenharmony_ci        let mut namespace = Namespace::ROOT;
2433d722a9Sopenharmony_ci        let mut attrs = input.call(Attribute::parse_outer)?;
2533d722a9Sopenharmony_ci        for attr in &attrs {
2633d722a9Sopenharmony_ci            let path = &attr.path().segments;
2733d722a9Sopenharmony_ci            if path.len() == 2 && path[0].ident == "cxx" && path[1].ident == "bridge" {
2833d722a9Sopenharmony_ci                cxx_bridge = true;
2933d722a9Sopenharmony_ci                namespace = parse_args(attr)?;
3033d722a9Sopenharmony_ci                break;
3133d722a9Sopenharmony_ci            }
3233d722a9Sopenharmony_ci        }
3333d722a9Sopenharmony_ci
3433d722a9Sopenharmony_ci        let ahead = input.fork();
3533d722a9Sopenharmony_ci        ahead.parse::<Visibility>()?;
3633d722a9Sopenharmony_ci        ahead.parse::<Option<Token![unsafe]>>()?;
3733d722a9Sopenharmony_ci        if !ahead.peek(Token![mod]) {
3833d722a9Sopenharmony_ci            let item: Item = input.parse()?;
3933d722a9Sopenharmony_ci            if cxx_bridge {
4033d722a9Sopenharmony_ci                return Err(Error::new_spanned(item, "expected a module"));
4133d722a9Sopenharmony_ci            }
4233d722a9Sopenharmony_ci            continue;
4333d722a9Sopenharmony_ci        }
4433d722a9Sopenharmony_ci
4533d722a9Sopenharmony_ci        if cxx_bridge {
4633d722a9Sopenharmony_ci            let mut module: Module = input.parse()?;
4733d722a9Sopenharmony_ci            module.namespace = namespace;
4833d722a9Sopenharmony_ci            attrs.extend(module.attrs);
4933d722a9Sopenharmony_ci            module.attrs = attrs;
5033d722a9Sopenharmony_ci            modules.push(module);
5133d722a9Sopenharmony_ci        } else {
5233d722a9Sopenharmony_ci            input.advance_to(&ahead);
5333d722a9Sopenharmony_ci            input.parse::<Token![mod]>()?;
5433d722a9Sopenharmony_ci            input.parse::<Ident>()?;
5533d722a9Sopenharmony_ci            let semi: Option<Token![;]> = input.parse()?;
5633d722a9Sopenharmony_ci            if semi.is_none() {
5733d722a9Sopenharmony_ci                let content;
5833d722a9Sopenharmony_ci                braced!(content in input);
5933d722a9Sopenharmony_ci                parse(&content, modules)?;
6033d722a9Sopenharmony_ci            }
6133d722a9Sopenharmony_ci        }
6233d722a9Sopenharmony_ci    }
6333d722a9Sopenharmony_ci    Ok(())
6433d722a9Sopenharmony_ci}
6533d722a9Sopenharmony_ci
6633d722a9Sopenharmony_cifn parse_args(attr: &Attribute) -> Result<Namespace> {
6733d722a9Sopenharmony_ci    if let Meta::Path(_) = attr.meta {
6833d722a9Sopenharmony_ci        Ok(Namespace::ROOT)
6933d722a9Sopenharmony_ci    } else {
7033d722a9Sopenharmony_ci        attr.parse_args_with(Namespace::parse_bridge_attr_namespace)
7133d722a9Sopenharmony_ci    }
7233d722a9Sopenharmony_ci}
73