Add the #[wasm_bindgen(static_method_of = Class)] attribute

This is similar to `js_namespace` but translates into a static method on `Class`
rather than a free function. This allows us to have bindings to things like
`Object.keys` as `Object::keys`.
This commit is contained in:
Nick Fitzgerald 2018-06-22 14:42:48 -07:00
parent 56fa901442
commit 911a32c0d5

View File

@ -1,6 +1,7 @@
use proc_macro2::{Ident, Span, TokenStream, TokenTree};
use quote::ToTokens;
use shared;
use std::iter::FromIterator;
use syn;
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
@ -412,6 +413,24 @@ impl Program {
ty: class.clone(),
kind: MethodKind::Normal,
}
} else if let Some(cls) = wasm.opts.static_method_of() {
let class = cls.to_string();
let kind = MethodKind::Static;
let segments = syn::punctuated::Punctuated::from_iter(Some(syn::PathSegment {
ident: cls.clone(),
arguments: syn::PathArguments::None,
}));
let ty = syn::Type::Path(syn::TypePath {
qself: None,
path: syn::Path {
leading_colon: None,
segments,
},
});
ImportFunctionKind::Method { class, ty, kind }
} else if wasm.opts.constructor() {
let class = match wasm.ret {
Some(ref ty) => ty,
@ -888,6 +907,16 @@ impl BindgenAttrs {
})
}
fn static_method_of(&self) -> Option<&Ident> {
self.attrs
.iter()
.filter_map(|a| match a {
BindgenAttr::StaticMethodOf(c) => Some(c),
_ => None
})
.next()
}
fn method(&self) -> bool {
self.attrs.iter().any(|a| match a {
BindgenAttr::Method => true,
@ -980,6 +1009,7 @@ pub enum BindgenAttr {
Catch,
Constructor,
Method,
StaticMethodOf(Ident),
JsNamespace(Ident),
Module(String),
Version(String),
@ -999,6 +1029,13 @@ impl syn::synom::Synom for BindgenAttr {
|
call!(term, "method") => { |_| BindgenAttr::Method }
|
do_parse!(
call!(term, "static_method_of") >>
punct!(=) >>
cls: call!(term2ident) >>
(cls)
)=> { BindgenAttr::StaticMethodOf }
|
do_parse!(
call!(term, "getter") >>
val: option!(do_parse!(