133d722a9Sopenharmony_ciuse crate::syntax::cfg::CfgExpr; 233d722a9Sopenharmony_ciuse crate::syntax::namespace::Namespace; 333d722a9Sopenharmony_ciuse quote::quote; 433d722a9Sopenharmony_ciuse syn::parse::{Error, Parse, ParseStream, Result}; 533d722a9Sopenharmony_ciuse syn::{ 633d722a9Sopenharmony_ci braced, token, Abi, Attribute, ForeignItem, Ident, Item as RustItem, ItemEnum, ItemImpl, 733d722a9Sopenharmony_ci ItemStruct, ItemUse, LitStr, Token, Visibility, 833d722a9Sopenharmony_ci}; 933d722a9Sopenharmony_ci 1033d722a9Sopenharmony_cipub struct Module { 1133d722a9Sopenharmony_ci pub cfg: CfgExpr, 1233d722a9Sopenharmony_ci pub namespace: Namespace, 1333d722a9Sopenharmony_ci pub attrs: Vec<Attribute>, 1433d722a9Sopenharmony_ci pub vis: Visibility, 1533d722a9Sopenharmony_ci pub unsafety: Option<Token![unsafe]>, 1633d722a9Sopenharmony_ci pub mod_token: Token![mod], 1733d722a9Sopenharmony_ci pub ident: Ident, 1833d722a9Sopenharmony_ci pub brace_token: token::Brace, 1933d722a9Sopenharmony_ci pub content: Vec<Item>, 2033d722a9Sopenharmony_ci} 2133d722a9Sopenharmony_ci 2233d722a9Sopenharmony_cipub enum Item { 2333d722a9Sopenharmony_ci Struct(ItemStruct), 2433d722a9Sopenharmony_ci Enum(ItemEnum), 2533d722a9Sopenharmony_ci ForeignMod(ItemForeignMod), 2633d722a9Sopenharmony_ci Use(ItemUse), 2733d722a9Sopenharmony_ci Impl(ItemImpl), 2833d722a9Sopenharmony_ci Other(RustItem), 2933d722a9Sopenharmony_ci} 3033d722a9Sopenharmony_ci 3133d722a9Sopenharmony_cipub struct ItemForeignMod { 3233d722a9Sopenharmony_ci pub attrs: Vec<Attribute>, 3333d722a9Sopenharmony_ci pub unsafety: Option<Token![unsafe]>, 3433d722a9Sopenharmony_ci pub abi: Abi, 3533d722a9Sopenharmony_ci pub brace_token: token::Brace, 3633d722a9Sopenharmony_ci pub items: Vec<ForeignItem>, 3733d722a9Sopenharmony_ci} 3833d722a9Sopenharmony_ci 3933d722a9Sopenharmony_ciimpl Parse for Module { 4033d722a9Sopenharmony_ci fn parse(input: ParseStream) -> Result<Self> { 4133d722a9Sopenharmony_ci let cfg = CfgExpr::Unconditional; 4233d722a9Sopenharmony_ci let namespace = Namespace::ROOT; 4333d722a9Sopenharmony_ci let mut attrs = input.call(Attribute::parse_outer)?; 4433d722a9Sopenharmony_ci let vis: Visibility = input.parse()?; 4533d722a9Sopenharmony_ci let unsafety: Option<Token![unsafe]> = input.parse()?; 4633d722a9Sopenharmony_ci let mod_token: Token![mod] = input.parse()?; 4733d722a9Sopenharmony_ci let ident: Ident = input.parse()?; 4833d722a9Sopenharmony_ci 4933d722a9Sopenharmony_ci let semi: Option<Token![;]> = input.parse()?; 5033d722a9Sopenharmony_ci if let Some(semi) = semi { 5133d722a9Sopenharmony_ci let span = quote!(#vis #mod_token #semi); 5233d722a9Sopenharmony_ci return Err(Error::new_spanned( 5333d722a9Sopenharmony_ci span, 5433d722a9Sopenharmony_ci "#[cxx::bridge] module must have inline contents", 5533d722a9Sopenharmony_ci )); 5633d722a9Sopenharmony_ci } 5733d722a9Sopenharmony_ci 5833d722a9Sopenharmony_ci let content; 5933d722a9Sopenharmony_ci let brace_token = braced!(content in input); 6033d722a9Sopenharmony_ci attrs.extend(content.call(Attribute::parse_inner)?); 6133d722a9Sopenharmony_ci 6233d722a9Sopenharmony_ci let mut items = Vec::new(); 6333d722a9Sopenharmony_ci while !content.is_empty() { 6433d722a9Sopenharmony_ci items.push(content.parse()?); 6533d722a9Sopenharmony_ci } 6633d722a9Sopenharmony_ci 6733d722a9Sopenharmony_ci Ok(Module { 6833d722a9Sopenharmony_ci cfg, 6933d722a9Sopenharmony_ci namespace, 7033d722a9Sopenharmony_ci attrs, 7133d722a9Sopenharmony_ci vis, 7233d722a9Sopenharmony_ci unsafety, 7333d722a9Sopenharmony_ci mod_token, 7433d722a9Sopenharmony_ci ident, 7533d722a9Sopenharmony_ci brace_token, 7633d722a9Sopenharmony_ci content: items, 7733d722a9Sopenharmony_ci }) 7833d722a9Sopenharmony_ci } 7933d722a9Sopenharmony_ci} 8033d722a9Sopenharmony_ci 8133d722a9Sopenharmony_ciimpl Parse for Item { 8233d722a9Sopenharmony_ci fn parse(input: ParseStream) -> Result<Self> { 8333d722a9Sopenharmony_ci let attrs = input.call(Attribute::parse_outer)?; 8433d722a9Sopenharmony_ci 8533d722a9Sopenharmony_ci let ahead = input.fork(); 8633d722a9Sopenharmony_ci let unsafety = if ahead.parse::<Option<Token![unsafe]>>()?.is_some() 8733d722a9Sopenharmony_ci && ahead.parse::<Option<Token![extern]>>()?.is_some() 8833d722a9Sopenharmony_ci && ahead.parse::<Option<LitStr>>().is_ok() 8933d722a9Sopenharmony_ci && ahead.peek(token::Brace) 9033d722a9Sopenharmony_ci { 9133d722a9Sopenharmony_ci Some(input.parse()?) 9233d722a9Sopenharmony_ci } else { 9333d722a9Sopenharmony_ci None 9433d722a9Sopenharmony_ci }; 9533d722a9Sopenharmony_ci 9633d722a9Sopenharmony_ci let item = input.parse()?; 9733d722a9Sopenharmony_ci match item { 9833d722a9Sopenharmony_ci RustItem::Struct(mut item) => { 9933d722a9Sopenharmony_ci item.attrs.splice(..0, attrs); 10033d722a9Sopenharmony_ci Ok(Item::Struct(item)) 10133d722a9Sopenharmony_ci } 10233d722a9Sopenharmony_ci RustItem::Enum(mut item) => { 10333d722a9Sopenharmony_ci item.attrs.splice(..0, attrs); 10433d722a9Sopenharmony_ci Ok(Item::Enum(item)) 10533d722a9Sopenharmony_ci } 10633d722a9Sopenharmony_ci RustItem::ForeignMod(mut item) => { 10733d722a9Sopenharmony_ci item.attrs.splice(..0, attrs); 10833d722a9Sopenharmony_ci Ok(Item::ForeignMod(ItemForeignMod { 10933d722a9Sopenharmony_ci attrs: item.attrs, 11033d722a9Sopenharmony_ci unsafety, 11133d722a9Sopenharmony_ci abi: item.abi, 11233d722a9Sopenharmony_ci brace_token: item.brace_token, 11333d722a9Sopenharmony_ci items: item.items, 11433d722a9Sopenharmony_ci })) 11533d722a9Sopenharmony_ci } 11633d722a9Sopenharmony_ci RustItem::Impl(mut item) => { 11733d722a9Sopenharmony_ci item.attrs.splice(..0, attrs); 11833d722a9Sopenharmony_ci Ok(Item::Impl(item)) 11933d722a9Sopenharmony_ci } 12033d722a9Sopenharmony_ci RustItem::Use(mut item) => { 12133d722a9Sopenharmony_ci item.attrs.splice(..0, attrs); 12233d722a9Sopenharmony_ci Ok(Item::Use(item)) 12333d722a9Sopenharmony_ci } 12433d722a9Sopenharmony_ci other => Ok(Item::Other(other)), 12533d722a9Sopenharmony_ci } 12633d722a9Sopenharmony_ci } 12733d722a9Sopenharmony_ci} 128