diff options
author | Aleksey Kladov <[email protected]> | 2018-11-25 16:02:14 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-11-25 16:02:14 +0000 |
commit | b6fcd462781826795e6ab32a69cd332496b537c2 (patch) | |
tree | bb44eaedf546e20a8b29b9b421fb0c3accc1ce74 /crates/ra_analysis/src/descriptors/function | |
parent | 8f5fb8341314e94b1d91afa50ca895f78180f948 (diff) |
Codify Arena pattern
Diffstat (limited to 'crates/ra_analysis/src/descriptors/function')
-rw-r--r-- | crates/ra_analysis/src/descriptors/function/scope.rs | 36 |
1 files changed, 15 insertions, 21 deletions
diff --git a/crates/ra_analysis/src/descriptors/function/scope.rs b/crates/ra_analysis/src/descriptors/function/scope.rs index bbe16947c..54d7fa456 100644 --- a/crates/ra_analysis/src/descriptors/function/scope.rs +++ b/crates/ra_analysis/src/descriptors/function/scope.rs | |||
@@ -6,15 +6,17 @@ use ra_syntax::{ | |||
6 | AstNode, SmolStr, SyntaxNodeRef, | 6 | AstNode, SmolStr, SyntaxNodeRef, |
7 | }; | 7 | }; |
8 | 8 | ||
9 | use crate::syntax_ptr::LocalSyntaxPtr; | 9 | use crate::{ |
10 | syntax_ptr::LocalSyntaxPtr, | ||
11 | arena::{Arena, Id}, | ||
12 | }; | ||
10 | 13 | ||
11 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] | 14 | pub(crate) type ScopeId = Id<ScopeData>; |
12 | pub(crate) struct ScopeId(u32); | ||
13 | 15 | ||
14 | #[derive(Debug, PartialEq, Eq)] | 16 | #[derive(Debug, PartialEq, Eq)] |
15 | pub struct FnScopes { | 17 | pub struct FnScopes { |
16 | pub(crate) self_param: Option<LocalSyntaxPtr>, | 18 | pub(crate) self_param: Option<LocalSyntaxPtr>, |
17 | scopes: Vec<ScopeData>, | 19 | scopes: Arena<ScopeData>, |
18 | scope_for: FxHashMap<LocalSyntaxPtr, ScopeId>, | 20 | scope_for: FxHashMap<LocalSyntaxPtr, ScopeId>, |
19 | } | 21 | } |
20 | 22 | ||
@@ -25,7 +27,7 @@ pub struct ScopeEntry { | |||
25 | } | 27 | } |
26 | 28 | ||
27 | #[derive(Debug, PartialEq, Eq)] | 29 | #[derive(Debug, PartialEq, Eq)] |
28 | struct ScopeData { | 30 | pub(crate) struct ScopeData { |
29 | parent: Option<ScopeId>, | 31 | parent: Option<ScopeId>, |
30 | entries: Vec<ScopeEntry>, | 32 | entries: Vec<ScopeEntry>, |
31 | } | 33 | } |
@@ -37,7 +39,7 @@ impl FnScopes { | |||
37 | .param_list() | 39 | .param_list() |
38 | .and_then(|it| it.self_param()) | 40 | .and_then(|it| it.self_param()) |
39 | .map(|it| LocalSyntaxPtr::new(it.syntax())), | 41 | .map(|it| LocalSyntaxPtr::new(it.syntax())), |
40 | scopes: Vec::new(), | 42 | scopes: Arena::default(), |
41 | scope_for: FxHashMap::default(), | 43 | scope_for: FxHashMap::default(), |
42 | }; | 44 | }; |
43 | let root = scopes.root_scope(); | 45 | let root = scopes.root_scope(); |
@@ -48,26 +50,24 @@ impl FnScopes { | |||
48 | scopes | 50 | scopes |
49 | } | 51 | } |
50 | pub(crate) fn entries(&self, scope: ScopeId) -> &[ScopeEntry] { | 52 | pub(crate) fn entries(&self, scope: ScopeId) -> &[ScopeEntry] { |
51 | &self.get(scope).entries | 53 | &self.scopes[scope].entries |
52 | } | 54 | } |
53 | pub fn scope_chain<'a>(&'a self, node: SyntaxNodeRef) -> impl Iterator<Item = ScopeId> + 'a { | 55 | pub fn scope_chain<'a>(&'a self, node: SyntaxNodeRef) -> impl Iterator<Item = ScopeId> + 'a { |
54 | generate(self.scope_for(node), move |&scope| self.get(scope).parent) | 56 | generate(self.scope_for(node), move |&scope| { |
57 | self.scopes[scope].parent | ||
58 | }) | ||
55 | } | 59 | } |
56 | fn root_scope(&mut self) -> ScopeId { | 60 | fn root_scope(&mut self) -> ScopeId { |
57 | let res = ScopeId(self.scopes.len() as u32); | ||
58 | self.scopes.push(ScopeData { | 61 | self.scopes.push(ScopeData { |
59 | parent: None, | 62 | parent: None, |
60 | entries: vec![], | 63 | entries: vec![], |
61 | }); | 64 | }) |
62 | res | ||
63 | } | 65 | } |
64 | fn new_scope(&mut self, parent: ScopeId) -> ScopeId { | 66 | fn new_scope(&mut self, parent: ScopeId) -> ScopeId { |
65 | let res = ScopeId(self.scopes.len() as u32); | ||
66 | self.scopes.push(ScopeData { | 67 | self.scopes.push(ScopeData { |
67 | parent: Some(parent), | 68 | parent: Some(parent), |
68 | entries: vec![], | 69 | entries: vec![], |
69 | }); | 70 | }) |
70 | res | ||
71 | } | 71 | } |
72 | fn add_bindings(&mut self, scope: ScopeId, pat: ast::Pat) { | 72 | fn add_bindings(&mut self, scope: ScopeId, pat: ast::Pat) { |
73 | let entries = pat | 73 | let entries = pat |
@@ -75,7 +75,7 @@ impl FnScopes { | |||
75 | .descendants() | 75 | .descendants() |
76 | .filter_map(ast::BindPat::cast) | 76 | .filter_map(ast::BindPat::cast) |
77 | .filter_map(ScopeEntry::new); | 77 | .filter_map(ScopeEntry::new); |
78 | self.get_mut(scope).entries.extend(entries); | 78 | self.scopes[scope].entries.extend(entries); |
79 | } | 79 | } |
80 | fn add_params_bindings(&mut self, scope: ScopeId, params: Option<ast::ParamList>) { | 80 | fn add_params_bindings(&mut self, scope: ScopeId, params: Option<ast::ParamList>) { |
81 | params | 81 | params |
@@ -93,12 +93,6 @@ impl FnScopes { | |||
93 | .filter_map(|it| self.scope_for.get(&it).map(|&scope| scope)) | 93 | .filter_map(|it| self.scope_for.get(&it).map(|&scope| scope)) |
94 | .next() | 94 | .next() |
95 | } | 95 | } |
96 | fn get(&self, scope: ScopeId) -> &ScopeData { | ||
97 | &self.scopes[scope.0 as usize] | ||
98 | } | ||
99 | fn get_mut(&mut self, scope: ScopeId) -> &mut ScopeData { | ||
100 | &mut self.scopes[scope.0 as usize] | ||
101 | } | ||
102 | } | 96 | } |
103 | 97 | ||
104 | impl ScopeEntry { | 98 | impl ScopeEntry { |