From e22b6edae5787039dc0b85112702bb8d16a2aa60 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 23 Jan 2019 18:09:45 +0300 Subject: refactor --- crates/ra_hir/src/module_tree.rs | 179 ++++++++++++++++++--------------------- 1 file changed, 81 insertions(+), 98 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/module_tree.rs b/crates/ra_hir/src/module_tree.rs index dd3aa6d73..b201bf69b 100644 --- a/crates/ra_hir/src/module_tree.rs +++ b/crates/ra_hir/src/module_tree.rs @@ -131,7 +131,8 @@ impl ModuleTree { source_root: SourceRootId, ) -> Arc { db.check_canceled(); - let res = create_module_tree(db, source_root); + let mut res = ModuleTree::default(); + res.init(db, source_root); Arc::new(res) } @@ -144,6 +145,85 @@ impl ModuleTree { Some(res) } + fn init(&mut self, db: &impl HirDatabase, source_root: SourceRootId) { + let mut roots = FxHashMap::default(); + let mut visited = FxHashSet::default(); + + let source_root = db.source_root(source_root); + for &file_id in source_root.files.values() { + let source = SourceItemId { + file_id: file_id.into(), + item_id: None, + }; + if visited.contains(&source) { + continue; // TODO: use explicit crate_roots here + } + assert!(!roots.contains_key(&file_id)); + let module_id = + self.init_subtree(db, &source_root, &mut visited, &mut roots, None, source); + roots.insert(file_id, module_id); + } + } + + fn init_subtree( + &mut self, + db: &impl HirDatabase, + source_root: &SourceRoot, + visited: &mut FxHashSet, + roots: &mut FxHashMap, + parent: Option, + source: SourceItemId, + ) -> ModuleId { + visited.insert(source); + let id = self.alloc_mod(ModuleData { + source, + parent, + children: Vec::new(), + }); + for sub in db.submodules(source).iter() { + let link = self.alloc_link(LinkData { + source: sub.source, + name: sub.name.clone(), + owner: id, + points_to: Vec::new(), + problem: None, + }); + + let (points_to, problem) = if sub.is_declaration { + let (points_to, problem) = resolve_submodule(db, source.file_id, &sub.name); + let points_to = points_to + .into_iter() + .map(|file_id| match roots.remove(&file_id) { + Some(module_id) => { + self.mods[module_id].parent = Some(link); + module_id + } + None => self.init_subtree( + db, + source_root, + visited, + roots, + Some(link), + SourceItemId { + file_id: file_id.into(), + item_id: None, + }, + ), + }) + .collect::>(); + (points_to, problem) + } else { + let points_to = + self.init_subtree(db, source_root, visited, roots, Some(link), sub.source); + (vec![points_to], None) + }; + + self.links[link].points_to = points_to; + self.links[link].problem = problem; + } + id + } + fn alloc_mod(&mut self, data: ModuleData) -> ModuleId { self.mods.alloc(data) } @@ -221,103 +301,6 @@ impl LinkId { } } -fn create_module_tree<'a>(db: &impl HirDatabase, source_root: SourceRootId) -> ModuleTree { - let mut tree = ModuleTree::default(); - - let mut roots = FxHashMap::default(); - let mut visited = FxHashSet::default(); - - let source_root = db.source_root(source_root); - for &file_id in source_root.files.values() { - let source = SourceItemId { - file_id: file_id.into(), - item_id: None, - }; - if visited.contains(&source) { - continue; // TODO: use explicit crate_roots here - } - assert!(!roots.contains_key(&file_id)); - let module_id = build_subtree( - db, - &source_root, - &mut tree, - &mut visited, - &mut roots, - None, - source, - ); - roots.insert(file_id, module_id); - } - tree -} - -fn build_subtree( - db: &impl HirDatabase, - source_root: &SourceRoot, - tree: &mut ModuleTree, - visited: &mut FxHashSet, - roots: &mut FxHashMap, - parent: Option, - source: SourceItemId, -) -> ModuleId { - visited.insert(source); - let id = tree.alloc_mod(ModuleData { - source, - parent, - children: Vec::new(), - }); - for sub in db.submodules(source).iter() { - let link = tree.alloc_link(LinkData { - source: sub.source, - name: sub.name.clone(), - owner: id, - points_to: Vec::new(), - problem: None, - }); - - let (points_to, problem) = if sub.is_declaration { - let (points_to, problem) = resolve_submodule(db, source.file_id, &sub.name); - let points_to = points_to - .into_iter() - .map(|file_id| match roots.remove(&file_id) { - Some(module_id) => { - tree.mods[module_id].parent = Some(link); - module_id - } - None => build_subtree( - db, - source_root, - tree, - visited, - roots, - Some(link), - SourceItemId { - file_id: file_id.into(), - item_id: None, - }, - ), - }) - .collect::>(); - (points_to, problem) - } else { - let points_to = build_subtree( - db, - source_root, - tree, - visited, - roots, - Some(link), - sub.source, - ); - (vec![points_to], None) - }; - - tree.links[link].points_to = points_to; - tree.links[link].problem = problem; - } - id -} - fn resolve_submodule( db: &impl HirDatabase, file_id: HirFileId, -- cgit v1.2.3