@@ -28,7 +28,7 @@ use crate::{
28
28
db:: DefDatabase , nameres:: ModuleSource , resolver:: HasResolver , test_db:: TestDB , AsMacroCall ,
29
29
} ;
30
30
31
- fn check ( ra_fixture : & str , expect : Expect ) {
31
+ fn check ( ra_fixture : & str , mut expect : Expect ) {
32
32
let db = TestDB :: with_files ( ra_fixture) ;
33
33
let krate = db. crate_graph ( ) . iter ( ) . next ( ) . unwrap ( ) ;
34
34
let def_map = db. crate_def_map ( krate) ;
@@ -65,16 +65,29 @@ fn check(ra_fixture: &str, expect: Expect) {
65
65
format_to ! ( expn_text, "/* error: {} */" , err) ;
66
66
}
67
67
if let Some ( ( parse, _token_map) ) = exp. value {
68
+ assert ! (
69
+ parse. errors( ) . is_empty( ) ,
70
+ "parse errors in expansion: \n {:#?}" ,
71
+ parse. errors( )
72
+ ) ;
68
73
let pp = pretty_print_macro_expansion ( parse. syntax_node ( ) ) ;
69
74
let indent = IndentLevel :: from_node ( call. syntax ( ) ) ;
70
75
let pp = reindent ( indent, pp) ;
71
76
format_to ! ( expn_text, "{}" , pp) ;
77
+ if call. to_string ( ) . contains ( "// +tree" ) {
78
+ let tree = format ! ( "{:#?}" , parse. syntax_node( ) )
79
+ . split_inclusive ( "\n " )
80
+ . map ( |line| format ! ( "// {}" , line) )
81
+ . collect :: < String > ( ) ;
82
+ format_to ! ( expn_text, "\n {}" , tree)
83
+ }
72
84
}
73
85
let range = call. syntax ( ) . text_range ( ) ;
74
86
let range: Range < usize > = range. into ( ) ;
75
87
expanded_text. replace_range ( range, & expn_text)
76
88
}
77
89
90
+ expect. indent ( false ) ;
78
91
expect. assert_eq ( & expanded_text) ;
79
92
}
80
93
@@ -97,20 +110,37 @@ fn reindent(indent: IndentLevel, pp: String) -> String {
97
110
fn pretty_print_macro_expansion ( expn : SyntaxNode ) -> String {
98
111
let mut res = String :: new ( ) ;
99
112
let mut prev_kind = SyntaxKind :: EOF ;
113
+ let mut indent_level = 0 ;
100
114
for token in iter:: successors ( expn. first_token ( ) , |t| t. next_token ( ) ) {
101
115
let curr_kind = token. kind ( ) ;
102
116
let space = match ( prev_kind, curr_kind) {
103
117
_ if prev_kind. is_trivia ( ) || curr_kind. is_trivia ( ) => "" ,
118
+ ( T ! [ '{' ] , T ! [ '}' ] ) => "" ,
104
119
( T ! [ =] , _) | ( _, T ! [ =] ) => " " ,
105
120
( _, T ! [ '{' ] ) => " " ,
106
- ( T ! [ ; ] | T ! [ '}' ] , _) => "\n " ,
121
+ ( T ! [ ; ] | T ! [ '{' ] | T ! [ '}' ] , _) => "\n " ,
122
+ ( _, T ! [ '}' ] ) => "\n " ,
107
123
( IDENT | LIFETIME_IDENT , IDENT | LIFETIME_IDENT ) => " " ,
108
124
( IDENT , _) if curr_kind. is_keyword ( ) => " " ,
109
125
( _, IDENT ) if prev_kind. is_keyword ( ) => " " ,
126
+ ( T ! [ >] , IDENT ) => " " ,
127
+ ( T ! [ >] , _) if curr_kind. is_keyword ( ) => " " ,
128
+ ( T ! [ ->] , _) | ( _, T ! [ ->] ) => " " ,
129
+ ( T ! [ &&] , _) | ( _, T ! [ &&] ) => " " ,
110
130
_ => "" ,
111
131
} ;
112
132
133
+ match prev_kind {
134
+ T ! [ '{' ] => indent_level += 1 ,
135
+ T ! [ '}' ] => indent_level -= 1 ,
136
+ _ => ( ) ,
137
+ }
138
+
113
139
res. push_str ( space) ;
140
+ if space == "\n " {
141
+ let level = if curr_kind == T ! [ '}' ] { indent_level - 1 } else { indent_level } ;
142
+ res. push_str ( & " " . repeat ( level) ) ;
143
+ }
114
144
prev_kind = curr_kind;
115
145
format_to ! ( res, "{}" , token)
116
146
}
0 commit comments