aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_expand/src/db.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_expand/src/db.rs')
-rw-r--r--crates/ra_hir_expand/src/db.rs43
1 files changed, 34 insertions, 9 deletions
diff --git a/crates/ra_hir_expand/src/db.rs b/crates/ra_hir_expand/src/db.rs
index f5c8bc22f..29dde3d80 100644
--- a/crates/ra_hir_expand/src/db.rs
+++ b/crates/ra_hir_expand/src/db.rs
@@ -72,6 +72,30 @@ pub trait AstDatabase: SourceDatabase {
72 fn intern_eager_expansion(&self, eager: EagerCallLoc) -> EagerMacroId; 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.
79pub 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
75pub(crate) fn ast_id_map(db: &dyn AstDatabase, file_id: HirFileId) -> Arc<AstIdMap> { 99pub(crate) fn ast_id_map(db: &dyn AstDatabase, file_id: HirFileId) -> Arc<AstIdMap> {
76 let map = 100 let map =
77 db.parse_or_expand(file_id).map_or_else(AstIdMap::default, |it| AstIdMap::from_source(&it)); 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 macro_expand_with_arg(db, id, None) 157 macro_expand_with_arg(db, id, None)
134} 158}
135 159
136pub fn expander( 160fn expander(db: &dyn AstDatabase, id: MacroCallId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>> {
137 db: &dyn AstDatabase,
138 id: MacroCallId,
139) -> Option<Arc<(TokenExpander, mbe::TokenMap)>> {
140 let lazy_id = match id { 161 let lazy_id = match id {
141 MacroCallId::LazyMacro(id) => id, 162 MacroCallId::LazyMacro(id) => id,
142 MacroCallId::EagerMacro(_id) => { 163 MacroCallId::EagerMacro(_id) => {
@@ -149,7 +170,7 @@ pub fn expander(
149 Some(macro_rules) 170 Some(macro_rules)
150} 171}
151 172
152pub(crate) fn macro_expand_with_arg( 173fn macro_expand_with_arg(
153 db: &dyn AstDatabase, 174 db: &dyn AstDatabase,
154 id: MacroCallId, 175 id: MacroCallId,
155 arg: Option<Arc<(tt::Subtree, mbe::TokenMap)>>, 176 arg: Option<Arc<(tt::Subtree, mbe::TokenMap)>>,
@@ -158,7 +179,9 @@ pub(crate) fn macro_expand_with_arg(
158 MacroCallId::LazyMacro(id) => id, 179 MacroCallId::LazyMacro(id) => id,
159 MacroCallId::EagerMacro(id) => { 180 MacroCallId::EagerMacro(id) => {
160 if arg.is_some() { 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 } else { 185 } else {
163 return Ok(db.lookup_intern_eager_expansion(id).subtree); 186 return Ok(db.lookup_intern_eager_expansion(id).subtree);
164 } 187 }
@@ -225,13 +248,15 @@ pub fn parse_macro_with_arg(
225 .collect::<Vec<_>>() 248 .collect::<Vec<_>>()
226 .join("\n"); 249 .join("\n");
227 250
228 eprintln!( 251 log::warn!(
229 "fail on macro_parse: (reason: {} macro_call: {:#}) parents: {}", 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::warn!("fail on macro_parse: (reason: {})", err);
235 } 260 }
236 } 261 }
237 }) 262 })