Skip to content

Commit 6d12f9b

Browse files
committed
Updates to scanning and rendering of functions
1 parent b75ae1c commit 6d12f9b

File tree

2 files changed

+96
-20
lines changed

2 files changed

+96
-20
lines changed

scripts/render-function.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import type Parser from "web-tree-sitter";
55
import type { SyntaxNode } from "web-tree-sitter";
66
import { type Language, supportedLanguages } from "../src/control-flow/cfg.ts";
77
import {
8-
deserializeColorList,
9-
listToScheme,
8+
deserializeColorList, getDarkColorList, getLightColorList,
9+
listToScheme
1010
} from "../src/control-flow/colors.ts";
1111
import { graphToDot } from "../src/control-flow/render.ts";
1212
import { getLanguage, iterFunctions } from "../src/file-parsing/bun.ts";
@@ -32,11 +32,24 @@ export function getFuncDef(sourceCode: string, func: SyntaxNode): string {
3232
return normalizeFuncdef(sourceCode.slice(func.startIndex, body.startIndex));
3333
}
3434

35-
3635
function writeError(message: string): void {
3736
Bun.write(Bun.stderr, `${message}\n`);
3837
}
3938

39+
async function getColorScheme(
40+
colors?:string
41+
) {
42+
if (!colors || colors === "dark") {
43+
return listToScheme(getDarkColorList())
44+
}
45+
if (colors === "light") {
46+
return listToScheme(getLightColorList())
47+
}
48+
return colors
49+
? listToScheme(deserializeColorList(await Bun.file(colors).text()))
50+
: undefined;
51+
}
52+
4053
async function main() {
4154
process.on("SIGINT", () => {
4255
// close watcher when Ctrl-C is pressed
@@ -122,9 +135,7 @@ async function main() {
122135
const graphviz = await Graphviz.load();
123136
const cfg = buildCFG(func, language);
124137

125-
const colorScheme = values.colors
126-
? listToScheme(deserializeColorList(await Bun.file(values.colors).text()))
127-
: undefined;
138+
const colorScheme = await getColorScheme(values.colors)
128139

129140
const svg = graphviz.dot(graphToDot(cfg, false, undefined, colorScheme));
130141

scripts/scan-codebase.ts

Lines changed: 79 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,54 +8,119 @@ import * as path from "node:path";
88
*/
99
import { parseArgs } from "node:util";
1010
import { Glob } from "bun";
11-
import { buildCFG } from "./cfg-helper.ts";
1211
import {
1312
fileTypes,
1413
getLanguage,
1514
iterFunctions,
1615
} from "../src/file-parsing/bun.ts";
17-
import {getFuncDef} from "./render-function.ts";
16+
import { buildCFG } from "./cfg-helper.ts";
17+
import { getFuncDef } from "./render-function.ts";
1818

1919
export function iterSourceFiles(root: string): IterableIterator<string> {
2020
const sourceGlob = new Glob(
2121
`**/*.{${fileTypes.map(({ ext }) => ext).join(",")}}`,
2222
);
2323
return sourceGlob.scanSync(root);
2424
}
25+
function* iterFilenames(
26+
root: string,
27+
dirsToInclude: string[],
28+
): IterableIterator<string> {
29+
if (dirsToInclude.length === 1 && dirsToInclude[0] === "*") {
30+
yield* iterSourceFiles(root);
31+
} else {
32+
for (const dir of dirsToInclude) {
33+
for (const filename of iterSourceFiles(path.join(root, dir))) {
34+
// We want the path relative to the root
35+
yield path.join(dir, filename);
36+
}
37+
}
38+
}
39+
}
2540

26-
async function* iterInfo(root: string) {
27-
for (const filename of iterSourceFiles(root)) {
28-
const filepath = path.join(root, filename);
29-
const code = await Bun.file(filepath).text();
41+
async function* iterFunctionInfo(
42+
root: string,
43+
filenames: IterableIterator<string>,
44+
): AsyncIterableIterator<{
45+
node_count: number;
46+
start_position: { row:number, column:number };
47+
funcdef: string;
48+
filename: string;
49+
}> {
50+
for (const filename of filenames) {
51+
const code = await Bun.file(path.join(root, filename)).text();
3052
const language = getLanguage(filename);
3153
for (const func of iterFunctions(code, language)) {
3254
const cfg = buildCFG(func, language);
3355
yield {
34-
file: filename,
35-
startIndex: func.startIndex,
36-
nodeCount: cfg.graph.order,
37-
funcDef: getFuncDef(code, func),
38-
startPosition: func.startPosition,
56+
node_count: cfg.graph.order,
57+
start_position: func.startPosition,
58+
funcdef: getFuncDef(code, func),
59+
filename: filename.replaceAll("\\", "/"),
3960
};
4061
}
4162
}
4263
}
4364

65+
async function generateIndex(
66+
/** Project name on GitHub */
67+
project: string,
68+
/** Git ref */
69+
ref: string,
70+
/** Root on local filesystem */
71+
root: string,
72+
/** Directories to index, relative to the root */
73+
dirsToInclude: string[],
74+
) {
75+
const filenames = iterFilenames(root, dirsToInclude);
76+
const functions = await Array.fromAsync(iterFunctionInfo(root, filenames));
77+
return {
78+
version: 1,
79+
content: {
80+
index_type: "github",
81+
project,
82+
ref,
83+
functions,
84+
},
85+
};
86+
}
87+
4488
async function main() {
45-
const { values } = parseArgs({
89+
const {
90+
values,
91+
positionals: [_runtime, _this, ...dirsToInclude],
92+
} = parseArgs({
4693
args: Bun.argv,
4794
options: {
95+
project: {
96+
type: "string",
97+
},
98+
ref: {
99+
type: "string",
100+
},
48101
root: {
49102
type: "string",
50103
},
104+
out: {
105+
type: "string",
106+
},
51107
},
52108
strict: true,
53109
allowPositionals: true,
54110
});
55111

56-
const root = values.root ?? ".";
112+
if (!values.project || !values.ref || !values.root) {
113+
throw new Error("Missing arguments");
114+
}
57115

58-
process.stdout.write(JSON.stringify(await Array.fromAsync(iterInfo(root))));
116+
const output = JSON.stringify(
117+
await generateIndex(values.project, values.ref, values.root, dirsToInclude),
118+
);
119+
if (values.out) {
120+
await Bun.write(values.out, output);
121+
} else {
122+
await Bun.write(Bun.stdout, output);
123+
}
59124
}
60125

61126
if (require.main === module) {

0 commit comments

Comments
 (0)