@@ -53,7 +53,7 @@ use std::sync::Arc;
53
53
use externalfiles:: ExternalHtml ;
54
54
55
55
use serialize:: json:: { ToJson , Json , as_json} ;
56
- use syntax:: abi;
56
+ use syntax:: { abi, ast } ;
57
57
use syntax:: feature_gate:: UnstableFeatures ;
58
58
use rustc:: hir:: def_id:: { CrateNum , CRATE_DEF_INDEX , DefId , LOCAL_CRATE } ;
59
59
use rustc:: middle:: privacy:: AccessLevels ;
@@ -62,7 +62,7 @@ use rustc::hir;
62
62
use rustc:: util:: nodemap:: { FxHashMap , FxHashSet } ;
63
63
use rustc_data_structures:: flock;
64
64
65
- use clean:: { self , Attributes , GetDefId , SelfTy , Mutability } ;
65
+ use clean:: { self , AttributesExt , GetDefId , SelfTy , Mutability } ;
66
66
use doctree;
67
67
use fold:: DocFolder ;
68
68
use html:: escape:: Escape ;
@@ -453,30 +453,26 @@ pub fn run(mut krate: clean::Crate,
453
453
454
454
// Crawl the crate attributes looking for attributes which control how we're
455
455
// going to emit HTML
456
- if let Some ( attrs) = krate. module . as_ref ( ) . map ( |m| m. attrs . list ( "doc" ) ) {
457
- for attr in attrs {
458
- match * attr {
459
- clean :: NameValue ( ref x , ref s )
460
- if "html_favicon_url" == * x => {
456
+ if let Some ( attrs) = krate. module . as_ref ( ) . map ( |m| & m. attrs ) {
457
+ for attr in attrs. lists ( "doc" ) {
458
+ let name = attr. name ( ) . map ( |s| s . as_str ( ) ) ;
459
+ match ( name . as_ref ( ) . map ( |s| & s [ .. ] ) , attr . value_str ( ) ) {
460
+ ( Some ( "html_favicon_url" ) , Some ( s ) ) => {
461
461
scx. layout . favicon = s. to_string ( ) ;
462
462
}
463
- clean:: NameValue ( ref x, ref s)
464
- if "html_logo_url" == * x => {
463
+ ( Some ( "html_logo_url" ) , Some ( s) ) => {
465
464
scx. layout . logo = s. to_string ( ) ;
466
465
}
467
- clean:: NameValue ( ref x, ref s)
468
- if "html_playground_url" == * x => {
466
+ ( Some ( "html_playground_url" ) , Some ( s) ) => {
469
467
markdown:: PLAYGROUND . with ( |slot| {
470
468
let name = krate. name . clone ( ) ;
471
- * slot. borrow_mut ( ) = Some ( ( Some ( name) , s. clone ( ) ) ) ;
469
+ * slot. borrow_mut ( ) = Some ( ( Some ( name) , s. to_string ( ) ) ) ;
472
470
} ) ;
473
471
}
474
- clean:: NameValue ( ref x, ref s)
475
- if "issue_tracker_base_url" == * x => {
472
+ ( Some ( "issue_tracker_base_url" ) , Some ( s) ) => {
476
473
scx. issue_tracker_base_url = Some ( s. to_string ( ) ) ;
477
474
}
478
- clean:: Word ( ref x)
479
- if "html_no_source" == * x => {
475
+ ( Some ( "html_no_source" ) , None ) if attr. is_word ( ) => {
480
476
scx. include_sources = false ;
481
477
}
482
478
_ => { }
@@ -860,13 +856,16 @@ fn extern_location(e: &clean::ExternalCrate, dst: &Path) -> ExternalLocation {
860
856
861
857
// Failing that, see if there's an attribute specifying where to find this
862
858
// external crate
863
- e. attrs . list ( "doc" ) . value ( "html_root_url" ) . map ( |url| {
864
- let mut url = url. to_owned ( ) ;
859
+ e. attrs . lists ( "doc" )
860
+ . filter ( |a| a. check_name ( "html_root_url" ) )
861
+ . filter_map ( |a| a. value_str ( ) )
862
+ . map ( |url| {
863
+ let mut url = url. to_string ( ) ;
865
864
if !url. ends_with ( "/" ) {
866
865
url. push ( '/' )
867
866
}
868
867
Remote ( url)
869
- } ) . unwrap_or ( Unknown ) // Well, at least we tried.
868
+ } ) . next ( ) . unwrap_or ( Unknown ) // Well, at least we tried.
870
869
}
871
870
872
871
impl < ' a > DocFolder for SourceCollector < ' a > {
@@ -2511,49 +2510,47 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
2511
2510
Ok ( ( ) )
2512
2511
}
2513
2512
2514
- fn attribute_without_value ( s : & str ) -> bool {
2515
- [ "must_use" , "no_mangle" , "unsafe_destructor_blind_to_params" ] . iter ( ) . any ( |x| x == & s)
2516
- }
2517
-
2518
- fn attribute_with_value ( s : & str ) -> bool {
2519
- [ "export_name" , "lang" , "link_section" , "must_use" ] . iter ( ) . any ( |x| x == & s)
2520
- }
2521
-
2522
- fn attribute_with_values ( s : & str ) -> bool {
2523
- [ "repr" ] . iter ( ) . any ( |x| x == & s)
2524
- }
2513
+ fn render_attribute ( attr : & ast:: MetaItem ) -> Option < String > {
2514
+ let name = attr. name ( ) ;
2525
2515
2526
- fn render_attribute ( attr : & clean:: Attribute , recurse : bool ) -> Option < String > {
2527
- match * attr {
2528
- clean:: Word ( ref s) if attribute_without_value ( & * s) || recurse => {
2529
- Some ( format ! ( "{}" , s) )
2530
- }
2531
- clean:: NameValue ( ref k, ref v) if attribute_with_value ( & * k) => {
2532
- Some ( format ! ( "{} = \" {}\" " , k, v) )
2533
- }
2534
- clean:: List ( ref k, ref values) if attribute_with_values ( & * k) => {
2535
- let display: Vec < _ > = values. iter ( )
2536
- . filter_map ( |value| render_attribute ( value, true ) )
2537
- . map ( |entry| format ! ( "{}" , entry) )
2538
- . collect ( ) ;
2516
+ if attr. is_word ( ) {
2517
+ Some ( format ! ( "{}" , name) )
2518
+ } else if let Some ( v) = attr. value_str ( ) {
2519
+ Some ( format ! ( "{} = {:?}" , name, & v. as_str( ) [ ..] ) )
2520
+ } else if let Some ( values) = attr. meta_item_list ( ) {
2521
+ let display: Vec < _ > = values. iter ( ) . filter_map ( |attr| {
2522
+ attr. meta_item ( ) . and_then ( |mi| render_attribute ( mi) )
2523
+ } ) . collect ( ) ;
2539
2524
2540
- if display. len ( ) > 0 {
2541
- Some ( format ! ( "{}({})" , k, display. join( ", " ) ) )
2542
- } else {
2543
- None
2544
- }
2545
- }
2546
- _ => {
2525
+ if display. len ( ) > 0 {
2526
+ Some ( format ! ( "{}({})" , name, display. join( ", " ) ) )
2527
+ } else {
2547
2528
None
2548
2529
}
2530
+ } else {
2531
+ None
2549
2532
}
2550
2533
}
2551
2534
2535
+ const ATTRIBUTE_WHITELIST : & ' static [ & ' static str ] = & [
2536
+ "export_name" ,
2537
+ "lang" ,
2538
+ "link_section" ,
2539
+ "must_use" ,
2540
+ "no_mangle" ,
2541
+ "repr" ,
2542
+ "unsafe_destructor_blind_to_params"
2543
+ ] ;
2544
+
2552
2545
fn render_attributes ( w : & mut fmt:: Formatter , it : & clean:: Item ) -> fmt:: Result {
2553
2546
let mut attrs = String :: new ( ) ;
2554
2547
2555
- for attr in & it. attrs {
2556
- if let Some ( s) = render_attribute ( attr, false ) {
2548
+ for attr in & it. attrs . other_attrs {
2549
+ let name = attr. name ( ) ;
2550
+ if !ATTRIBUTE_WHITELIST . contains ( & & name. as_str ( ) [ ..] ) {
2551
+ continue ;
2552
+ }
2553
+ if let Some ( s) = render_attribute ( attr. meta ( ) ) {
2557
2554
attrs. push_str ( & format ! ( "#[{}]\n " , s) ) ;
2558
2555
}
2559
2556
}
@@ -2810,7 +2807,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
2810
2807
}
2811
2808
write ! ( w, "</span>" ) ?;
2812
2809
write ! ( w, "</h3>\n " ) ?;
2813
- if let Some ( ref dox) = i. impl_item . attrs . value ( "doc" ) {
2810
+ if let Some ( ref dox) = i. impl_item . doc_value ( ) {
2814
2811
write ! ( w, "<div class='docblock'>{}</div>" , Markdown ( dox) ) ?;
2815
2812
}
2816
2813
}
0 commit comments