aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/source_binder.rs40
-rw-r--r--crates/ra_hir_def/src/body.rs22
-rw-r--r--crates/ra_hir_def/src/body/lower.rs20
-rw-r--r--crates/ra_hir_def/src/lib.rs2
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};
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(
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
29pub struct Expander { 29pub(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
37impl Expander { 37impl 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
115pub struct Mark { 119pub(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
164impl Body { 169impl 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};
48use ra_db::{impl_intern_key, salsa, CrateId}; 48use ra_db::{impl_intern_key, salsa, CrateId};
49use ra_syntax::{ast, AstNode}; 49use ra_syntax::{ast, AstNode};
50 50
51pub use crate::body::Expander; 51use crate::body::Expander;
52use crate::builtin_type::BuiltinType; 52use crate::builtin_type::BuiltinType;
53 53
54#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 54#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]