Skip to content

Commit

Permalink
Give generate tree command its own indipendent implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
regexident committed Oct 8, 2023
1 parent 42d3022 commit 478fe29
Show file tree
Hide file tree
Showing 20 changed files with 726 additions and 718 deletions.
155 changes: 53 additions & 102 deletions src/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::path::Path;

use clap::Parser;
use log::{debug, trace};
use petgraph::stable_graph::NodeIndex;

use ra_ap_cfg::{CfgAtom, CfgDiff};
use ra_ap_hir::{self, Crate};
use ra_ap_ide::{AnalysisHost, RootDatabase};
Expand All @@ -22,25 +22,26 @@ use ra_ap_vfs::Vfs;

use crate::{
graph::{
builder::{Builder as GraphBuilder, Options as GraphBuilderOptions},
cycles::tri_color::{CycleDetector, TriColorDepthFirstSearch},
filter::{Filter as GraphFilter, Options as GraphFilterOptions},
Graph,
builder::Options as GraphBuilderOptions, command::Command as GenerateGraphCommand,
filter::Options as GraphFilterOptions, options::Options as GraphOptions,
printer::Options as GraphPrinterOptions,
},
options::{
general::Options as GeneralOptions, project::Options as ProjectOptions,
selection::Options as SelectionOptions,
},
target::{select_package, select_target},
tree::{
builder::Options as TreeBuilderOptions, command::Command as GenerateTreeCommand,
filter::Options as TreeFilterOptions, options::Options as TreeOptions,
printer::Options as TreePrinterOptions,
},
};

pub mod graph;
pub mod tree;

#[derive(Parser, Clone, PartialEq, Eq, Debug)]
pub enum Command {
#[command(name = "tree", about = "Print crate as a tree.")]
Tree(tree::Options),
Tree(TreeOptions),

#[command(
name = "graph",
Expand All @@ -50,7 +51,7 @@ pub enum Command {
`cargo modules generate dependencies | xdot -`
"#
)]
Graph(graph::Options),
Graph(GraphOptions),
}

impl Command {
Expand Down Expand Up @@ -96,49 +97,55 @@ impl Command {

let krate = self.find_crate(db, &vfs, &target)?;

let graph_builder = {
let builder_options = self.builder_options();
GraphBuilder::new(builder_options, db, &vfs, krate)
};

let graph_filter = {
let filter_options = self.filter_options();
GraphFilter::new(filter_options, db, krate)
};

trace!("Building graph ...");

let (graph, crate_node_idx) = graph_builder.build()?;

if self.filter_options().acyclic {
if let Some(cycle) =
TriColorDepthFirstSearch::new(&graph).run_from(crate_node_idx, &mut CycleDetector)
{
assert!(cycle.len() >= 2);
let first = graph[cycle[0]].display_path();
let last = graph[*cycle.last().unwrap()].display_path();
let drawing = draw_cycle(&graph, cycle);
anyhow::bail!("Circular dependency between `{first}` and `{last}`.\n\n{drawing}");
}
}

trace!("Filtering graph ...");

let graph = graph_filter.filter(&graph, crate_node_idx)?;

trace!("Generating output ...");

match self {
#[allow(unused_variables)]
Self::Tree(options) => {
let command = tree::Command::new(options.clone());
command.run(&graph, crate_node_idx, krate, db)?;
let builder_options = TreeBuilderOptions {
orphans: options.selection.orphans,
};
let filter_options = TreeFilterOptions {
focus_on: options.selection.focus_on.clone(),
max_depth: options.selection.max_depth,
acyclic: false,
modules: true,
types: options.selection.types,
traits: options.selection.traits,
fns: options.selection.fns,
tests: options.selection.tests,
uses: false,
externs: false,
};
let printer_options = TreePrinterOptions {};

let command =
GenerateTreeCommand::new(builder_options, filter_options, printer_options);
command.run(krate, db, &vfs)?;
Ok(())
}
#[allow(unused_variables)]
Self::Graph(options) => {
let command = graph::Command::new(options.clone());
command.run(&graph, crate_node_idx, krate, db)?;
let builder_options = GraphBuilderOptions {
orphans: options.selection.orphans,
};
let filter_options = GraphFilterOptions {
focus_on: options.selection.focus_on.clone(),
max_depth: options.selection.max_depth,
acyclic: options.acyclic,
types: options.selection.types,
traits: options.selection.traits,
fns: options.selection.fns,
tests: options.selection.tests,
modules: options.modules,
uses: options.uses,
externs: options.externs,
};
let printer_options = GraphPrinterOptions {
layout: options.layout,
full_paths: options.externs,
};
let command =
GenerateGraphCommand::new(builder_options, filter_options, printer_options);
command.run(krate, db, &vfs)?;
Ok(())
}
}
Expand Down Expand Up @@ -351,60 +358,4 @@ impl Command {
Self::Graph(options) => &mut options.selection,
}
}

fn builder_options(&self) -> GraphBuilderOptions {
match self {
Self::Tree(options) => GraphBuilderOptions {
orphans: options.selection.orphans,
},
Self::Graph(options) => GraphBuilderOptions {
orphans: options.selection.orphans,
},
}
}

fn filter_options(&self) -> GraphFilterOptions {
match self {
Self::Tree(options) => GraphFilterOptions {
focus_on: options.selection.focus_on.clone(),
max_depth: options.selection.max_depth,
acyclic: false,
modules: true,
types: options.selection.types,
traits: options.selection.traits,
fns: options.selection.fns,
tests: options.selection.tests,
uses: false,
externs: false,
},
Self::Graph(options) => GraphFilterOptions {
focus_on: options.selection.focus_on.clone(),
max_depth: options.selection.max_depth,
acyclic: options.acyclic,
types: options.selection.types,
traits: options.selection.traits,
fns: options.selection.fns,
tests: options.selection.tests,
modules: options.modules,
uses: options.uses,
externs: options.externs,
},
}
}
}

fn draw_cycle(graph: &Graph, cycle: Vec<NodeIndex>) -> String {
assert!(!cycle.is_empty());

let first = graph[cycle[0]].display_path();
let mut drawing = format!("┌> {first}\n");

for (i, node) in cycle[1..].iter().enumerate() {
let path = graph[*node].display_path();
drawing += &format!("│ {:>width$}└─> {path}\n", "", width = i * 4);
}

drawing += &format!("└──{:─>width$}┘", "", width = (cycle.len() - 1) * 4);

drawing
}
2 changes: 1 addition & 1 deletion src/generate/tree.rs → src/generate/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub use crate::options::generate::tree::Options;

use crate::{
graph::Graph,
printer::tree::{Options as PrinterOptions, Printer},
printer::printer::{Options as PrinterOptions, Printer},
};

pub struct Command {
Expand Down
69 changes: 0 additions & 69 deletions src/generate/graph.rs

This file was deleted.

3 changes: 3 additions & 0 deletions src/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@
use petgraph::stable_graph::{NodeIndex, StableGraph};

pub(crate) mod builder;
pub(crate) mod command;
pub(super) mod cycles;
pub(crate) mod edge;
pub(super) mod filter;
pub(crate) mod node;
pub(crate) mod options;
pub(super) mod orphans;
pub(super) mod printer;
pub(crate) mod util;
pub(super) mod walker;

Expand Down
13 changes: 3 additions & 10 deletions src/graph/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use std::{
collections::HashMap,
path::{Path, PathBuf},
};
use std::collections::HashMap;

use log::trace;
use petgraph::graph::{EdgeIndex, NodeIndex};
use ra_ap_hir::{self as hir, Crate, ModuleSource};
use ra_ap_hir::{self as hir, Crate};
use ra_ap_ide_db::RootDatabase;
use ra_ap_vfs::Vfs;

Expand All @@ -19,11 +16,7 @@ use crate::{
node::Node,
util, Graph,
},
item::{
attr::{ItemAttrs, ItemCfgAttr, ItemTestAttr},
visibility::ItemVisibility,
Item,
},
item::Item,
};

use super::orphans::add_orphan_nodes_to;
Expand Down
Loading

0 comments on commit 478fe29

Please sign in to comment.