diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2015-02-10 08:43:01 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2015-02-10 08:43:01 -0800 |
| commit | bbc8a54c63c843676ce5801cb2e97f0b4e691646 (patch) | |
| tree | 18995c5fd8d376dac8610e9a58cab6cc817e4f21 /src/libsyntax | |
| parent | c33acf658a5b6e14d57016ea5a455277f7e0c966 (diff) | |
| parent | 5354317037368124d180acc3f8754bdb2b0387b8 (diff) | |
| download | rust-bbc8a54c63c843676ce5801cb2e97f0b4e691646.tar.gz rust-bbc8a54c63c843676ce5801cb2e97f0b4e691646.zip | |
rollup merge of #22116: kmcallister/cfg_attr
Fixes #22070. Fixes #19372. r? @sfackler
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/config.rs | 49 | ||||
| -rw-r--r-- | src/libsyntax/ext/base.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/cfg_attr.rs | 34 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 32 | ||||
| -rw-r--r-- | src/libsyntax/lib.rs | 1 |
6 files changed, 68 insertions, 54 deletions
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index eb845e463a0..7ca0591be50 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -12,7 +12,7 @@ use attr::AttrMetaMethods; use diagnostic::SpanHandler; use fold::Folder; use {ast, fold, attr}; -use codemap::Spanned; +use codemap::{Spanned, respan}; use ptr::P; use util::small_vector::SmallVector; @@ -26,6 +26,7 @@ struct Context<F> where F: FnMut(&[ast::Attribute]) -> bool { // Support conditional compilation by transforming the AST, stripping out // any items that do not belong in the current configuration pub fn strip_unconfigured_items(diagnostic: &SpanHandler, krate: ast::Crate) -> ast::Crate { + let krate = process_cfg_attr(diagnostic, krate); let config = krate.config.clone(); strip_items(krate, |attrs| in_cfg(diagnostic, &config, attrs)) } @@ -281,3 +282,49 @@ fn in_cfg(diagnostic: &SpanHandler, cfg: &[P<ast::MetaItem>], attrs: &[ast::Attr attr::cfg_matches(diagnostic, cfg, &*mis[0]) }) } + +struct CfgAttrFolder<'a> { + diag: &'a SpanHandler, + config: ast::CrateConfig, +} + +// Process `#[cfg_attr]`. +fn process_cfg_attr(diagnostic: &SpanHandler, krate: ast::Crate) -> ast::Crate { + let mut fld = CfgAttrFolder { + diag: diagnostic, + config: krate.config.clone(), + }; + fld.fold_crate(krate) +} + +impl<'a> fold::Folder for CfgAttrFolder<'a> { + fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> { + if !attr.check_name("cfg_attr") { + return fold::noop_fold_attribute(attr, self); + } + + let (cfg, mi) = match attr.meta_item_list() { + Some([ref cfg, ref mi]) => (cfg, mi), + _ => { + self.diag.span_err(attr.span, "expected `#[cfg_attr(<cfg pattern>, <attr>)]`"); + return None; + } + }; + + if attr::cfg_matches(self.diag, &self.config[], &cfg) { + Some(respan(mi.span, ast::Attribute_ { + id: attr::mk_attr_id(), + style: attr.node.style, + value: mi.clone(), + is_sugared_doc: false, + })) + } else { + None + } + } + + // Need the ability to run pre-expansion. + fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac { + fold::noop_fold_mac(mac, self) + } +} diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 778b2cabea6..64ae6162ef4 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -528,8 +528,6 @@ fn initial_syntax_expander_table(ecfg: &expand::ExpansionConfig) -> SyntaxEnv { syntax_expanders.insert(intern("cfg"), builtin_normal_expander( ext::cfg::expand_cfg)); - syntax_expanders.insert(intern("cfg_attr"), - Modifier(box ext::cfg_attr::expand)); syntax_expanders.insert(intern("trace_macros"), builtin_normal_expander( ext::trace_macros::expand_trace_macros)); diff --git a/src/libsyntax/ext/cfg_attr.rs b/src/libsyntax/ext/cfg_attr.rs deleted file mode 100644 index 72eaa3e47be..00000000000 --- a/src/libsyntax/ext/cfg_attr.rs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use ast; -use attr; -use codemap::Span; -use ext::base::ExtCtxt; -use ext::build::AstBuilder; -use ptr::P; - -pub fn expand(cx: &mut ExtCtxt, sp: Span, mi: &ast::MetaItem, it: P<ast::Item>) -> P<ast::Item> { - let (cfg, attr) = match mi.node { - ast::MetaList(_, ref mis) if mis.len() == 2 => (&mis[0], &mis[1]), - _ => { - cx.span_err(sp, "expected `#[cfg_attr(<cfg pattern>, <attr>)]`"); - return it; - } - }; - - let mut out = (*it).clone(); - if attr::cfg_matches(&cx.parse_sess.span_diagnostic, &cx.cfg, &**cfg) { - out.attrs.push(cx.attribute(attr.span, attr.clone())); - } - - P(out) -} - diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index fd7593f2a3b..131bbc41005 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -844,7 +844,7 @@ fn expand_arm(arm: ast::Arm, fld: &mut MacroExpander) -> ast::Arm { arm.guard.map(|g| fld.fold_expr(rename_fld.fold_expr(g))); let rewritten_body = fld.fold_expr(rename_fld.fold_expr(arm.body)); ast::Arm { - attrs: arm.attrs.move_map(|x| fld.fold_attribute(x)), + attrs: fold::fold_attrs(arm.attrs, fld), pats: rewritten_pats, guard: rewritten_guard, body: rewritten_body, @@ -1273,7 +1273,7 @@ fn expand_method(m: P<ast::Method>, fld: &mut MacroExpander) -> SmallVector<P<as let (rewritten_fn_decl, rewritten_body) = expand_and_rename_fn_decl_and_block(decl, body, fld); SmallVector::one(P(ast::Method { - attrs: m.attrs.move_map(|a| fld.fold_attribute(a)), + attrs: fold::fold_attrs(m.attrs, fld), id: id, span: fld.new_span(m.span), node: ast::MethDecl(fld.fold_ident(ident), diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 8f1d15f6da8..1fb0642d24f 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -223,7 +223,7 @@ pub trait Folder : Sized { noop_fold_lifetime_def(l, self) } - fn fold_attribute(&mut self, at: Attribute) -> Attribute { + fn fold_attribute(&mut self, at: Attribute) -> Option<Attribute> { noop_fold_attribute(at, self) } @@ -373,9 +373,13 @@ pub fn noop_fold_view_path<T: Folder>(view_path: P<ViewPath>, fld: &mut T) -> P< }) } +pub fn fold_attrs<T: Folder>(attrs: Vec<Attribute>, fld: &mut T) -> Vec<Attribute> { + attrs.into_iter().flat_map(|x| fld.fold_attribute(x).into_iter()).collect() +} + pub fn noop_fold_arm<T: Folder>(Arm {attrs, pats, guard, body}: Arm, fld: &mut T) -> Arm { Arm { - attrs: attrs.move_map(|x| fld.fold_attribute(x)), + attrs: fold_attrs(attrs, fld), pats: pats.move_map(|x| fld.fold_pat(x)), guard: guard.map(|x| fld.fold_expr(x)), body: fld.fold_expr(body), @@ -475,7 +479,7 @@ pub fn noop_fold_variant<T: Folder>(v: P<Variant>, fld: &mut T) -> P<Variant> { node: Variant_ { id: fld.new_id(id), name: name, - attrs: attrs.move_map(|x| fld.fold_attribute(x)), + attrs: fold_attrs(attrs, fld), kind: match kind { TupleVariantKind(variant_args) => { TupleVariantKind(variant_args.move_map(|x| @@ -553,9 +557,9 @@ pub fn noop_fold_local<T: Folder>(l: P<Local>, fld: &mut T) -> P<Local> { }) } -pub fn noop_fold_attribute<T: Folder>(at: Attribute, fld: &mut T) -> Attribute { +pub fn noop_fold_attribute<T: Folder>(at: Attribute, fld: &mut T) -> Option<Attribute> { let Spanned {node: Attribute_ {id, style, value, is_sugared_doc}, span} = at; - Spanned { + Some(Spanned { node: Attribute_ { id: id, style: style, @@ -563,7 +567,7 @@ pub fn noop_fold_attribute<T: Folder>(at: Attribute, fld: &mut T) -> Attribute { is_sugared_doc: is_sugared_doc }, span: fld.new_span(span) - } + }) } pub fn noop_fold_explicit_self_underscore<T: Folder>(es: ExplicitSelf_, fld: &mut T) @@ -845,8 +849,8 @@ pub fn noop_fold_typedef<T>(t: Typedef, folder: &mut T) where T: Folder { let new_id = folder.new_id(t.id); let new_span = folder.new_span(t.span); - let new_attrs = t.attrs.iter().map(|attr| { - folder.fold_attribute((*attr).clone()) + let new_attrs = t.attrs.iter().flat_map(|attr| { + folder.fold_attribute((*attr).clone()).into_iter() }).collect(); let new_ident = folder.fold_ident(t.ident); let new_type = folder.fold_ty(t.typ); @@ -866,7 +870,7 @@ pub fn noop_fold_associated_type<T>(at: AssociatedType, folder: &mut T) { let new_attrs = at.attrs .iter() - .map(|attr| folder.fold_attribute((*attr).clone())) + .flat_map(|attr| folder.fold_attribute((*attr).clone()).into_iter()) .collect(); let new_param = folder.fold_ty_param(at.ty_param); ast::AssociatedType { @@ -909,7 +913,7 @@ pub fn noop_fold_struct_field<T: Folder>(f: StructField, fld: &mut T) -> StructF id: fld.new_id(id), kind: kind, ty: fld.fold_ty(ty), - attrs: attrs.move_map(|a| fld.fold_attribute(a)) + attrs: fold_attrs(attrs, fld), }, span: fld.new_span(span) } @@ -1072,7 +1076,7 @@ pub fn noop_fold_type_method<T: Folder>(m: TypeMethod, fld: &mut T) -> TypeMetho TypeMethod { id: fld.new_id(id), ident: fld.fold_ident(ident), - attrs: attrs.move_map(|a| fld.fold_attribute(a)), + attrs: fold_attrs(attrs, fld), unsafety: unsafety, abi: abi, decl: fld.fold_fn_decl(decl), @@ -1154,7 +1158,7 @@ pub fn noop_fold_item_simple<T: Folder>(Item {id, ident, attrs, node, vis, span} Item { id: id, ident: folder.fold_ident(ident), - attrs: attrs.move_map(|e| folder.fold_attribute(e)), + attrs: fold_attrs(attrs, folder), node: node, vis: vis, span: folder.new_span(span) @@ -1165,7 +1169,7 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: P<ForeignItem>, folder: &mut T) -> ni.map(|ForeignItem {id, ident, attrs, node, span, vis}| ForeignItem { id: folder.new_id(id), ident: folder.fold_ident(ident), - attrs: attrs.move_map(|x| folder.fold_attribute(x)), + attrs: fold_attrs(attrs, folder), node: match node { ForeignItemFn(fdec, generics) => { ForeignItemFn(folder.fold_fn_decl(fdec), folder.fold_generics(generics)) @@ -1184,7 +1188,7 @@ pub fn noop_fold_foreign_item<T: Folder>(ni: P<ForeignItem>, folder: &mut T) -> pub fn noop_fold_method<T: Folder>(m: P<Method>, folder: &mut T) -> SmallVector<P<Method>> { SmallVector::one(m.map(|Method {id, attrs, node, span}| Method { id: folder.new_id(id), - attrs: attrs.move_map(|a| folder.fold_attribute(a)), + attrs: fold_attrs(attrs, folder), node: match node { MethDecl(ident, generics, diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 08e795ef80d..41850ada3e6 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -96,7 +96,6 @@ pub mod ext { pub mod base; pub mod build; pub mod cfg; - pub mod cfg_attr; pub mod concat; pub mod concat_idents; pub mod deriving; |
