@@ -12,7 +12,7 @@ use attr::AttrMetaMethods;
1212use diagnostic:: SpanHandler ;
1313use fold:: Folder ;
1414use { ast, fold, attr} ;
15- use codemap:: Spanned ;
15+ use codemap:: { Spanned , respan } ;
1616use ptr:: P ;
1717
1818use util:: small_vector:: SmallVector ;
@@ -26,6 +26,7 @@ struct Context<F> where F: FnMut(&[ast::Attribute]) -> bool {
2626// Support conditional compilation by transforming the AST, stripping out
2727// any items that do not belong in the current configuration
2828pub fn strip_unconfigured_items ( diagnostic : & SpanHandler , krate : ast:: Crate ) -> ast:: Crate {
29+ let krate = process_cfg_attr ( diagnostic, krate) ;
2930 let config = krate. config . clone ( ) ;
3031 strip_items ( krate, |attrs| in_cfg ( diagnostic, & config, attrs) )
3132}
@@ -281,3 +282,49 @@ fn in_cfg(diagnostic: &SpanHandler, cfg: &[P<ast::MetaItem>], attrs: &[ast::Attr
281282 attr:: cfg_matches ( diagnostic, cfg, & * mis[ 0 ] )
282283 } )
283284}
285+
286+ struct CfgAttrFolder < ' a > {
287+ diag : & ' a SpanHandler ,
288+ config : ast:: CrateConfig ,
289+ }
290+
291+ // Process `#[cfg_attr]`.
292+ fn process_cfg_attr ( diagnostic : & SpanHandler , krate : ast:: Crate ) -> ast:: Crate {
293+ let mut fld = CfgAttrFolder {
294+ diag : diagnostic,
295+ config : krate. config . clone ( ) ,
296+ } ;
297+ fld. fold_crate ( krate)
298+ }
299+
300+ impl < ' a > fold:: Folder for CfgAttrFolder < ' a > {
301+ fn fold_attribute ( & mut self , attr : ast:: Attribute ) -> Option < ast:: Attribute > {
302+ if !attr. check_name ( "cfg_attr" ) {
303+ return fold:: noop_fold_attribute ( attr, self ) ;
304+ }
305+
306+ let ( cfg, mi) = match attr. meta_item_list ( ) {
307+ Some ( [ ref cfg, ref mi] ) => ( cfg, mi) ,
308+ _ => {
309+ self . diag . span_err ( attr. span , "expected `#[cfg_attr(<cfg pattern>, <attr>)]`" ) ;
310+ return None ;
311+ }
312+ } ;
313+
314+ if attr:: cfg_matches ( self . diag , & self . config [ ] , & cfg) {
315+ Some ( respan ( mi. span , ast:: Attribute_ {
316+ id : attr:: mk_attr_id ( ) ,
317+ style : attr. node . style ,
318+ value : mi. clone ( ) ,
319+ is_sugared_doc : false ,
320+ } ) )
321+ } else {
322+ None
323+ }
324+ }
325+
326+ // Need the ability to run pre-expansion.
327+ fn fold_mac ( & mut self , mac : ast:: Mac ) -> ast:: Mac {
328+ fold:: noop_fold_mac ( mac, self )
329+ }
330+ }
0 commit comments