Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle the possibility that the class name is in its own Group #2159

Merged
merged 4 commits into from
May 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions crates/macro-support/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,14 @@ impl<'a> ConvertToAst<BindgenAttrs> for &'a mut syn::ItemStruct {
}
}

fn get_ty(mut ty: &syn::Type) -> &syn::Type {
while let syn::Type::Group(g) = ty {
ty = &g.elem;
}

ty
}

impl<'a> ConvertToAst<(BindgenAttrs, &'a ast::ImportModule)> for syn::ForeignItemFn {
type Target = ast::ImportKind;

Expand Down Expand Up @@ -414,7 +422,7 @@ impl<'a> ConvertToAst<(BindgenAttrs, &'a ast::ImportModule)> for syn::ForeignIte
let class = wasm.arguments.get(0).ok_or_else(|| {
err_span!(self, "imported methods must have at least one argument")
})?;
let class = match &*class.ty {
let class = match get_ty(&class.ty) {
syn::Type::Reference(syn::TypeReference {
mutability: None,
elem,
Expand All @@ -425,7 +433,7 @@ impl<'a> ConvertToAst<(BindgenAttrs, &'a ast::ImportModule)> for syn::ForeignIte
"first argument of method must be a shared reference"
),
};
let class_name = match *class {
let class_name = match get_ty(class) {
syn::Type::Path(syn::TypePath {
qself: None,
ref path,
Expand Down Expand Up @@ -466,7 +474,7 @@ impl<'a> ConvertToAst<(BindgenAttrs, &'a ast::ImportModule)> for syn::ForeignIte
Some(ref ty) => ty,
_ => bail_span!(self, "constructor returns must be bare types"),
};
let class_name = match *class {
let class_name = match get_ty(class) {
syn::Type::Path(syn::TypePath {
qself: None,
ref path,
Expand Down Expand Up @@ -666,9 +674,9 @@ fn function_from_decl(
Some(i) => i,
None => return t,
};
let path = match t {
syn::Type::Path(syn::TypePath { qself: None, path }) => path,
other => return other,
let path = match get_ty(&t) {
syn::Type::Path(syn::TypePath { qself: None, path }) => path.clone(),
other => return other.clone(),
};
let new_path = if path.segments.len() == 1 && path.segments[0].ident == "Self" {
self_ty.clone().into()
Expand Down Expand Up @@ -869,7 +877,7 @@ impl<'a> MacroParse<BindgenAttrs> for &'a mut syn::ItemImpl {
"#[wasm_bindgen] generic impls aren't supported"
);
}
let name = match *self.self_ty {
let name = match get_ty(&self.self_ty) {
syn::Type::Path(syn::TypePath {
qself: None,
ref path,
Expand Down Expand Up @@ -1286,7 +1294,7 @@ fn extract_first_ty_param(ty: Option<&syn::Type>) -> Result<Option<syn::Type>, D
Some(t) => t,
None => return Ok(None),
};
let path = match *t {
let path = match *get_ty(&t) {
syn::Type::Path(syn::TypePath {
qself: None,
ref path,
Expand All @@ -1309,7 +1317,7 @@ fn extract_first_ty_param(ty: Option<&syn::Type>) -> Result<Option<syn::Type>, D
syn::GenericArgument::Type(t) => t,
other => bail_span!(other, "must be a type parameter"),
};
match ty {
match get_ty(&ty) {
syn::Type::Tuple(t) if t.elems.len() == 0 => return Ok(None),
_ => {}
}
Expand Down
15 changes: 11 additions & 4 deletions crates/test-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,7 @@ pub fn wasm_bindgen_test(
}
}
}
let ident = match body.next() {
Some(TokenTree::Ident(token)) => token,
_ => panic!("expected a function name"),
};
let ident = find_ident(&mut body).expect("expected a function name");

let mut tokens = Vec::<TokenTree>::new();

Expand Down Expand Up @@ -78,3 +75,13 @@ pub fn wasm_bindgen_test(

tokens.into_iter().collect::<TokenStream>().into()
}

fn find_ident(iter: &mut token_stream::IntoIter) -> Option<Ident> {
match iter.next()? {
TokenTree::Ident(i) => Some(i),
TokenTree::Group(g) if g.delimiter() == Delimiter::None => {
find_ident(&mut g.stream().into_iter())
}
_ => None,
}
}