Skip to content

Commit aa4ceed

Browse files
committed
Basic support for raise
1 parent 049c802 commit aa4ceed

File tree

4 files changed

+85
-33
lines changed

4 files changed

+85
-33
lines changed

src/control-flow/cfg-defs.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { MultiDirectedGraph } from "graphology";
22
import type Parser from "web-tree-sitter";
33

44
export type NodeType =
5+
| "YIELD"
6+
| "RAISE"
57
| "MARKER_COMMENT"
68
| "LOOP_HEAD"
79
| "LOOP_EXIT"

src/control-flow/cfg-python.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,12 +171,25 @@ export class CFGBuilder {
171171
return this.processWithStatement(node);
172172
case "try_statement":
173173
return this.processTryStatement(node);
174-
default: {
175-
const newNode = this.addNode("STATEMENT", node.text);
176-
return { entry: newNode, exit: newNode };
177-
}
174+
case "raise_statement":
175+
return this.processRaiseStatement(node);
176+
default:
177+
return this.defaultProcessStatement(node);
178178
}
179179
}
180+
private defaultProcessStatement(syntax: Parser.SyntaxNode): BasicBlock {
181+
// const match = this.matchQuery(syntax, "yield", `(yield) @yield`);
182+
// if (match.captures.length > 0) {
183+
// const yieldNode = this.addNode("YIELD", syntax.text);
184+
// return { entry: yieldNode, exit: yieldNode };
185+
// }
186+
const newNode = this.addNode("STATEMENT", syntax.text);
187+
return { entry: newNode, exit: newNode };
188+
}
189+
private processRaiseStatement(raiseSyntax: Parser.SyntaxNode): BasicBlock {
190+
const raiseNode = this.addNode("RAISE", raiseSyntax.text);
191+
return { entry: raiseNode, exit: null };
192+
}
180193
private processReturnStatement(returnSyntax: Parser.SyntaxNode): BasicBlock {
181194
const returnNode = this.addNode("RETURN", returnSyntax.text);
182195
return { entry: returnNode, exit: null, returns: [returnNode] };

src/control-flow/render.ts

Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -116,35 +116,6 @@ function getParents(cluster: Cluster) {
116116
return parents.toReversed();
117117
}
118118

119-
function renderNode(graph: CFGGraph, node: string, verbose: boolean): string {
120-
let label = "";
121-
if (verbose) {
122-
label = `${node} ${graph.getNodeAttributes(node).type} ${graph.getNodeAttributes(node).code}`;
123-
124-
const clusterAttrs = graph.getNodeAttribute(node, "cluster");
125-
label = `${clusterAttrs?.id} ${clusterAttrs?.type}\n${label}`;
126-
}
127-
let shape = "box";
128-
let fillColor = "lightgray";
129-
let minHeight = 0.2;
130-
if (graph.degree(node) === 0) {
131-
minHeight = 0.5;
132-
} else if (graph.inDegree(node) === 0) {
133-
shape = "invhouse";
134-
fillColor = "#48AB30";
135-
minHeight = 0.5;
136-
} else if (graph.outDegree(node) === 0) {
137-
shape = "house";
138-
fillColor = "#AB3030";
139-
minHeight = 0.5;
140-
}
141-
142-
const height = Math.max(
143-
graph.getNodeAttribute(node, "lines") * 0.3,
144-
minHeight,
145-
);
146-
return ` ${node} [label="${label}" shape="${shape}" fillcolor="${fillColor}" style="filled" height=${height}];\n`;
147-
}
148119

149120
function renderHierarchy(
150121
cfg: CFG,
@@ -335,3 +306,46 @@ function renderEdge(
335306
}
336307
return ` ${source} -> ${target} [${formatStyle(dotAttrs)}];\n`;
337308
}
309+
310+
function renderNode(graph: CFGGraph, node: string, verbose: boolean): string {
311+
const dotAttrs: DotAttributes = {};
312+
dotAttrs.style = "filled"
313+
dotAttrs.label = "";
314+
const nodeAttrs = graph.getNodeAttributes(node);
315+
if (verbose) {
316+
dotAttrs.label = `${node} ${nodeAttrs.type} ${graph.getNodeAttributes(node).code}`;
317+
318+
const clusterAttrs = graph.getNodeAttribute(node, "cluster");
319+
dotAttrs.label = `${clusterAttrs?.id} ${clusterAttrs?.type}\n${dotAttrs.label}`;
320+
}
321+
dotAttrs.shape = "box";
322+
dotAttrs.fillcolor = "lightgray";
323+
let minHeight = 0.2;
324+
if (graph.degree(node) === 0) {
325+
dotAttrs.minHeight = 0.5;
326+
} else if (graph.inDegree(node) === 0) {
327+
dotAttrs.shape = "invhouse";
328+
dotAttrs.fillcolor = "#48AB30";
329+
minHeight = 0.5;
330+
} else if (graph.outDegree(node) === 0) {
331+
dotAttrs.shape = "house";
332+
dotAttrs.fillcolor = "#AB3030";
333+
minHeight = 0.5;
334+
}
335+
switch (nodeAttrs.type) {
336+
case "RAISE":
337+
dotAttrs.shape = "triangle";
338+
dotAttrs.fillcolor = "#fdd";
339+
break;
340+
case "YIELD":
341+
dotAttrs.shallow = "hexagon";
342+
dotAttrs.fillcolor = "aqua";
343+
break;
344+
}
345+
346+
dotAttrs.height = Math.max(
347+
graph.getNodeAttribute(node, "lines") * 0.3,
348+
minHeight,
349+
);
350+
return ` ${node} [${formatStyle(dotAttrs)}];\n`;
351+
}

src/test/commentTestSamples/sample.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,29 @@ def WithNestedCluster():
156156
return
157157

158158

159+
# render: true,
160+
# exits: 999
161+
def raise_exception():
162+
raise
163+
164+
# render: true,
165+
# exits: 999
166+
def raise_again():
167+
try:
168+
raise x
169+
except:
170+
if x:
171+
pass
172+
else:
173+
if x:
174+
pass
175+
176+
# render: true,
177+
# exits: 3
178+
def yield_value():
179+
for x in y:
180+
yield x
181+
159182

160183
# exits: 0,
161184
# render: true

0 commit comments

Comments
 (0)