@@ -3,10 +3,12 @@ use crate::clean::blanket_impl::BlanketImplFinder;
3
3
use crate :: clean:: {
4
4
inline, Clean , Crate , Generic , GenericArg , GenericArgs , ImportSource , Item , ItemKind , Lifetime ,
5
5
Path , PathSegment , PolyTrait , Primitive , PrimitiveType , ResolvedPath , Type , TypeBinding ,
6
+ Visibility ,
6
7
} ;
7
8
use crate :: core:: DocContext ;
8
9
use crate :: formats:: item_type:: ItemType ;
9
10
11
+ use rustc_ast as ast;
10
12
use rustc_ast:: tokenstream:: TokenTree ;
11
13
use rustc_hir as hir;
12
14
use rustc_hir:: def:: { DefKind , Res } ;
@@ -577,3 +579,37 @@ pub(super) fn render_macro_arms<'a>(
577
579
pub ( super ) fn render_macro_matcher ( matcher : & TokenTree ) -> String {
578
580
rustc_ast_pretty:: pprust:: tt_to_string ( matcher)
579
581
}
582
+
583
+ pub ( super ) fn display_macro_source (
584
+ cx : & mut DocContext < ' _ > ,
585
+ name : Symbol ,
586
+ def : & ast:: MacroDef ,
587
+ def_id : DefId ,
588
+ vis : impl Clean < Visibility > ,
589
+ ) -> String {
590
+ let tts: Vec < _ > = def. body . inner_tokens ( ) . into_trees ( ) . collect ( ) ;
591
+ // Extract the spans of all matchers. They represent the "interface" of the macro.
592
+ let matchers = tts. chunks ( 4 ) . map ( |arm| & arm[ 0 ] ) ;
593
+
594
+ if def. macro_rules {
595
+ format ! ( "macro_rules! {} {{\n {}}}" , name, render_macro_arms( matchers, ";" ) )
596
+ } else {
597
+ let vis = vis. clean ( cx) ;
598
+
599
+ if matchers. len ( ) <= 1 {
600
+ format ! (
601
+ "{}macro {}{} {{\n ...\n }}" ,
602
+ vis. to_src_with_space( cx. tcx, def_id) ,
603
+ name,
604
+ matchers. map( render_macro_matcher) . collect:: <String >( ) ,
605
+ )
606
+ } else {
607
+ format ! (
608
+ "{}macro {} {{\n {}}}" ,
609
+ vis. to_src_with_space( cx. tcx, def_id) ,
610
+ name,
611
+ render_macro_arms( matchers, "," ) ,
612
+ )
613
+ }
614
+ }
615
+ }
0 commit comments