mirror of
https://github.com/rustwasm/wasm-bindgen.git
synced 2024-11-25 09:02:46 +03: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 quote::{Tokens, ToTokens};
|
||||
use shared;
|
||||
@ -50,7 +49,12 @@ pub struct Struct {
|
||||
|
||||
pub struct Enum {
|
||||
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 {
|
||||
@ -231,7 +235,10 @@ impl Program {
|
||||
_ => panic!("Enums may only have number literal values")
|
||||
};
|
||||
|
||||
(v.ident, value)
|
||||
Variant {
|
||||
name: v.ident,
|
||||
value,
|
||||
}
|
||||
}).collect();
|
||||
self.enums.push(Enum {
|
||||
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 cnt = {
|
||||
let mut a = LiteralBuilder {
|
||||
dst: &mut tmp,
|
||||
cnt: 0,
|
||||
};
|
||||
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 mut a = literal::LiteralBuilder::new(&mut tmp);
|
||||
Literal::literal(self, &mut a);
|
||||
a.finish()
|
||||
};
|
||||
let cnt = cnt as u32;
|
||||
(quote! {
|
||||
@ -442,19 +427,6 @@ impl Function {
|
||||
rust_attrs: attrs,
|
||||
}, 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> {
|
||||
@ -527,43 +499,6 @@ impl Type {
|
||||
|
||||
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 {
|
||||
@ -592,191 +527,26 @@ impl Export {
|
||||
};
|
||||
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 {
|
||||
fn wbg_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 {
|
||||
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 {
|
||||
pub fn infer_getter_property(&self) -> 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();
|
||||
assert!(name.starts_with("set_"), "setters must start with `set_`");
|
||||
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 {
|
||||
fn from(s: syn::ItemStruct, _opts: BindgenAttrs) -> Struct {
|
||||
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)]
|
||||
pub struct BindgenAttrs {
|
||||
attrs: Vec<BindgenAttr>,
|
||||
@ -848,7 +618,7 @@ impl BindgenAttrs {
|
||||
.next()
|
||||
}
|
||||
|
||||
fn getter(&self) -> bool {
|
||||
pub fn getter(&self) -> bool {
|
||||
self.attrs.iter()
|
||||
.any(|a| {
|
||||
match *a {
|
||||
@ -858,7 +628,7 @@ impl BindgenAttrs {
|
||||
})
|
||||
}
|
||||
|
||||
fn setter(&self) -> bool {
|
||||
pub fn setter(&self) -> bool {
|
||||
self.attrs.iter()
|
||||
.any(|a| {
|
||||
match *a {
|
||||
|
@ -23,6 +23,7 @@ macro_rules! my_quote {
|
||||
}
|
||||
|
||||
mod ast;
|
||||
mod literal;
|
||||
|
||||
#[proc_macro_attribute]
|
||||
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 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! {
|
||||
#[no_mangle]
|
||||
@ -559,7 +560,7 @@ impl ToTokens for ast::Enum {
|
||||
let incoming_u32 = quote! { n };
|
||||
let enum_name_as_string = enum_name.to_string();
|
||||
let cast_clauses = self.variants.iter().map(|variant| {
|
||||
let &(variant_name, _) = variant;
|
||||
let variant_name = &variant.name;
|
||||
quote! {
|
||||
if #incoming_u32 == #enum_name::#variant_name as u32 {
|
||||
#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…
Reference in New Issue
Block a user