aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/code_model_api.rs4
-rw-r--r--crates/ra_hir/src/db.rs11
-rw-r--r--crates/ra_hir/src/expr.rs86
-rw-r--r--crates/ra_hir/src/expr/scope.rs12
4 files changed, 53 insertions, 60 deletions
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs
index f8521e895..c77b8acc7 100644
--- a/crates/ra_hir/src/code_model_api.rs
+++ b/crates/ra_hir/src/code_model_api.rs
@@ -484,7 +484,7 @@ impl Function {
484 } 484 }
485 485
486 pub fn body_source_map(&self, db: &impl HirDatabase) -> Arc<BodySourceMap> { 486 pub fn body_source_map(&self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
487 db.body_source_map(*self) 487 db.body_with_source_map(*self).1
488 } 488 }
489 489
490 pub fn body(&self, db: &impl HirDatabase) -> Arc<Body> { 490 pub fn body(&self, db: &impl HirDatabase) -> Arc<Body> {
@@ -497,7 +497,7 @@ impl Function {
497 497
498 pub fn scopes(&self, db: &impl HirDatabase) -> ScopesWithSyntaxMapping { 498 pub fn scopes(&self, db: &impl HirDatabase) -> ScopesWithSyntaxMapping {
499 let scopes = db.expr_scopes(*self); 499 let scopes = db.expr_scopes(*self);
500 let syntax_mapping = db.body_source_map(*self); 500 let syntax_mapping = db.body_with_source_map(*self).1;
501 ScopesWithSyntaxMapping { scopes, syntax_mapping } 501 ScopesWithSyntaxMapping { scopes, syntax_mapping }
502 } 502 }
503 503
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index cb1c24561..a669dc9b0 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -105,11 +105,14 @@ pub trait HirDatabase: PersistentHirDatabase {
105 #[salsa::invoke(crate::ty::type_for_field)] 105 #[salsa::invoke(crate::ty::type_for_field)]
106 fn type_for_field(&self, field: StructField) -> Ty; 106 fn type_for_field(&self, field: StructField) -> Ty;
107 107
108 #[salsa::invoke(crate::expr::body_hir)] 108 #[salsa::invoke(crate::expr::body_with_source_map_query)]
109 fn body_hir(&self, func: Function) -> Arc<crate::expr::Body>; 109 fn body_with_source_map(
110 &self,
111 func: Function,
112 ) -> (Arc<crate::expr::Body>, Arc<crate::expr::BodySourceMap>);
110 113
111 #[salsa::invoke(crate::expr::body_source_map)] 114 #[salsa::invoke(crate::expr::body_hir_query)]
112 fn body_source_map(&self, func: Function) -> Arc<crate::expr::BodySourceMap>; 115 fn body_hir(&self, func: Function) -> Arc<crate::expr::Body>;
113 116
114 #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] 117 #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)]
115 fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>; 118 fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>;
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index b1398411b..4e399ec6d 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -48,13 +48,13 @@ pub struct Body {
48/// expression containing it; but for type inference etc., we want to operate on 48/// expression containing it; but for type inference etc., we want to operate on
49/// a structure that is agnostic to the actual positions of expressions in the 49/// a structure that is agnostic to the actual positions of expressions in the
50/// file, so that we don't recompute types whenever some whitespace is typed. 50/// file, so that we don't recompute types whenever some whitespace is typed.
51#[derive(Debug, Eq, PartialEq)] 51#[derive(Default, Debug, Eq, PartialEq)]
52pub struct BodySourceMap { 52pub struct BodySourceMap {
53 body: Arc<Body>, 53 // body: Arc<Body>,
54 expr_syntax_mapping: FxHashMap<SyntaxNodePtr, ExprId>, 54 expr_map: FxHashMap<SyntaxNodePtr, ExprId>,
55 expr_syntax_mapping_back: ArenaMap<ExprId, SyntaxNodePtr>, 55 expr_map_back: ArenaMap<ExprId, SyntaxNodePtr>,
56 pat_syntax_mapping: FxHashMap<SyntaxNodePtr, PatId>, 56 pat_map: FxHashMap<SyntaxNodePtr, PatId>,
57 pat_syntax_mapping_back: ArenaMap<PatId, SyntaxNodePtr>, 57 pat_map_back: ArenaMap<PatId, SyntaxNodePtr>,
58} 58}
59 59
60impl Body { 60impl Body {
@@ -79,7 +79,7 @@ impl Body {
79 } 79 }
80 80
81 pub fn syntax_mapping(&self, db: &impl HirDatabase) -> Arc<BodySourceMap> { 81 pub fn syntax_mapping(&self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
82 db.body_source_map(self.owner) 82 db.body_with_source_map(self.owner).1
83 } 83 }
84} 84}
85 85
@@ -121,31 +121,27 @@ impl Index<PatId> for Body {
121 121
122impl BodySourceMap { 122impl BodySourceMap {
123 pub fn expr_syntax(&self, expr: ExprId) -> Option<SyntaxNodePtr> { 123 pub fn expr_syntax(&self, expr: ExprId) -> Option<SyntaxNodePtr> {
124 self.expr_syntax_mapping_back.get(expr).cloned() 124 self.expr_map_back.get(expr).cloned()
125 } 125 }
126 126
127 pub fn syntax_expr(&self, ptr: SyntaxNodePtr) -> Option<ExprId> { 127 pub fn syntax_expr(&self, ptr: SyntaxNodePtr) -> Option<ExprId> {
128 self.expr_syntax_mapping.get(&ptr).cloned() 128 self.expr_map.get(&ptr).cloned()
129 } 129 }
130 130
131 pub fn node_expr(&self, node: &ast::Expr) -> Option<ExprId> { 131 pub fn node_expr(&self, node: &ast::Expr) -> Option<ExprId> {
132 self.expr_syntax_mapping.get(&SyntaxNodePtr::new(node.syntax())).cloned() 132 self.expr_map.get(&SyntaxNodePtr::new(node.syntax())).cloned()
133 } 133 }
134 134
135 pub fn pat_syntax(&self, pat: PatId) -> Option<SyntaxNodePtr> { 135 pub fn pat_syntax(&self, pat: PatId) -> Option<SyntaxNodePtr> {
136 self.pat_syntax_mapping_back.get(pat).cloned() 136 self.pat_map_back.get(pat).cloned()
137 } 137 }
138 138
139 pub fn syntax_pat(&self, ptr: SyntaxNodePtr) -> Option<PatId> { 139 pub fn syntax_pat(&self, ptr: SyntaxNodePtr) -> Option<PatId> {
140 self.pat_syntax_mapping.get(&ptr).cloned() 140 self.pat_map.get(&ptr).cloned()
141 } 141 }
142 142
143 pub fn node_pat(&self, node: &ast::Pat) -> Option<PatId> { 143 pub fn node_pat(&self, node: &ast::Pat) -> Option<PatId> {
144 self.pat_syntax_mapping.get(&SyntaxNodePtr::new(node.syntax())).cloned() 144 self.pat_map.get(&SyntaxNodePtr::new(node.syntax())).cloned()
145 }
146
147 pub fn body(&self) -> &Arc<Body> {
148 &self.body
149 } 145 }
150} 146}
151 147
@@ -467,18 +463,11 @@ impl Pat {
467 463
468// Queries 464// Queries
469 465
470pub(crate) fn body_hir(db: &impl HirDatabase, func: Function) -> Arc<Body> {
471 Arc::clone(&body_source_map(db, func).body)
472}
473
474struct ExprCollector { 466struct ExprCollector {
475 owner: Function, 467 owner: Function,
476 exprs: Arena<ExprId, Expr>, 468 exprs: Arena<ExprId, Expr>,
477 pats: Arena<PatId, Pat>, 469 pats: Arena<PatId, Pat>,
478 expr_syntax_mapping: FxHashMap<SyntaxNodePtr, ExprId>, 470 source_map: BodySourceMap,
479 expr_syntax_mapping_back: ArenaMap<ExprId, SyntaxNodePtr>,
480 pat_syntax_mapping: FxHashMap<SyntaxNodePtr, PatId>,
481 pat_syntax_mapping_back: ArenaMap<PatId, SyntaxNodePtr>,
482 params: Vec<PatId>, 471 params: Vec<PatId>,
483 body_expr: Option<ExprId>, 472 body_expr: Option<ExprId>,
484} 473}
@@ -489,10 +478,7 @@ impl ExprCollector {
489 owner, 478 owner,
490 exprs: Arena::default(), 479 exprs: Arena::default(),
491 pats: Arena::default(), 480 pats: Arena::default(),
492 expr_syntax_mapping: FxHashMap::default(), 481 source_map: BodySourceMap::default(),
493 expr_syntax_mapping_back: ArenaMap::default(),
494 pat_syntax_mapping: FxHashMap::default(),
495 pat_syntax_mapping_back: ArenaMap::default(),
496 params: Vec::new(), 482 params: Vec::new(),
497 body_expr: None, 483 body_expr: None,
498 } 484 }
@@ -500,15 +486,15 @@ impl ExprCollector {
500 486
501 fn alloc_expr(&mut self, expr: Expr, syntax_ptr: SyntaxNodePtr) -> ExprId { 487 fn alloc_expr(&mut self, expr: Expr, syntax_ptr: SyntaxNodePtr) -> ExprId {
502 let id = self.exprs.alloc(expr); 488 let id = self.exprs.alloc(expr);
503 self.expr_syntax_mapping.insert(syntax_ptr, id); 489 self.source_map.expr_map.insert(syntax_ptr, id);
504 self.expr_syntax_mapping_back.insert(id, syntax_ptr); 490 self.source_map.expr_map_back.insert(id, syntax_ptr);
505 id 491 id
506 } 492 }
507 493
508 fn alloc_pat(&mut self, pat: Pat, syntax_ptr: SyntaxNodePtr) -> PatId { 494 fn alloc_pat(&mut self, pat: Pat, syntax_ptr: SyntaxNodePtr) -> PatId {
509 let id = self.pats.alloc(pat); 495 let id = self.pats.alloc(pat);
510 self.pat_syntax_mapping.insert(syntax_ptr, id); 496 self.source_map.pat_map.insert(syntax_ptr, id);
511 self.pat_syntax_mapping_back.insert(id, syntax_ptr); 497 self.source_map.pat_map_back.insert(id, syntax_ptr);
512 id 498 id
513 } 499 }
514 500
@@ -639,7 +625,7 @@ impl ExprCollector {
639 ast::ExprKind::ParenExpr(e) => { 625 ast::ExprKind::ParenExpr(e) => {
640 let inner = self.collect_expr_opt(e.expr()); 626 let inner = self.collect_expr_opt(e.expr());
641 // make the paren expr point to the inner expression as well 627 // make the paren expr point to the inner expression as well
642 self.expr_syntax_mapping.insert(syntax_ptr, inner); 628 self.source_map.expr_map.insert(syntax_ptr, inner);
643 inner 629 inner
644 } 630 }
645 ast::ExprKind::ReturnExpr(e) => { 631 ast::ExprKind::ReturnExpr(e) => {
@@ -660,9 +646,11 @@ impl ExprCollector {
660 } else if let Some(nr) = field.name_ref() { 646 } else if let Some(nr) = field.name_ref() {
661 // field shorthand 647 // field shorthand
662 let id = self.exprs.alloc(Expr::Path(Path::from_name_ref(nr))); 648 let id = self.exprs.alloc(Expr::Path(Path::from_name_ref(nr)));
663 self.expr_syntax_mapping 649 self.source_map
650 .expr_map
664 .insert(SyntaxNodePtr::new(nr.syntax()), id); 651 .insert(SyntaxNodePtr::new(nr.syntax()), id);
665 self.expr_syntax_mapping_back 652 self.source_map
653 .expr_map_back
666 .insert(id, SyntaxNodePtr::new(nr.syntax())); 654 .insert(id, SyntaxNodePtr::new(nr.syntax()));
667 id 655 id
668 } else { 656 } else {
@@ -910,7 +898,7 @@ impl ExprCollector {
910 self.body_expr = Some(body); 898 self.body_expr = Some(body);
911 } 899 }
912 900
913 fn into_body_source_map(self) -> BodySourceMap { 901 fn finish(self) -> (Body, BodySourceMap) {
914 let body = Body { 902 let body = Body {
915 owner: self.owner, 903 owner: self.owner,
916 exprs: self.exprs, 904 exprs: self.exprs,
@@ -918,28 +906,30 @@ impl ExprCollector {
918 params: self.params, 906 params: self.params,
919 body_expr: self.body_expr.expect("A body should have been collected"), 907 body_expr: self.body_expr.expect("A body should have been collected"),
920 }; 908 };
921 BodySourceMap { 909 (body, self.source_map)
922 body: Arc::new(body),
923 expr_syntax_mapping: self.expr_syntax_mapping,
924 expr_syntax_mapping_back: self.expr_syntax_mapping_back,
925 pat_syntax_mapping: self.pat_syntax_mapping,
926 pat_syntax_mapping_back: self.pat_syntax_mapping_back,
927 }
928 } 910 }
929} 911}
930 912
931pub(crate) fn body_source_map(db: &impl HirDatabase, func: Function) -> Arc<BodySourceMap> { 913pub(crate) fn body_with_source_map_query(
914 db: &impl HirDatabase,
915 func: Function,
916) -> (Arc<Body>, Arc<BodySourceMap>) {
932 let mut collector = ExprCollector::new(func); 917 let mut collector = ExprCollector::new(func);
933 918
934 // TODO: consts, etc. 919 // TODO: consts, etc.
935 collector.collect_fn_body(&func.source(db).1); 920 collector.collect_fn_body(&func.source(db).1);
936 921
937 Arc::new(collector.into_body_source_map()) 922 let (body, source_map) = collector.finish();
923 (Arc::new(body), Arc::new(source_map))
924}
925
926pub(crate) fn body_hir_query(db: &impl HirDatabase, func: Function) -> Arc<Body> {
927 db.body_with_source_map(func).0
938} 928}
939 929
940#[cfg(test)] 930#[cfg(test)]
941pub(crate) fn collect_fn_body_syntax(function: Function, node: &ast::FnDef) -> BodySourceMap { 931fn collect_fn_body_syntax(function: Function, node: &ast::FnDef) -> (Body, BodySourceMap) {
942 let mut collector = ExprCollector::new(function); 932 let mut collector = ExprCollector::new(function);
943 collector.collect_fn_body(node); 933 collector.collect_fn_body(node);
944 collector.into_body_source_map() 934 collector.finish()
945} 935}
diff --git a/crates/ra_hir/src/expr/scope.rs b/crates/ra_hir/src/expr/scope.rs
index bb919dcfa..d5824eb81 100644
--- a/crates/ra_hir/src/expr/scope.rs
+++ b/crates/ra_hir/src/expr/scope.rs
@@ -316,11 +316,11 @@ mod tests {
316 let marker: &ast::PathExpr = find_node_at_offset(file.syntax(), off).unwrap(); 316 let marker: &ast::PathExpr = find_node_at_offset(file.syntax(), off).unwrap();
317 let fn_def: &ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap(); 317 let fn_def: &ast::FnDef = find_node_at_offset(file.syntax(), off).unwrap();
318 let irrelevant_function = Function { id: crate::ids::FunctionId::from_raw(0.into()) }; 318 let irrelevant_function = Function { id: crate::ids::FunctionId::from_raw(0.into()) };
319 let body_hir = expr::collect_fn_body_syntax(irrelevant_function, fn_def); 319 let (body, syntax_mapping) = expr::collect_fn_body_syntax(irrelevant_function, fn_def);
320 let scopes = ExprScopes::new(Arc::clone(body_hir.body())); 320 let scopes = ExprScopes::new(Arc::new(body));
321 let scopes = ScopesWithSyntaxMapping { 321 let scopes = ScopesWithSyntaxMapping {
322 scopes: Arc::new(scopes), 322 scopes: Arc::new(scopes),
323 syntax_mapping: Arc::new(body_hir), 323 syntax_mapping: Arc::new(syntax_mapping),
324 }; 324 };
325 let actual = scopes 325 let actual = scopes
326 .scope_chain(marker.syntax()) 326 .scope_chain(marker.syntax())
@@ -417,11 +417,11 @@ mod tests {
417 let name_ref: &ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap(); 417 let name_ref: &ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap();
418 418
419 let irrelevant_function = Function { id: crate::ids::FunctionId::from_raw(0.into()) }; 419 let irrelevant_function = Function { id: crate::ids::FunctionId::from_raw(0.into()) };
420 let body_hir = expr::collect_fn_body_syntax(irrelevant_function, fn_def); 420 let (body, syntax_mapping) = expr::collect_fn_body_syntax(irrelevant_function, fn_def);
421 let scopes = ExprScopes::new(Arc::clone(body_hir.body())); 421 let scopes = ExprScopes::new(Arc::new(body));
422 let scopes = ScopesWithSyntaxMapping { 422 let scopes = ScopesWithSyntaxMapping {
423 scopes: Arc::new(scopes), 423 scopes: Arc::new(scopes),
424 syntax_mapping: Arc::new(body_hir), 424 syntax_mapping: Arc::new(syntax_mapping),
425 }; 425 };
426 let local_name_entry = scopes.resolve_local_name(name_ref).unwrap(); 426 let local_name_entry = scopes.resolve_local_name(name_ref).unwrap();
427 let local_name = local_name_entry.ptr(); 427 let local_name = local_name_entry.ptr();