mirror of
https://github.com/rustwasm/wasm-bindgen.git
synced 2024-11-24 14:42:35 +03:00
Rename static
to namespace
This commit renames the `static` attribute to `namespace` and simultaneously reduces and expands the scope. The `namespace` attribute can now be applied to all imports in addition to functions, and it no longer recognizes full typed paths but rather just a bare identifier. The `namespace` attribute will generate a Rust namespace to invoke the item through if one doesn't already exist (aka bindign a type).
This commit is contained in:
parent
dd054fa357
commit
4a4f8b18b6
@ -658,7 +658,7 @@ extern {
|
||||
#[wasm_bindgen(constructor)]
|
||||
fn new(arg: i32) -> Bar;
|
||||
|
||||
#[wasm_bindgen(static = Bar)]
|
||||
#[wasm_bindgen(namespace = Bar)]
|
||||
fn another_function() -> i32;
|
||||
|
||||
#[wasm_bindgen(method)]
|
||||
@ -698,8 +698,8 @@ let's go through one-by-one:
|
||||
* `#[wasm_bindgen(constructor)]` - this indicates that the binding's name isn't
|
||||
actually used in JS but rather translates to `new Bar()`. The return value of
|
||||
this function must be a bare type, like `Bar`.
|
||||
* `#[wasm_bindgen(static = Bar)]` - this attribute indicates that the function
|
||||
declaration is a static function accessed through the `Bar` class in JS.
|
||||
* `#[wasm_bindgen(namespace = Bar)]` - this attribute indicates that the
|
||||
function declaration is namespaced through the `Bar` class in JS.
|
||||
* `#[wasm_bindgen(method)]` - and finally, this attribute indicates that a
|
||||
method call is going to happen. The first argument must be a JS struct, like
|
||||
`Bar`, and the call in JS looks like `Bar.prototype.set.call(...)`.
|
||||
|
@ -1044,12 +1044,9 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
for f in self.program.exports.iter() {
|
||||
self.generate_export(f);
|
||||
}
|
||||
for f in self.program.imported_functions.iter() {
|
||||
for f in self.program.imports.iter() {
|
||||
self.generate_import(f);
|
||||
}
|
||||
for f in self.program.imported_fields.iter() {
|
||||
self.generate_import_field(f);
|
||||
}
|
||||
for e in self.program.enums.iter() {
|
||||
self.generate_enum(e);
|
||||
}
|
||||
@ -1322,35 +1319,36 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
(format!("{} {}", prefix, dst), format!("{} {}", prefix, dst_ts))
|
||||
}
|
||||
|
||||
pub fn generate_import_field(&mut self, import: &shared::ImportField) {
|
||||
let name = import.shim_name();
|
||||
self.cx.imports_to_rewrite.insert(name.clone());
|
||||
|
||||
if let Some(ref module) = import.module {
|
||||
self.cx.imports.push_str(&format!("
|
||||
import {{ {} }} from '{}';
|
||||
", import.name, module));
|
||||
pub fn generate_import(&mut self, import: &shared::Import) {
|
||||
match import.kind {
|
||||
shared::ImportKind::Function(ref f) => {
|
||||
self.generate_import_function(import, f)
|
||||
}
|
||||
shared::ImportKind::Static(ref s) => {
|
||||
self.generate_import_static(import, s)
|
||||
}
|
||||
shared::ImportKind::Type(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_import_static(&mut self,
|
||||
info: &shared::Import,
|
||||
import: &shared::ImportStatic) {
|
||||
// TODO: should support more types to import here
|
||||
let name = shared::static_import_shim_name(&import.name);
|
||||
self.cx.imports_to_rewrite.insert(name.clone());
|
||||
let obj = self.import_name(info, &import.name);
|
||||
self.cx.expose_add_heap_object();
|
||||
self.cx.globals.push_str(&format!("
|
||||
export function {}() {{
|
||||
return addHeapObject({});
|
||||
}}
|
||||
", name, import.name));
|
||||
", name, obj));
|
||||
}
|
||||
|
||||
pub fn generate_import(&mut self, import: &shared::Import) {
|
||||
if let Some(ref module) = import.module {
|
||||
let name_to_import = import.class.as_ref().unwrap_or(&import.function.name);
|
||||
|
||||
if self.cx.imported_names.insert(name_to_import.clone()) {
|
||||
self.cx.imports.push_str(&format!("
|
||||
import {{ {} }} from '{}';
|
||||
", name_to_import, module));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_import_function(&mut self,
|
||||
info: &shared::Import,
|
||||
import: &shared::ImportFunction) {
|
||||
let name = shared::mangled_import_name(import.class.as_ref().map(|s| &**s),
|
||||
&import.function.name);
|
||||
self.cx.imports_to_rewrite.insert(name.clone());
|
||||
@ -1361,12 +1359,6 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
let mut invoc_args = Vec::new();
|
||||
let mut abi_args = Vec::new();
|
||||
|
||||
// if import.method {
|
||||
// abi_args.push("ptr".to_string());
|
||||
// invoc_args.push("getObject(ptr)".to_string());
|
||||
// self.cx.expose_get_object();
|
||||
// }
|
||||
|
||||
let mut extra = String::new();
|
||||
|
||||
for (i, arg) in import.function.arguments.iter().enumerate() {
|
||||
@ -1444,9 +1436,10 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
let function_name = &import.function.name;
|
||||
let invoc = match import.class {
|
||||
Some(ref class) if import.js_new => {
|
||||
format!("new {}", class)
|
||||
format!("new {}", self.import_name(info, class))
|
||||
}
|
||||
Some(ref class) if import.method => {
|
||||
let class = self.import_name(info, class);
|
||||
let target = if let Some(ref g) = import.getter {
|
||||
format!(
|
||||
"Object.getOwnPropertyDescriptor({}.prototype, '{}').get;",
|
||||
@ -1468,12 +1461,23 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
format!("{}_target.call", name)
|
||||
}
|
||||
Some(ref class) => {
|
||||
let class = self.import_name(info, class);
|
||||
self.cx.globals.push_str(&format!("
|
||||
const {}_target = {}.{};
|
||||
", name, class, function_name));
|
||||
format!("{}_target", name)
|
||||
}
|
||||
None => function_name.to_string(),
|
||||
None => {
|
||||
let import = self.import_name(info, function_name);
|
||||
if import.contains(".") {
|
||||
self.cx.globals.push_str(&format!("
|
||||
const {}_target = {};
|
||||
", name, import));
|
||||
format!("{}_target", name)
|
||||
} else {
|
||||
import
|
||||
}
|
||||
}
|
||||
};
|
||||
let invoc = format!("{}({})", invoc, invoc_args);
|
||||
let invoc = match import.function.ret {
|
||||
@ -1551,6 +1555,22 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
self.cx.typescript.push_str(&variants);
|
||||
self.cx.typescript.push_str("}\n");
|
||||
}
|
||||
|
||||
fn import_name(&mut self, import: &shared::Import, item: &str) -> String {
|
||||
if let Some(ref module) = import.module {
|
||||
let name = import.namespace.as_ref().map(|s| &**s).unwrap_or(item);
|
||||
|
||||
if self.cx.imported_names.insert(name.to_string()) {
|
||||
self.cx.imports.push_str(&format!("
|
||||
import {{ {} }} from '{}';
|
||||
", name, module));
|
||||
}
|
||||
}
|
||||
match import.namespace {
|
||||
Some(ref s) => format!("{}.{}", s, item),
|
||||
None => item.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct VectorType {
|
||||
|
@ -168,6 +168,7 @@ fn extract_programs(module: &mut Module) -> Vec<shared::Program> {
|
||||
let json = a[3..].iter()
|
||||
.map(|i| char::from_u32(i.0).unwrap())
|
||||
.collect::<String>();
|
||||
println!("{}", json);
|
||||
let p: shared::Program = match serde_json::from_str(&json) {
|
||||
Ok(f) => f,
|
||||
Err(e) => {
|
||||
|
@ -9,9 +9,7 @@ pub struct Program {
|
||||
pub exports: Vec<Export>,
|
||||
pub imports: Vec<Import>,
|
||||
pub enums: Vec<Enum>,
|
||||
pub imported_types: Vec<ImportedType>,
|
||||
pub structs: Vec<Struct>,
|
||||
pub imported_fields: Vec<ImportField>,
|
||||
}
|
||||
|
||||
pub struct Export {
|
||||
@ -23,17 +21,44 @@ pub struct Export {
|
||||
|
||||
pub struct Import {
|
||||
pub module: Option<String>,
|
||||
pub namespace: Option<syn::Ident>,
|
||||
pub kind: ImportKind,
|
||||
pub function: Function,
|
||||
}
|
||||
|
||||
pub enum ImportKind {
|
||||
Method { class: String, ty: syn::Type },
|
||||
Static { class: String, ty: syn::Type },
|
||||
JsConstructor { class: String, ty: syn::Type },
|
||||
Function(ImportFunction),
|
||||
Static(ImportStatic),
|
||||
Type(ImportType),
|
||||
}
|
||||
|
||||
pub struct ImportFunction {
|
||||
pub function: Function,
|
||||
pub kind: ImportFunctionKind,
|
||||
}
|
||||
|
||||
pub enum ImportFunctionKind {
|
||||
Method {
|
||||
class: String,
|
||||
ty: syn::Type,
|
||||
},
|
||||
JsConstructor {
|
||||
class: String,
|
||||
ty: syn::Type,
|
||||
},
|
||||
Normal,
|
||||
}
|
||||
|
||||
pub struct ImportStatic {
|
||||
pub vis: syn::Visibility,
|
||||
pub ty: syn::Type,
|
||||
pub name: syn::Ident,
|
||||
}
|
||||
|
||||
pub struct ImportType {
|
||||
pub vis: syn::Visibility,
|
||||
pub name: syn::Ident,
|
||||
}
|
||||
|
||||
pub struct Function {
|
||||
pub name: syn::Ident,
|
||||
pub arguments: Vec<Type>,
|
||||
@ -58,18 +83,6 @@ pub struct Variant {
|
||||
pub value: u32,
|
||||
}
|
||||
|
||||
pub struct ImportedType {
|
||||
pub vis: syn::Visibility,
|
||||
pub name: syn::Ident,
|
||||
}
|
||||
|
||||
pub struct ImportField {
|
||||
pub vis: syn::Visibility,
|
||||
pub ty: syn::Type,
|
||||
pub module: Option<String>,
|
||||
pub name: syn::Ident,
|
||||
}
|
||||
|
||||
pub enum Type {
|
||||
// special
|
||||
Vector(VectorType, bool),
|
||||
@ -206,22 +219,6 @@ impl Program {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn push_foreign_mod(&mut self, f: syn::ItemForeignMod, opts: BindgenAttrs) {
|
||||
match f.abi.name {
|
||||
Some(ref l) if l.value() == "C" => {}
|
||||
None => {}
|
||||
_ => panic!("only foreign mods with the `C` ABI are allowed"),
|
||||
}
|
||||
for item in f.items.into_iter() {
|
||||
match item {
|
||||
syn::ForeignItem::Fn(f) => self.push_foreign_fn(f, &opts),
|
||||
syn::ForeignItem::Type(t) => self.push_foreign_ty(t, &opts),
|
||||
syn::ForeignItem::Static(s) => self.push_foreign_static(s, &opts),
|
||||
_ => panic!("only foreign functions/types allowed for now"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push_enum(&mut self, item: syn::ItemEnum, _opts: BindgenAttrs) {
|
||||
match item.vis {
|
||||
syn::Visibility::Public(_) => {}
|
||||
@ -255,11 +252,38 @@ impl Program {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn push_foreign_fn(&mut self,
|
||||
mut f: syn::ForeignItemFn,
|
||||
module_opts: &BindgenAttrs) {
|
||||
let opts = BindgenAttrs::find(&mut f.attrs);
|
||||
pub fn push_foreign_mod(&mut self, f: syn::ItemForeignMod, opts: BindgenAttrs) {
|
||||
match f.abi.name {
|
||||
Some(ref l) if l.value() == "C" => {}
|
||||
None => {}
|
||||
_ => panic!("only foreign mods with the `C` ABI are allowed"),
|
||||
}
|
||||
for mut item in f.items.into_iter() {
|
||||
let item_opts = {
|
||||
let attrs = match item {
|
||||
syn::ForeignItem::Fn(ref mut f) => &mut f.attrs,
|
||||
syn::ForeignItem::Type(ref mut t) => &mut t.attrs,
|
||||
syn::ForeignItem::Static(ref mut s) => &mut s.attrs,
|
||||
_ => panic!("only foreign functions/types allowed for now"),
|
||||
};
|
||||
BindgenAttrs::find(attrs)
|
||||
};
|
||||
let module = item_opts.module().or(opts.module()).map(|s| s.to_string());
|
||||
let namespace = item_opts.namespace().or(opts.namespace());
|
||||
let mut kind = match item {
|
||||
syn::ForeignItem::Fn(f) => self.push_foreign_fn(f, item_opts),
|
||||
syn::ForeignItem::Type(t) => self.push_foreign_ty(t),
|
||||
syn::ForeignItem::Static(s) => self.push_foreign_static(s),
|
||||
_ => panic!("only foreign functions/types allowed for now"),
|
||||
};
|
||||
|
||||
self.imports.push(Import { module, namespace, kind });
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push_foreign_fn(&mut self, f: syn::ForeignItemFn, opts: BindgenAttrs)
|
||||
-> ImportKind
|
||||
{
|
||||
let mut wasm = Function::from_decl(f.ident,
|
||||
f.decl,
|
||||
f.attrs,
|
||||
@ -298,7 +322,7 @@ impl Program {
|
||||
let class_name = extract_path_ident(class_name)
|
||||
.expect("first argument of method must be a bare type");
|
||||
|
||||
ImportKind::Method {
|
||||
ImportFunctionKind::Method {
|
||||
class: class_name.as_ref().to_string(),
|
||||
ty: class.clone(),
|
||||
}
|
||||
@ -314,54 +338,40 @@ impl Program {
|
||||
let class_name = extract_path_ident(class_name)
|
||||
.expect("first argument of method must be a bare type");
|
||||
|
||||
ImportKind::JsConstructor {
|
||||
ImportFunctionKind::JsConstructor {
|
||||
class: class_name.as_ref().to_string(),
|
||||
ty: class.clone(),
|
||||
}
|
||||
|
||||
} else if let Some(class) = wasm.opts.static_receiver() {
|
||||
let class_name = match *class {
|
||||
syn::Type::Path(syn::TypePath { qself: None, ref path }) => path,
|
||||
_ => panic!("first argument of method must be a path"),
|
||||
};
|
||||
let class_name = extract_path_ident(class_name)
|
||||
.expect("first argument of method must be a bare type");
|
||||
ImportKind::Static {
|
||||
class: class_name.to_string(),
|
||||
ty: class.clone(),
|
||||
}
|
||||
} else {
|
||||
ImportKind::Normal
|
||||
ImportFunctionKind::Normal
|
||||
};
|
||||
|
||||
self.imports.push(Import {
|
||||
module: module_opts.module().map(|s| s.to_string()),
|
||||
kind,
|
||||
ImportKind::Function(ImportFunction {
|
||||
function: wasm,
|
||||
});
|
||||
kind,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn push_foreign_ty(&mut self,
|
||||
f: syn::ForeignItemType,
|
||||
_module_opts: &BindgenAttrs) {
|
||||
self.imported_types.push(ImportedType {
|
||||
pub fn push_foreign_ty(&mut self, f: syn::ForeignItemType)
|
||||
-> ImportKind
|
||||
{
|
||||
ImportKind::Type(ImportType {
|
||||
vis: f.vis,
|
||||
name: f.ident
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
pub fn push_foreign_static(&mut self,
|
||||
f: syn::ForeignItemStatic,
|
||||
module_opts: &BindgenAttrs) {
|
||||
pub fn push_foreign_static(&mut self, f: syn::ForeignItemStatic)
|
||||
-> ImportKind
|
||||
{
|
||||
if f.mutability.is_some() {
|
||||
panic!("cannot import mutable globals yet")
|
||||
}
|
||||
self.imported_fields.push(ImportField {
|
||||
module: module_opts.module().map(|s| s.to_string()),
|
||||
ImportKind::Static(ImportStatic {
|
||||
ty: *f.ty,
|
||||
vis: f.vis,
|
||||
name: f.ident
|
||||
});
|
||||
name: f.ident,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn literal(&self, dst: &mut Tokens) -> usize {
|
||||
@ -552,7 +562,7 @@ impl Export {
|
||||
}
|
||||
}
|
||||
|
||||
impl Import {
|
||||
impl ImportFunction {
|
||||
pub fn infer_getter_property(&self) -> String {
|
||||
self.function.name.as_ref().to_string()
|
||||
}
|
||||
@ -630,11 +640,11 @@ impl BindgenAttrs {
|
||||
})
|
||||
}
|
||||
|
||||
fn static_receiver(&self) -> Option<&syn::Type> {
|
||||
fn namespace(&self) -> Option<syn::Ident> {
|
||||
self.attrs.iter()
|
||||
.filter_map(|a| {
|
||||
match *a {
|
||||
BindgenAttr::Static(ref s) => Some(s),
|
||||
BindgenAttr::Namespace(s) => Some(s),
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
@ -681,7 +691,7 @@ enum BindgenAttr {
|
||||
Catch,
|
||||
Constructor,
|
||||
Method,
|
||||
Static(syn::Type),
|
||||
Namespace(syn::Ident),
|
||||
Module(String),
|
||||
Getter,
|
||||
Setter,
|
||||
@ -700,11 +710,11 @@ impl syn::synom::Synom for BindgenAttr {
|
||||
call!(term, "setter") => { |_| BindgenAttr::Setter }
|
||||
|
|
||||
do_parse!(
|
||||
call!(term, "static") >>
|
||||
call!(term, "namespace") >>
|
||||
punct!(=) >>
|
||||
s: syn!(syn::Type) >>
|
||||
(s)
|
||||
)=> { BindgenAttr::Static }
|
||||
ns: syn!(syn::Ident) >>
|
||||
(ns)
|
||||
)=> { BindgenAttr::Namespace }
|
||||
|
|
||||
do_parse!(
|
||||
call!(term, "module") >>
|
||||
@ -815,12 +825,3 @@ impl ToTokens for VectorType {
|
||||
me.to_tokens(tokens);
|
||||
}
|
||||
}
|
||||
|
||||
impl ImportField {
|
||||
pub fn shared(&self) -> shared::ImportField {
|
||||
shared::ImportField {
|
||||
module: self.module.clone(),
|
||||
name: self.name.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ extern crate wasm_bindgen_shared as shared;
|
||||
use std::borrow::Cow;
|
||||
use std::env;
|
||||
use std::sync::atomic::*;
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::Span;
|
||||
@ -69,18 +70,44 @@ impl ToTokens for ast::Program {
|
||||
for s in self.structs.iter() {
|
||||
s.to_tokens(tokens);
|
||||
}
|
||||
let mut types = HashSet::new();
|
||||
let mut buckets = BTreeMap::new();
|
||||
for i in self.imports.iter() {
|
||||
i.to_tokens(tokens);
|
||||
buckets.entry(i.namespace)
|
||||
.or_insert(Vec::new())
|
||||
.push(i);
|
||||
if let ast::ImportKind::Type(ref t) = i.kind {
|
||||
types.insert(t.name);
|
||||
}
|
||||
}
|
||||
for (namespace, imports) in buckets {
|
||||
let mut sub_tokens = Tokens::new();
|
||||
for import in imports {
|
||||
import.kind.to_tokens(&mut sub_tokens);
|
||||
}
|
||||
match namespace {
|
||||
Some(ns) if types.contains(&ns) => {
|
||||
(quote! { impl #ns { #sub_tokens } }).to_tokens(tokens);
|
||||
}
|
||||
Some(ns) => {
|
||||
(quote! {
|
||||
// TODO: allow controlling `pub` here.
|
||||
//
|
||||
// TODO: we don't really want to generate a type here,
|
||||
// it'd be preferrable to generate a namespace indicator
|
||||
// or something like that (but modules interact weirdly
|
||||
// with imports and such)
|
||||
pub struct #ns { _priv: () }
|
||||
|
||||
impl #ns { #sub_tokens }
|
||||
}).to_tokens(tokens);
|
||||
}
|
||||
None => sub_tokens.to_tokens(tokens),
|
||||
}
|
||||
}
|
||||
for e in self.enums.iter() {
|
||||
e.to_tokens(tokens);
|
||||
}
|
||||
for it in self.imported_types.iter() {
|
||||
it.to_tokens(tokens);
|
||||
}
|
||||
for it in self.imported_fields.iter() {
|
||||
it.to_tokens(tokens);
|
||||
}
|
||||
|
||||
// Generate a static which will eventually be what lives in a custom section
|
||||
// of the wasm executable. For now it's just a plain old static, but we'll
|
||||
@ -311,7 +338,7 @@ impl ToTokens for ast::Export {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for ast::ImportedType {
|
||||
impl ToTokens for ast::ImportType {
|
||||
fn to_tokens(&self, tokens: &mut Tokens) {
|
||||
let vis = &self.vis;
|
||||
let name = &self.name;
|
||||
@ -344,23 +371,32 @@ impl ToTokens for ast::ImportedType {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for ast::Import {
|
||||
impl ToTokens for ast::ImportKind {
|
||||
fn to_tokens(&self, tokens: &mut Tokens) {
|
||||
match *self {
|
||||
ast::ImportKind::Function(ref f) => f.to_tokens(tokens),
|
||||
ast::ImportKind::Static(ref s) => s.to_tokens(tokens),
|
||||
ast::ImportKind::Type(ref t) => t.to_tokens(tokens),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for ast::ImportFunction {
|
||||
fn to_tokens(&self, tokens: &mut Tokens) {
|
||||
let mut class_ty = None;
|
||||
let mut is_method = false;
|
||||
let mut class_name = None;
|
||||
match self.kind {
|
||||
ast::ImportKind::Method { ref ty, ref class } => {
|
||||
ast::ImportFunctionKind::Method { ref ty, ref class } => {
|
||||
is_method = true;
|
||||
class_ty = Some(ty);
|
||||
class_name = Some(class);
|
||||
}
|
||||
ast::ImportKind::Static { ref ty, ref class } |
|
||||
ast::ImportKind::JsConstructor { ref ty, ref class } => {
|
||||
ast::ImportFunctionKind::JsConstructor { ref ty, ref class } => {
|
||||
class_ty = Some(ty);
|
||||
class_name = Some(class);
|
||||
}
|
||||
ast::ImportKind::Normal => {}
|
||||
ast::ImportFunctionKind::Normal => {}
|
||||
}
|
||||
let import_name = shared::mangled_import_name(
|
||||
class_name.map(|s| &**s),
|
||||
@ -595,11 +631,12 @@ impl ToTokens for ast::Enum {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for ast::ImportField {
|
||||
impl ToTokens for ast::ImportStatic {
|
||||
fn to_tokens(&self, into: &mut Tokens) {
|
||||
let name = self.name;
|
||||
let ty = &self.ty;
|
||||
let shim_name = syn::Ident::from(self.shared().shim_name());
|
||||
let shim_name = shared::static_import_shim_name(name.as_ref());
|
||||
let shim_name = syn::Ident::from(shim_name);
|
||||
let vis = &self.vis;
|
||||
(my_quote! {
|
||||
#vis static #name: ::wasm_bindgen::JsStatic<#ty> = {
|
||||
|
@ -107,8 +107,7 @@ impl Literal for ast::Program {
|
||||
fn literal(&self, a: &mut LiteralBuilder) {
|
||||
a.fields(&[
|
||||
("exports", &|a| a.list_of(&self.exports)),
|
||||
("imported_functions", &|a| a.list_of(&self.imports)),
|
||||
("imported_fields", &|a| a.list_of(&self.imported_fields)),
|
||||
("imports", &|a| a.list_of(&self.imports)),
|
||||
("enums", &|a| a.list_of(&self.enums)),
|
||||
("custom_type_names", &|a| {
|
||||
let names = self.exports
|
||||
@ -199,25 +198,46 @@ impl Literal for ast::Export {
|
||||
}
|
||||
|
||||
impl Literal for ast::Import {
|
||||
fn literal(&self, a: &mut LiteralBuilder) {
|
||||
a.fields(&[
|
||||
("module", &|a| match self.module {
|
||||
Some(ref s) => a.str(s),
|
||||
None => a.append("null"),
|
||||
}),
|
||||
("namespace", &|a| match self.namespace {
|
||||
Some(ref s) => a.str(s.as_ref()),
|
||||
None => a.append("null"),
|
||||
}),
|
||||
("kind", &|a| self.kind.literal(a)),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
impl Literal for ast::ImportKind {
|
||||
fn literal(&self, a: &mut LiteralBuilder) {
|
||||
match *self {
|
||||
ast::ImportKind::Function(ref f) => f.literal(a),
|
||||
ast::ImportKind::Static(ref s) => s.literal(a),
|
||||
ast::ImportKind::Type(ref t) => t.literal(a),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Literal for ast::ImportFunction {
|
||||
fn literal(&self, a: &mut LiteralBuilder) {
|
||||
let mut method = false;
|
||||
let mut js_new = false;
|
||||
let mut statik = false;
|
||||
let mut class_name = None;
|
||||
match self.kind {
|
||||
ast::ImportKind::Method { ref class, .. } => {
|
||||
ast::ImportFunctionKind::Method { ref class, .. } => {
|
||||
method = true;
|
||||
class_name = Some(class);
|
||||
}
|
||||
ast::ImportKind::JsConstructor { ref class, .. } => {
|
||||
ast::ImportFunctionKind::JsConstructor { ref class, .. } => {
|
||||
js_new = true;
|
||||
class_name = Some(class);
|
||||
}
|
||||
ast::ImportKind::Static { ref class, .. } => {
|
||||
statik = true;
|
||||
class_name = Some(class);
|
||||
}
|
||||
ast::ImportKind::Normal => {}
|
||||
ast::ImportFunctionKind::Normal => {}
|
||||
}
|
||||
|
||||
let mut getter = None;
|
||||
@ -230,14 +250,10 @@ impl Literal for ast::Import {
|
||||
setter = Some(self.infer_setter_property());
|
||||
}
|
||||
a.fields(&[
|
||||
("module", &|a| match self.module {
|
||||
Some(ref s) => a.str(s),
|
||||
None => a.append("null"),
|
||||
}),
|
||||
("kind", &|a| a.str("function")),
|
||||
("catch", &|a| a.bool(self.function.opts.catch())),
|
||||
("method", &|a| a.bool(method)),
|
||||
("js_new", &|a| a.bool(js_new)),
|
||||
("statik", &|a| a.bool(statik)),
|
||||
("getter", &|a| match getter {
|
||||
Some(ref s) => a.str(s),
|
||||
None => a.append("null"),
|
||||
@ -273,14 +289,19 @@ impl Literal for ast::Variant {
|
||||
}
|
||||
}
|
||||
|
||||
impl Literal for ast::ImportField {
|
||||
impl Literal for ast::ImportStatic {
|
||||
fn literal(&self, a: &mut LiteralBuilder) {
|
||||
a.fields(&[
|
||||
("kind", &|a| a.str("static")),
|
||||
("name", &|a| a.str(self.name.as_ref())),
|
||||
("module", &|a| match self.module {
|
||||
Some(ref s) => a.str(s),
|
||||
None => a.append("null"),
|
||||
}),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
impl Literal for ast::ImportType {
|
||||
fn literal(&self, a: &mut LiteralBuilder) {
|
||||
a.fields(&[
|
||||
("kind", &|a| a.str("type")),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
@ -11,8 +11,7 @@ pub const SCHEMA_VERSION: &str = "0";
|
||||
pub struct Program {
|
||||
pub exports: Vec<Export>,
|
||||
pub enums: Vec<Enum>,
|
||||
pub imported_functions: Vec<Import>,
|
||||
pub imported_fields: Vec<ImportField>,
|
||||
pub imports: Vec<Import>,
|
||||
pub custom_type_names: Vec<CustomTypeName>,
|
||||
pub version: String,
|
||||
pub schema_version: String,
|
||||
@ -20,11 +19,25 @@ pub struct Program {
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Import {
|
||||
pub module: Option<String>,
|
||||
pub namespace: Option<String>,
|
||||
pub kind: ImportKind,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(tag = "kind", rename_all = "lowercase")]
|
||||
pub enum ImportKind {
|
||||
Function(ImportFunction),
|
||||
Static(ImportStatic),
|
||||
Type(ImportType),
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct ImportFunction {
|
||||
pub module: Option<String>,
|
||||
pub catch: bool,
|
||||
pub method: bool,
|
||||
pub js_new: bool,
|
||||
pub statik: bool,
|
||||
pub getter: Option<String>,
|
||||
pub setter: Option<String>,
|
||||
pub class: Option<String>,
|
||||
@ -32,11 +45,15 @@ pub struct Import {
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct ImportField {
|
||||
pub struct ImportStatic {
|
||||
pub module: Option<String>,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct ImportType {
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Export {
|
||||
pub class: Option<String>,
|
||||
@ -99,6 +116,10 @@ pub fn mangled_import_name(struct_: Option<&str>, f: &str) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn static_import_shim_name(statik: &str) -> String {
|
||||
format!("__wbg_field_import_shim_{}", statik)
|
||||
}
|
||||
|
||||
pub type Type = char;
|
||||
|
||||
pub const TYPE_VECTOR_JSVALUE: char = '\u{5b}';
|
||||
@ -155,9 +176,3 @@ pub fn version() -> String {
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
impl ImportField {
|
||||
pub fn shim_name(&self) -> String {
|
||||
format!("__wbg_field_import_shim_{}", self.name)
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,7 @@ use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern {
|
||||
type console;
|
||||
|
||||
#[wasm_bindgen(static = console)]
|
||||
#[wasm_bindgen(namespace = console)]
|
||||
fn log(s: &str);
|
||||
}
|
||||
|
||||
|
@ -22,10 +22,9 @@ fn simple() {
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern {
|
||||
type Math;
|
||||
#[wasm_bindgen(static = Math)]
|
||||
#[wasm_bindgen(namespace = Math)]
|
||||
fn random() -> f64;
|
||||
#[wasm_bindgen(static = Math)]
|
||||
#[wasm_bindgen(namespace = Math)]
|
||||
fn log(a: f64) -> f64;
|
||||
}
|
||||
"#)
|
||||
@ -53,8 +52,7 @@ fn import_class() {
|
||||
|
||||
#[wasm_bindgen(module = "./another")]
|
||||
extern {
|
||||
type Foo;
|
||||
#[wasm_bindgen(static = Foo)]
|
||||
#[wasm_bindgen(namespace = Foo)]
|
||||
fn bar();
|
||||
}
|
||||
|
||||
@ -98,7 +96,7 @@ fn construct() {
|
||||
#[wasm_bindgen(module = "./another")]
|
||||
extern {
|
||||
type Foo;
|
||||
#[wasm_bindgen(static = Foo)]
|
||||
#[wasm_bindgen(namespace = Foo)]
|
||||
fn create() -> Foo;
|
||||
#[wasm_bindgen(method)]
|
||||
fn get_internal_string(this: &Foo) -> String;
|
||||
@ -219,7 +217,7 @@ fn switch_methods() {
|
||||
#[wasm_bindgen(constructor)]
|
||||
fn new() -> Foo;
|
||||
|
||||
#[wasm_bindgen(static = Foo)]
|
||||
#[wasm_bindgen(namespace = Foo)]
|
||||
fn a();
|
||||
|
||||
#[wasm_bindgen(method)]
|
||||
|
Loading…
Reference in New Issue
Block a user