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/module | |
parent | 8f5fb8341314e94b1d91afa50ca895f78180f948 (diff) |
Codify Arena pattern
Diffstat (limited to 'crates/ra_analysis/src/descriptors/module')
-rw-r--r-- | crates/ra_analysis/src/descriptors/module/imp.rs | 11 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/module/mod.rs | 76 |
2 files changed, 31 insertions, 56 deletions
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 | } |