Auto merge of #6156 - Manishearth:warn_fix, r=larsbergstrom

r? @larsbergstrom


(The diff is borked here, but I only just added `if let`s and wrapped/unwrapped in `Annotatable`s)

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/6156)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2015-05-21 13:27:27 -05:00
commit ef7fa99bd2
3 changed files with 53 additions and 47 deletions

View file

@ -5,23 +5,28 @@
use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::codemap::Span; use syntax::codemap::Span;
use syntax::ptr::P; use syntax::ptr::P;
use syntax::ast::{Item, MetaItem, Expr}; use syntax::ast::{MetaItem, Expr};
use syntax::ast; use syntax::ast;
use syntax::ext::build::AstBuilder; use syntax::ext::build::AstBuilder;
use syntax::ext::deriving::generic::{combine_substructure, EnumMatching, FieldInfo, MethodDef, Struct, Substructure, TraitDef, ty}; 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> { pub fn expand_dom_struct(cx: &mut ExtCtxt, sp: Span, _: &MetaItem, anno: Annotatable) -> Annotatable {
let mut item2 = (*item).clone(); if let Annotatable::Item(item) = anno {
item2.attrs.push(quote_attr!(cx, #[must_root])); let mut item2 = (*item).clone();
item2.attrs.push(quote_attr!(cx, #[privatize])); item2.attrs.push(quote_attr!(cx, #[must_root]));
item2.attrs.push(quote_attr!(cx, #[jstraceable])); item2.attrs.push(quote_attr!(cx, #[privatize]));
item2.attrs.push(quote_attr!(cx, #[jstraceable]));
// The following attributes are only for internal usage // The following attributes are only for internal usage
item2.attrs.push(quote_attr!(cx, #[_generate_reflector])); item2.attrs.push(quote_attr!(cx, #[_generate_reflector]));
// #[dom_struct] gets consumed, so this lets us keep around a residue // #[dom_struct] gets consumed, so this lets us keep around a residue
// Do NOT register a modifier/decorator on this attribute // Do NOT register a modifier/decorator on this attribute
item2.attrs.push(quote_attr!(cx, #[_dom_struct_marker])); item2.attrs.push(quote_attr!(cx, #[_dom_struct_marker]));
P(item2) 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` /// Provides the hook to expand `#[jstraceable]` into an implementation of `JSTraceable`

View file

@ -39,9 +39,9 @@ pub mod casing;
#[plugin_registrar] #[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) { 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("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_lower", casing::expand_lower);
reg.register_macro("to_upper", casing::expand_upper); reg.register_macro("to_upper", casing::expand_upper);
reg.register_lint_pass(box lints::transmute_type::TransmutePass as LintPassObject); reg.register_lint_pass(box lints::transmute_type::TransmutePass as LintPassObject);

View file

@ -2,45 +2,46 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * 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::codemap::Span;
use syntax::ptr::P; use syntax::ast::MetaItem;
use syntax::ast::{Item, MetaItem};
use syntax::ast; use syntax::ast;
use utils::match_ty_unwrap; use utils::match_ty_unwrap;
pub fn expand_reflector(cx: &mut ExtCtxt, span: Span, _: &MetaItem, item: &Item, push: &mut FnMut(P<Item>) -> ()) { pub fn expand_reflector(cx: &mut ExtCtxt, span: Span, _: &MetaItem, annotatable: Annotatable, push: &mut FnMut(Annotatable)) {
if let ast::ItemStruct(ref def, _) = item.node { if let Annotatable::Item(item) = annotatable {
let struct_name = item.ident; if let ast::ItemStruct(ref def, _) = item.node {
// This path has to be hardcoded, unfortunately, since we can't resolve paths at expansion time let struct_name = item.ident;
match def.fields.iter().find(|f| match_ty_unwrap(&*f.node.ty, &["dom", "bindings", "utils", "Reflector"]).is_some()) { // This path has to be hardcoded, unfortunately, since we can't resolve paths at expansion time
// If it has a field that is a Reflector, use that match def.fields.iter().find(|f| match_ty_unwrap(&*f.node.ty, &["dom", "bindings", "utils", "Reflector"]).is_some()) {
Some(f) => { // If it has a field that is a Reflector, use that
let field_name = f.node.ident(); Some(f) => {
let impl_item = quote_item!(cx, let field_name = f.node.ident();
impl ::dom::bindings::utils::Reflectable for $struct_name { let impl_item = quote_item!(cx,
fn reflector<'a>(&'a self) -> &'a ::dom::bindings::utils::Reflector { impl ::dom::bindings::utils::Reflectable for $struct_name {
&self.$field_name fn reflector<'a>(&'a self) -> &'a ::dom::bindings::utils::Reflector {
&self.$field_name
}
} }
} );
); impl_item.map(|it| push(Annotatable::Item(it)))
impl_item.map(|it| push(it)) },
}, // Or just call it on the first field (supertype).
// Or just call it on the first field (supertype). None => {
None => { let field_name = def.fields[0].node.ident();
let field_name = def.fields[0].node.ident(); let impl_item = quote_item!(cx,
let impl_item = quote_item!(cx, impl ::dom::bindings::utils::Reflectable for $struct_name {
impl ::dom::bindings::utils::Reflectable for $struct_name { fn reflector<'a>(&'a self) -> &'a ::dom::bindings::utils::Reflector {
fn reflector<'a>(&'a self) -> &'a ::dom::bindings::utils::Reflector { self.$field_name.reflector()
self.$field_name.reflector() }
} }
} );
); impl_item.map(|it| push(Annotatable::Item(it)))
impl_item.map(|it| push(it)) }
} };
}; } else {
} else { cx.span_err(span, "#[dom_struct] seems to have been applied to a non-struct");
cx.span_err(span, "#[dom_struct] seems to have been applied to a non-struct"); }
} }
} }