@@ -7,23 +7,36 @@ use std::{
77
88use dot:: Id ;
99use ide_db:: {
10- base_db:: { CrateGraph , CrateId , Dependency , SourceDatabase } ,
10+ base_db:: { CrateGraph , CrateId , Dependency , SourceDatabase , SourceDatabaseExt } ,
1111 RootDatabase ,
1212} ;
13+ use rustc_hash:: FxHashSet ;
1314
1415// Feature: View Crate Graph
1516//
1617// Renders the currently loaded crate graph as an SVG graphic. Requires the `dot` tool, which
1718// is part of graphviz, to be installed.
1819//
20+ // Only workspace crates are included, no crates.io dependencies or sysroot crates.
21+ //
1922// |===
2023// | Editor | Action Name
2124//
2225// | VS Code | **Rust Analyzer: View Crate Graph**
2326// |===
2427pub ( crate ) fn view_crate_graph ( db : & RootDatabase ) -> Result < String , String > {
28+ let crate_graph = db. crate_graph ( ) ;
29+ let crates_to_render = crate_graph
30+ . iter ( )
31+ . filter ( |krate| {
32+ // Only render workspace crates
33+ let root_id = db. file_source_root ( crate_graph[ * krate] . root_file_id ) ;
34+ !db. source_root ( root_id) . is_library
35+ } )
36+ . collect ( ) ;
37+ let graph = DotCrateGraph { graph : crate_graph, crates_to_render } ;
38+
2539 let mut dot = Vec :: new ( ) ;
26- let graph = DotCrateGraph ( db. crate_graph ( ) ) ;
2740 dot:: render ( & graph, & mut dot) . unwrap ( ) ;
2841
2942 render_svg ( & dot) . map_err ( |e| e. to_string ( ) )
@@ -36,27 +49,36 @@ fn render_svg(dot: &[u8]) -> Result<String, Box<dyn Error>> {
3649 . stdin ( Stdio :: piped ( ) )
3750 . stdout ( Stdio :: piped ( ) )
3851 . spawn ( )
39- . map_err ( |err| format ! ( "failed to spawn `dot -Tsvg `: {}" , err) ) ?;
52+ . map_err ( |err| format ! ( "failed to spawn `dot`: {}" , err) ) ?;
4053 child. stdin . unwrap ( ) . write_all ( & dot) ?;
4154
4255 let mut svg = String :: new ( ) ;
4356 child. stdout . unwrap ( ) . read_to_string ( & mut svg) ?;
4457 Ok ( svg)
4558}
4659
47- struct DotCrateGraph ( Arc < CrateGraph > ) ;
60+ struct DotCrateGraph {
61+ graph : Arc < CrateGraph > ,
62+ crates_to_render : FxHashSet < CrateId > ,
63+ }
4864
4965type Edge < ' a > = ( CrateId , & ' a Dependency ) ;
5066
5167impl < ' a > dot:: GraphWalk < ' a , CrateId , Edge < ' a > > for DotCrateGraph {
5268 fn nodes ( & ' a self ) -> dot:: Nodes < ' a , CrateId > {
53- self . 0 . iter ( ) . collect ( )
69+ self . crates_to_render . iter ( ) . copied ( ) . collect ( )
5470 }
5571
5672 fn edges ( & ' a self ) -> dot:: Edges < ' a , Edge < ' a > > {
57- self . 0
73+ self . crates_to_render
5874 . iter ( )
59- . flat_map ( |krate| self . 0 [ krate] . dependencies . iter ( ) . map ( move |dep| ( krate, dep) ) )
75+ . flat_map ( |krate| {
76+ self . graph [ * krate]
77+ . dependencies
78+ . iter ( )
79+ . filter ( |dep| self . crates_to_render . contains ( & dep. crate_id ) )
80+ . map ( move |dep| ( * krate, dep) )
81+ } )
6082 . collect ( )
6183 }
6284
@@ -75,7 +97,7 @@ impl<'a> dot::Labeller<'a, CrateId, Edge<'a>> for DotCrateGraph {
7597 }
7698
7799 fn node_id ( & ' a self , n : & CrateId ) -> Id < ' a > {
78- let name = self . 0 [ * n] . display_name . as_ref ( ) . map_or ( "_missing_name_" , |name| & * name) ;
100+ let name = self . graph [ * n] . display_name . as_ref ( ) . map_or ( "_missing_name_" , |name| & * name) ;
79101 Id :: new ( format ! ( "{}_{}" , name, n. 0 ) ) . unwrap ( )
80102 }
81103}
0 commit comments