aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/plugins/jstraceable.rs29
-rw-r--r--components/plugins/lib.rs4
-rw-r--r--components/plugins/reflector.rs67
3 files changed, 53 insertions, 47 deletions
diff --git a/components/plugins/jstraceable.rs b/components/plugins/jstraceable.rs
index 4c23a1897a5..d11b0956bae 100644
--- a/components/plugins/jstraceable.rs
+++ b/components/plugins/jstraceable.rs
@@ -5,23 +5,28 @@
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::codemap::Span;
use syntax::ptr::P;
-use syntax::ast::{Item, MetaItem, Expr};
+use syntax::ast::{MetaItem, Expr};
use syntax::ast;
use syntax::ext::build::AstBuilder;
use syntax::ext::deriving::generic::{combine_substructure, EnumMatching, FieldInfo, MethodDef, Struct, Substructure, TraitDef, ty};
-pub fn expand_dom_struct(cx: &mut ExtCtxt, _: Span, _: &MetaItem, item: P<Item>) -> P<Item> {
- let mut item2 = (*item).clone();
- item2.attrs.push(quote_attr!(cx, #[must_root]));
- item2.attrs.push(quote_attr!(cx, #[privatize]));
- item2.attrs.push(quote_attr!(cx, #[jstraceable]));
+pub fn expand_dom_struct(cx: &mut ExtCtxt, sp: Span, _: &MetaItem, anno: Annotatable) -> Annotatable {
+ if let Annotatable::Item(item) = anno {
+ let mut item2 = (*item).clone();
+ item2.attrs.push(quote_attr!(cx, #[must_root]));
+ item2.attrs.push(quote_attr!(cx, #[privatize]));
+ item2.attrs.push(quote_attr!(cx, #[jstraceable]));
- // The following attributes are only for internal usage
- item2.attrs.push(quote_attr!(cx, #[_generate_reflector]));
- // #[dom_struct] gets consumed, so this lets us keep around a residue
- // Do NOT register a modifier/decorator on this attribute
- item2.attrs.push(quote_attr!(cx, #[_dom_struct_marker]));
- P(item2)
+ // The following attributes are only for internal usage
+ item2.attrs.push(quote_attr!(cx, #[_generate_reflector]));
+ // #[dom_struct] gets consumed, so this lets us keep around a residue
+ // Do NOT register a modifier/decorator on this attribute
+ item2.attrs.push(quote_attr!(cx, #[_dom_struct_marker]));
+ Annotatable::Item(P(item2))
+ } else {
+ cx.span_err(sp, "#[dom_struct] applied to something other than a struct");
+ anno
+ }
}
/// Provides the hook to expand `#[jstraceable]` into an implementation of `JSTraceable`
diff --git a/components/plugins/lib.rs b/components/plugins/lib.rs
index 887e78689a9..a74cbe83f30 100644
--- a/components/plugins/lib.rs
+++ b/components/plugins/lib.rs
@@ -39,9 +39,9 @@ pub mod casing;
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
- reg.register_syntax_extension(intern("dom_struct"), Modifier(box jstraceable::expand_dom_struct));
+ reg.register_syntax_extension(intern("dom_struct"), MultiModifier(box jstraceable::expand_dom_struct));
reg.register_syntax_extension(intern("jstraceable"), MultiDecorator(box jstraceable::expand_jstraceable));
- reg.register_syntax_extension(intern("_generate_reflector"), Decorator(box reflector::expand_reflector));
+ reg.register_syntax_extension(intern("_generate_reflector"), MultiDecorator(box reflector::expand_reflector));
reg.register_macro("to_lower", casing::expand_lower);
reg.register_macro("to_upper", casing::expand_upper);
reg.register_lint_pass(box lints::transmute_type::TransmutePass as LintPassObject);
diff --git a/components/plugins/reflector.rs b/components/plugins/reflector.rs
index 6c2213cdabc..d369dcbd3f3 100644
--- a/components/plugins/reflector.rs
+++ b/components/plugins/reflector.rs
@@ -2,45 +2,46 @@
* 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::ext::base::ExtCtxt;
+use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::codemap::Span;
-use syntax::ptr::P;
-use syntax::ast::{Item, MetaItem};
+use syntax::ast::MetaItem;
use syntax::ast;
use utils::match_ty_unwrap;
-pub fn expand_reflector(cx: &mut ExtCtxt, span: Span, _: &MetaItem, item: &Item, push: &mut FnMut(P<Item>) -> ()) {
- if let ast::ItemStruct(ref def, _) = item.node {
- let struct_name = item.ident;
- // This path has to be hardcoded, unfortunately, since we can't resolve paths at expansion time
- match def.fields.iter().find(|f| match_ty_unwrap(&*f.node.ty, &["dom", "bindings", "utils", "Reflector"]).is_some()) {
- // If it has a field that is a Reflector, use that
- Some(f) => {
- let field_name = f.node.ident();
- let impl_item = quote_item!(cx,
- impl ::dom::bindings::utils::Reflectable for $struct_name {
- fn reflector<'a>(&'a self) -> &'a ::dom::bindings::utils::Reflector {
- &self.$field_name
+pub fn expand_reflector(cx: &mut ExtCtxt, span: Span, _: &MetaItem, annotatable: Annotatable, push: &mut FnMut(Annotatable)) {
+ if let Annotatable::Item(item) = annotatable {
+ if let ast::ItemStruct(ref def, _) = item.node {
+ let struct_name = item.ident;
+ // This path has to be hardcoded, unfortunately, since we can't resolve paths at expansion time
+ match def.fields.iter().find(|f| match_ty_unwrap(&*f.node.ty, &["dom", "bindings", "utils", "Reflector"]).is_some()) {
+ // If it has a field that is a Reflector, use that
+ Some(f) => {
+ let field_name = f.node.ident();
+ let impl_item = quote_item!(cx,
+ impl ::dom::bindings::utils::Reflectable for $struct_name {
+ fn reflector<'a>(&'a self) -> &'a ::dom::bindings::utils::Reflector {
+ &self.$field_name
+ }
}
- }
- );
- impl_item.map(|it| push(it))
- },
- // Or just call it on the first field (supertype).
- None => {
- let field_name = def.fields[0].node.ident();
- let impl_item = quote_item!(cx,
- impl ::dom::bindings::utils::Reflectable for $struct_name {
- fn reflector<'a>(&'a self) -> &'a ::dom::bindings::utils::Reflector {
- self.$field_name.reflector()
+ );
+ impl_item.map(|it| push(Annotatable::Item(it)))
+ },
+ // Or just call it on the first field (supertype).
+ None => {
+ let field_name = def.fields[0].node.ident();
+ let impl_item = quote_item!(cx,
+ impl ::dom::bindings::utils::Reflectable for $struct_name {
+ fn reflector<'a>(&'a self) -> &'a ::dom::bindings::utils::Reflector {
+ self.$field_name.reflector()
+ }
}
- }
- );
- impl_item.map(|it| push(it))
- }
- };
- } else {
- cx.span_err(span, "#[dom_struct] seems to have been applied to a non-struct");
+ );
+ impl_item.map(|it| push(Annotatable::Item(it)))
+ }
+ };
+ } else {
+ cx.span_err(span, "#[dom_struct] seems to have been applied to a non-struct");
+ }
}
}