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