diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2018-11-25 16:03:13 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2018-11-25 16:03:13 +0000 |
commit | 8a572043e7effe1d0b36a0d247960111312edc2a (patch) | |
tree | bb44eaedf546e20a8b29b9b421fb0c3accc1ce74 /crates/ra_analysis/src/descriptors | |
parent | 8f5fb8341314e94b1d91afa50ca895f78180f948 (diff) | |
parent | b6fcd462781826795e6ab32a69cd332496b537c2 (diff) |
Merge #242
242: Codify Arena pattern r=matklad a=matklad
bors r+
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_analysis/src/descriptors')
-rw-r--r-- | crates/ra_analysis/src/descriptors/function/scope.rs | 36 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/module/imp.rs | 11 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/module/mod.rs | 76 |
3 files changed, 46 insertions, 77 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 { |
diff --git a/crates/ra_analysis/src/descriptors/module/imp.rs b/crates/ra_analysis/src/descriptors/module/imp.rs index d4dce861f..80892acb7 100644 --- a/crates/ra_analysis/src/descriptors/module/imp.rs +++ b/crates/ra_analysis/src/descriptors/module/imp.rs | |||
@@ -94,10 +94,7 @@ fn create_module_tree<'a>( | |||
94 | db: &impl DescriptorDatabase, | 94 | db: &impl DescriptorDatabase, |
95 | source_root: SourceRootId, | 95 | source_root: SourceRootId, |
96 | ) -> Cancelable<ModuleTree> { | 96 | ) -> Cancelable<ModuleTree> { |
97 | let mut tree = ModuleTree { | 97 | let mut tree = ModuleTree::default(); |
98 | mods: Vec::new(), | ||
99 | links: Vec::new(), | ||
100 | }; | ||
101 | 98 | ||
102 | let mut roots = FxHashMap::default(); | 99 | let mut roots = FxHashMap::default(); |
103 | let mut visited = FxHashSet::default(); | 100 | let mut visited = FxHashSet::default(); |
@@ -154,7 +151,7 @@ fn build_subtree( | |||
154 | .into_iter() | 151 | .into_iter() |
155 | .map(|file_id| match roots.remove(&file_id) { | 152 | .map(|file_id| match roots.remove(&file_id) { |
156 | Some(module_id) => { | 153 | Some(module_id) => { |
157 | tree.module_mut(module_id).parent = Some(link); | 154 | tree.mods[module_id].parent = Some(link); |
158 | Ok(module_id) | 155 | Ok(module_id) |
159 | } | 156 | } |
160 | None => build_subtree( | 157 | None => build_subtree( |
@@ -184,8 +181,8 @@ fn build_subtree( | |||
184 | } | 181 | } |
185 | }; | 182 | }; |
186 | 183 | ||
187 | tree.link_mut(link).points_to = points_to; | 184 | tree.links[link].points_to = points_to; |
188 | tree.link_mut(link).problem = problem; | 185 | tree.links[link].problem = problem; |
189 | } | 186 | } |
190 | Ok(id) | 187 | Ok(id) |
191 | } | 188 | } |
diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs index acc6c1c5a..54ff95b66 100644 --- a/crates/ra_analysis/src/descriptors/module/mod.rs +++ b/crates/ra_analysis/src/descriptors/module/mod.rs | |||
@@ -15,7 +15,8 @@ use relative_path::RelativePathBuf; | |||
15 | use crate::{ | 15 | use crate::{ |
16 | db::SyntaxDatabase, syntax_ptr::SyntaxPtr, FileId, FilePosition, Cancelable, | 16 | db::SyntaxDatabase, syntax_ptr::SyntaxPtr, FileId, FilePosition, Cancelable, |
17 | descriptors::{Path, PathKind, DescriptorDatabase}, | 17 | descriptors::{Path, PathKind, DescriptorDatabase}, |
18 | input::SourceRootId | 18 | input::SourceRootId, |
19 | arena::{Arena, Id}, | ||
19 | }; | 20 | }; |
20 | 21 | ||
21 | pub(crate) use self::nameres::ModuleScope; | 22 | pub(crate) use self::nameres::ModuleScope; |
@@ -157,26 +158,22 @@ impl ModuleDescriptor { | |||
157 | /// Module encapsulate the logic of transitioning from the fuzzy world of files | 158 | /// Module encapsulate the logic of transitioning from the fuzzy world of files |
158 | /// (which can have multiple parents) to the precise world of modules (which | 159 | /// (which can have multiple parents) to the precise world of modules (which |
159 | /// always have one parent). | 160 | /// always have one parent). |
160 | #[derive(Debug, PartialEq, Eq, Hash)] | 161 | #[derive(Default, Debug, PartialEq, Eq)] |
161 | pub(crate) struct ModuleTree { | 162 | pub(crate) struct ModuleTree { |
162 | mods: Vec<ModuleData>, | 163 | mods: Arena<ModuleData>, |
163 | links: Vec<LinkData>, | 164 | links: Arena<LinkData>, |
164 | } | 165 | } |
165 | 166 | ||
166 | impl ModuleTree { | 167 | impl ModuleTree { |
167 | fn modules<'a>(&'a self) -> impl Iterator<Item = ModuleId> + 'a { | 168 | fn modules<'a>(&'a self) -> impl Iterator<Item = ModuleId> + 'a { |
168 | self.mods | 169 | self.mods.keys() |
169 | .iter() | ||
170 | .enumerate() | ||
171 | .map(|(idx, _)| ModuleId(idx as u32)) | ||
172 | } | 170 | } |
173 | 171 | ||
174 | fn modules_for_source(&self, source: ModuleSource) -> Vec<ModuleId> { | 172 | fn modules_for_source(&self, source: ModuleSource) -> Vec<ModuleId> { |
175 | self.mods | 173 | self.mods |
176 | .iter() | 174 | .items() |
177 | .enumerate() | ||
178 | .filter(|(_idx, it)| it.source == source) | 175 | .filter(|(_idx, it)| it.source == source) |
179 | .map(|(idx, _)| ModuleId(idx as u32)) | 176 | .map(|(idx, _)| idx) |
180 | .collect() | 177 | .collect() |
181 | } | 178 | } |
182 | 179 | ||
@@ -201,11 +198,8 @@ enum ModuleSourceNode { | |||
201 | Module(ast::ModuleNode), | 198 | Module(ast::ModuleNode), |
202 | } | 199 | } |
203 | 200 | ||
204 | #[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] | 201 | pub(crate) type ModuleId = Id<ModuleData>; |
205 | pub(crate) struct ModuleId(u32); | 202 | type LinkId = Id<LinkData>; |
206 | |||
207 | #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] | ||
208 | struct LinkId(u32); | ||
209 | 203 | ||
210 | #[derive(Clone, Debug, Hash, PartialEq, Eq)] | 204 | #[derive(Clone, Debug, Hash, PartialEq, Eq)] |
211 | pub enum Problem { | 205 | pub enum Problem { |
@@ -220,14 +214,14 @@ pub enum Problem { | |||
220 | 214 | ||
221 | impl ModuleId { | 215 | impl ModuleId { |
222 | fn source(self, tree: &ModuleTree) -> ModuleSource { | 216 | fn source(self, tree: &ModuleTree) -> ModuleSource { |
223 | tree.module(self).source | 217 | tree.mods[self].source |
224 | } | 218 | } |
225 | fn parent_link(self, tree: &ModuleTree) -> Option<LinkId> { | 219 | fn parent_link(self, tree: &ModuleTree) -> Option<LinkId> { |
226 | tree.module(self).parent | 220 | tree.mods[self].parent |
227 | } | 221 | } |
228 | fn parent(self, tree: &ModuleTree) -> Option<ModuleId> { | 222 | fn parent(self, tree: &ModuleTree) -> Option<ModuleId> { |
229 | let link = self.parent_link(tree)?; | 223 | let link = self.parent_link(tree)?; |
230 | Some(tree.link(link).owner) | 224 | Some(tree.links[link].owner) |
231 | } | 225 | } |
232 | fn crate_root(self, tree: &ModuleTree) -> ModuleId { | 226 | fn crate_root(self, tree: &ModuleTree) -> ModuleId { |
233 | generate(Some(self), move |it| it.parent(tree)) | 227 | generate(Some(self), move |it| it.parent(tree)) |
@@ -235,27 +229,26 @@ impl ModuleId { | |||
235 | .unwrap() | 229 | .unwrap() |
236 | } | 230 | } |
237 | fn child(self, tree: &ModuleTree, name: &str) -> Option<ModuleId> { | 231 | fn child(self, tree: &ModuleTree, name: &str) -> Option<ModuleId> { |
238 | let link = tree | 232 | let link = tree.mods[self] |
239 | .module(self) | ||
240 | .children | 233 | .children |
241 | .iter() | 234 | .iter() |
242 | .map(|&it| tree.link(it)) | 235 | .map(|&it| &tree.links[it]) |
243 | .find(|it| it.name == name)?; | 236 | .find(|it| it.name == name)?; |
244 | Some(*link.points_to.first()?) | 237 | Some(*link.points_to.first()?) |
245 | } | 238 | } |
246 | fn children<'a>(self, tree: &'a ModuleTree) -> impl Iterator<Item = (SmolStr, ModuleId)> + 'a { | 239 | fn children<'a>(self, tree: &'a ModuleTree) -> impl Iterator<Item = (SmolStr, ModuleId)> + 'a { |
247 | tree.module(self).children.iter().filter_map(move |&it| { | 240 | tree.mods[self].children.iter().filter_map(move |&it| { |
248 | let link = tree.link(it); | 241 | let link = &tree.links[it]; |
249 | let module = *link.points_to.first()?; | 242 | let module = *link.points_to.first()?; |
250 | Some((link.name.clone(), module)) | 243 | Some((link.name.clone(), module)) |
251 | }) | 244 | }) |
252 | } | 245 | } |
253 | fn problems(self, tree: &ModuleTree, db: &impl SyntaxDatabase) -> Vec<(SyntaxNode, Problem)> { | 246 | fn problems(self, tree: &ModuleTree, db: &impl SyntaxDatabase) -> Vec<(SyntaxNode, Problem)> { |
254 | tree.module(self) | 247 | tree.mods[self] |
255 | .children | 248 | .children |
256 | .iter() | 249 | .iter() |
257 | .filter_map(|&it| { | 250 | .filter_map(|&it| { |
258 | let p = tree.link(it).problem.clone()?; | 251 | let p = tree.links[it].problem.clone()?; |
259 | let s = it.bind_source(tree, db); | 252 | let s = it.bind_source(tree, db); |
260 | let s = s.borrowed().name().unwrap().syntax().owned(); | 253 | let s = s.borrowed().name().unwrap().syntax().owned(); |
261 | Some((s, p)) | 254 | Some((s, p)) |
@@ -266,17 +259,17 @@ impl ModuleId { | |||
266 | 259 | ||
267 | impl LinkId { | 260 | impl LinkId { |
268 | fn owner(self, tree: &ModuleTree) -> ModuleId { | 261 | fn owner(self, tree: &ModuleTree) -> ModuleId { |
269 | tree.link(self).owner | 262 | tree.links[self].owner |
270 | } | 263 | } |
271 | fn name(self, tree: &ModuleTree) -> SmolStr { | 264 | fn name(self, tree: &ModuleTree) -> SmolStr { |
272 | tree.link(self).name.clone() | 265 | tree.links[self].name.clone() |
273 | } | 266 | } |
274 | fn bind_source<'a>(self, tree: &ModuleTree, db: &impl SyntaxDatabase) -> ast::ModuleNode { | 267 | fn bind_source<'a>(self, tree: &ModuleTree, db: &impl SyntaxDatabase) -> ast::ModuleNode { |
275 | let owner = self.owner(tree); | 268 | let owner = self.owner(tree); |
276 | match owner.source(tree).resolve(db) { | 269 | match owner.source(tree).resolve(db) { |
277 | ModuleSourceNode::SourceFile(root) => { | 270 | ModuleSourceNode::SourceFile(root) => { |
278 | let ast = imp::modules(root.borrowed()) | 271 | let ast = imp::modules(root.borrowed()) |
279 | .find(|(name, _)| name == &tree.link(self).name) | 272 | .find(|(name, _)| name == &tree.links[self].name) |
280 | .unwrap() | 273 | .unwrap() |
281 | .1; | 274 | .1; |
282 | ast.owned() | 275 | ast.owned() |
@@ -287,7 +280,7 @@ impl LinkId { | |||
287 | } | 280 | } |
288 | 281 | ||
289 | #[derive(Debug, PartialEq, Eq, Hash)] | 282 | #[derive(Debug, PartialEq, Eq, Hash)] |
290 | struct ModuleData { | 283 | pub(crate) struct ModuleData { |
291 | source: ModuleSource, | 284 | source: ModuleSource, |
292 | parent: Option<LinkId>, | 285 | parent: Option<LinkId>, |
293 | children: Vec<LinkId>, | 286 | children: Vec<LinkId>, |
@@ -339,28 +332,13 @@ struct LinkData { | |||
339 | } | 332 | } |
340 | 333 | ||
341 | impl ModuleTree { | 334 | impl ModuleTree { |
342 | fn module(&self, id: ModuleId) -> &ModuleData { | ||
343 | &self.mods[id.0 as usize] | ||
344 | } | ||
345 | fn module_mut(&mut self, id: ModuleId) -> &mut ModuleData { | ||
346 | &mut self.mods[id.0 as usize] | ||
347 | } | ||
348 | fn link(&self, id: LinkId) -> &LinkData { | ||
349 | &self.links[id.0 as usize] | ||
350 | } | ||
351 | fn link_mut(&mut self, id: LinkId) -> &mut LinkData { | ||
352 | &mut self.links[id.0 as usize] | ||
353 | } | ||
354 | |||
355 | fn push_mod(&mut self, data: ModuleData) -> ModuleId { | 335 | fn push_mod(&mut self, data: ModuleData) -> ModuleId { |
356 | let id = ModuleId(self.mods.len() as u32); | 336 | self.mods.push(data) |
357 | self.mods.push(data); | ||
358 | id | ||
359 | } | 337 | } |
360 | fn push_link(&mut self, data: LinkData) -> LinkId { | 338 | fn push_link(&mut self, data: LinkData) -> LinkId { |
361 | let id = LinkId(self.links.len() as u32); | 339 | let owner = data.owner; |
362 | self.mods[data.owner.0 as usize].children.push(id); | 340 | let id = self.links.push(data); |
363 | self.links.push(data); | 341 | self.mods[owner].children.push(id); |
364 | id | 342 | id |
365 | } | 343 | } |
366 | } | 344 | } |