Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/dataflow/extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,16 @@ function emitNode(id: number, kind: GraphNode["kind"], ast: Node | null, build:
const target = ast ?? build.fn; // ENTRY/EXIT carry the whole callable's span
const s = build.sf.getLineAndColumnAtPos(target.getStart());
const e = build.sf.getLineAndColumnAtPos(target.getEnd());
return { id, kind, start_line: s.line, start_column: s.column, end_line: e.line, end_column: e.column };
return {
id,
kind,
start_line: s.line,
start_column: s.column,
end_line: e.line,
end_column: e.column,
start_offset: target.getStart(),
end_offset: target.getEnd(),
};
}

function hasRestParam(build: FunctionCfgBuild): boolean {
Expand Down
3 changes: 3 additions & 0 deletions src/schema/graphs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ export interface GraphNode {
start_column: number;
end_line: number;
end_column: number;
/** UTF-16 char offsets into the owning module's `source` (same convention as L1 `span.bytes`). */
start_offset: number;
end_offset: number;
}

// ----------------------------------------------------------------------------------------------
Expand Down
Binary file modified src/schema/v2/dataflow.ts
Binary file not shown.
10 changes: 10 additions & 0 deletions test/schema-v2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,16 @@ describe("schema v2 — L3 intraprocedural dataflow", () => {
test("no dangling endpoints at L3", () => {
expect(danglingCount(dfL3)).toBe(0);
});

test("a sampled L3 statement node is source-sliceable (span.bytes reproduces its text)", () => {
const mod = dfL3.application.symbol_table["src/flow.ts"];
const classify = mod.functions.classify as V2Callable;
const stmt = classify.body["4:3"];
expect(stmt?.kind).toBe("statement");
const [s, e] = (stmt as { span: { bytes: [number, number] } }).span.bytes;
expect(e).toBeGreaterThan(s);
expect(mod.source.slice(s, e)).toBe('let label = "none";');
});
});

describe("schema v2 — L4 interprocedural SDG", () => {
Expand Down