Skip to content

Commit bd9948c

Browse files
committed
Initial support for yield
1 parent aa4ceed commit bd9948c

File tree

4 files changed

+42
-23
lines changed

4 files changed

+42
-23
lines changed

src/control-flow/cfg-defs.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type Parser from "web-tree-sitter";
33

44
export type NodeType =
55
| "YIELD"
6-
| "RAISE"
6+
| "THROW"
77
| "MARKER_COMMENT"
88
| "LOOP_HEAD"
99
| "LOOP_EXIT"
@@ -154,6 +154,10 @@ export function mergeNodeAttrs(
154154
if (from.cluster !== into.cluster) {
155155
return null;
156156
}
157+
const noMergeTypes: NodeType[] = ["YIELD", "THROW"];
158+
if (noMergeTypes.includes(from.type) || noMergeTypes.includes(into.type)) {
159+
return null;
160+
}
157161
return {
158162
type: from.type,
159163
code: `${from.code}\n${into.code}`,

src/control-flow/cfg-python.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -178,16 +178,16 @@ export class CFGBuilder {
178178
}
179179
}
180180
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-
// }
181+
const hasYield = this.matchExistsIn(syntax, "yield", `(yield) @yield`);
182+
if (hasYield) {
183+
const yieldNode = this.addNode("YIELD", syntax.text);
184+
return { entry: yieldNode, exit: yieldNode };
185+
}
186186
const newNode = this.addNode("STATEMENT", syntax.text);
187187
return { entry: newNode, exit: newNode };
188188
}
189189
private processRaiseStatement(raiseSyntax: Parser.SyntaxNode): BasicBlock {
190-
const raiseNode = this.addNode("RAISE", raiseSyntax.text);
190+
const raiseNode = this.addNode("THROW", raiseSyntax.text);
191191
return { entry: raiseNode, exit: null };
192192
}
193193
private processReturnStatement(returnSyntax: Parser.SyntaxNode): BasicBlock {
@@ -506,6 +506,17 @@ export class CFGBuilder {
506506
return match;
507507
}
508508

509+
private matchExistsIn(
510+
syntax: Parser.SyntaxNode,
511+
mainName: string,
512+
queryString: string,
513+
): boolean {
514+
const language = syntax.tree.getLanguage();
515+
const query = language.query(queryString);
516+
const matches = query.matches(syntax);
517+
return matches.length > 0;
518+
}
519+
509520
private getSyntax(
510521
match: Parser.QueryMatch,
511522
name: string,

src/control-flow/render.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,11 @@ function buildHierarchy(cfg: CFG): Hierarchy {
8686
// for (const cluster of clusterNodes.keys()) {
8787
// console.log(cluster.id, getParents(cluster).map(c => c.id))
8888
// }
89-
// showHierarchy(hierarchy);
89+
// _showHierarchy(hierarchy);
9090
return hierarchy;
9191
}
9292

93-
function showHierarchy(hierarchy: Hierarchy) {
93+
function _showHierarchy(hierarchy: Hierarchy) {
9494
const stack: [Hierarchy, number][] = [[hierarchy, 0]];
9595
const spaces = " ";
9696
for (
@@ -116,7 +116,6 @@ function getParents(cluster: Cluster) {
116116
return parents.toReversed();
117117
}
118118

119-
120119
function renderHierarchy(
121120
cfg: CFG,
122121
hierarchy: Hierarchy,
@@ -309,7 +308,7 @@ function renderEdge(
309308

310309
function renderNode(graph: CFGGraph, node: string, verbose: boolean): string {
311310
const dotAttrs: DotAttributes = {};
312-
dotAttrs.style = "filled"
311+
dotAttrs.style = "filled";
313312
dotAttrs.label = "";
314313
const nodeAttrs = graph.getNodeAttributes(node);
315314
if (verbose) {
@@ -333,13 +332,14 @@ function renderNode(graph: CFGGraph, node: string, verbose: boolean): string {
333332
minHeight = 0.5;
334333
}
335334
switch (nodeAttrs.type) {
336-
case "RAISE":
335+
case "THROW":
337336
dotAttrs.shape = "triangle";
338337
dotAttrs.fillcolor = "#fdd";
339338
break;
340339
case "YIELD":
341-
dotAttrs.shallow = "hexagon";
342-
dotAttrs.fillcolor = "aqua";
340+
dotAttrs.shape = "hexagon";
341+
dotAttrs.orientation = 90;
342+
dotAttrs.fillcolor = "deepskyblue";
343343
break;
344344
}
345345

src/test/commentTestSamples/sample.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,7 @@ def WithNestedCluster():
161161
def raise_exception():
162162
raise
163163

164-
# render: true,
165-
# exits: 999
164+
# render: true
166165
def raise_again():
167166
try:
168167
raise x
@@ -180,7 +179,8 @@ def yield_value():
180179
yield x
181180

182181

183-
# exits: 0,
182+
# exits: 2,
183+
# nodes: 4,
184184
# render: true
185185
def try_except():
186186
try:
@@ -189,7 +189,8 @@ def try_except():
189189
g()
190190
return
191191

192-
# exits: 0,
192+
# exits: 1,
193+
# nodes: 5,
193194
# render: true
194195
def try_except_finally():
195196
try:
@@ -200,7 +201,8 @@ def try_except_finally():
200201
h()
201202
return
202203

203-
# exits: 0,
204+
# exits: 2,
205+
# nodes: 9,
204206
# render: true
205207
def try_many_except_finally():
206208
try:
@@ -215,15 +217,15 @@ def try_many_except_finally():
215217
return
216218

217219

218-
# exits: 0,
220+
# exits: 1,
221+
# nodes: 6,
219222
# render: true
220223
def try_except_else_finally():
221224
try: pass
222225
except: pass
223226
else: pass
224227
finally: pass
225228

226-
# exits: 0,
227229
# render: true
228230
def massive_try_except_else_finally():
229231
try:
@@ -249,7 +251,8 @@ def massive_try_except_else_finally():
249251
for y in a:
250252
pass
251253

252-
# exits: 5,
254+
# exits: 2,
255+
# nodes: 8,
253256
# render: true
254257
def try_finally():
255258
try:
@@ -259,7 +262,8 @@ def try_finally():
259262
finally:
260263
pass
261264

262-
# exits: 5,
265+
# exits: 1,
266+
# nodes: 5,
263267
# render: true
264268
def try_with_finally():
265269
try:

0 commit comments

Comments
 (0)