-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvisualizers.py
65 lines (51 loc) · 2.08 KB
/
visualizers.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
"""Graphviz visualizations of Program Graphs."""
import re
import pygraphviz
from python_graphs.program_graph import ProgramGraph
from python_graphs import program_graph_dataclasses as pb
def to_graphviz(graph: ProgramGraph, spans=False, relpos=False):
"""Creates a grapvhviz representation of a ProgramGraph.
Args:
graph: A ProgramGraph object to visualize.
Returns:
A pygraphviz object representing the ProgramGraph.
"""
SUB = str.maketrans("0123456789", "₀₁₂₃₄₅₆₇₈₉")
g = pygraphviz.AGraph(strict=False, directed=True)
for _, node in graph.nodes.items():
has_child = len([c for c in graph.children(node)])
node_attrs = {}
if node.ast_type:
node_attrs['label'] = str(node.ast_type)
if spans:
node_attrs['label'] = str(node.span)
if relpos:
relpos_str = str(node.relpos).translate(SUB)
node_attrs['label'] += relpos_str
# remove formatting for the render
node_attrs['label'] = re.sub('\s+', ' ', node_attrs['label'])
if has_child:
node_attrs['shape'] = 'box'
else:
node_attrs['shape'] = 'point'
node_type_colors = {}
if node.node_type in node_type_colors:
node_attrs['color'] = node_type_colors[node.node_type]
node_attrs['colorscheme'] = 'svg'
g.add_node(node.id, **node_attrs)
for edge in graph.edges:
edge_attrs = {}
# edge_attrs['label'] = edge.type
edge_colors = {
pb.EdgeType.LAST_READ: 'red',
pb.EdgeType.LAST_WRITE: 'blue',
pb.EdgeType.COMPUTED_FROM: 'green'
}
if edge.type in edge_colors:
edge_attrs['color'] = edge_colors[edge.type]
edge_attrs['colorscheme'] = 'svg'
g.add_edge(edge.id1, edge.id2, **edge_attrs)
return g
def render_sast(graph: ProgramGraph, path='/tmp/graph.png', spans=False, relpos=False):
g = to_graphviz(graph, spans, relpos)
g.draw(path, prog='dot')