@@ -72,6 +72,30 @@ pub trait AstDatabase: SourceDatabase {
72
72
fn intern_eager_expansion ( & self , eager : EagerCallLoc ) -> EagerMacroId ;
73
73
}
74
74
75
+ /// This expands the given macro call, but with different arguments. This is
76
+ /// used for completion, where we want to see what 'would happen' if we insert a
77
+ /// token. The `token_to_map` mapped down into the expansion, with the mapped
78
+ /// token returned.
79
+ pub fn expand_hypothetical (
80
+ db : & impl AstDatabase ,
81
+ actual_macro_call : MacroCallId ,
82
+ hypothetical_args : & ra_syntax:: ast:: TokenTree ,
83
+ token_to_map : ra_syntax:: SyntaxToken ,
84
+ ) -> Option < ( SyntaxNode , ra_syntax:: SyntaxToken ) > {
85
+ let macro_file = MacroFile { macro_call_id : actual_macro_call } ;
86
+ let ( tt, tmap_1) = crate :: syntax_node_to_token_tree ( hypothetical_args. syntax ( ) ) . unwrap ( ) ;
87
+ let range =
88
+ token_to_map. text_range ( ) . checked_sub ( hypothetical_args. syntax ( ) . text_range ( ) . start ( ) ) ?;
89
+ let token_id = tmap_1. token_by_range ( range) ?;
90
+ let macro_def = expander ( db, actual_macro_call) ?;
91
+ let ( node, tmap_2) =
92
+ parse_macro_with_arg ( db, macro_file, Some ( std:: sync:: Arc :: new ( ( tt, tmap_1) ) ) ) ?;
93
+ let token_id = macro_def. 0 . map_id_down ( token_id) ;
94
+ let range = tmap_2. range_by_token ( token_id) ?. by_kind ( token_to_map. kind ( ) ) ?;
95
+ let token = ra_syntax:: algo:: find_covering_element ( & node. syntax_node ( ) , range) . into_token ( ) ?;
96
+ Some ( ( node. syntax_node ( ) , token) )
97
+ }
98
+
75
99
pub ( crate ) fn ast_id_map ( db : & dyn AstDatabase , file_id : HirFileId ) -> Arc < AstIdMap > {
76
100
let map =
77
101
db. parse_or_expand ( file_id) . map_or_else ( AstIdMap :: default, |it| AstIdMap :: from_source ( & it) ) ;
@@ -133,10 +157,7 @@ pub(crate) fn macro_expand(
133
157
macro_expand_with_arg ( db, id, None )
134
158
}
135
159
136
- pub fn expander (
137
- db : & dyn AstDatabase ,
138
- id : MacroCallId ,
139
- ) -> Option < Arc < ( TokenExpander , mbe:: TokenMap ) > > {
160
+ fn expander ( db : & dyn AstDatabase , id : MacroCallId ) -> Option < Arc < ( TokenExpander , mbe:: TokenMap ) > > {
140
161
let lazy_id = match id {
141
162
MacroCallId :: LazyMacro ( id) => id,
142
163
MacroCallId :: EagerMacro ( _id) => {
@@ -149,7 +170,7 @@ pub fn expander(
149
170
Some ( macro_rules)
150
171
}
151
172
152
- pub ( crate ) fn macro_expand_with_arg (
173
+ fn macro_expand_with_arg (
153
174
db : & dyn AstDatabase ,
154
175
id : MacroCallId ,
155
176
arg : Option < Arc < ( tt:: Subtree , mbe:: TokenMap ) > > ,
@@ -158,7 +179,9 @@ pub(crate) fn macro_expand_with_arg(
158
179
MacroCallId :: LazyMacro ( id) => id,
159
180
MacroCallId :: EagerMacro ( id) => {
160
181
if arg. is_some ( ) {
161
- return Err ( "hypothetical macro expansion not implemented for eager macro" . to_owned ( ) ) ;
182
+ return Err (
183
+ "hypothetical macro expansion not implemented for eager macro" . to_owned ( )
184
+ ) ;
162
185
} else {
163
186
return Ok ( db. lookup_intern_eager_expansion ( id) . subtree ) ;
164
187
}
@@ -225,13 +248,15 @@ pub fn parse_macro_with_arg(
225
248
. collect :: < Vec < _ > > ( )
226
249
. join ( "\n " ) ;
227
250
228
- eprintln ! (
251
+ log :: debug !(
229
252
"fail on macro_parse: (reason: {} macro_call: {:#}) parents: {}" ,
230
- err, node. value, parents
253
+ err,
254
+ node. value,
255
+ parents
231
256
) ;
232
257
}
233
258
_ => {
234
- eprintln ! ( "fail on macro_parse: (reason: {})" , err) ;
259
+ log :: debug !( "fail on macro_parse: (reason: {})" , err) ;
235
260
}
236
261
}
237
262
} )
0 commit comments