diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/code_model_api.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 11 | ||||
-rw-r--r-- | crates/ra_hir/src/expr.rs | 86 | ||||
-rw-r--r-- | crates/ra_hir/src/expr/scope.rs | 12 |
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)] |
52 | pub struct BodySourceMap { | 52 | pub 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 | ||
60 | impl Body { | 60 | impl 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 | ||
122 | impl BodySourceMap { | 122 | impl 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 | ||
470 | pub(crate) fn body_hir(db: &impl HirDatabase, func: Function) -> Arc<Body> { | ||
471 | Arc::clone(&body_source_map(db, func).body) | ||
472 | } | ||
473 | |||
474 | struct ExprCollector { | 466 | struct 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 | ||
931 | pub(crate) fn body_source_map(db: &impl HirDatabase, func: Function) -> Arc<BodySourceMap> { | 913 | pub(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 | |||
926 | pub(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)] |
941 | pub(crate) fn collect_fn_body_syntax(function: Function, node: &ast::FnDef) -> BodySourceMap { | 931 | fn 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(); |