@@ -33,6 +33,42 @@ public class DotExporter {
3333 public static final boolean DUMP_DOTS = DOTS_FOLDER != null && !DOTS_FOLDER .trim ().isEmpty ();
3434 public static final boolean DUMP_ERROR_DOTS = DOTS_ERROR_FOLDER != null && !DOTS_ERROR_FOLDER .trim ().isEmpty ();
3535
36+ private static final boolean DARK_MODE = false ;
37+ private static final String THEME_HEADER = DARK_MODE ?
38+ """
39+ bgcolor="#181818";
40+
41+ node [
42+ fontcolor = "#e6e6e6",
43+ style = filled,
44+ color = "#e6e6e6",
45+ fillcolor = "#333333"
46+ ]
47+
48+ edge [
49+ color = "#e6e6e6",
50+ fontcolor = "#e6e6e6"
51+ ]
52+ """ : "" ;
53+ public static final String BG_DOM_ERROR = DARK_MODE ? "coral1" : "coral4" ;
54+ public static final String BG_DOM_INFO = DARK_MODE ? "navy" : "lightblue" ;
55+ public static final String BG_DOM_NEWSTAT = DARK_MODE ? "seagreen" : "lawngreen" ;
56+ public static final String BG_DOM_NEWSTAT_CHILDREN = DARK_MODE ? "red4" : "pink" ;
57+ public static final String BG_DOM_OLDSTAT = DARK_MODE ? "orange4" : "orange" ;
58+ public static final String BG_DOM_SUCCESS = DARK_MODE ? "seagreen" : "lawngreen" ;
59+ public static final String BG_DOM_WARN = DARK_MODE ? "tan1" : "tan4" ;
60+ private static final String BG_VAR_CATCH = DARK_MODE ? "goldrod" : "gold" ;
61+ private static final String BG_VAR_DEAD_READ = "gray59" ;
62+ private static final String BG_VAR_PARAM = DARK_MODE ? "skyblue4" : "skyblue1" ;
63+ private static final String BG_VAR_WRITE = DARK_MODE ? "palegreen4" : "palegreen1" ;
64+ private static final String FG_BLACK = DARK_MODE ? "white" : "black" ;
65+ private static final String FG_BLUE = DARK_MODE ? "cyan" : "blue" ;
66+ private static final String FG_GREEN = DARK_MODE ? "limegreen" : "green" ;
67+ private static final String FG_ORANGE = "orange" ;
68+ private static final String FG_PINK = DARK_MODE ? "lightpink" : "pink" ;
69+ private static final String FG_PURPLE = DARK_MODE ? "plum" : "purple" ;
70+ private static final String FG_RED = DARK_MODE ? "\" #ff6666\" " : "red" ;
71+
3672 private static final boolean EXTENDED_MODE = false ;
3773 private static final boolean STATEMENT_LR_MODE = false ;
3874 private static final boolean SAME_RANK_MODE = false ;
@@ -65,6 +101,7 @@ private static String statToDot(Statement stat, String name, Map<Statement, Stri
65101 Set <Integer > referenced = new HashSet <>();
66102
67103 buffer .append ("digraph " + name + " {\r \n " );
104+ buffer .append (THEME_HEADER );
68105
69106 if (STATEMENT_LR_MODE ) {
70107 buffer .append (" rankdir = LR;\r \n " );
@@ -77,8 +114,8 @@ private static String statToDot(Statement stat, String name, Map<Statement, Stri
77114 DummyExitStatement exit = null ;
78115 if (stat instanceof RootStatement ) {
79116 exit = ((RootStatement )stat ).getDummyExit ();
117+ stats .add (exit );
80118 }
81- stats .add (exit );
82119
83120 // Pre process
84121 Map <StatEdge , String > extraData = new HashMap <>();
@@ -166,14 +203,14 @@ private static String statToDot(Statement stat, String name, Map<Statement, Stri
166203 if (labelEdge .explicit ) {
167204 data += "Explicit" ;
168205 }
169- buffer .append (src + "->" + destId + " [color=orange ,label=\" Label Edge (" + data + ") (Contained by " + st .id + ")\" ];\r \n " );
206+ buffer .append (src + "->" + destId + " [color=" + FG_ORANGE + " ,label=\" Label Edge (" + data + ") (Contained by " + st .id + ")\" ];\r \n " );
170207 }
171208 }
172209
173210 // Neighbor set is redundant
174211// for (Statement neighbour : st.getNeighbours(Statement.STATEDGE_ALL, Statement.DIRECTION_FORWARD)) {
175212// String destId = neighbour.id + (neighbour.getSuccessorEdges(StatEdge.TYPE_EXCEPTION).isEmpty()?"":"000000");
176- // buffer.append(sourceId + "->" + destId + " [arrowhead=tee,color=purple ];\r\n");
213+ // buffer.append(sourceId + "->" + destId + " [arrowhead=tee,color=" + FG_PURPLE + " ];\r\n");
177214// }
178215
179216 if (EXTENDED_MODE ) {
@@ -182,7 +219,7 @@ private static String statToDot(Statement stat, String name, Map<Statement, Stri
182219
183220 String edgeType = getEdgeType (edge );
184221
185- buffer .append (sourceId + "->" + destId + "[color=pink " + (edgeType != null ? ",fontcolor=blue ,label=\" " + edgeType + "\" " : "" ) + "];\r \n " );
222+ buffer .append (sourceId + "->" + destId + "[color=" + FG_PINK + (edgeType != null ? ",fontcolor=" + FG_BLUE + " ,label=\" " + edgeType + "\" " : "" ) + "];\r \n " );
186223
187224 referenced .add (edge .getSource ().id );
188225
@@ -233,32 +270,32 @@ private static String statToDot(Statement stat, String name, Map<Statement, Stri
233270 }
234271 }
235272
236- buffer .append (sourceId + " -> " + destId + " [arrowhead=vee,color=red " + (!label .equals ("" ) ? ",fontcolor=red ,label=\" " + label + "\" " : "" ) + "];\r \n " );
273+ buffer .append (sourceId + " -> " + destId + " [arrowhead=vee,color=" + FG_RED + (!label .equals ("" ) ? ",fontcolor=" + FG_RED + " ,label=\" " + label + "\" " : "" ) + "];\r \n " );
237274 referenced .add (s .id );
238275 }
239276
240277 if (!foundFirst && st .getFirst () != null ) {
241278 String destId = st .getFirst ().id + (st .getFirst ().getSuccessorEdges (StatEdge .TYPE_EXCEPTION ).isEmpty ()?"" :"000000" );
242- buffer .append (sourceId + "->" + destId + " [arrowhead=vee,color=red ,fontcolor=red ,label=\" Dangling First statement!\" ];\r \n " );
279+ buffer .append (sourceId + "->" + destId + " [arrowhead=vee,color=" + FG_RED + " ,fontcolor=" + FG_RED + " ,label=\" Dangling First statement!\" ];\r \n " );
243280 }
244281
245282 if (isIf ) {
246283 if (!foundIf && ((IfStatement ) st ).getIfstat () != null ) {
247284 String destId = ((IfStatement ) st ).getIfstat ().id + (st .getFirst ().getSuccessorEdges (StatEdge .TYPE_EXCEPTION ).isEmpty ()?"" :"000000" );
248- buffer .append (sourceId + "->" + destId + " [arrowhead=vee,color=red ,fontcolor=red ,label=\" Dangling If statement!\" ];\r \n " );
285+ buffer .append (sourceId + "->" + destId + " [arrowhead=vee,color=" + FG_RED + " ,fontcolor=" + FG_RED + " ,label=\" Dangling If statement!\" ];\r \n " );
249286 }
250287
251288 if (!foundElse && ((IfStatement ) st ).getElsestat () != null ) {
252289 String destId = ((IfStatement ) st ).getElsestat ().id + (((IfStatement ) st ).getElsestat ().getSuccessorEdges (StatEdge .TYPE_EXCEPTION ).isEmpty ()?"" :"000000" );
253- buffer .append (sourceId + "->" + destId + " [arrowhead=vee,color=red ,fontcolor=red ,label=\" Dangling Else statement!\" ];\r \n " );
290+ buffer .append (sourceId + "->" + destId + " [arrowhead=vee,color=" + FG_RED + " ,fontcolor=" + FG_RED + " ,label=\" Dangling Else statement!\" ];\r \n " );
254291 }
255292 }
256293
257294 visitedNodes .add (st .id );
258295
259296 String extra = extraProps == null || !extraProps .containsKey (st ) ? "" : "," + extraProps .get (st );
260297
261- String node = sourceId + " [shape=box,label=\" " + st .id + " (" + getStatType (st ) + ")\\ n" + toJava (st ) + "\" " + (st == stat ? ",color=red" : "" ) + extra + "];\n " ;
298+ String node = sourceId + " [shape=box,label=\" " + st .id + " (" + getStatType (st ) + ")\\ n" + toJava (st ) + "\" " + (st == stat ? ",color=" + FG_RED : "" ) + extra + "];\n " ;
262299// if (edges || st == stat) {
263300 buffer .append (node );
264301// } else {
@@ -291,13 +328,13 @@ private static String statToDot(Statement stat, String name, Map<Statement, Stri
291328
292329 // Exits
293330 if (exit != null ) {
294- buffer .append (exit .id + " [color=green ,label=\" " + exit .id + " (Canonical Return)\" ];\n " );
331+ buffer .append (exit .id + " [color=" + FG_GREEN + " ,label=\" " + exit .id + " (Canonical Return)\" ];\n " );
295332 referenced .remove (exit .id );
296333 }
297334
298335// for (Integer exit : exits) {
299336// if (!visitedNodes.contains(exit)) {
300- // buffer.append(exit + " [color=green ,label=\"" + exit + " (Canonical Return)\"];\r\n");
337+ // buffer.append(exit + " [color=" + FG_green + " ,label=\"" + exit + " (Canonical Return)\"];\r\n");
301338// }
302339//
303340// referenced.remove(exit);
@@ -307,7 +344,7 @@ private static String statToDot(Statement stat, String name, Map<Statement, Stri
307344
308345 // Unresolved statement references
309346 for (Integer integer : referenced ) {
310- buffer .append (integer + " [color=red ,label=\" " + integer + " (Unknown statement!)\" ];\r \n " );
347+ buffer .append (integer + " [color=" + FG_RED + " ,label=\" " + integer + " (Unknown statement!)\" ];\r \n " );
311348 }
312349
313350 for (StatEdge labelEdge : extraData .keySet ()) {
@@ -319,7 +356,7 @@ private static String statToDot(Statement stat, String name, Map<Statement, Stri
319356 String destId = labelEdge .getDestination ().id + (labelEdge .getDestination ().getSuccessorEdges (StatEdge .TYPE_EXCEPTION ).isEmpty () ? "" : "000000" );
320357 String label = "Floating extra edge: (" + extraData .get (labelEdge ) + ")" ;
321358
322- buffer .append (src + " -> " + destId + " [arrowhead=vee,color=purple ,fontcolor=red ,label=\" " + label + "\" ];\r \n " );
359+ buffer .append (src + " -> " + destId + " [arrowhead=vee,color=" + FG_PURPLE + " ,fontcolor=" + FG_RED + " ,label=\" " + label + "\" ];\r \n " );
323360 }
324361
325362// if (subgraph.size() > 0) {
@@ -341,6 +378,7 @@ private static String statementHierarchy(Statement stat) {
341378 StringBuffer buffer = new StringBuffer ();
342379
343380 buffer .append ("digraph G {\r \n " );
381+ buffer .append (THEME_HEADER );
344382
345383 buffer .append ("subgraph cluster_root {\r \n " );
346384
@@ -400,12 +438,12 @@ private static String getEdgeType(StatEdge edge) {
400438
401439 private static String getEdgeMeta (StatEdge edge ) {
402440 switch (edge .getType ()) {
403- case StatEdge .TYPE_REGULAR : return "weight=1, color=black" ;
404- case StatEdge .TYPE_EXCEPTION : return "weight=1, color=orange , style=dashed" ;
405- case StatEdge .TYPE_BREAK : return "weight=0.4, color=blue" ;
406- case StatEdge .TYPE_CONTINUE : return "weight=0.2, color=green" ;
407- case StatEdge .TYPE_FINALLYEXIT : return "weight=1, color=orange , style=dotted" ;
408- default : return "weight=1, color=purple" ;
441+ case StatEdge .TYPE_REGULAR : return "weight=1, color=" + FG_BLACK ;
442+ case StatEdge .TYPE_EXCEPTION : return "weight=1, color=" + FG_ORANGE + " , style=dashed" ;
443+ case StatEdge .TYPE_BREAK : return "weight=0.4, color=" + FG_BLUE ;
444+ case StatEdge .TYPE_CONTINUE : return "weight=0.2, color=" + FG_GREEN ;
445+ case StatEdge .TYPE_FINALLYEXIT : return "weight=1, color=" + FG_ORANGE + " , style=dotted" ;
446+ default : return "weight=1, color=" + FG_PURPLE ;
409447 }
410448 }
411449
@@ -454,6 +492,7 @@ private static String cfgToDot(String name, ControlFlowGraph graph, boolean show
454492 StringBuffer buffer = new StringBuffer ();
455493
456494 buffer .append ("digraph " + name + " {\r \n " );
495+ buffer .append (THEME_HEADER );
457496
458497 List <BasicBlock > blocks = graph .getBlocks ();
459498 for (BasicBlock block : blocks ) {
@@ -473,7 +512,7 @@ private static String cfgToDot(String name, ControlFlowGraph graph, boolean show
473512 }
474513
475514// for (BasicBlock pred : preds) {
476- // buffer.append(block.getDebugId() + " -> " + pred.getDebugId() + " [color=blue ];\r\n");
515+ // buffer.append(block.getDebugId() + " -> " + pred.getDebugId() + " [color=" + FG_blue + " ];\r\n");
477516// }
478517
479518 suc = block .getSuccExceptions ();
@@ -490,7 +529,7 @@ private static String cfgToDot(String name, ControlFlowGraph graph, boolean show
490529 }
491530
492531// for (BasicBlock pred : preds) {
493- // buffer.append(block.getDebugId() + " -> " + pred.getDebugId() + " [color=blue ,style=dotted];\r\n");
532+ // buffer.append(block.getDebugId() + " -> " + pred.getDebugId() + " [color=" + FG_blue + " ,style=dotted];\r\n");
494533// }
495534 }
496535
@@ -515,6 +554,7 @@ private static String decompileRecordToDot(DecompileRecord decompileRecord) {
515554 int size = names .size ();
516555
517556 builder .append ("digraph decompileRecord {\n " );
557+ builder .append (THEME_HEADER );
518558
519559 for (int i = 0 ; i < size ; i ++) {
520560 builder .append ("\t " ).append (i ).append (" [label=\" " ).append (names .get (i )).append ("\" ];\n " );
@@ -534,6 +574,7 @@ private static String varsToDot(VarVersionsGraph graph, Map<VarVersionPair, VarV
534574 StringBuilder builder = new StringBuilder ();
535575
536576 builder .append ("digraph G {\r \n " );
577+ builder .append (THEME_HEADER );
537578
538579 for (VarVersionNode node : graph .nodes ) {
539580 appendNode (builder , node );
@@ -549,19 +590,19 @@ private static String varsToDot(VarVersionsGraph graph, Map<VarVersionPair, VarV
549590 builder .append (" [shape=box, " );
550591 break ;
551592 case WRITE :
552- builder .append (" [shape=box, style=filled, fillcolor=palegreen1 , " );
593+ builder .append (" [shape=box, style=filled, fillcolor=" + BG_VAR_WRITE + " , " );
553594 break ;
554595 case PHANTOM :
555596 builder .append (" [shape=box; style=dotted, " );
556597 break ;
557598 case DEAD_READ :
558- builder .append (" [shape=box, style=filled, fillcolor=grey59 , " );
599+ builder .append (" [shape=box, style=filled, fillcolor=" + BG_VAR_DEAD_READ + " , " );
559600 break ;
560601 case PARAM :
561- builder .append (" [shape=box, style=filled, fillcolor=skyblue1 , " );
602+ builder .append (" [shape=box, style=filled, fillcolor=" + BG_VAR_PARAM + " , " );
562603 break ;
563604 case CATCH :
564- builder .append (" [shape=box, style=filled, fillcolor=gold , " );
605+ builder .append (" [shape=box, style=filled, fillcolor=" + BG_VAR_CATCH + " , " );
565606 break ;
566607 }
567608 }
@@ -590,7 +631,7 @@ private static String varsToDot(VarVersionsGraph graph, Map<VarVersionPair, VarV
590631 appendNode (builder , from );
591632 builder .append ("->" );
592633 appendNode (builder , to );
593- builder .append (" [color=green ];\r \n " );
634+ builder .append (" [color=" + FG_GREEN + " ];\r \n " );
594635 }
595636 }
596637
@@ -615,6 +656,7 @@ private static String domEngineToDot(DominatorEngine doms) {
615656 StringBuilder builder = new StringBuilder ();
616657
617658 builder .append ("digraph G {\r \n " );
659+ builder .append (THEME_HEADER );
618660
619661 Set <Integer > nodes = new HashSet <>();
620662
@@ -637,6 +679,7 @@ private static String digraphToDot(DirectGraph graph, Map<String, SFormsFastMapD
637679 StringBuffer buffer = new StringBuffer ();
638680
639681 buffer .append ("digraph G {\r \n " );
682+ buffer .append (THEME_HEADER );
640683
641684 List <DirectNode > blocks = graph .nodes ;
642685 for (DirectNode block : blocks ) {
@@ -670,7 +713,7 @@ private static String digraphToDot(DirectGraph graph, Map<String, SFormsFastMapD
670713 }
671714
672715 if (block .tryFinally != null ) {
673- buffer .append ("x" + (block .id )+" -> x" +(block .tryFinally .id ) + "[color=blue ];\r \n " );
716+ buffer .append ("x" + (block .id )+" -> x" +(block .tryFinally .id ) + "[color=" + FG_BLUE + " ];\r \n " );
674717 }
675718 }
676719
0 commit comments