aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/source_binder.rs40
1 files changed, 21 insertions, 19 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 3af477818..2c422af8b 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -17,7 +17,7 @@ use hir_def::{
17 nameres::ModuleSource, 17 nameres::ModuleSource,
18 path::path, 18 path::path,
19 resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs}, 19 resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs},
20 AssocItemId, DefWithBodyId, Expander, 20 AssocItemId, DefWithBodyId,
21}; 21};
22use hir_expand::{ 22use hir_expand::{
23 hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile, MacroCallId, MacroCallKind, 23 hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile, MacroCallId, MacroCallKind,
@@ -215,10 +215,27 @@ impl SourceAnalyzer {
215 self.body_source_map.as_ref()?.node_pat(src) 215 self.body_source_map.as_ref()?.node_pat(src)
216 } 216 }
217 217
218 fn expand_expr(
219 &self,
220 db: &impl HirDatabase,
221 expr: InFile<&ast::Expr>,
222 ) -> Option<InFile<ast::Expr>> {
223 let macro_call = ast::MacroCall::cast(expr.value.syntax().clone())?;
224 let macro_file =
225 self.body_source_map.as_ref()?.node_macro_file(expr.with_value(&macro_call))?;
226 let expanded = db.parse_or_expand(macro_file)?;
227 let kind = expanded.kind();
228 let expr = InFile::new(macro_file, ast::Expr::cast(expanded)?);
229
230 if ast::MacroCall::can_cast(kind) {
231 self.expand_expr(db, expr.as_ref())
232 } else {
233 Some(expr)
234 }
235 }
236
218 pub fn type_of(&self, db: &impl HirDatabase, expr: &ast::Expr) -> Option<Type> { 237 pub fn type_of(&self, db: &impl HirDatabase, expr: &ast::Expr) -> Option<Type> {
219 let expr_id = if let Some(macro_call) = ast::MacroCall::cast(expr.syntax().clone()) { 238 let expr_id = if let Some(expr) = self.expand_expr(db, InFile::new(self.file_id, expr)) {
220 let mut expander = Expander::new(db, self.file_id, self.body_owner?.module(db).id);
221 let expr = expand_macro_call_to_expr(db, &mut expander, macro_call)?;
222 self.body_source_map.as_ref()?.node_expr(expr.as_ref())? 239 self.body_source_map.as_ref()?.node_expr(expr.as_ref())?
223 } else { 240 } else {
224 self.expr_id(expr)? 241 self.expr_id(expr)?
@@ -508,21 +525,6 @@ fn scope_for_offset(
508 }) 525 })
509} 526}
510 527
511fn expand_macro_call_to_expr(
512 db: &impl HirDatabase,
513 expander: &mut Expander,
514 macro_call: ast::MacroCall,
515) -> Option<InFile<ast::Expr>> {
516 let (mark, expr): (_, ast::Expr) = expander.enter_expand(db, macro_call)?;
517 let expr = if let Some(child) = ast::MacroCall::cast(expr.syntax().clone()) {
518 expand_macro_call_to_expr(db, expander, child)
519 } else {
520 Some(expander.to_source(expr))
521 };
522 expander.exit(db, mark);
523 expr
524}
525
526// XXX: during completion, cursor might be outside of any particular 528// XXX: during completion, cursor might be outside of any particular
527// expression. Try to figure out the correct scope... 529// expression. Try to figure out the correct scope...
528fn adjust( 530fn adjust(