Delete now-unused mermaid visualization
Joe Savona committed
Sep 11, 2023 at 16:58 UTC
d2f46b14370df69360de8afc36639fb5fd947e8b
1 file changed
-292
compiler/packages/babel-plugin-react-forget/src/Utils/VisualizeHIRMermaid.ts
deleted
-292
@@ -1,292 +0,0 @@
1
-/**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- */
7
-
8
-import { BasicBlock, BlockId, HIRFunction, Terminal } from "../HIR/HIR";
9
-import { printInstruction, printPlace } from "../HIR/PrintHIR";
10
-import { assertExhaustive } from "./utils";
11
-
12
-const INSTRUCTIONS_NODE_NAME = "instrs";
13
-const TERMINAL_NODE_NAME = "terminal";
14
-
15
-enum MermaidFlowchartDirection {
16
- TopBottom = "TB", // top to bottom
17
- TopDown = "TD", // top-down/ same as top to bottom
18
- BottomTop = "BT", // bottom to top
19
- RightLeft = "RL", // right to left
20
- LeftRight = "LR", // left to right
21
-}
22
-
23
-function printBlockId(id: BlockId): string {
24
- return `bb${id}`;
25
-}
26
-
27
-/**
28
- * Prints a mermaid arrow with optional label connecting BasicBlocks for use in the "Jumps" section.
29
- */
30
-function printJumpArrow(
31
- from: BlockId,
32
- to: BlockId,
33
- label: string | null
34
-): string {
35
- const fromId = printBlockId(from);
36
- const toId = printBlockId(to);
37
- if (label != null) {
38
- return `${fromId}_${TERMINAL_NODE_NAME} -- "${label}" --> ${toId}\n`;
39
- }
40
- return `${fromId}_${TERMINAL_NODE_NAME} --> ${toId}\n`;
41
-}
42
-
43
-/**
44
- * Prints a mermaid arrow connecting a BasicBlock's instructions to its Terminal for use in the
45
- * "Basic Blocks" section.
46
- */
47
-function printTerminalArrow(blockId: BlockId, block: BasicBlock): string {
48
- const bbId = printBlockId(blockId);
49
- if (block.instructions.length > 0) {
50
- return `${bbId}_${INSTRUCTIONS_NODE_NAME} --> ${bbId}_${TERMINAL_NODE_NAME}(["${printTerminalLabel(
51
- block.terminal
52
- )}"])`;
53
- }
54
- return `${bbId}_${TERMINAL_NODE_NAME}(["${printTerminalLabel(
55
- block.terminal
56
- )}"])`;
57
-}
58
-
59
-/**
60
- * Prints a BasicBlock as a mermaid `subgraph`, with instructions as a single multiline mermaid node
61
- * and the terminal as an arrow connecting the instruction node with the terminal.
62
- */
63
-function printBlockSubgraphs(blockId: BlockId, block: BasicBlock): string {
64
- const buffer = [];
65
- const bbId = printBlockId(blockId);
66
- const instructions = block.instructions
67
- .map((instr) => ` ${printInstruction(instr).replaceAll('"', "'")}\n`)
68
- .join("");
69
- buffer.push(` subgraph ${bbId}\n`);
70
- if (block.instructions.length > 0) {
71
- buffer.push(` ${bbId}_${INSTRUCTIONS_NODE_NAME}["\n`);
72
- buffer.push(instructions);
73
- buffer.push(' "]\n');
74
- }
75
- buffer.push(` ${printTerminalArrow(blockId, block)}`);
76
- buffer.push("\n end\n");
77
- return buffer.join("");
78
-}
79
-
80
-function printTerminalLabel(terminal: Terminal): string {
81
- const buffer = [];
82
- switch (terminal.kind) {
83
- case "if": {
84
- buffer.push(`If (${printPlace(terminal.test)})`);
85
- break;
86
- }
87
- case "branch": {
88
- buffer.push(`Branch (${printPlace(terminal.test)})`);
89
- break;
90
- }
91
- case "goto": {
92
- buffer.push("Goto");
93
- break;
94
- }
95
- case "return": {
96
- if (terminal.value != null) {
97
- buffer.push(`Return ${printPlace(terminal.value)}`);
98
- } else {
99
- buffer.push("Return");
100
- }
101
- break;
102
- }
103
- case "switch":
104
- buffer.push(`Switch (${printPlace(terminal.test)})`);
105
- break;
106
- case "throw":
107
- buffer.push(`Throw ${printPlace(terminal.value)}`);
108
- break;
109
- case "logical": {
110
- buffer.push(`Logical ${terminal.operator}`);
111
- break;
112
- }
113
- case "ternary": {
114
- buffer.push("Ternary");
115
- break;
116
- }
117
- case "optional": {
118
- buffer.push("Optional");
119
- break;
120
- }
121
- case "do-while": {
122
- buffer.push("DoWhile");
123
- break;
124
- }
125
- case "while":
126
- buffer.push("While");
127
- break;
128
- case "for":
129
- buffer.push("For");
130
- break;
131
- case "for-of":
132
- buffer.push("ForOf");
133
- break;
134
- case "label": {
135
- buffer.push("Label");
136
- break;
137
- }
138
- case "sequence": {
139
- buffer.push("Sequence");
140
- break;
141
- }
142
- case "for-in":
143
- case "try":
144
- case "maybe-throw":
145
- case "unsupported": {
146
- break;
147
- }
148
- default:
149
- assertExhaustive(terminal, `unhandled terminal ${terminal}`);
150
- }
151
- return buffer.join("");
152
-}
153
-
154
-function printTerminalArrows(blockId: BlockId, terminal: Terminal): string {
155
- const buffer = [];
156
- switch (terminal.kind) {
157
- case "if": {
158
- buffer.push(printJumpArrow(blockId, terminal.consequent, "then"));
159
- buffer.push(printJumpArrow(blockId, terminal.alternate, "else"));
160
- if (
161
- terminal.fallthrough != null &&
162
- terminal.alternate !== terminal.fallthrough
163
- ) {
164
- buffer.push(
165
- printJumpArrow(blockId, terminal.fallthrough, "fallthrough")
166
- );
167
- }
168
- break;
169
- }
170
- case "branch": {
171
- buffer.push(printJumpArrow(blockId, terminal.consequent, "then"));
172
- buffer.push(printJumpArrow(blockId, terminal.alternate, "else"));
173
- break;
174
- }
175
- case "logical": {
176
- buffer.push(printJumpArrow(blockId, terminal.test, "test"));
177
- buffer.push(printJumpArrow(blockId, terminal.fallthrough, "fallthrough"));
178
- break;
179
- }
180
- case "ternary": {
181
- buffer.push(printJumpArrow(blockId, terminal.test, "test"));
182
- buffer.push(printJumpArrow(blockId, terminal.fallthrough, "fallthrough"));
183
- break;
184
- }
185
- case "optional": {
186
- buffer.push(printJumpArrow(blockId, terminal.test, "test"));
187
- buffer.push(printJumpArrow(blockId, terminal.fallthrough, "fallthrough"));
188
- break;
189
- }
190
- case "goto": {
191
- buffer.push(printJumpArrow(blockId, terminal.block, null));
192
- break;
193
- }
194
- case "switch": {
195
- terminal.cases.forEach((case_) => {
196
- if (case_.test != null) {
197
- buffer.push(
198
- printJumpArrow(blockId, case_.block, printPlace(case_.test))
199
- );
200
- } else {
201
- buffer.push(printJumpArrow(blockId, case_.block, "default"));
202
- }
203
- });
204
- if (terminal.fallthrough != null) {
205
- buffer.push(
206
- printJumpArrow(blockId, terminal.fallthrough, "fallthrough")
207
- );
208
- }
209
- break;
210
- }
211
- case "do-while": {
212
- buffer.push(printJumpArrow(blockId, terminal.loop, "loop"));
213
- buffer.push(printJumpArrow(blockId, terminal.test, "test"));
214
- buffer.push(printJumpArrow(blockId, terminal.fallthrough, "fallthrough"));
215
- break;
216
- }
217
- case "while": {
218
- buffer.push(printJumpArrow(blockId, terminal.test, "test"));
219
- buffer.push(printJumpArrow(blockId, terminal.loop, "loop"));
220
- buffer.push(printJumpArrow(blockId, terminal.fallthrough, "fallthrough"));
221
- break;
222
- }
223
- case "for": {
224
- buffer.push(printJumpArrow(blockId, terminal.init, "init"));
225
- buffer.push(printJumpArrow(blockId, terminal.test, "test"));
226
- if (terminal.update !== null) {
227
- buffer.push(printJumpArrow(blockId, terminal.update, "update"));
228
- }
229
- buffer.push(printJumpArrow(blockId, terminal.loop, "loop"));
230
- buffer.push(printJumpArrow(blockId, terminal.fallthrough, "fallthrough"));
231
- break;
232
- }
233
- case "for-of": {
234
- buffer.push(printJumpArrow(blockId, terminal.init, "init"));
235
- buffer.push(printJumpArrow(blockId, terminal.loop, "loop"));
236
- break;
237
- }
238
- case "label": {
239
- buffer.push(printJumpArrow(blockId, terminal.block, "block"));
240
- if (terminal.fallthrough != null) {
241
- buffer.push(
242
- printJumpArrow(blockId, terminal.fallthrough, "fallthrough")
243
- );
244
- }
245
- break;
246
- }
247
- case "sequence": {
248
- buffer.push(printJumpArrow(blockId, terminal.block, "block"));
249
- buffer.push(printJumpArrow(blockId, terminal.fallthrough, "fallthrough"));
250
- break;
251
- }
252
- case "for-in":
253
- case "try":
254
- case "maybe-throw":
255
- case "throw":
256
- case "return":
257
- case "unsupported": {
258
- break;
259
- }
260
- default:
261
- assertExhaustive(terminal, `unhandled terminal ${terminal}`);
262
- }
263
- return buffer.map((line) => ` ${line}`).join("");
264
-}
265
-
266
-/**
267
- * Visualizes the HIR as a mermaid.js diagram.
268
- */
269
-export default function visualizeHIRMermaid(fn: HIRFunction): string {
270
- const ir = fn.body;
271
- const subgraphs = [];
272
- const jumps = [];
273
-
274
- for (const [blockId, block] of ir.blocks) {
275
- const subgraph = printBlockSubgraphs(blockId, block);
276
- const jump = printTerminalArrows(blockId, block.terminal);
277
-
278
- if (subgraph.length > 0) {
279
- subgraphs.push(subgraph);
280
- }
281
-
282
- if (jump.length > 0) {
283
- jumps.push(jump);
284
- }
285
- }
286
-
287
- return `flowchart ${MermaidFlowchartDirection.TopBottom}
288
- %% Basic Blocks
289
-${subgraphs.length ? subgraphs.join("") : " %% empty"}
290
- %% Jumps
291
-${jumps.length ? jumps.join("") : " %% empty"}`;
292
-}