diff options
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 40 |
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 | }; |
22 | use hir_expand::{ | 22 | use 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(¯o_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 | ||
511 | fn 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... |
528 | fn adjust( | 530 | fn adjust( |