diff options
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 40 | ||||
-rw-r--r-- | crates/ra_hir_def/src/body.rs | 22 | ||||
-rw-r--r-- | crates/ra_hir_def/src/body/lower.rs | 20 | ||||
-rw-r--r-- | crates/ra_hir_def/src/lib.rs | 2 |
4 files changed, 51 insertions, 33 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( |
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 8ab92b23a..142c52d35 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs | |||
@@ -26,7 +26,7 @@ use crate::{ | |||
26 | DefWithBodyId, HasModule, Lookup, ModuleId, | 26 | DefWithBodyId, HasModule, Lookup, ModuleId, |
27 | }; | 27 | }; |
28 | 28 | ||
29 | pub struct Expander { | 29 | pub(crate) struct Expander { |
30 | crate_def_map: Arc<CrateDefMap>, | 30 | crate_def_map: Arc<CrateDefMap>, |
31 | current_file_id: HirFileId, | 31 | current_file_id: HirFileId, |
32 | hygiene: Hygiene, | 32 | hygiene: Hygiene, |
@@ -35,14 +35,18 @@ pub struct Expander { | |||
35 | } | 35 | } |
36 | 36 | ||
37 | impl Expander { | 37 | impl Expander { |
38 | pub fn new(db: &impl DefDatabase, current_file_id: HirFileId, module: ModuleId) -> Expander { | 38 | pub(crate) fn new( |
39 | db: &impl DefDatabase, | ||
40 | current_file_id: HirFileId, | ||
41 | module: ModuleId, | ||
42 | ) -> Expander { | ||
39 | let crate_def_map = db.crate_def_map(module.krate); | 43 | let crate_def_map = db.crate_def_map(module.krate); |
40 | let hygiene = Hygiene::new(db, current_file_id); | 44 | let hygiene = Hygiene::new(db, current_file_id); |
41 | let ast_id_map = db.ast_id_map(current_file_id); | 45 | let ast_id_map = db.ast_id_map(current_file_id); |
42 | Expander { crate_def_map, current_file_id, hygiene, ast_id_map, module } | 46 | Expander { crate_def_map, current_file_id, hygiene, ast_id_map, module } |
43 | } | 47 | } |
44 | 48 | ||
45 | pub fn enter_expand<T: ast::AstNode, DB: DefDatabase>( | 49 | pub(crate) fn enter_expand<T: ast::AstNode, DB: DefDatabase>( |
46 | &mut self, | 50 | &mut self, |
47 | db: &DB, | 51 | db: &DB, |
48 | macro_call: ast::MacroCall, | 52 | macro_call: ast::MacroCall, |
@@ -80,14 +84,14 @@ impl Expander { | |||
80 | None | 84 | None |
81 | } | 85 | } |
82 | 86 | ||
83 | pub fn exit(&mut self, db: &impl DefDatabase, mut mark: Mark) { | 87 | pub(crate) fn exit(&mut self, db: &impl DefDatabase, mut mark: Mark) { |
84 | self.hygiene = Hygiene::new(db, mark.file_id); | 88 | self.hygiene = Hygiene::new(db, mark.file_id); |
85 | self.current_file_id = mark.file_id; | 89 | self.current_file_id = mark.file_id; |
86 | self.ast_id_map = mem::take(&mut mark.ast_id_map); | 90 | self.ast_id_map = mem::take(&mut mark.ast_id_map); |
87 | mark.bomb.defuse(); | 91 | mark.bomb.defuse(); |
88 | } | 92 | } |
89 | 93 | ||
90 | pub fn to_source<T>(&self, value: T) -> InFile<T> { | 94 | pub(crate) fn to_source<T>(&self, value: T) -> InFile<T> { |
91 | InFile { file_id: self.current_file_id, value } | 95 | InFile { file_id: self.current_file_id, value } |
92 | } | 96 | } |
93 | 97 | ||
@@ -112,7 +116,7 @@ impl Expander { | |||
112 | } | 116 | } |
113 | } | 117 | } |
114 | 118 | ||
115 | pub struct Mark { | 119 | pub(crate) struct Mark { |
116 | file_id: HirFileId, | 120 | file_id: HirFileId, |
117 | ast_id_map: Arc<AstIdMap>, | 121 | ast_id_map: Arc<AstIdMap>, |
118 | bomb: DropBomb, | 122 | bomb: DropBomb, |
@@ -159,6 +163,7 @@ pub struct BodySourceMap { | |||
159 | pat_map: FxHashMap<PatSource, PatId>, | 163 | pat_map: FxHashMap<PatSource, PatId>, |
160 | pat_map_back: ArenaMap<PatId, PatSource>, | 164 | pat_map_back: ArenaMap<PatId, PatSource>, |
161 | field_map: FxHashMap<(ExprId, usize), AstPtr<ast::RecordField>>, | 165 | field_map: FxHashMap<(ExprId, usize), AstPtr<ast::RecordField>>, |
166 | expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, HirFileId>, | ||
162 | } | 167 | } |
163 | 168 | ||
164 | impl Body { | 169 | impl Body { |
@@ -233,6 +238,11 @@ impl BodySourceMap { | |||
233 | self.expr_map.get(&src).cloned() | 238 | self.expr_map.get(&src).cloned() |
234 | } | 239 | } |
235 | 240 | ||
241 | pub fn node_macro_file(&self, node: InFile<&ast::MacroCall>) -> Option<HirFileId> { | ||
242 | let src = node.map(|it| AstPtr::new(it)); | ||
243 | self.expansions.get(&src).cloned() | ||
244 | } | ||
245 | |||
236 | pub fn field_init_shorthand_expr(&self, node: InFile<&ast::RecordField>) -> Option<ExprId> { | 246 | pub fn field_init_shorthand_expr(&self, node: InFile<&ast::RecordField>) -> Option<ExprId> { |
237 | let src = node.map(|it| Either::Right(AstPtr::new(it))); | 247 | let src = node.map(|it| Either::Right(AstPtr::new(it))); |
238 | self.expr_map.get(&src).cloned() | 248 | self.expr_map.get(&src).cloned() |
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 5323af097..57c77304c 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs | |||
@@ -446,14 +446,20 @@ where | |||
446 | } | 446 | } |
447 | } | 447 | } |
448 | // FIXME expand to statements in statement position | 448 | // FIXME expand to statements in statement position |
449 | ast::Expr::MacroCall(e) => match self.expander.enter_expand(self.db, e) { | 449 | ast::Expr::MacroCall(e) => { |
450 | Some((mark, expansion)) => { | 450 | let macro_call = self.expander.to_source(AstPtr::new(&e)); |
451 | let id = self.collect_expr(expansion); | 451 | match self.expander.enter_expand(self.db, e.clone()) { |
452 | self.expander.exit(self.db, mark); | 452 | Some((mark, expansion)) => { |
453 | id | 453 | self.source_map |
454 | .expansions | ||
455 | .insert(macro_call, self.expander.current_file_id); | ||
456 | let id = self.collect_expr(expansion); | ||
457 | self.expander.exit(self.db, mark); | ||
458 | id | ||
459 | } | ||
460 | None => self.alloc_expr(Expr::Missing, syntax_ptr), | ||
454 | } | 461 | } |
455 | None => self.alloc_expr(Expr::Missing, syntax_ptr), | 462 | } |
456 | }, | ||
457 | 463 | ||
458 | // FIXME implement HIR for these: | 464 | // FIXME implement HIR for these: |
459 | ast::Expr::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), | 465 | ast::Expr::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index f58ce9a95..f6c7f38d1 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs | |||
@@ -48,7 +48,7 @@ use ra_arena::{impl_arena_id, RawId}; | |||
48 | use ra_db::{impl_intern_key, salsa, CrateId}; | 48 | use ra_db::{impl_intern_key, salsa, CrateId}; |
49 | use ra_syntax::{ast, AstNode}; | 49 | use ra_syntax::{ast, AstNode}; |
50 | 50 | ||
51 | pub use crate::body::Expander; | 51 | use crate::body::Expander; |
52 | use crate::builtin_type::BuiltinType; | 52 | use crate::builtin_type::BuiltinType; |
53 | 53 | ||
54 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 54 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |