diff --git a/gen/src/file.rs b/gen/src/file.rs index c6964071..1b324cb6 100644 --- a/gen/src/file.rs +++ b/gen/src/file.rs @@ -67,6 +67,6 @@ fn parse_args(attr: &Attribute) -> Result { if attr.tokens.is_empty() { Ok(Namespace::none()) } else { - attr.parse_args() + attr.parse_args_with(Namespace::parse_bridge_attr_namespace) } } diff --git a/macro/src/lib.rs b/macro/src/lib.rs index 291b03ce..4d9b9861 100644 --- a/macro/src/lib.rs +++ b/macro/src/lib.rs @@ -18,7 +18,7 @@ use crate::syntax::file::Module; use crate::syntax::namespace::Namespace; use crate::syntax::qualified::QualifiedName; use proc_macro::TokenStream; -use syn::parse::{Parse, ParseStream, Result}; +use syn::parse::{Parse, ParseStream, Parser, Result}; use syn::parse_macro_input; /// `#[cxx::bridge] mod ffi { ... }` @@ -42,7 +42,10 @@ use syn::parse_macro_input; pub fn bridge(args: TokenStream, input: TokenStream) -> TokenStream { let _ = syntax::error::ERRORS; - let namespace = parse_macro_input!(args as Namespace); + let namespace = match Namespace::parse_bridge_attr_namespace.parse(args) { + Ok(ns) => ns, + Err(err) => return err.to_compile_error().into(), + }; let mut ffi = parse_macro_input!(input as Module); ffi.namespace = namespace; diff --git a/syntax/attrs.rs b/syntax/attrs.rs index 25af2296..af73b7a5 100644 --- a/syntax/attrs.rs +++ b/syntax/attrs.rs @@ -132,8 +132,7 @@ fn parse_function_alias_attribute(input: ParseStream) -> Result { } fn parse_namespace_attribute(input: ParseStream) -> Result { - let content; - syn::parenthesized!(content in input); - let namespace = content.parse::()?; + input.parse::()?; + let namespace = input.parse::()?; Ok(namespace) } diff --git a/syntax/namespace.rs b/syntax/namespace.rs index 49b31d14..b4c6716d 100644 --- a/syntax/namespace.rs +++ b/syntax/namespace.rs @@ -24,19 +24,23 @@ impl Namespace { pub fn iter(&self) -> Iter { self.segments.iter() } + + pub fn parse_bridge_attr_namespace(input: ParseStream) -> Result { + if input.is_empty() { + return Ok(Namespace::none()); + } + + input.parse::()?; + input.parse::()?; + let ns = input.parse::()?; + input.parse::>()?; + Ok(ns) + } } impl Parse for Namespace { fn parse(input: ParseStream) -> Result { - let mut segments = Vec::new(); - if !input.is_empty() { - input.parse::()?; - input.parse::()?; - segments = input - .call(QualifiedName::parse_quoted_or_unquoted)? - .segments; - input.parse::>()?; - } + let segments = QualifiedName::parse_quoted_or_unquoted(input)?.segments; Ok(Namespace { segments }) } } diff --git a/tests/ffi/class_in_ns.rs b/tests/ffi/class_in_ns.rs index 8b505613..a03da78c 100644 --- a/tests/ffi/class_in_ns.rs +++ b/tests/ffi/class_in_ns.rs @@ -10,12 +10,12 @@ pub mod ffi3 { extern "C" { include!("tests/ffi/tests.h"); - #[namespace (namespace = I)] + #[namespace = "I"] type I; fn get(self: &I) -> u32; - #[namespace (namespace = I)] + #[namespace = "I"] fn ns_c_return_unique_ptr_ns() -> UniquePtr; } } diff --git a/tests/ffi/extra.rs b/tests/ffi/extra.rs index 633cf937..58700a2f 100644 --- a/tests/ffi/extra.rs +++ b/tests/ffi/extra.rs @@ -20,12 +20,12 @@ pub mod ffi2 { type D = crate::other::D; type E = crate::other::E; - #[namespace (namespace = F)] + #[namespace = "F"] type F = crate::other::f::F; - #[namespace (namespace = G)] + #[namespace = "G"] type G = crate::other::G; - #[namespace(namespace = H)] + #[namespace = "H"] type H; fn c_take_trivial_ptr(d: UniquePtr); @@ -47,9 +47,9 @@ pub mod ffi2 { fn c_return_ns_unique_ptr() -> UniquePtr; fn c_take_ref_ns_c(h: &H); - #[namespace (namespace = other)] + #[namespace = "other"] fn ns_c_take_trivial(d: D); - #[namespace (namespace = other)] + #[namespace = "other"] fn ns_c_return_trivial() -> D; } } diff --git a/tests/ffi/lib.rs b/tests/ffi/lib.rs index be145f37..17146ce7 100644 --- a/tests/ffi/lib.rs +++ b/tests/ffi/lib.rs @@ -76,27 +76,27 @@ pub mod ffi { CVal, } - #[namespace(namespace = A)] + #[namespace = "A"] #[derive(Clone)] struct AShared { z: usize, } - #[namespace(namespace = A)] + #[namespace = "A"] enum AEnum { AAVal, ABVal = 2020, ACVal, } - #[namespace(namespace = A::B)] + #[namespace = "A::B"] enum ABEnum { ABAVal, ABBVal = 2020, ABCVal, } - #[namespace(namespace = A::B)] + #[namespace = "A::B"] #[derive(Clone)] struct ABShared { z: usize, @@ -201,7 +201,7 @@ pub mod ffi { #[rust_name = "str_overloaded_function"] fn cOverloadedFunction(x: &str) -> String; - #[namespace (namespace = other)] + #[namespace = "other"] fn ns_c_take_ns_shared(shared: AShared); }