aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src/descriptors/module
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-11-25 16:02:14 +0000
committerAleksey Kladov <[email protected]>2018-11-25 16:02:14 +0000
commitb6fcd462781826795e6ab32a69cd332496b537c2 (patch)
treebb44eaedf546e20a8b29b9b421fb0c3accc1ce74 /crates/ra_analysis/src/descriptors/module
parent8f5fb8341314e94b1d91afa50ca895f78180f948 (diff)
Codify Arena pattern
Diffstat (limited to 'crates/ra_analysis/src/descriptors/module')
-rw-r--r--crates/ra_analysis/src/descriptors/module/imp.rs11
-rw-r--r--crates/ra_analysis/src/descriptors/module/mod.rs76
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;
15use crate::{ 15use 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
21pub(crate) use self::nameres::ModuleScope; 22pub(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)]
161pub(crate) struct ModuleTree { 162pub(crate) struct ModuleTree {
162 mods: Vec<ModuleData>, 163 mods: Arena<ModuleData>,
163 links: Vec<LinkData>, 164 links: Arena<LinkData>,
164} 165}
165 166
166impl ModuleTree { 167impl 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)] 201pub(crate) type ModuleId = Id<ModuleData>;
205pub(crate) struct ModuleId(u32); 202type LinkId = Id<LinkData>;
206
207#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
208struct LinkId(u32);
209 203
210#[derive(Clone, Debug, Hash, PartialEq, Eq)] 204#[derive(Clone, Debug, Hash, PartialEq, Eq)]
211pub enum Problem { 205pub enum Problem {
@@ -220,14 +214,14 @@ pub enum Problem {
220 214
221impl ModuleId { 215impl 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
267impl LinkId { 260impl 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)]
290struct ModuleData { 283pub(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
341impl ModuleTree { 334impl 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}