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