@@ -53,7 +53,7 @@ use std::sync::Arc;
5353use externalfiles:: ExternalHtml ;
5454
5555use serialize:: json:: { ToJson , Json , as_json} ;
56- use syntax:: abi;
56+ use syntax:: { abi, ast } ;
5757use syntax:: feature_gate:: UnstableFeatures ;
5858use rustc:: hir:: def_id:: { CrateNum , CRATE_DEF_INDEX , DefId , LOCAL_CRATE } ;
5959use rustc:: middle:: privacy:: AccessLevels ;
@@ -62,7 +62,7 @@ use rustc::hir;
6262use rustc:: util:: nodemap:: { FxHashMap , FxHashSet } ;
6363use rustc_data_structures:: flock;
6464
65- use clean:: { self , Attributes , GetDefId , SelfTy , Mutability } ;
65+ use clean:: { self , AttributesExt , GetDefId , SelfTy , Mutability } ;
6666use doctree;
6767use fold:: DocFolder ;
6868use html:: escape:: Escape ;
@@ -453,30 +453,26 @@ pub fn run(mut krate: clean::Crate,
453453
454454 // Crawl the crate attributes looking for attributes which control how we're
455455 // 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 ) ) => {
461461 scx. layout . favicon = s. to_string ( ) ;
462462 }
463- clean:: NameValue ( ref x, ref s)
464- if "html_logo_url" == * x => {
463+ ( Some ( "html_logo_url" ) , Some ( s) ) => {
465464 scx. layout . logo = s. to_string ( ) ;
466465 }
467- clean:: NameValue ( ref x, ref s)
468- if "html_playground_url" == * x => {
466+ ( Some ( "html_playground_url" ) , Some ( s) ) => {
469467 markdown:: PLAYGROUND . with ( |slot| {
470468 let name = krate. name . clone ( ) ;
471- * slot. borrow_mut ( ) = Some ( ( Some ( name) , s. clone ( ) ) ) ;
469+ * slot. borrow_mut ( ) = Some ( ( Some ( name) , s. to_string ( ) ) ) ;
472470 } ) ;
473471 }
474- clean:: NameValue ( ref x, ref s)
475- if "issue_tracker_base_url" == * x => {
472+ ( Some ( "issue_tracker_base_url" ) , Some ( s) ) => {
476473 scx. issue_tracker_base_url = Some ( s. to_string ( ) ) ;
477474 }
478- clean:: Word ( ref x)
479- if "html_no_source" == * x => {
475+ ( Some ( "html_no_source" ) , None ) if attr. is_word ( ) => {
480476 scx. include_sources = false ;
481477 }
482478 _ => { }
@@ -860,13 +856,16 @@ fn extern_location(e: &clean::ExternalCrate, dst: &Path) -> ExternalLocation {
860856
861857 // Failing that, see if there's an attribute specifying where to find this
862858 // 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 ( ) ;
865864 if !url. ends_with ( "/" ) {
866865 url. push ( '/' )
867866 }
868867 Remote ( url)
869- } ) . unwrap_or ( Unknown ) // Well, at least we tried.
868+ } ) . next ( ) . unwrap_or ( Unknown ) // Well, at least we tried.
870869}
871870
872871impl < ' a > DocFolder for SourceCollector < ' a > {
@@ -2511,49 +2510,47 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
25112510 Ok ( ( ) )
25122511}
25132512
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 ( ) ;
25252515
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 ( ) ;
25392524
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 {
25472528 None
25482529 }
2530+ } else {
2531+ None
25492532 }
25502533}
25512534
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+
25522545fn render_attributes ( w : & mut fmt:: Formatter , it : & clean:: Item ) -> fmt:: Result {
25532546 let mut attrs = String :: new ( ) ;
25542547
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 ( ) ) {
25572554 attrs. push_str ( & format ! ( "#[{}]\n " , s) ) ;
25582555 }
25592556 }
@@ -2810,7 +2807,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
28102807 }
28112808 write ! ( w, "</span>" ) ?;
28122809 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 ( ) {
28142811 write ! ( w, "<div class='docblock'>{}</div>" , Markdown ( dox) ) ?;
28152812 }
28162813 }
0 commit comments