diff options
-rw-r--r-- | components/jstraceable_derive/Cargo.toml | 15 | ||||
-rw-r--r-- | components/jstraceable_derive/lib.rs | 58 | ||||
-rw-r--r-- | components/plugins/jstraceable.rs | 65 | ||||
-rw-r--r-- | components/plugins/lib.rs | 3 | ||||
-rw-r--r-- | components/script/Cargo.toml | 1 | ||||
-rw-r--r-- | components/script/dom/validitystate.rs | 2 | ||||
-rw-r--r-- | components/script/lib.rs | 2 | ||||
-rw-r--r-- | components/servo/Cargo.lock | 10 | ||||
-rw-r--r-- | ports/cef/Cargo.lock | 10 |
9 files changed, 98 insertions, 68 deletions
diff --git a/components/jstraceable_derive/Cargo.toml b/components/jstraceable_derive/Cargo.toml new file mode 100644 index 00000000000..765678c0341 --- /dev/null +++ b/components/jstraceable_derive/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "jstraceable_derive" +version = "0.0.1" +authors = ["The Servo Project Developers"] +license = "MPL-2.0" +publish = false + +[lib] +path = "lib.rs" +proc-macro = true + +[dependencies] +syn = "0.9" +quote = "0.3" +synstructure = "0.2" diff --git a/components/jstraceable_derive/lib.rs b/components/jstraceable_derive/lib.rs new file mode 100644 index 00000000000..9b4899306f9 --- /dev/null +++ b/components/jstraceable_derive/lib.rs @@ -0,0 +1,58 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#![feature(proc_macro, proc_macro_lib)] + +extern crate proc_macro; +#[macro_use] extern crate quote; +extern crate syn; +extern crate synstructure; + +#[cfg(not(test))] +#[proc_macro_derive(JSTraceable)] +pub fn expand_token_stream(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + expand_string(&input.to_string()).parse().unwrap() +} + +fn expand_string(input: &str) -> String { + let mut type_ = syn::parse_macro_input(input).unwrap(); + + let style = synstructure::BindStyle::Ref.into(); + let match_body = synstructure::each_field(&mut type_, &style, |binding| { + Some(quote! { #binding.trace(tracer); }) + }); + + let name = &type_.ident; + let (impl_generics, ty_generics, mut where_clause) = type_.generics.split_for_impl(); + for param in &type_.generics.ty_params { + where_clause.predicates.push(syn::WherePredicate::BoundPredicate(syn::WhereBoundPredicate { + bound_lifetimes: Vec::new(), + bounded_ty: syn::Ty::Path(None, param.ident.clone().into()), + bounds: vec![syn::TyParamBound::Trait( + syn::PolyTraitRef { + bound_lifetimes: Vec::new(), + trait_ref: syn::parse_path("::dom::bindings::trace::JSTraceable").unwrap(), + }, + syn::TraitBoundModifier::None + )], + })) + } + + let tokens = quote! { + #type_ + + impl #impl_generics ::dom::bindings::trace::JSTraceable for #name #ty_generics #where_clause { + #[inline] + #[allow(unused_variables, unused_imports)] + fn trace(&self, tracer: *mut ::js::jsapi::JSTracer) { + use ::dom::bindings::trace::JSTraceable; + match *self { + #match_body + } + } + } + }; + + tokens.to_string() +} diff --git a/components/plugins/jstraceable.rs b/components/plugins/jstraceable.rs index e41d56765ce..f1e0ed496b6 100644 --- a/components/plugins/jstraceable.rs +++ b/components/plugins/jstraceable.rs @@ -2,13 +2,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use syntax::ast::{Expr, MetaItem, Mutability}; +use syntax::ast::MetaItem; use syntax::codemap::Span; use syntax::ext::base::{Annotatable, ExtCtxt}; -use syntax::ext::build::AstBuilder; use syntax::ptr::P; -use syntax_ext::deriving::generic::{Struct, Substructure, TraitDef, ty}; -use syntax_ext::deriving::generic::{combine_substructure, EnumMatching, FieldInfo, MethodDef}; pub fn expand_dom_struct(cx: &mut ExtCtxt, sp: Span, _: &MetaItem, anno: Annotatable) -> Annotatable { if let Annotatable::Item(item) = anno { @@ -29,63 +26,3 @@ pub fn expand_dom_struct(cx: &mut ExtCtxt, sp: Span, _: &MetaItem, anno: Annotat anno } } - -/// Provides the hook to expand `#[derive(JSTraceable)]` into an implementation of `JSTraceable` -/// -/// The expansion basically calls `trace()` on all of the fields of the struct/enum, erroring if they do not -/// implement the method. -pub fn expand_jstraceable(cx: &mut ExtCtxt, span: Span, mitem: &MetaItem, item: &Annotatable, - push: &mut FnMut(Annotatable)) { - let trait_def = TraitDef { - is_unsafe: false, - span: span, - attributes: Vec::new(), - path: ty::Path::new(vec!("dom", "bindings", "trace", "JSTraceable")), - additional_bounds: Vec::new(), - generics: ty::LifetimeBounds::empty(), - supports_unions: true, - methods: vec![ - MethodDef { - name: "trace", - generics: ty::LifetimeBounds::empty(), - explicit_self: ty::borrowed_explicit_self(), - args: vec!(ty::Ptr(box ty::Literal(ty::Path::new(vec!("js", "jsapi", "JSTracer"))), - ty::Raw(Mutability::Mutable))), - ret_ty: ty::nil_ty(), - attributes: vec![quote_attr!(cx, #[inline])], - is_unsafe: false, - combine_substructure: combine_substructure(box jstraceable_substructure), - unify_fieldless_variants: true, - } - ], - associated_types: vec![], - }; - trait_def.expand(cx, mitem, item, push) -} - -// Mostly copied from syntax::ext::deriving::hash -/// Defines how the implementation for `trace()` is to be generated -fn jstraceable_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> { - let state_expr = if substr.nonself_args.len() == 1 { - &substr.nonself_args[0] - } else { - cx.span_bug(trait_span, "incorrect number of arguments in `jstraceable`") - }; - let trace_ident = substr.method_ident; - let call_trace = |span, thing_expr| { - let expr = cx.expr_method_call(span, thing_expr, trace_ident, vec!(state_expr.clone())); - cx.stmt_expr(expr) - }; - let mut stmts = Vec::new(); - - let fields = match *substr.fields { - Struct(_, ref fs) | EnumMatching(_, _, ref fs) => fs, - _ => cx.span_bug(trait_span, "impossible substructure in `jstraceable`") - }; - - for &FieldInfo { ref self_, span, .. } in fields { - stmts.push(call_trace(span, self_.clone())); - } - - cx.expr_block(cx.block(trait_span, stmts)) -} diff --git a/components/plugins/lib.rs b/components/plugins/lib.rs index e62243e8024..5ebb54aba31 100644 --- a/components/plugins/lib.rs +++ b/components/plugins/lib.rs @@ -25,7 +25,6 @@ extern crate rustc; extern crate rustc_plugin; #[macro_use] extern crate syntax; -extern crate syntax_ext; use rustc_plugin::Registry; use syntax::ext::base::*; @@ -44,8 +43,6 @@ mod utils; #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { reg.register_syntax_extension(intern("dom_struct"), MultiModifier(box jstraceable::expand_dom_struct)); - reg.register_syntax_extension(intern("derive_JSTraceable"), - MultiDecorator(box jstraceable::expand_jstraceable)); reg.register_syntax_extension(intern("_generate_reflector"), MultiDecorator(box reflector::expand_reflector)); reg.register_late_lint_pass(box lints::unrooted_must_root::UnrootedPass::new()); diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index b65b1da3eb4..610ee51278c 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -42,6 +42,7 @@ hyper_serde = "0.1.4" image = "0.10" ipc-channel = "0.5" js = {git = "https://github.com/servo/rust-mozjs", features = ["promises"]} +jstraceable_derive = {path = "../jstraceable_derive"} libc = "0.2" log = "0.3.5" mime = "0.2.1" diff --git a/components/script/dom/validitystate.rs b/components/script/dom/validitystate.rs index 21740b16bfc..c6bb0761f3c 100644 --- a/components/script/dom/validitystate.rs +++ b/components/script/dom/validitystate.rs @@ -10,7 +10,7 @@ use dom::element::Element; use dom::window::Window; // https://html.spec.whatwg.org/multipage/#validity-states -#[derive_JSTraceable] +#[derive(JSTraceable)] #[derive(HeapSizeOf)] pub enum ValidityStatus { ValueMissing, diff --git a/components/script/lib.rs b/components/script/lib.rs index 96e9cb29731..78e28f24fb0 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -54,6 +54,8 @@ extern crate image; extern crate ipc_channel; #[macro_use] extern crate js; +#[macro_use] +extern crate jstraceable_derive; extern crate libc; #[macro_use] extern crate log; diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index 282d6152888..fb702d1be31 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -1119,6 +1119,15 @@ dependencies = [ ] [[package]] +name = "jstraceable_derive" +version = "0.0.1" +dependencies = [ + "quote 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "kernel32-sys" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1970,6 +1979,7 @@ dependencies = [ "image 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "js 0.1.3 (git+https://github.com/servo/rust-mozjs)", + "jstraceable_derive 0.0.1", "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index 959bf30a134..e4479c8417e 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -1026,6 +1026,15 @@ dependencies = [ ] [[package]] +name = "jstraceable_derive" +version = "0.0.1" +dependencies = [ + "quote 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "kernel32-sys" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1821,6 +1830,7 @@ dependencies = [ "image 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "js 0.1.3 (git+https://github.com/servo/rust-mozjs)", + "jstraceable_derive 0.0.1", "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", |