]>
Commit | Line | Data |
---|---|---|
5099ac24 FG |
1 | //! Implementation of GraphWalk for DropRanges so we can visualize the control |
2 | //! flow graph when needed for debugging. | |
3 | ||
4 | use rustc_graphviz as dot; | |
5 | ||
6 | use super::{DropRangesBuilder, PostOrderId}; | |
7 | ||
8 | /// Writes the CFG for DropRangesBuilder to a .dot file for visualization. | |
9 | /// | |
10 | /// It is not normally called, but is kept around to easily add debugging | |
11 | /// code when needed. | |
12 | #[allow(dead_code)] | |
13 | pub(super) fn write_graph_to_file(drop_ranges: &DropRangesBuilder, filename: &str) { | |
14 | dot::render(drop_ranges, &mut std::fs::File::create(filename).unwrap()).unwrap(); | |
15 | } | |
16 | ||
17 | impl<'a> dot::GraphWalk<'a> for DropRangesBuilder { | |
18 | type Node = PostOrderId; | |
19 | ||
20 | type Edge = (PostOrderId, PostOrderId); | |
21 | ||
22 | fn nodes(&'a self) -> dot::Nodes<'a, Self::Node> { | |
23 | self.nodes.iter_enumerated().map(|(i, _)| i).collect() | |
24 | } | |
25 | ||
26 | fn edges(&'a self) -> dot::Edges<'a, Self::Edge> { | |
27 | self.nodes | |
28 | .iter_enumerated() | |
29 | .flat_map(|(i, node)| { | |
30 | if node.successors.len() == 0 { | |
31 | vec![(i, i + 1)] | |
32 | } else { | |
33 | node.successors.iter().map(move |&s| (i, s)).collect() | |
34 | } | |
35 | }) | |
36 | .collect() | |
37 | } | |
38 | ||
39 | fn source(&'a self, edge: &Self::Edge) -> Self::Node { | |
40 | edge.0 | |
41 | } | |
42 | ||
43 | fn target(&'a self, edge: &Self::Edge) -> Self::Node { | |
44 | edge.1 | |
45 | } | |
46 | } | |
47 | ||
48 | impl<'a> dot::Labeller<'a> for DropRangesBuilder { | |
49 | type Node = PostOrderId; | |
50 | ||
51 | type Edge = (PostOrderId, PostOrderId); | |
52 | ||
53 | fn graph_id(&'a self) -> dot::Id<'a> { | |
54 | dot::Id::new("drop_ranges").unwrap() | |
55 | } | |
56 | ||
57 | fn node_id(&'a self, n: &Self::Node) -> dot::Id<'a> { | |
58 | dot::Id::new(format!("id{}", n.index())).unwrap() | |
59 | } | |
60 | ||
61 | fn node_label(&'a self, n: &Self::Node) -> dot::LabelText<'a> { | |
62 | dot::LabelText::LabelStr( | |
63 | format!( | |
64 | "{:?}, local_id: {}", | |
65 | n, | |
66 | self.post_order_map | |
67 | .iter() | |
68 | .find(|(_hir_id, &post_order_id)| post_order_id == *n) | |
69 | .map_or("<unknown>".into(), |(hir_id, _)| format!( | |
70 | "{}", | |
71 | hir_id.local_id.index() | |
72 | )) | |
73 | ) | |
74 | .into(), | |
75 | ) | |
76 | } | |
77 | } |