Skip to content

Commit

Permalink
Simplify recursive tree data structure used by structure command
Browse files Browse the repository at this point in the history
  • Loading branch information
regexident committed Dec 13, 2023
1 parent 7b6b9ea commit 53165d3
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 116 deletions.
57 changes: 26 additions & 31 deletions src/structure/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@ use scopeguard::defer;

use crate::{
item::Item,
structure::{
options::Options,
tree::{Node, Tree},
},
structure::{options::Options, tree::Tree},
};

#[derive(Debug)]
Expand Down Expand Up @@ -52,12 +49,10 @@ impl<'a> Builder<'a> {

let module = crate_hir.root_module();

let root_node = self.process_module(module);

root_node.map(Tree::new)
self.process_module(module)
}

fn process_impl(&mut self, impl_hir: hir::Impl) -> Vec<Node> {
fn process_impl(&mut self, impl_hir: hir::Impl) -> Vec<Tree> {
impl_hir
.items(self.db)
.into_iter()
Expand All @@ -71,7 +66,7 @@ impl<'a> Builder<'a> {
.collect()
}

fn process_moduledef(&mut self, module_def_hir: hir::ModuleDef) -> Option<Node> {
fn process_moduledef(&mut self, module_def_hir: hir::ModuleDef) -> Option<Tree> {
trace!("Processing moduledef {module_def_hir:?}...");

defer! {
Expand All @@ -97,29 +92,29 @@ impl<'a> Builder<'a> {
}
}

fn process_module(&mut self, module_hir: hir::Module) -> Option<Node> {
fn process_module(&mut self, module_hir: hir::Module) -> Option<Tree> {
trace!("Processing module {module_hir:?}...");

defer! {
trace!("Finished processing module {module_hir:?}.");
}

let item = Item::new(ModuleDef::Module(module_hir));
let mut node = Node::new(item, vec![]);
let mut node = Tree::new(item, vec![]);

let subnodes = module_hir
let subtrees = module_hir
.declarations(self.db)
.into_iter()
.filter_map(|module_def_hir| self.process_moduledef(module_def_hir));

for subnode in subnodes {
node.push_subnode(subnode);
for subtree in subtrees {
node.push_subtree(subtree);
}

Some(node)
}

fn process_function(&mut self, function_hir: hir::Function) -> Option<Node> {
fn process_function(&mut self, function_hir: hir::Function) -> Option<Tree> {
trace!("Processing function {function_hir:?}...");

defer! {
Expand All @@ -129,7 +124,7 @@ impl<'a> Builder<'a> {
self.simple_node(hir::ModuleDef::Function(function_hir))
}

fn process_adt(&mut self, adt_hir: hir::Adt) -> Option<Node> {
fn process_adt(&mut self, adt_hir: hir::Adt) -> Option<Tree> {
trace!("Processing adt {adt_hir:?}...");

defer! {
Expand All @@ -144,16 +139,16 @@ impl<'a> Builder<'a> {

if let Some(node) = node.as_mut() {
for impl_hir in hir::Impl::all_for_type(self.db, adt_hir.ty(self.db)) {
for subnode in self.process_impl(impl_hir) {
node.push_subnode(subnode);
for subtree in self.process_impl(impl_hir) {
node.push_subtree(subtree);
}
}
}

node
}

fn process_struct(&mut self, struct_hir: hir::Struct) -> Option<Node> {
fn process_struct(&mut self, struct_hir: hir::Struct) -> Option<Tree> {
trace!("Processing struct {struct_hir:?}...");

defer! {
Expand All @@ -163,7 +158,7 @@ impl<'a> Builder<'a> {
self.simple_node(hir::ModuleDef::Adt(hir::Adt::Struct(struct_hir)))
}

fn process_enum(&mut self, enum_hir: hir::Enum) -> Option<Node> {
fn process_enum(&mut self, enum_hir: hir::Enum) -> Option<Tree> {
trace!("Processing enum {enum_hir:?}...");

defer! {
Expand All @@ -173,7 +168,7 @@ impl<'a> Builder<'a> {
self.simple_node(hir::ModuleDef::Adt(hir::Adt::Enum(enum_hir)))
}

fn process_union(&mut self, union_hir: hir::Union) -> Option<Node> {
fn process_union(&mut self, union_hir: hir::Union) -> Option<Tree> {
trace!("Processing union {union_hir:?}...");

defer! {
Expand All @@ -183,7 +178,7 @@ impl<'a> Builder<'a> {
self.simple_node(hir::ModuleDef::Adt(hir::Adt::Union(union_hir)))
}

fn process_variant(&mut self, variant_hir: hir::Variant) -> Option<Node> {
fn process_variant(&mut self, variant_hir: hir::Variant) -> Option<Tree> {
trace!("Processing variant {variant_hir:?}...");

defer! {
Expand All @@ -193,7 +188,7 @@ impl<'a> Builder<'a> {
None
}

fn process_const(&mut self, const_hir: hir::Const) -> Option<Node> {
fn process_const(&mut self, const_hir: hir::Const) -> Option<Tree> {
trace!("Processing const {const_hir:?}...");

defer! {
Expand All @@ -203,7 +198,7 @@ impl<'a> Builder<'a> {
None
}

fn process_static(&mut self, static_hir: hir::Static) -> Option<Node> {
fn process_static(&mut self, static_hir: hir::Static) -> Option<Tree> {
trace!("Processing static {static_hir:?}...");

defer! {
Expand All @@ -213,7 +208,7 @@ impl<'a> Builder<'a> {
self.simple_node(hir::ModuleDef::Static(static_hir))
}

fn process_trait(&mut self, trait_hir: hir::Trait) -> Option<Node> {
fn process_trait(&mut self, trait_hir: hir::Trait) -> Option<Tree> {
trace!("Processing trait {trait_hir:?}...");

defer! {
Expand All @@ -223,7 +218,7 @@ impl<'a> Builder<'a> {
self.simple_node(hir::ModuleDef::Trait(trait_hir))
}

fn process_trait_alias(&mut self, trait_alias_hir: hir::TraitAlias) -> Option<Node> {
fn process_trait_alias(&mut self, trait_alias_hir: hir::TraitAlias) -> Option<Tree> {
trace!("Processing trait alias {trait_alias_hir:?}...");

defer! {
Expand All @@ -233,7 +228,7 @@ impl<'a> Builder<'a> {
self.simple_node(hir::ModuleDef::TraitAlias(trait_alias_hir))
}

fn process_type_alias(&mut self, type_alias_hir: hir::TypeAlias) -> Option<Node> {
fn process_type_alias(&mut self, type_alias_hir: hir::TypeAlias) -> Option<Tree> {
trace!("Processing type alias {type_alias_hir:?}...");

defer! {
Expand All @@ -243,7 +238,7 @@ impl<'a> Builder<'a> {
self.simple_node(hir::ModuleDef::TypeAlias(type_alias_hir))
}

fn process_builtin_type(&mut self, builtin_type_hir: hir::BuiltinType) -> Option<Node> {
fn process_builtin_type(&mut self, builtin_type_hir: hir::BuiltinType) -> Option<Tree> {
trace!("Processing builtin type {builtin_type_hir:?}...");

defer! {
Expand All @@ -253,7 +248,7 @@ impl<'a> Builder<'a> {
self.simple_node(hir::ModuleDef::BuiltinType(builtin_type_hir))
}

fn process_macro(&mut self, macro_hir: hir::Macro) -> Option<Node> {
fn process_macro(&mut self, macro_hir: hir::Macro) -> Option<Tree> {
trace!("Processing macro {macro_hir:?}...");

defer! {
Expand All @@ -263,8 +258,8 @@ impl<'a> Builder<'a> {
None
}

fn simple_node(&mut self, module_def_hir: hir::ModuleDef) -> Option<Node> {
fn simple_node(&mut self, module_def_hir: hir::ModuleDef) -> Option<Tree> {
let item = Item::new(module_def_hir);
Some(Node::new(item, vec![]))
Some(Tree::new(item, vec![]))
}
}
65 changes: 30 additions & 35 deletions src/structure/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ use ra_ap_syntax::ast;

use crate::{
analyzer,
structure::{
options::Options,
tree::{Node, Tree},
},
structure::{options::Options, tree::Tree},
};

#[derive(Debug)]
Expand Down Expand Up @@ -39,49 +36,47 @@ impl<'a> Filter<'a> {

let max_depth = self.options.max_depth.unwrap_or(usize::MAX);

let root_node = self
.filter_node(&tree.root_node, None, max_depth, &use_tree)
.expect("root node");

let tree = Tree::new(root_node);
let tree = self
.filter_tree(tree, None, max_depth, &use_tree)
.expect("root tree");

Ok(tree)
}

fn filter_node(
fn filter_tree(
&self,
node: &Node,
tree: &Tree,
depth: Option<usize>,
max_depth: usize,
focus_tree: &ast::UseTree,
) -> Option<Node> {
let path = node.item.display_path(self.db);
) -> Option<Tree> {
let path = tree.item.display_path(self.db);

let is_focus_node = analyzer::use_tree_matches_item_path(focus_tree, &path);
let is_focus_tree = analyzer::use_tree_matches_item_path(focus_tree, &path);

let depth = if is_focus_node { Some(0) } else { depth };
let depth = if is_focus_tree { Some(0) } else { depth };

let should_be_retained = self.should_retain_moduledef(node.item.hir);
let should_be_retained = self.should_retain_moduledef(tree.item.hir);

let subnode_contains_focus_node = node
.subnodes
let subtree_contains_focus_tree = tree
.subtrees
.iter()
.map(|node| self.is_or_contains_focus_node(node, focus_tree));
.map(|tree| self.is_or_contains_focus_tree(tree, focus_tree));

let is_or_contains_focus_node =
is_focus_node || subnode_contains_focus_node.clone().any(|flag| flag);
let is_or_contains_focus_tree =
is_focus_tree || subtree_contains_focus_tree.clone().any(|flag| flag);

let subnodes: Vec<Node> = node
.subnodes
let subtrees: Vec<Tree> = tree
.subtrees
.iter()
.zip(subnode_contains_focus_node)
.filter_map(|(node, is_or_contains_focus_node)| {
let depth = if is_or_contains_focus_node {
.zip(subtree_contains_focus_tree)
.filter_map(|(tree, is_or_contains_focus_tree)| {
let depth = if is_or_contains_focus_tree {
Some(0)
} else {
depth.map(|depth| depth + 1)
};
self.filter_node(node, depth, max_depth, focus_tree)
self.filter_tree(tree, depth, max_depth, focus_tree)
})
.collect();

Expand All @@ -93,26 +88,26 @@ impl<'a> Filter<'a> {
if depth > max_depth {
return None;
}
} else if !is_or_contains_focus_node {
} else if !is_or_contains_focus_tree {
return None;
}

let item = node.item.clone();
let node = Node::new(item, subnodes);
let item = tree.item.clone();
let tree = Tree::new(item, subtrees);

Some(node)
Some(tree)
}

fn is_or_contains_focus_node(&self, node: &Node, focus_tree: &ast::UseTree) -> bool {
let path = node.item.display_path(self.db);
fn is_or_contains_focus_tree(&self, tree: &Tree, focus_tree: &ast::UseTree) -> bool {
let path = tree.item.display_path(self.db);

if analyzer::use_tree_matches_item_path(focus_tree, &path) {
return true;
}

node.subnodes
tree.subtrees
.iter()
.any(|node| self.is_or_contains_focus_node(node, focus_tree))
.any(|tree| self.is_or_contains_focus_tree(tree, focus_tree))
}

fn should_retain_moduledef(&self, module_def_hir: hir::ModuleDef) -> bool {
Expand Down
Loading

0 comments on commit 53165d3

Please sign in to comment.