mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-04-02 02:11:06 +00:00
Merge pull request #63 from fitzgen/literals
wasm-bindgen-macro: Formalize building literals with a trait
This commit is contained in:
commit
8b74c6c6ec
@ -1,5 +1,4 @@
|
|||||||
use std::collections::BTreeSet;
|
use literal::{self, Literal};
|
||||||
|
|
||||||
use proc_macro2::Span;
|
use proc_macro2::Span;
|
||||||
use quote::{Tokens, ToTokens};
|
use quote::{Tokens, ToTokens};
|
||||||
use shared;
|
use shared;
|
||||||
@ -50,7 +49,12 @@ pub struct Struct {
|
|||||||
|
|
||||||
pub struct Enum {
|
pub struct Enum {
|
||||||
pub name: syn::Ident,
|
pub name: syn::Ident,
|
||||||
pub variants: Vec<(syn::Ident, u32)>
|
pub variants: Vec<Variant>
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Variant {
|
||||||
|
pub name: syn::Ident,
|
||||||
|
pub value: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ImportedType {
|
pub struct ImportedType {
|
||||||
@ -231,7 +235,10 @@ impl Program {
|
|||||||
_ => panic!("Enums may only have number literal values")
|
_ => panic!("Enums may only have number literal values")
|
||||||
};
|
};
|
||||||
|
|
||||||
(v.ident, value)
|
Variant {
|
||||||
|
name: v.ident,
|
||||||
|
value,
|
||||||
|
}
|
||||||
}).collect();
|
}).collect();
|
||||||
self.enums.push(Enum {
|
self.enums.push(Enum {
|
||||||
name: item.ident,
|
name: item.ident,
|
||||||
@ -334,34 +341,12 @@ impl Program {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wbg_literal(&self, dst: &mut Tokens) -> usize {
|
pub fn literal(&self, dst: &mut Tokens) -> usize {
|
||||||
let mut tmp = Tokens::new();
|
let mut tmp = Tokens::new();
|
||||||
let cnt = {
|
let cnt = {
|
||||||
let mut a = LiteralBuilder {
|
let mut a = literal::LiteralBuilder::new(&mut tmp);
|
||||||
dst: &mut tmp,
|
Literal::literal(self, &mut a);
|
||||||
cnt: 0,
|
a.finish()
|
||||||
};
|
|
||||||
a.fields(&[
|
|
||||||
("exports", &|a| a.list(&self.exports, Export::wbg_literal)),
|
|
||||||
("imports", &|a| a.list(&self.imports, Import::wbg_literal)),
|
|
||||||
("enums", &|a| a.list(&self.enums, Enum::wbg_literal)),
|
|
||||||
("custom_type_names", &|a| {
|
|
||||||
let names = self.exports.iter()
|
|
||||||
.filter_map(|e| e.class)
|
|
||||||
.chain(self.structs.iter().map(|s| s.name))
|
|
||||||
.collect::<BTreeSet<_>>();
|
|
||||||
a.list(&names, |s, a| {
|
|
||||||
let val = shared::name_to_descriptor(s.as_ref());
|
|
||||||
a.fields(&[
|
|
||||||
("descriptor", &|a| a.char(val)),
|
|
||||||
("name", &|a| a.str(s.as_ref()))
|
|
||||||
]);
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
("version", &|a| a.str(&shared::version())),
|
|
||||||
("schema_version", &|a| a.str(&shared::SCHEMA_VERSION)),
|
|
||||||
]);
|
|
||||||
a.cnt
|
|
||||||
};
|
};
|
||||||
let cnt = cnt as u32;
|
let cnt = cnt as u32;
|
||||||
(quote! {
|
(quote! {
|
||||||
@ -442,19 +427,6 @@ impl Function {
|
|||||||
rust_attrs: attrs,
|
rust_attrs: attrs,
|
||||||
}, mutable)
|
}, mutable)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wbg_literal(&self, a: &mut LiteralBuilder) {
|
|
||||||
a.fields(&[
|
|
||||||
("name", &|a| a.str(self.name.as_ref())),
|
|
||||||
("arguments", &|a| a.list(&self.arguments, Type::wbg_literal)),
|
|
||||||
("ret", &|a| {
|
|
||||||
match self.ret {
|
|
||||||
Some(ref s) => s.wbg_literal(a),
|
|
||||||
None => a.append("null"),
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extract_path_ident(path: &syn::Path) -> Option<syn::Ident> {
|
pub fn extract_path_ident(path: &syn::Path) -> Option<syn::Ident> {
|
||||||
@ -527,43 +499,6 @@ impl Type {
|
|||||||
|
|
||||||
Type::ByValue(ty.clone())
|
Type::ByValue(ty.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wbg_literal(&self, a: &mut LiteralBuilder) {
|
|
||||||
match *self {
|
|
||||||
Type::Vector(VectorType::String, true) => a.char(shared::TYPE_STRING),
|
|
||||||
Type::Vector(VectorType::String, false) => a.char(shared::TYPE_BORROWED_STR),
|
|
||||||
Type::Vector(VectorType::U8, true) => a.char(shared::TYPE_VECTOR_U8),
|
|
||||||
Type::Vector(VectorType::U8, false) => a.char(shared::TYPE_SLICE_U8),
|
|
||||||
Type::Vector(VectorType::I8, true) => a.char(shared::TYPE_VECTOR_I8),
|
|
||||||
Type::Vector(VectorType::I8, false) => a.char(shared::TYPE_SLICE_I8),
|
|
||||||
Type::Vector(VectorType::U16, true) => a.char(shared::TYPE_VECTOR_U16),
|
|
||||||
Type::Vector(VectorType::U16, false) => a.char(shared::TYPE_SLICE_U16),
|
|
||||||
Type::Vector(VectorType::I16, true) => a.char(shared::TYPE_VECTOR_I16),
|
|
||||||
Type::Vector(VectorType::I16, false) => a.char(shared::TYPE_SLICE_I16),
|
|
||||||
Type::Vector(VectorType::U32, true) => a.char(shared::TYPE_VECTOR_U32),
|
|
||||||
Type::Vector(VectorType::U32, false) => a.char(shared::TYPE_SLICE_U32),
|
|
||||||
Type::Vector(VectorType::I32, true) => a.char(shared::TYPE_VECTOR_I32),
|
|
||||||
Type::Vector(VectorType::I32, false) => a.char(shared::TYPE_SLICE_I32),
|
|
||||||
Type::Vector(VectorType::F32, true) => a.char(shared::TYPE_VECTOR_F32),
|
|
||||||
Type::Vector(VectorType::F32, false) => a.char(shared::TYPE_SLICE_F32),
|
|
||||||
Type::Vector(VectorType::F64, true) => a.char(shared::TYPE_VECTOR_F64),
|
|
||||||
Type::Vector(VectorType::F64, false) => a.char(shared::TYPE_SLICE_F64),
|
|
||||||
Type::Vector(VectorType::JsValue, true) => a.char(shared::TYPE_VECTOR_JSVALUE),
|
|
||||||
Type::Vector(VectorType::JsValue, false) => panic!("Slices of JsValues not supported"),
|
|
||||||
Type::ByValue(ref t) => {
|
|
||||||
a.as_char(my_quote! {
|
|
||||||
<#t as ::wasm_bindgen::convert::WasmBoundary>::DESCRIPTOR
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Type::ByRef(ref ty) |
|
|
||||||
Type::ByMutRef(ref ty) => {
|
|
||||||
a.as_char(my_quote! {
|
|
||||||
(<#ty as ::wasm_bindgen::convert::WasmBoundary>::DESCRIPTOR |
|
|
||||||
::wasm_bindgen::convert::DESCRIPTOR_CUSTOM_REF_FLAG)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Export {
|
impl Export {
|
||||||
@ -592,191 +527,26 @@ impl Export {
|
|||||||
};
|
};
|
||||||
syn::LitStr::new(&name, Span::def_site())
|
syn::LitStr::new(&name, Span::def_site())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wbg_literal(&self, a: &mut LiteralBuilder) {
|
|
||||||
a.fields(&[
|
|
||||||
("class", &|a| {
|
|
||||||
match self.class {
|
|
||||||
Some(ref s) => a.str(s.as_ref()),
|
|
||||||
None => a.append("null"),
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
("method", &|a| a.bool(self.method)),
|
|
||||||
("function", &|a| self.function.wbg_literal(a)),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Import {
|
impl Import {
|
||||||
fn wbg_literal(&self, a: &mut LiteralBuilder) {
|
pub fn infer_getter_property(&self) -> String {
|
||||||
let mut method = false;
|
|
||||||
let mut js_new = false;
|
|
||||||
let mut statik = false;
|
|
||||||
let mut class_name = None;
|
|
||||||
match self.kind {
|
|
||||||
ImportKind::Method { ref class, .. } => {
|
|
||||||
method = true;
|
|
||||||
class_name = Some(class);
|
|
||||||
}
|
|
||||||
ImportKind::JsConstructor { ref class, .. } => {
|
|
||||||
js_new = true;
|
|
||||||
class_name = Some(class);
|
|
||||||
}
|
|
||||||
ImportKind::Static { ref class, .. } => {
|
|
||||||
statik = true;
|
|
||||||
class_name = Some(class);
|
|
||||||
}
|
|
||||||
ImportKind::Normal => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut getter = None;
|
|
||||||
let mut setter = None;
|
|
||||||
|
|
||||||
if self.function.opts.getter() {
|
|
||||||
getter = Some(self.infer_getter_property());
|
|
||||||
}
|
|
||||||
if self.function.opts.setter() {
|
|
||||||
setter = Some(self.infer_setter_property());
|
|
||||||
}
|
|
||||||
a.fields(&[
|
|
||||||
("module", &|a| {
|
|
||||||
match self.module {
|
|
||||||
Some(ref s) => a.str(s),
|
|
||||||
None => a.append("null"),
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
("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"),
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
("setter", &|a| {
|
|
||||||
match setter {
|
|
||||||
Some(ref s) => a.str(s),
|
|
||||||
None => a.append("null"),
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
("function", &|a| self.function.wbg_literal(a)),
|
|
||||||
("class", &|a| {
|
|
||||||
match class_name {
|
|
||||||
Some(s) => a.str(s),
|
|
||||||
None => a.append("null"),
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn infer_getter_property(&self) -> String {
|
|
||||||
self.function.name.as_ref().to_string()
|
self.function.name.as_ref().to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn infer_setter_property(&self) -> String {
|
pub fn infer_setter_property(&self) -> String {
|
||||||
let name = self.function.name.as_ref();
|
let name = self.function.name.as_ref();
|
||||||
assert!(name.starts_with("set_"), "setters must start with `set_`");
|
assert!(name.starts_with("set_"), "setters must start with `set_`");
|
||||||
name[4..].to_string()
|
name[4..].to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Enum {
|
|
||||||
fn wbg_literal(&self, a: &mut LiteralBuilder) {
|
|
||||||
a.fields(&[
|
|
||||||
("name", &|a| a.str(self.name.as_ref())),
|
|
||||||
("variants", &|a| a.list(&self.variants, |v, a| {
|
|
||||||
let &(name, value) = v;
|
|
||||||
a.fields(&[("name", &|a| a.str(name.as_ref())),
|
|
||||||
("value", &|a| a.append(&format!("{}", value)))])
|
|
||||||
})),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Struct {
|
impl Struct {
|
||||||
fn from(s: syn::ItemStruct, _opts: BindgenAttrs) -> Struct {
|
fn from(s: syn::ItemStruct, _opts: BindgenAttrs) -> Struct {
|
||||||
Struct { name: s.ident }
|
Struct { name: s.ident }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LiteralBuilder<'a> {
|
|
||||||
dst: &'a mut Tokens,
|
|
||||||
cnt: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> LiteralBuilder<'a> {
|
|
||||||
fn char_lit(&mut self, c: char) {
|
|
||||||
if self.cnt > 0 {
|
|
||||||
::syn::token::Comma::default().to_tokens(self.dst);
|
|
||||||
}
|
|
||||||
self.cnt += 1;
|
|
||||||
(c as u32).to_tokens(self.dst);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn append(&mut self, s: &str) {
|
|
||||||
for c in s.chars() {
|
|
||||||
self.char_lit(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn str(&mut self, s: &str) {
|
|
||||||
self.append("\"");
|
|
||||||
self.append(s);
|
|
||||||
self.append("\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bool(&mut self, v: bool) {
|
|
||||||
if v {
|
|
||||||
self.append("true")
|
|
||||||
} else {
|
|
||||||
self.append("false")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn char(&mut self, s: char) {
|
|
||||||
self.append("\"");
|
|
||||||
self.char_lit(s);
|
|
||||||
self.append("\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_char(&mut self, tokens: Tokens) {
|
|
||||||
self.append("\"");
|
|
||||||
::syn::token::Comma::default().to_tokens(self.dst);
|
|
||||||
tokens.to_tokens(self.dst);
|
|
||||||
self.cnt += 1;
|
|
||||||
self.append("\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fields(&mut self, fields: &[(&str, &Fn(&mut Self))]) {
|
|
||||||
self.append("{");
|
|
||||||
for (i, &(field, cb)) in fields.iter().enumerate() {
|
|
||||||
if i > 0 {
|
|
||||||
self.append(",");
|
|
||||||
}
|
|
||||||
self.str(field);
|
|
||||||
self.append(":");
|
|
||||||
cb(self);
|
|
||||||
}
|
|
||||||
self.append("}");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn list<T, F>(&mut self, list: T, mut cb: F)
|
|
||||||
where F: FnMut(T::Item, &mut Self),
|
|
||||||
T: IntoIterator,
|
|
||||||
{
|
|
||||||
self.append("[");
|
|
||||||
for (i, element) in list.into_iter().enumerate() {
|
|
||||||
if i > 0 {
|
|
||||||
self.append(",");
|
|
||||||
}
|
|
||||||
cb(element, self);
|
|
||||||
}
|
|
||||||
self.append("]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct BindgenAttrs {
|
pub struct BindgenAttrs {
|
||||||
attrs: Vec<BindgenAttr>,
|
attrs: Vec<BindgenAttr>,
|
||||||
@ -848,7 +618,7 @@ impl BindgenAttrs {
|
|||||||
.next()
|
.next()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getter(&self) -> bool {
|
pub fn getter(&self) -> bool {
|
||||||
self.attrs.iter()
|
self.attrs.iter()
|
||||||
.any(|a| {
|
.any(|a| {
|
||||||
match *a {
|
match *a {
|
||||||
@ -858,7 +628,7 @@ impl BindgenAttrs {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setter(&self) -> bool {
|
pub fn setter(&self) -> bool {
|
||||||
self.attrs.iter()
|
self.attrs.iter()
|
||||||
.any(|a| {
|
.any(|a| {
|
||||||
match *a {
|
match *a {
|
||||||
|
@ -23,6 +23,7 @@ macro_rules! my_quote {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod ast;
|
mod ast;
|
||||||
|
mod literal;
|
||||||
|
|
||||||
#[proc_macro_attribute]
|
#[proc_macro_attribute]
|
||||||
pub fn wasm_bindgen(attr: TokenStream, input: TokenStream) -> TokenStream {
|
pub fn wasm_bindgen(attr: TokenStream, input: TokenStream) -> TokenStream {
|
||||||
@ -96,7 +97,7 @@ impl ToTokens for ast::Program {
|
|||||||
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 = self.wbg_literal(&mut generated_static_value);
|
let generated_static_length = self.literal(&mut generated_static_value);
|
||||||
|
|
||||||
(my_quote! {
|
(my_quote! {
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@ -559,7 +560,7 @@ impl ToTokens for ast::Enum {
|
|||||||
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 = self.variants.iter().map(|variant| {
|
let cast_clauses = self.variants.iter().map(|variant| {
|
||||||
let &(variant_name, _) = variant;
|
let variant_name = &variant.name;
|
||||||
quote! {
|
quote! {
|
||||||
if #incoming_u32 == #enum_name::#variant_name as u32 {
|
if #incoming_u32 == #enum_name::#variant_name as u32 {
|
||||||
#enum_name::#variant_name
|
#enum_name::#variant_name
|
||||||
|
273
crates/wasm-bindgen-macro/src/literal.rs
Normal file
273
crates/wasm-bindgen-macro/src/literal.rs
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
use ast;
|
||||||
|
use proc_macro2::Span;
|
||||||
|
use quote::{ToTokens, Tokens};
|
||||||
|
use shared;
|
||||||
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
|
pub struct LiteralBuilder<'a> {
|
||||||
|
dst: &'a mut Tokens,
|
||||||
|
cnt: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> LiteralBuilder<'a> {
|
||||||
|
pub fn new(dst: &'a mut Tokens) -> LiteralBuilder<'a> {
|
||||||
|
LiteralBuilder {
|
||||||
|
dst,
|
||||||
|
cnt: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn finish(self) -> usize {
|
||||||
|
self.cnt
|
||||||
|
}
|
||||||
|
|
||||||
|
fn char_lit(&mut self, c: char) {
|
||||||
|
if self.cnt > 0 {
|
||||||
|
::syn::token::Comma::default().to_tokens(self.dst);
|
||||||
|
}
|
||||||
|
self.cnt += 1;
|
||||||
|
(c as u32).to_tokens(self.dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn append(&mut self, s: &str) {
|
||||||
|
for c in s.chars() {
|
||||||
|
self.char_lit(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn str(&mut self, s: &str) {
|
||||||
|
self.append("\"");
|
||||||
|
self.append(s);
|
||||||
|
self.append("\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bool(&mut self, v: bool) {
|
||||||
|
if v {
|
||||||
|
self.append("true")
|
||||||
|
} else {
|
||||||
|
self.append("false")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn char(&mut self, s: char) {
|
||||||
|
self.append("\"");
|
||||||
|
self.char_lit(s);
|
||||||
|
self.append("\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_char(&mut self, tokens: Tokens) {
|
||||||
|
self.append("\"");
|
||||||
|
::syn::token::Comma::default().to_tokens(self.dst);
|
||||||
|
tokens.to_tokens(self.dst);
|
||||||
|
self.cnt += 1;
|
||||||
|
self.append("\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fields(&mut self, fields: &[(&str, &Fn(&mut Self))]) {
|
||||||
|
self.append("{");
|
||||||
|
for (i, &(field, cb)) in fields.iter().enumerate() {
|
||||||
|
if i > 0 {
|
||||||
|
self.append(",");
|
||||||
|
}
|
||||||
|
self.str(field);
|
||||||
|
self.append(":");
|
||||||
|
cb(self);
|
||||||
|
}
|
||||||
|
self.append("}");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn list_of<'b, T, U>(&mut self, list: T)
|
||||||
|
where
|
||||||
|
T: IntoIterator<Item = &'b U>,
|
||||||
|
U: 'b + Literal,
|
||||||
|
{
|
||||||
|
self.list(list, U::literal)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn list<T, F>(&mut self, list: T, mut cb: F)
|
||||||
|
where F: FnMut(T::Item, &mut Self),
|
||||||
|
T: IntoIterator,
|
||||||
|
{
|
||||||
|
self.append("[");
|
||||||
|
for (i, element) in list.into_iter().enumerate() {
|
||||||
|
if i > 0 {
|
||||||
|
self.append(",");
|
||||||
|
}
|
||||||
|
cb(element, self);
|
||||||
|
}
|
||||||
|
self.append("]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Literal {
|
||||||
|
fn literal(&self, a: &mut LiteralBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Literal for ast::Program {
|
||||||
|
fn literal(&self, a: &mut LiteralBuilder) {
|
||||||
|
a.fields(&[
|
||||||
|
("exports", &|a| a.list_of(&self.exports)),
|
||||||
|
("imports", &|a| a.list_of(&self.imports)),
|
||||||
|
("enums", &|a| a.list_of(&self.enums)),
|
||||||
|
("custom_type_names", &|a| {
|
||||||
|
let names = self.exports
|
||||||
|
.iter()
|
||||||
|
.filter_map(|e| e.class)
|
||||||
|
.chain(self.structs.iter().map(|s| s.name))
|
||||||
|
.collect::<BTreeSet<_>>();
|
||||||
|
a.list(&names, |s, a| {
|
||||||
|
let val = shared::name_to_descriptor(s.as_ref());
|
||||||
|
a.fields(&[
|
||||||
|
("descriptor", &|a| a.char(val)),
|
||||||
|
("name", &|a| a.str(s.as_ref())),
|
||||||
|
]);
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
("version", &|a| a.str(&shared::version())),
|
||||||
|
("schema_version", &|a| a.str(&shared::SCHEMA_VERSION)),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Literal for ast::Function {
|
||||||
|
fn literal(&self, a: &mut LiteralBuilder) {
|
||||||
|
a.fields(&[
|
||||||
|
("name", &|a| a.str(self.name.as_ref())),
|
||||||
|
("arguments", &|a| a.list_of(&self.arguments)),
|
||||||
|
("ret", &|a| match self.ret {
|
||||||
|
Some(ref s) => s.literal(a),
|
||||||
|
None => a.append("null"),
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Literal for ast::Type {
|
||||||
|
fn literal(&self, a: &mut LiteralBuilder) {
|
||||||
|
match *self {
|
||||||
|
ast::Type::Vector(ast::VectorType::String, true) => a.char(shared::TYPE_STRING),
|
||||||
|
ast::Type::Vector(ast::VectorType::String, false) => a.char(shared::TYPE_BORROWED_STR),
|
||||||
|
ast::Type::Vector(ast::VectorType::U8, true) => a.char(shared::TYPE_VECTOR_U8),
|
||||||
|
ast::Type::Vector(ast::VectorType::U8, false) => a.char(shared::TYPE_SLICE_U8),
|
||||||
|
ast::Type::Vector(ast::VectorType::I8, true) => a.char(shared::TYPE_VECTOR_I8),
|
||||||
|
ast::Type::Vector(ast::VectorType::I8, false) => a.char(shared::TYPE_SLICE_I8),
|
||||||
|
ast::Type::Vector(ast::VectorType::U16, true) => a.char(shared::TYPE_VECTOR_U16),
|
||||||
|
ast::Type::Vector(ast::VectorType::U16, false) => a.char(shared::TYPE_SLICE_U16),
|
||||||
|
ast::Type::Vector(ast::VectorType::I16, true) => a.char(shared::TYPE_VECTOR_I16),
|
||||||
|
ast::Type::Vector(ast::VectorType::I16, false) => a.char(shared::TYPE_SLICE_I16),
|
||||||
|
ast::Type::Vector(ast::VectorType::U32, true) => a.char(shared::TYPE_VECTOR_U32),
|
||||||
|
ast::Type::Vector(ast::VectorType::U32, false) => a.char(shared::TYPE_SLICE_U32),
|
||||||
|
ast::Type::Vector(ast::VectorType::I32, true) => a.char(shared::TYPE_VECTOR_I32),
|
||||||
|
ast::Type::Vector(ast::VectorType::I32, false) => a.char(shared::TYPE_SLICE_I32),
|
||||||
|
ast::Type::Vector(ast::VectorType::F32, true) => a.char(shared::TYPE_VECTOR_F32),
|
||||||
|
ast::Type::Vector(ast::VectorType::F32, false) => a.char(shared::TYPE_SLICE_F32),
|
||||||
|
ast::Type::Vector(ast::VectorType::F64, true) => a.char(shared::TYPE_VECTOR_F64),
|
||||||
|
ast::Type::Vector(ast::VectorType::F64, false) => a.char(shared::TYPE_SLICE_F64),
|
||||||
|
ast::Type::Vector(ast::VectorType::JsValue, true) => {
|
||||||
|
a.char(shared::TYPE_VECTOR_JSVALUE)
|
||||||
|
}
|
||||||
|
ast::Type::Vector(ast::VectorType::JsValue, false) => {
|
||||||
|
panic!("Slices of JsValues not supported")
|
||||||
|
}
|
||||||
|
ast::Type::ByValue(ref t) => {
|
||||||
|
a.as_char(my_quote! {
|
||||||
|
<#t as ::wasm_bindgen::convert::WasmBoundary>::DESCRIPTOR
|
||||||
|
});
|
||||||
|
}
|
||||||
|
ast::Type::ByRef(ref ty) | ast::Type::ByMutRef(ref ty) => {
|
||||||
|
a.as_char(my_quote! {
|
||||||
|
(<#ty as ::wasm_bindgen::convert::WasmBoundary>::DESCRIPTOR |
|
||||||
|
::wasm_bindgen::convert::DESCRIPTOR_CUSTOM_REF_FLAG)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Literal for ast::Export {
|
||||||
|
fn literal(&self, a: &mut LiteralBuilder) {
|
||||||
|
a.fields(&[
|
||||||
|
("class", &|a| match self.class {
|
||||||
|
Some(ref s) => a.str(s.as_ref()),
|
||||||
|
None => a.append("null"),
|
||||||
|
}),
|
||||||
|
("method", &|a| a.bool(self.method)),
|
||||||
|
("function", &|a| self.function.literal(a)),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Literal for ast::Import {
|
||||||
|
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, .. } => {
|
||||||
|
method = true;
|
||||||
|
class_name = Some(class);
|
||||||
|
}
|
||||||
|
ast::ImportKind::JsConstructor { ref class, .. } => {
|
||||||
|
js_new = true;
|
||||||
|
class_name = Some(class);
|
||||||
|
}
|
||||||
|
ast::ImportKind::Static { ref class, .. } => {
|
||||||
|
statik = true;
|
||||||
|
class_name = Some(class);
|
||||||
|
}
|
||||||
|
ast::ImportKind::Normal => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut getter = None;
|
||||||
|
let mut setter = None;
|
||||||
|
|
||||||
|
if self.function.opts.getter() {
|
||||||
|
getter = Some(self.infer_getter_property());
|
||||||
|
}
|
||||||
|
if self.function.opts.setter() {
|
||||||
|
setter = Some(self.infer_setter_property());
|
||||||
|
}
|
||||||
|
a.fields(&[
|
||||||
|
("module", &|a| match self.module {
|
||||||
|
Some(ref s) => a.str(s),
|
||||||
|
None => a.append("null"),
|
||||||
|
}),
|
||||||
|
("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"),
|
||||||
|
}),
|
||||||
|
("setter", &|a| match setter {
|
||||||
|
Some(ref s) => a.str(s),
|
||||||
|
None => a.append("null"),
|
||||||
|
}),
|
||||||
|
("function", &|a| self.function.literal(a)),
|
||||||
|
("class", &|a| match class_name {
|
||||||
|
Some(s) => a.str(s),
|
||||||
|
None => a.append("null"),
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Literal for ast::Enum {
|
||||||
|
fn literal(&self, a: &mut LiteralBuilder) {
|
||||||
|
a.fields(&[
|
||||||
|
("name", &|a| a.str(self.name.as_ref())),
|
||||||
|
("variants", &|a| a.list_of(&self.variants)),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Literal for ast::Variant {
|
||||||
|
fn literal(&self, a: &mut LiteralBuilder) {
|
||||||
|
a.fields(&[
|
||||||
|
("name", &|a| a.str(self.name.as_ref())),
|
||||||
|
("value", &|a| a.append(&format!("{}", self.value))),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user