Skip to content

Commit 2fea772

Browse files
Add dark theme for dot exports (#526)
1 parent bdda2d1 commit 2fea772

File tree

2 files changed

+77
-34
lines changed

2 files changed

+77
-34
lines changed

src/org/jetbrains/java/decompiler/modules/decompiler/decompose/DomTracer.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,27 +50,27 @@ private void add(Statement gen, String s, Map<Statement, String> props) {
5050
}
5151

5252
void error(Statement stat, String s) {
53-
this.add(stat, s, Map.of(stat, "fillcolor=coral1,style=filled"));
53+
this.add(stat, s, Map.of(stat, "fillcolor=" + DotExporter.BG_DOM_ERROR + ",style=filled"));
5454
}
5555

5656
void warn(Statement stat, String s) {
57-
this.add(stat, s, Map.of(stat, "fillcolor=tan1,style=filled"));
57+
this.add(stat, s, Map.of(stat, "fillcolor=" + DotExporter.BG_DOM_WARN + ",style=filled"));
5858
}
5959

6060
void info(Statement stat, String s) {
61-
this.add(stat, s, Map.of(stat, "fillcolor=lightblue,style=filled"));
61+
this.add(stat, s, Map.of(stat, "fillcolor=" + DotExporter.BG_DOM_INFO + ",style=filled"));
6262
}
6363

6464
void success(Statement stat, String s) {
65-
this.add(stat, s, Map.of(stat, "fillcolor=lawngreen,style=filled"));
65+
this.add(stat, s, Map.of(stat, "fillcolor=" + DotExporter.BG_DOM_SUCCESS + ",style=filled"));
6666
}
6767

6868
void successCreated(Statement stat, String s, Statement newStat) {
6969
Map<Statement, String> props = new HashMap<>();
70-
props.put(stat, "fillcolor=orange,style=filled");
71-
props.put(newStat, "fillcolor=lawngreen,style=filled");
70+
props.put(stat, "fillcolor=" + DotExporter.BG_DOM_OLDSTAT + ",style=filled");
71+
props.put(newStat, "fillcolor=" + DotExporter.BG_DOM_NEWSTAT + ",style=filled");
7272
for (Statement st : newStat.getStats()) {
73-
props.put(st, "fillcolor=pink,style=filled");
73+
props.put(st, "fillcolor=" + DotExporter.BG_DOM_NEWSTAT_CHILDREN + ",style=filled");
7474
}
7575
this.add(stat, s, props);
7676
}

src/org/jetbrains/java/decompiler/util/DotExporter.java

Lines changed: 70 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)