11//! Renderer for macro invocations.
22
3- use hir:: { Documentation , HasSource } ;
3+ use hir:: { db :: HirDatabase , Documentation , HasAttrs , HasSource } ;
44use syntax:: display:: macro_label;
55use test_utils:: mark;
66
@@ -27,12 +27,48 @@ struct MacroRender<'a> {
2727 ket : & ' static str ,
2828}
2929
30+ pub fn guess_macro_braces (
31+ db : & dyn HirDatabase ,
32+ macro_ : hir:: MacroDef ,
33+ ) -> ( & ' static str , & ' static str ) {
34+ let macro_name = match macro_. name ( db) {
35+ Some ( name) => name. to_string ( ) ,
36+ None => return ( "(" , ")" ) ,
37+ } ;
38+ let macro_docs = macro_. docs ( db) ;
39+ let macro_docs = macro_docs. as_ref ( ) . map ( Documentation :: as_str) . unwrap_or ( "" ) ;
40+
41+ let mut votes = [ 0 , 0 , 0 ] ;
42+ for ( idx, s) in macro_docs. match_indices ( & macro_name) {
43+ let ( before, after) = ( & macro_docs[ ..idx] , & macro_docs[ idx + s. len ( ) ..] ) ;
44+ // Ensure to match the full word
45+ if after. starts_with ( '!' )
46+ && !before. ends_with ( |c : char | c == '_' || c. is_ascii_alphanumeric ( ) )
47+ {
48+ // It may have spaces before the braces like `foo! {}`
49+ match after[ 1 ..] . chars ( ) . find ( |& c| !c. is_whitespace ( ) ) {
50+ Some ( '{' ) => votes[ 0 ] += 1 ,
51+ Some ( '[' ) => votes[ 1 ] += 1 ,
52+ Some ( '(' ) => votes[ 2 ] += 1 ,
53+ _ => { }
54+ }
55+ }
56+ }
57+
58+ // Insert a space before `{}`.
59+ // We prefer the last one when some votes equal.
60+ let ( _vote, ( bra, ket) ) = votes
61+ . iter ( )
62+ . zip ( & [ ( " {" , "}" ) , ( "[" , "]" ) , ( "(" , ")" ) ] )
63+ . max_by_key ( |& ( & vote, _) | vote)
64+ . unwrap ( ) ;
65+ ( * bra, * ket)
66+ }
67+
3068impl < ' a > MacroRender < ' a > {
3169 fn new ( ctx : RenderContext < ' a > , name : String , macro_ : hir:: MacroDef ) -> MacroRender < ' a > {
3270 let docs = ctx. docs ( macro_) ;
33- let docs_str = docs. as_ref ( ) . map_or ( "" , |s| s. as_str ( ) ) ;
34- let ( bra, ket) = guess_macro_braces ( & name, docs_str) ;
35-
71+ let ( bra, ket) = guess_macro_braces ( ctx. db ( ) , macro_) ;
3672 MacroRender { ctx, name, macro_, docs, bra, ket }
3773 }
3874
@@ -97,34 +133,6 @@ impl<'a> MacroRender<'a> {
97133 }
98134}
99135
100- fn guess_macro_braces ( macro_name : & str , docs : & str ) -> ( & ' static str , & ' static str ) {
101- let mut votes = [ 0 , 0 , 0 ] ;
102- for ( idx, s) in docs. match_indices ( & macro_name) {
103- let ( before, after) = ( & docs[ ..idx] , & docs[ idx + s. len ( ) ..] ) ;
104- // Ensure to match the full word
105- if after. starts_with ( '!' )
106- && !before. ends_with ( |c : char | c == '_' || c. is_ascii_alphanumeric ( ) )
107- {
108- // It may have spaces before the braces like `foo! {}`
109- match after[ 1 ..] . chars ( ) . find ( |& c| !c. is_whitespace ( ) ) {
110- Some ( '{' ) => votes[ 0 ] += 1 ,
111- Some ( '[' ) => votes[ 1 ] += 1 ,
112- Some ( '(' ) => votes[ 2 ] += 1 ,
113- _ => { }
114- }
115- }
116- }
117-
118- // Insert a space before `{}`.
119- // We prefer the last one when some votes equal.
120- let ( _vote, ( bra, ket) ) = votes
121- . iter ( )
122- . zip ( & [ ( " {" , "}" ) , ( "[" , "]" ) , ( "(" , ")" ) ] )
123- . max_by_key ( |& ( & vote, _) | vote)
124- . unwrap ( ) ;
125- ( * bra, * ket)
126- }
127-
128136#[ cfg( test) ]
129137mod tests {
130138 use test_utils:: mark;
0 commit comments