Skip to content

Commit

Permalink
Fixing code generation
Browse files Browse the repository at this point in the history
  • Loading branch information
Pauan committed Feb 28, 2020
1 parent caa41b2 commit dd030b3
Show file tree
Hide file tree
Showing 188 changed files with 1,178 additions and 1,715 deletions.
57 changes: 0 additions & 57 deletions crates/backend/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,6 @@ pub struct Program {
pub enums: Vec<Enum>,
/// rust structs
pub structs: Vec<Struct>,
/// rust consts
pub consts: Vec<Const>,
/// "dictionaries", generated for WebIDL, which are basically just "typed
/// objects" in the sense that they represent a JS object with a particular
/// shape in JIT parlance.
pub dictionaries: Vec<Dictionary>,
/// custom typescript sections to be included in the definition file
pub typescript_custom_sections: Vec<String>,
/// Inline JS snippets
Expand All @@ -36,8 +30,6 @@ impl Program {
self.imports.is_empty() &&
self.enums.is_empty() &&
self.structs.is_empty() &&
self.consts.is_empty() &&
self.dictionaries.is_empty() &&
self.typescript_custom_sections.is_empty() &&
self.inline_js.is_empty()
}
Expand Down Expand Up @@ -284,55 +276,6 @@ pub enum TypeLocation {
ExportRet,
}

#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq))]
#[derive(Clone)]
pub struct Const {
pub vis: syn::Visibility,
pub name: Ident,
pub class: Option<Ident>,
pub ty: syn::Type,
pub value: ConstValue,
}

#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq))]
#[derive(Clone)]
/// same as webidl::ast::ConstValue
pub enum ConstValue {
BooleanLiteral(bool),
FloatLiteral(f64),
SignedIntegerLiteral(i64),
UnsignedIntegerLiteral(u64),
Null,
}

#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
#[derive(Clone)]
pub struct DictionaryConstructor {
pub doc_comment: Option<String>,
pub rust_attrs: Vec<syn::Attribute>,
}

#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
#[derive(Clone)]
pub struct Dictionary {
pub vis: syn::Visibility,
pub name: Ident,
pub fields: Vec<DictionaryField>,
pub constructor: Option<DictionaryConstructor>,
pub doc_comment: Option<String>,
}

#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
#[derive(Clone)]
pub struct DictionaryField {
pub rust_name: Ident,
pub js_name: String,
pub required: bool,
pub ty: syn::Type,
pub doc_comment: Option<String>,
pub rust_attrs: Vec<syn::Attribute>,
}

impl Export {
/// Mangles a rust -> javascript export, so that the created Ident will be unique over function
/// name and class name, if the function belongs to a javascript class.
Expand Down
157 changes: 0 additions & 157 deletions crates/backend/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,6 @@ impl TryToTokens for ast::Program {
for e in self.enums.iter() {
e.to_tokens(tokens);
}
for c in self.consts.iter() {
c.to_tokens(tokens);
}
for d in self.dictionaries.iter() {
d.to_tokens(tokens);
}

Diagnostic::from_vec(errors)?;

Expand Down Expand Up @@ -1211,157 +1205,6 @@ impl ToTokens for ast::ImportStatic {
}
}

impl ToTokens for ast::ConstValue {
fn to_tokens(&self, tokens: &mut TokenStream) {
use crate::ast::ConstValue::*;

match self {
BooleanLiteral(false) => quote!(false),
BooleanLiteral(true) => quote!(true),
// the actual type is unknown because of typedefs
// so we cannot use std::fxx::INFINITY
// but we can use type inference
FloatLiteral(f) if f.is_infinite() && f.is_sign_positive() => quote!(1.0 / 0.0),
FloatLiteral(f) if f.is_infinite() && f.is_sign_negative() => quote!(-1.0 / 0.0),
FloatLiteral(f) if f.is_nan() => quote!(0.0 / 0.0),
// again no suffix
// panics on +-inf, nan
FloatLiteral(f) => {
let f = Literal::f64_suffixed(*f);
quote!(#f)
}
SignedIntegerLiteral(i) => {
let i = Literal::i64_suffixed(*i);
quote!(#i)
}
UnsignedIntegerLiteral(i) => {
let i = Literal::u64_suffixed(*i);
quote!(#i)
}
Null => unimplemented!(),
}.to_tokens(tokens)
}
}

impl ToTokens for ast::Const {
fn to_tokens(&self, tokens: &mut TokenStream) {
let vis = &self.vis;
let name = &self.name;
let ty = &self.ty;
let value = &self.value;

let declaration = quote!(#vis const #name: #ty = #value as #ty;);

if let Some(class) = &self.class {
(quote! {
impl #class {
#declaration
}
})
.to_tokens(tokens);
} else {
declaration.to_tokens(tokens);
}
}
}

impl ToTokens for ast::Dictionary {
fn to_tokens(&self, tokens: &mut TokenStream) {
let name = &self.name;
let vis = &self.vis;
let mut methods = TokenStream::new();
for field in self.fields.iter() {
field.to_tokens(&mut methods);
}
let required_names = &self
.fields
.iter()
.filter(|f| f.required)
.map(|f| &f.rust_name)
.collect::<Vec<_>>();
let required_types = &self
.fields
.iter()
.filter(|f| f.required)
.map(|f| &f.ty)
.collect::<Vec<_>>();
let required_names2 = required_names;
let required_names3 = required_names;
let doc_comment = match &self.doc_comment {
None => "",
Some(doc_string) => doc_string,
};

let ctor = match &self.constructor {
Some(ctor) => {
let attrs = &ctor.rust_attrs;

let doc_comment = match &ctor.doc_comment {
None => "",
Some(doc_string) => doc_string,
};

quote! {
#(#attrs)*
#[doc = #doc_comment]
pub fn new(#(#required_names: #required_types),*) -> #name {
let mut ret: #name = ::js_sys::Object::new().into();
#(ret.#required_names2(#required_names3);)*
ret
}
}
},
None => quote! {},
};

(quote! {
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(extends = ::js_sys::Object)]
#[doc = #doc_comment]
#[derive(Clone, Debug)]
#vis type #name;
}

#[allow(clippy::all)]
impl #name {
#ctor
#methods
}
})
.to_tokens(tokens);
}
}

impl ToTokens for ast::DictionaryField {
fn to_tokens(&self, tokens: &mut TokenStream) {
let attrs = &self.rust_attrs;
let rust_name = &self.rust_name;
let js_name = &self.js_name;
let ty = &self.ty;
let doc_comment = match &self.doc_comment {
None => "",
Some(doc_string) => doc_string,
};
(quote! {
#(#attrs)*
#[allow(clippy::all)]
#[doc = #doc_comment]
pub fn #rust_name(&mut self, val: #ty) -> &mut Self {
use wasm_bindgen::JsValue;
let r = ::js_sys::Reflect::set(
self.as_ref(),
&JsValue::from(#js_name),
&JsValue::from(val),
);
debug_assert!(r.is_ok(), "setting properties should never fail on our dictionary objects");
let _ = r;
self
}
}).to_tokens(tokens);
}
}

/// Emits the necessary glue tokens for "descriptor", generating an appropriate
/// symbol name as well as attributes around the descriptor function itself.
struct Descriptor<'a, T> {
Expand Down
Loading

0 comments on commit dd030b3

Please sign in to comment.