@@ -72,6 +72,30 @@ pub trait AstDatabase: SourceDatabase {
7272 fn intern_eager_expansion ( & self , eager : EagerCallLoc ) -> EagerMacroId ;
7373}
7474
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) = mbe:: 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+
7599pub ( crate ) fn ast_id_map ( db : & dyn AstDatabase , file_id : HirFileId ) -> Arc < AstIdMap > {
76100 let map =
77101 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(
133157 macro_expand_with_arg ( db, id, None )
134158}
135159
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 ) > > {
140161 let lazy_id = match id {
141162 MacroCallId :: LazyMacro ( id) => id,
142163 MacroCallId :: EagerMacro ( _id) => {
@@ -149,7 +170,7 @@ pub fn expander(
149170 Some ( macro_rules)
150171}
151172
152- pub ( crate ) fn macro_expand_with_arg (
173+ fn macro_expand_with_arg (
153174 db : & dyn AstDatabase ,
154175 id : MacroCallId ,
155176 arg : Option < Arc < ( tt:: Subtree , mbe:: TokenMap ) > > ,
@@ -158,7 +179,9 @@ pub(crate) fn macro_expand_with_arg(
158179 MacroCallId :: LazyMacro ( id) => id,
159180 MacroCallId :: EagerMacro ( id) => {
160181 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+ ) ;
162185 } else {
163186 return Ok ( db. lookup_intern_eager_expansion ( id) . subtree ) ;
164187 }
@@ -225,13 +248,15 @@ pub fn parse_macro_with_arg(
225248 . collect :: < Vec < _ > > ( )
226249 . join ( "\n " ) ;
227250
228- eprintln ! (
251+ log :: warn !(
229252 "fail on macro_parse: (reason: {} macro_call: {:#}) parents: {}" ,
230- err, node. value, parents
253+ err,
254+ node. value,
255+ parents
231256 ) ;
232257 }
233258 _ => {
234- eprintln ! ( "fail on macro_parse: (reason: {})" , err) ;
259+ log :: warn !( "fail on macro_parse: (reason: {})" , err) ;
235260 }
236261 }
237262 } )
0 commit comments