mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-04-01 18:01:06 +00:00
Merge pull request #62 from fitzgen/to-tokens
Implement quote::ToTokens for AST types
This commit is contained in:
commit
c3b6191112
@ -10,7 +10,7 @@ pub struct Program {
|
||||
pub exports: Vec<Export>,
|
||||
pub imports: Vec<Import>,
|
||||
pub enums: Vec<Enum>,
|
||||
pub imported_types: Vec<(syn::Visibility, syn::Ident)>,
|
||||
pub imported_types: Vec<ImportedType>,
|
||||
pub structs: Vec<Struct>,
|
||||
}
|
||||
|
||||
@ -53,6 +53,11 @@ pub struct Enum {
|
||||
pub variants: Vec<(syn::Ident, u32)>
|
||||
}
|
||||
|
||||
pub struct ImportedType {
|
||||
pub vis: syn::Visibility,
|
||||
pub name: syn::Ident,
|
||||
}
|
||||
|
||||
pub enum Type {
|
||||
// special
|
||||
Vector(VectorType, bool),
|
||||
@ -323,7 +328,10 @@ impl Program {
|
||||
pub fn push_foreign_ty(&mut self,
|
||||
f: syn::ForeignItemType,
|
||||
_module_opts: &BindgenAttrs) {
|
||||
self.imported_types.push((f.vis, f.ident));
|
||||
self.imported_types.push(ImportedType {
|
||||
vis: f.vis,
|
||||
name: f.ident
|
||||
});
|
||||
}
|
||||
|
||||
pub fn wbg_literal(&self, dst: &mut Tokens) -> usize {
|
||||
|
@ -34,7 +34,7 @@ pub fn wasm_bindgen(attr: TokenStream, input: TokenStream) -> TokenStream {
|
||||
let mut ret = Tokens::new();
|
||||
let mut program = ast::Program::default();
|
||||
program.push_item(item, Some(opts), &mut ret);
|
||||
generate_wrappers(program, &mut ret);
|
||||
program.to_tokens(&mut ret);
|
||||
|
||||
// println!("{}", ret);
|
||||
|
||||
@ -59,22 +59,23 @@ fn to_ident_name(s: &str) -> Cow<str> {
|
||||
)
|
||||
}
|
||||
|
||||
// Generate wrappers for all the items that we've found
|
||||
fn generate_wrappers(program: ast::Program, tokens: &mut Tokens) {
|
||||
for export in program.exports.iter() {
|
||||
bindgen_export(export, tokens);
|
||||
impl ToTokens for ast::Program {
|
||||
// Generate wrappers for all the items that we've found
|
||||
fn to_tokens(&self, tokens: &mut Tokens) {
|
||||
for export in self.exports.iter() {
|
||||
export.to_tokens(tokens);
|
||||
}
|
||||
for s in program.structs.iter() {
|
||||
bindgen_struct(s, tokens);
|
||||
for s in self.structs.iter() {
|
||||
s.to_tokens(tokens);
|
||||
}
|
||||
for i in program.imports.iter() {
|
||||
bindgen_import(i, tokens);
|
||||
for i in self.imports.iter() {
|
||||
i.to_tokens(tokens);
|
||||
}
|
||||
for e in program.enums.iter() {
|
||||
bindgen_enum(e, tokens);
|
||||
for e in self.enums.iter() {
|
||||
e.to_tokens(tokens);
|
||||
}
|
||||
for &(ref vis, ref t) in program.imported_types.iter() {
|
||||
bindgen_imported_type(vis, t, tokens);
|
||||
for it in self.imported_types.iter() {
|
||||
it.to_tokens(tokens);
|
||||
}
|
||||
|
||||
// Generate a static which will eventually be what lives in a custom section
|
||||
@ -95,7 +96,7 @@ fn generate_wrappers(program: ast::Program, tokens: &mut Tokens) {
|
||||
let generated_static_name = syn::Ident::from(generated_static_name);
|
||||
|
||||
let mut generated_static_value = Tokens::new();
|
||||
let generated_static_length = program.wbg_literal(&mut generated_static_value);
|
||||
let generated_static_length = self.wbg_literal(&mut generated_static_value);
|
||||
|
||||
(my_quote! {
|
||||
#[no_mangle]
|
||||
@ -103,11 +104,13 @@ fn generate_wrappers(program: ast::Program, tokens: &mut Tokens) {
|
||||
pub static #generated_static_name: [u32; #generated_static_length] =
|
||||
[#generated_static_value];
|
||||
}).to_tokens(tokens);
|
||||
}
|
||||
}
|
||||
|
||||
fn bindgen_struct(s: &ast::Struct, into: &mut Tokens) {
|
||||
let name = &s.name;
|
||||
let free_fn = syn::Ident::from(shared::free_function(s.name.as_ref()));
|
||||
impl ToTokens for ast::Struct {
|
||||
fn to_tokens(&self, tokens: &mut Tokens) {
|
||||
let name = &self.name;
|
||||
let free_fn = syn::Ident::from(shared::free_function(self.name.as_ref()));
|
||||
let c = shared::name_to_descriptor(name.as_ref()) as u32;
|
||||
(my_quote! {
|
||||
impl ::wasm_bindgen::convert::WasmBoundary for #name {
|
||||
@ -150,20 +153,22 @@ fn bindgen_struct(s: &ast::Struct, into: &mut Tokens) {
|
||||
pub unsafe extern fn #free_fn(ptr: u32) {
|
||||
<#name as ::wasm_bindgen::convert::WasmBoundary>::from_js(ptr);
|
||||
}
|
||||
}).to_tokens(into);
|
||||
}).to_tokens(tokens);
|
||||
}
|
||||
}
|
||||
|
||||
fn bindgen_export(export: &ast::Export, into: &mut Tokens) {
|
||||
let generated_name = export.rust_symbol();
|
||||
let export_name = export.export_name();
|
||||
impl ToTokens for ast::Export {
|
||||
fn to_tokens(self: &ast::Export, into: &mut Tokens) {
|
||||
let generated_name = self.rust_symbol();
|
||||
let export_name = self.export_name();
|
||||
let mut args = vec![];
|
||||
let mut arg_conversions = vec![];
|
||||
let mut converted_arguments = vec![];
|
||||
let ret = syn::Ident::from("_ret");
|
||||
|
||||
let mut offset = 0;
|
||||
if export.method {
|
||||
let class = export.class.unwrap();
|
||||
if self.method {
|
||||
let class = self.class.unwrap();
|
||||
args.push(my_quote! { me: *mut ::wasm_bindgen::__rt::WasmRefCell<#class> });
|
||||
arg_conversions.push(my_quote! {
|
||||
::wasm_bindgen::__rt::assert_not_null(me);
|
||||
@ -172,7 +177,7 @@ fn bindgen_export(export: &ast::Export, into: &mut Tokens) {
|
||||
offset = 1;
|
||||
}
|
||||
|
||||
for (i, ty) in export.function.arguments.iter().enumerate() {
|
||||
for (i, ty) in self.function.arguments.iter().enumerate() {
|
||||
let i = i + offset;
|
||||
let ident = syn::Ident::from(format!("arg{}", i));
|
||||
match *ty {
|
||||
@ -251,7 +256,7 @@ fn bindgen_export(export: &ast::Export, into: &mut Tokens) {
|
||||
}
|
||||
let ret_ty;
|
||||
let convert_ret;
|
||||
match export.function.ret {
|
||||
match self.function.ret {
|
||||
Some(ast::Type::Vector(ref ty, true)) => {
|
||||
ret_ty = my_quote! { -> *mut #ty };
|
||||
convert_ret = my_quote! { Box::into_raw(Box::new(#ret)) };
|
||||
@ -275,10 +280,10 @@ fn bindgen_export(export: &ast::Export, into: &mut Tokens) {
|
||||
}
|
||||
}
|
||||
|
||||
let name = export.function.name;
|
||||
let receiver = match export.class {
|
||||
Some(_) if export.method => {
|
||||
if export.mutable {
|
||||
let name = self.function.name;
|
||||
let receiver = match self.class {
|
||||
Some(_) if self.method => {
|
||||
if self.mutable {
|
||||
my_quote! { me.borrow_mut().#name }
|
||||
} else {
|
||||
my_quote! { me.borrow().#name }
|
||||
@ -299,11 +304,13 @@ fn bindgen_export(export: &ast::Export, into: &mut Tokens) {
|
||||
}
|
||||
};
|
||||
tokens.to_tokens(into);
|
||||
}
|
||||
}
|
||||
|
||||
fn bindgen_imported_type(vis: &syn::Visibility,
|
||||
name: &syn::Ident,
|
||||
tokens: &mut Tokens) {
|
||||
impl ToTokens for ast::ImportedType {
|
||||
fn to_tokens(&self, tokens: &mut Tokens) {
|
||||
let vis = &self.vis;
|
||||
let name = &self.name;
|
||||
(my_quote! {
|
||||
#vis struct #name {
|
||||
obj: ::wasm_bindgen::JsValue,
|
||||
@ -330,14 +337,15 @@ fn bindgen_imported_type(vis: &syn::Visibility,
|
||||
}
|
||||
}
|
||||
}).to_tokens(tokens);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn bindgen_import(import: &ast::Import, tokens: &mut Tokens) {
|
||||
impl ToTokens for ast::Import {
|
||||
fn to_tokens(&self, tokens: &mut Tokens) {
|
||||
let mut class_ty = None;
|
||||
let mut is_method = false;
|
||||
let mut class_name = None;
|
||||
match import.kind {
|
||||
match self.kind {
|
||||
ast::ImportKind::Method { ref ty, ref class } => {
|
||||
is_method = true;
|
||||
class_ty = Some(ty);
|
||||
@ -352,18 +360,18 @@ fn bindgen_import(import: &ast::Import, tokens: &mut Tokens) {
|
||||
}
|
||||
let import_name = shared::mangled_import_name(
|
||||
class_name.map(|s| &**s),
|
||||
import.function.name.as_ref(),
|
||||
self.function.name.as_ref(),
|
||||
);
|
||||
let vis = &import.function.rust_vis;
|
||||
let ret = &import.function.rust_decl.output;
|
||||
let fn_token = &import.function.rust_decl.fn_token;
|
||||
let vis = &self.function.rust_vis;
|
||||
let ret = &self.function.rust_decl.output;
|
||||
let fn_token = &self.function.rust_decl.fn_token;
|
||||
|
||||
let mut abi_argument_names = Vec::new();
|
||||
let mut abi_arguments = Vec::new();
|
||||
let mut arg_conversions = Vec::new();
|
||||
let ret_ident = syn::Ident::from("_ret");
|
||||
|
||||
let names = import.function.rust_decl.inputs
|
||||
let names = self.function.rust_decl.inputs
|
||||
.iter()
|
||||
.map(|arg| {
|
||||
match *arg {
|
||||
@ -385,7 +393,7 @@ fn bindgen_import(import: &ast::Import, tokens: &mut Tokens) {
|
||||
}
|
||||
});
|
||||
|
||||
for (i, (ty, name)) in import.function.arguments.iter().zip(names).enumerate() {
|
||||
for (i, (ty, name)) in self.function.arguments.iter().zip(names).enumerate() {
|
||||
match *ty {
|
||||
ast::Type::Vector(ref ty, owned) => {
|
||||
let ptr = syn::Ident::from(format!("{}_ptr", name));
|
||||
@ -440,7 +448,7 @@ fn bindgen_import(import: &ast::Import, tokens: &mut Tokens) {
|
||||
}
|
||||
let abi_ret;
|
||||
let mut convert_ret;
|
||||
match import.function.ret {
|
||||
match self.function.ret {
|
||||
Some(ast::Type::ByValue(ref t)) => {
|
||||
abi_ret = my_quote! {
|
||||
<#t as ::wasm_bindgen::convert::WasmBoundary>::Js
|
||||
@ -483,7 +491,7 @@ fn bindgen_import(import: &ast::Import, tokens: &mut Tokens) {
|
||||
}
|
||||
|
||||
let mut exceptional_ret = my_quote! {};
|
||||
if import.function.opts.catch() {
|
||||
if self.function.opts.catch() {
|
||||
let exn_data = syn::Ident::from("exn_data");
|
||||
let exn_data_ptr = syn::Ident::from("exn_data_ptr");
|
||||
abi_argument_names.push(exn_data_ptr);
|
||||
@ -501,11 +509,11 @@ fn bindgen_import(import: &ast::Import, tokens: &mut Tokens) {
|
||||
};
|
||||
}
|
||||
|
||||
let name = import.function.name;
|
||||
let name = self.function.name;
|
||||
let import_name = syn::Ident::from(import_name);
|
||||
let attrs = &import.function.rust_attrs;
|
||||
let attrs = &self.function.rust_attrs;
|
||||
|
||||
let arguments = import.function.rust_decl.inputs
|
||||
let arguments = self.function.rust_decl.inputs
|
||||
.iter()
|
||||
.skip(if is_method { 1 } else { 0 })
|
||||
.collect::<Vec<_>>();
|
||||
@ -541,14 +549,16 @@ fn bindgen_import(import: &ast::Import, tokens: &mut Tokens) {
|
||||
} else {
|
||||
invocation.to_tokens(tokens);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn bindgen_enum(e: &ast::Enum, into: &mut Tokens) {
|
||||
let enum_name = &e.name;
|
||||
impl ToTokens for ast::Enum {
|
||||
fn to_tokens(&self, into: &mut Tokens) {
|
||||
let enum_name = &self.name;
|
||||
let c = shared::TYPE_ENUM as u32;
|
||||
let incoming_u32 = quote! { n };
|
||||
let enum_name_as_string = enum_name.to_string();
|
||||
let cast_clauses = e.variants.iter().map(|variant| {
|
||||
let cast_clauses = self.variants.iter().map(|variant| {
|
||||
let &(variant_name, _) = variant;
|
||||
quote! {
|
||||
if #incoming_u32 == #enum_name::#variant_name as u32 {
|
||||
@ -578,4 +588,5 @@ fn bindgen_enum(e: &ast::Enum, into: &mut Tokens) {
|
||||
}
|
||||
}
|
||||
}).to_tokens(into);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user