pep8analysis: print CFG as dot graph to OStream
[nit.git] / contrib / pep8analysis / src / cfg / dot_printer.nit
1 import cfg_base
2
3 redef class CFG
4 fun print_dot( f: OStream, long: Bool )
5 do
6 f.write("digraph \{\n")
7 f.write("charset=latin1\n")
8 f.write("node [shape=box,style=rounded,fontname=courier]\n")
9 for block in blocks do block.print_dot_nodes(f, long)
10 for block in blocks do block.print_dot_edges(f, long)
11 f.write("\}")
12 end
13 end
14
15 redef class BasicBlock
16 fun print_dot_nodes( f: OStream, long: Bool )
17 do
18 var lbl
19 if long then
20 lbl = "\"{name}:\\n{dot_node_text}\""
21 else
22 lbl = name
23 end
24 f.write( "{name} [label={lbl}]\n" )
25 end
26
27 fun dot_node_text : String
28 do
29 var code_lines = new Array[String]
30 for line in lines do code_lines.add(line.text)
31 var code = code_lines.join("")
32
33 code = code.replace("\n","\\l").replace("\"","\\\"").replace("\\n","|n").replace("/","\\/").replace("\r","")
34 # the last one is a hack
35 return "{dot_node_header}{code}{dot_node_footer}"
36 end
37
38 fun dot_node_header: String do return ""
39 fun dot_node_footer: String do return ""
40
41 fun print_dot_edges( f: OStream, long: Bool )
42 do
43 for s in successors do
44 f.write( "{name} -> {s.name}\n" )
45 end
46 var n = after_call
47 if n != null then
48 f.write( "{name} -> {n.name} [style=\"dashed\"]\n" )
49 end
50 end
51 end