diff options
author | Aleksey Kladov <[email protected]> | 2019-04-10 08:46:43 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-04-10 08:48:15 +0100 |
commit | 10726fdb65fda9144a5f9201272d065a268fc1b7 (patch) | |
tree | f5640991cbf0db2bfdad29b911435827cadfb4a8 /crates/ra_hir/src | |
parent | 1cd184d6539478c7e54c92835902921976dce5d1 (diff) |
type-safer source-map for bindings
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/either.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir/src/expr.rs | 28 | ||||
-rw-r--r-- | crates/ra_hir/src/expr/scope.rs | 15 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 2 |
4 files changed, 34 insertions, 21 deletions
diff --git a/crates/ra_hir/src/either.rs b/crates/ra_hir/src/either.rs index 6714529d9..4073cc82e 100644 --- a/crates/ra_hir/src/either.rs +++ b/crates/ra_hir/src/either.rs | |||
@@ -5,6 +5,16 @@ pub enum Either<A, B> { | |||
5 | } | 5 | } |
6 | 6 | ||
7 | impl<A, B> Either<A, B> { | 7 | impl<A, B> Either<A, B> { |
8 | pub fn either<R, F1, F2>(self, f1: F1, f2: F2) -> R | ||
9 | where | ||
10 | F1: FnOnce(A) -> R, | ||
11 | F2: FnOnce(B) -> R, | ||
12 | { | ||
13 | match self { | ||
14 | Either::A(a) => f1(a), | ||
15 | Either::B(b) => f2(b), | ||
16 | } | ||
17 | } | ||
8 | pub fn map<U, V, F1, F2>(self, f1: F1, f2: F2) -> Either<U, V> | 18 | pub fn map<U, V, F1, F2>(self, f1: F1, f2: F2) -> Either<U, V> |
9 | where | 19 | where |
10 | F1: FnOnce(A) -> U, | 20 | F1: FnOnce(A) -> U, |
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 589a9b2db..a2840c15d 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -10,7 +10,7 @@ use ra_syntax::{ | |||
10 | }; | 10 | }; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | Path, Name, HirDatabase, Resolver,DefWithBody, | 13 | Path, Name, HirDatabase, Resolver,DefWithBody, Either, |
14 | name::AsName, | 14 | name::AsName, |
15 | type_ref::{Mutability, TypeRef}, | 15 | type_ref::{Mutability, TypeRef}, |
16 | }; | 16 | }; |
@@ -51,11 +51,13 @@ pub struct Body { | |||
51 | pub struct BodySourceMap { | 51 | pub struct BodySourceMap { |
52 | expr_map: FxHashMap<SyntaxNodePtr, ExprId>, | 52 | expr_map: FxHashMap<SyntaxNodePtr, ExprId>, |
53 | expr_map_back: ArenaMap<ExprId, SyntaxNodePtr>, | 53 | expr_map_back: ArenaMap<ExprId, SyntaxNodePtr>, |
54 | pat_map: FxHashMap<SyntaxNodePtr, PatId>, | 54 | pat_map: FxHashMap<PatPrr, PatId>, |
55 | pat_map_back: ArenaMap<PatId, SyntaxNodePtr>, | 55 | pat_map_back: ArenaMap<PatId, PatPrr>, |
56 | field_map: FxHashMap<(ExprId, usize), AstPtr<ast::NamedField>>, | 56 | field_map: FxHashMap<(ExprId, usize), AstPtr<ast::NamedField>>, |
57 | } | 57 | } |
58 | 58 | ||
59 | type PatPrr = Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>; | ||
60 | |||
59 | impl Body { | 61 | impl Body { |
60 | pub fn params(&self) -> &[PatId] { | 62 | pub fn params(&self) -> &[PatId] { |
61 | &self.params | 63 | &self.params |
@@ -127,16 +129,16 @@ impl BodySourceMap { | |||
127 | self.expr_map.get(&SyntaxNodePtr::new(node.syntax())).cloned() | 129 | self.expr_map.get(&SyntaxNodePtr::new(node.syntax())).cloned() |
128 | } | 130 | } |
129 | 131 | ||
130 | pub fn pat_syntax(&self, pat: PatId) -> Option<SyntaxNodePtr> { | 132 | pub fn pat_syntax(&self, pat: PatId) -> Option<PatPrr> { |
131 | self.pat_map_back.get(pat).cloned() | 133 | self.pat_map_back.get(pat).cloned() |
132 | } | 134 | } |
133 | 135 | ||
134 | pub fn syntax_pat(&self, ptr: SyntaxNodePtr) -> Option<PatId> { | 136 | pub fn syntax_pat(&self, ptr: PatPrr) -> Option<PatId> { |
135 | self.pat_map.get(&ptr).cloned() | 137 | self.pat_map.get(&ptr).cloned() |
136 | } | 138 | } |
137 | 139 | ||
138 | pub fn node_pat(&self, node: &ast::Pat) -> Option<PatId> { | 140 | pub fn node_pat(&self, node: &ast::Pat) -> Option<PatId> { |
139 | self.pat_map.get(&SyntaxNodePtr::new(node.syntax())).cloned() | 141 | self.pat_map.get(&Either::A(AstPtr::new(node))).cloned() |
140 | } | 142 | } |
141 | 143 | ||
142 | pub fn field_syntax(&self, expr: ExprId, field: usize) -> AstPtr<ast::NamedField> { | 144 | pub fn field_syntax(&self, expr: ExprId, field: usize) -> AstPtr<ast::NamedField> { |
@@ -504,10 +506,10 @@ impl ExprCollector { | |||
504 | id | 506 | id |
505 | } | 507 | } |
506 | 508 | ||
507 | fn alloc_pat(&mut self, pat: Pat, syntax_ptr: SyntaxNodePtr) -> PatId { | 509 | fn alloc_pat(&mut self, pat: Pat, ptr: PatPrr) -> PatId { |
508 | let id = self.pats.alloc(pat); | 510 | let id = self.pats.alloc(pat); |
509 | self.source_map.pat_map.insert(syntax_ptr, id); | 511 | self.source_map.pat_map.insert(ptr, id); |
510 | self.source_map.pat_map_back.insert(id, syntax_ptr); | 512 | self.source_map.pat_map_back.insert(id, ptr); |
511 | id | 513 | id |
512 | } | 514 | } |
513 | 515 | ||
@@ -886,8 +888,8 @@ impl ExprCollector { | |||
886 | ast::PatKind::LiteralPat(_) => Pat::Missing, | 888 | ast::PatKind::LiteralPat(_) => Pat::Missing, |
887 | ast::PatKind::SlicePat(_) | ast::PatKind::RangePat(_) => Pat::Missing, | 889 | ast::PatKind::SlicePat(_) | ast::PatKind::RangePat(_) => Pat::Missing, |
888 | }; | 890 | }; |
889 | let syntax_ptr = SyntaxNodePtr::new(pat.syntax()); | 891 | let ptr = AstPtr::new(pat); |
890 | self.alloc_pat(pattern, syntax_ptr) | 892 | self.alloc_pat(pattern, Either::A(ptr)) |
891 | } | 893 | } |
892 | 894 | ||
893 | fn collect_pat_opt(&mut self, pat: Option<&ast::Pat>) -> PatId { | 895 | fn collect_pat_opt(&mut self, pat: Option<&ast::Pat>) -> PatId { |
@@ -911,14 +913,14 @@ impl ExprCollector { | |||
911 | fn collect_fn_body(&mut self, node: &ast::FnDef) { | 913 | fn collect_fn_body(&mut self, node: &ast::FnDef) { |
912 | if let Some(param_list) = node.param_list() { | 914 | if let Some(param_list) = node.param_list() { |
913 | if let Some(self_param) = param_list.self_param() { | 915 | if let Some(self_param) = param_list.self_param() { |
914 | let self_param = SyntaxNodePtr::new(self_param.syntax()); | 916 | let ptr = AstPtr::new(self_param); |
915 | let param_pat = self.alloc_pat( | 917 | let param_pat = self.alloc_pat( |
916 | Pat::Bind { | 918 | Pat::Bind { |
917 | name: Name::self_param(), | 919 | name: Name::self_param(), |
918 | mode: BindingAnnotation::Unannotated, | 920 | mode: BindingAnnotation::Unannotated, |
919 | subpat: None, | 921 | subpat: None, |
920 | }, | 922 | }, |
921 | self_param, | 923 | Either::B(ptr), |
922 | ); | 924 | ); |
923 | self.params.push(param_pat); | 925 | self.params.push(param_pat); |
924 | } | 926 | } |
diff --git a/crates/ra_hir/src/expr/scope.rs b/crates/ra_hir/src/expr/scope.rs index f1e6e0f02..725b6c00e 100644 --- a/crates/ra_hir/src/expr/scope.rs +++ b/crates/ra_hir/src/expr/scope.rs | |||
@@ -3,14 +3,14 @@ use std::sync::Arc; | |||
3 | use rustc_hash::{FxHashMap, FxHashSet}; | 3 | use rustc_hash::{FxHashMap, FxHashSet}; |
4 | 4 | ||
5 | use ra_syntax::{ | 5 | use ra_syntax::{ |
6 | AstNode, SyntaxNode, TextUnit, TextRange, SyntaxNodePtr, | 6 | AstNode, SyntaxNode, TextUnit, TextRange, SyntaxNodePtr, AstPtr, |
7 | algo::generate, | 7 | algo::generate, |
8 | ast, | 8 | ast, |
9 | }; | 9 | }; |
10 | use ra_arena::{Arena, RawId, impl_arena_id}; | 10 | use ra_arena::{Arena, RawId, impl_arena_id}; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | Name, AsName,DefWithBody, | 13 | Name, AsName,DefWithBody, Either, |
14 | expr::{PatId, ExprId, Pat, Expr, Body, Statement, BodySourceMap}, | 14 | expr::{PatId, ExprId, Pat, Expr, Body, Statement, BodySourceMap}, |
15 | HirDatabase, | 15 | HirDatabase, |
16 | }; | 16 | }; |
@@ -116,7 +116,7 @@ pub struct ScopesWithSourceMap { | |||
116 | #[derive(Debug, Clone, PartialEq, Eq)] | 116 | #[derive(Debug, Clone, PartialEq, Eq)] |
117 | pub struct ScopeEntryWithSyntax { | 117 | pub struct ScopeEntryWithSyntax { |
118 | name: Name, | 118 | name: Name, |
119 | ptr: SyntaxNodePtr, | 119 | ptr: Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>, |
120 | } | 120 | } |
121 | 121 | ||
122 | impl ScopeEntryWithSyntax { | 122 | impl ScopeEntryWithSyntax { |
@@ -124,7 +124,7 @@ impl ScopeEntryWithSyntax { | |||
124 | &self.name | 124 | &self.name |
125 | } | 125 | } |
126 | 126 | ||
127 | pub fn ptr(&self) -> SyntaxNodePtr { | 127 | pub fn ptr(&self) -> Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>> { |
128 | self.ptr | 128 | self.ptr |
129 | } | 129 | } |
130 | } | 130 | } |
@@ -192,14 +192,14 @@ impl ScopesWithSourceMap { | |||
192 | 192 | ||
193 | pub fn find_all_refs(&self, pat: &ast::BindPat) -> Vec<ReferenceDescriptor> { | 193 | pub fn find_all_refs(&self, pat: &ast::BindPat) -> Vec<ReferenceDescriptor> { |
194 | let fn_def = pat.syntax().ancestors().find_map(ast::FnDef::cast).unwrap(); | 194 | let fn_def = pat.syntax().ancestors().find_map(ast::FnDef::cast).unwrap(); |
195 | let name_ptr = SyntaxNodePtr::new(pat.syntax()); | 195 | let ptr = Either::A(AstPtr::new(pat.into())); |
196 | fn_def | 196 | fn_def |
197 | .syntax() | 197 | .syntax() |
198 | .descendants() | 198 | .descendants() |
199 | .filter_map(ast::NameRef::cast) | 199 | .filter_map(ast::NameRef::cast) |
200 | .filter(|name_ref| match self.resolve_local_name(*name_ref) { | 200 | .filter(|name_ref| match self.resolve_local_name(*name_ref) { |
201 | None => false, | 201 | None => false, |
202 | Some(entry) => entry.ptr() == name_ptr, | 202 | Some(entry) => entry.ptr() == ptr, |
203 | }) | 203 | }) |
204 | .map(|name_ref| ReferenceDescriptor { | 204 | .map(|name_ref| ReferenceDescriptor { |
205 | name: name_ref.syntax().text().to_string(), | 205 | name: name_ref.syntax().text().to_string(), |
@@ -429,7 +429,8 @@ mod tests { | |||
429 | let scopes = | 429 | let scopes = |
430 | ScopesWithSourceMap { scopes: Arc::new(scopes), source_map: Arc::new(source_map) }; | 430 | ScopesWithSourceMap { scopes: Arc::new(scopes), source_map: Arc::new(source_map) }; |
431 | let local_name_entry = scopes.resolve_local_name(name_ref).unwrap(); | 431 | let local_name_entry = scopes.resolve_local_name(name_ref).unwrap(); |
432 | let local_name = local_name_entry.ptr(); | 432 | let local_name = |
433 | local_name_entry.ptr().either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()); | ||
433 | assert_eq!(local_name.range(), expected_name.syntax().range()); | 434 | assert_eq!(local_name.range(), expected_name.syntax().range()); |
434 | } | 435 | } |
435 | 436 | ||
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index f6a325033..ecc63f376 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -2324,7 +2324,7 @@ fn infer(content: &str) -> String { | |||
2324 | 2324 | ||
2325 | for (pat, ty) in inference_result.type_of_pat.iter() { | 2325 | for (pat, ty) in inference_result.type_of_pat.iter() { |
2326 | let syntax_ptr = match body_source_map.pat_syntax(pat) { | 2326 | let syntax_ptr = match body_source_map.pat_syntax(pat) { |
2327 | Some(sp) => sp, | 2327 | Some(sp) => sp.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr()), |
2328 | None => continue, | 2328 | None => continue, |
2329 | }; | 2329 | }; |
2330 | types.push((syntax_ptr, ty)); | 2330 | types.push((syntax_ptr, ty)); |