From d065f4b05d1d950b38b9fb95ef7bef29dc62652b Mon Sep 17 00:00:00 2001 From: "R. Andrew Ohana" Date: Mon, 11 Jun 2018 18:35:20 -0700 Subject: [PATCH] webidl: add support for typedefs --- crates/backend/src/ast.rs | 8 ++++++ crates/backend/src/codegen.rs | 15 +++++++++++ crates/webidl/src/lib.rs | 32 +++++++++++++++++++++-- crates/webidl/tests/expected/Event.rs | 2 ++ crates/webidl/tests/fixtures/Event.webidl | 3 +++ 5 files changed, 58 insertions(+), 2 deletions(-) diff --git a/crates/backend/src/ast.rs b/crates/backend/src/ast.rs index e24e783f..4e761889 100644 --- a/crates/backend/src/ast.rs +++ b/crates/backend/src/ast.rs @@ -10,6 +10,7 @@ pub struct Program { pub imports: Vec, pub enums: Vec, pub structs: Vec, + pub type_aliases: Vec, } #[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))] @@ -120,6 +121,13 @@ pub enum TypeLocation { ExportRet, } +#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))] +pub struct TypeAlias { + pub vis: syn::Visibility, + pub dest: Ident, + pub src: syn::Type, +} + impl Program { pub fn push_item( &mut self, diff --git a/crates/backend/src/codegen.rs b/crates/backend/src/codegen.rs index de63b78f..e1ed09b7 100644 --- a/crates/backend/src/codegen.rs +++ b/crates/backend/src/codegen.rs @@ -59,6 +59,9 @@ impl ToTokens for ast::Program { for e in self.enums.iter() { e.to_tokens(tokens); } + for a in self.type_aliases.iter() { + a.to_tokens(tokens); + } // Generate a static which will eventually be what lives in a custom section // of the wasm executable. For now it's just a plain old static, but we'll @@ -823,3 +826,15 @@ impl ToTokens for ast::ImportStatic { }).to_tokens(into); } } + +impl ToTokens for ast::TypeAlias { + fn to_tokens(&self, into: &mut TokenStream) { + let vis = &self.vis; + let dest = &self.dest; + let src = &self.src; + (quote! { + #[allow(non_camel_case_types)] + #vis type #dest = #src; + }).to_tokens(into); + } +} diff --git a/crates/webidl/src/lib.rs b/crates/webidl/src/lib.rs index 2e0eee9a..c6d34530 100755 --- a/crates/webidl/src/lib.rs +++ b/crates/webidl/src/lib.rs @@ -123,6 +123,7 @@ impl<'a> WebidlParse<'a> for webidl::ast::Definition { webidl::ast::Definition::Interface(ref interface) => { interface.webidl_parse(program, ()) } + webidl::ast::Definition::Typedef(ref typedef) => typedef.webidl_parse(program, ()), // TODO webidl::ast::Definition::Callback(..) | webidl::ast::Definition::Dictionary(..) @@ -130,8 +131,7 @@ impl<'a> WebidlParse<'a> for webidl::ast::Definition { | webidl::ast::Definition::Implements(..) | webidl::ast::Definition::Includes(..) | webidl::ast::Definition::Mixin(..) - | webidl::ast::Definition::Namespace(..) - | webidl::ast::Definition::Typedef(..) => { + | webidl::ast::Definition::Namespace(..) => { warn!("Unsupported WebIDL definition: {:?}", self); Ok(()) } @@ -156,6 +156,34 @@ impl<'a> WebidlParse<'a> for webidl::ast::Interface { } } +impl<'a> WebidlParse<'a> for webidl::ast::Typedef { + type Extra = (); + + fn webidl_parse(&self, program: &mut backend::ast::Program, _: ()) -> Result<()> { + let dest = rust_ident(&self.name); + let src = match webidl_ty_to_syn_ty(&self.type_, TypePosition::Return) { + Some(src) => src, + None => { + warn!( + "typedef's source type is not yet supported: {:?}. Skipping typedef {:?}", + *self.type_, self + ); + return Ok(()); + } + }; + + program.type_aliases.push(backend::ast::TypeAlias { + vis: syn::Visibility::Public(syn::VisPublic { + pub_token: Default::default(), + }), + dest, + src, + }); + + Ok(()) + } +} + impl<'a> WebidlParse<'a> for webidl::ast::NonPartialInterface { type Extra = (); diff --git a/crates/webidl/tests/expected/Event.rs b/crates/webidl/tests/expected/Event.rs index 47606de4..77c147cf 100644 --- a/crates/webidl/tests/expected/Event.rs +++ b/crates/webidl/tests/expected/Event.rs @@ -224,6 +224,8 @@ impl Event { ); } } +#[allow(non_camel_case_types)] +pub type DOMHighResTimeStamp = f64; #[allow(non_upper_case_globals)] #[wasm_custom_section = "__wasm_bindgen_unstable"] const __WASM_BINDGEN_GENERATED_wasm_bindgen_webidl_0_2_11_0 : [ u8 ; 1299usize ] = * b"\x0F\x05\0\0{\"exports\":[],\"enums\":[],\"imports\":[{\"module\":null,\"version\":null,\"js_namespace\":null,\"kind\":{\"kind\":\"type\"}},{\"module\":null,\"version\":null,\"js_namespace\":null,\"kind\":{\"kind\":\"function\",\"shim\":\"__wbg_f_stopPropagation_stop_propagation_Event\",\"catch\":false,\"method\":true,\"js_new\":false,\"structural\":false,\"getter\":null,\"setter\":null,\"class\":\"Event\",\"function\":{\"name\":\"stopPropagation\"}}},{\"module\":null,\"version\":null,\"js_namespace\":null,\"kind\":{\"kind\":\"function\",\"shim\":\"__wbg_f_stopImmediatePropagation_stop_immediate_propagation_Event\",\"catch\":false,\"method\":true,\"js_new\":false,\"structural\":false,\"getter\":null,\"setter\":null,\"class\":\"Event\",\"function\":{\"name\":\"stopImmediatePropagation\"}}},{\"module\":null,\"version\":null,\"js_namespace\":null,\"kind\":{\"kind\":\"function\",\"shim\":\"__wbg_f_preventDefault_prevent_default_Event\",\"catch\":false,\"method\":true,\"js_new\":false,\"structural\":false,\"getter\":null,\"setter\":null,\"class\":\"Event\",\"function\":{\"name\":\"preventDefault\"}}},{\"module\":null,\"version\":null,\"js_namespace\":null,\"kind\":{\"kind\":\"function\",\"shim\":\"__wbg_f_initEvent_init_event_Event\",\"catch\":false,\"method\":true,\"js_new\":false,\"structural\":false,\"getter\":null,\"setter\":null,\"class\":\"Event\",\"function\":{\"name\":\"initEvent\"}}}],\"structs\":[],\"version\":\"0.2.11 (71107b8e8)\",\"schema_version\":\"4\"}" ; diff --git a/crates/webidl/tests/fixtures/Event.webidl b/crates/webidl/tests/fixtures/Event.webidl index 972961e9..8dea443a 100644 --- a/crates/webidl/tests/fixtures/Event.webidl +++ b/crates/webidl/tests/fixtures/Event.webidl @@ -10,6 +10,9 @@ * liability, trademark and document use rules apply. */ +// TODO: don't include this here, use Performance.webidl instead +typedef double DOMHighResTimeStamp; + [Constructor(DOMString type, optional EventInit eventInitDict), Exposed=(Window,Worker,System), ProbablyShortLivingWrapper] interface Event {