tiny.smg.command.calls.json
Defined in command.calls.
API (1)
Actions
Public operations.
Source
Source: tools/smg/src/command/calls/json.zig
zig
const std = @import("std");const pretty_json = @import("pretty").json;const smg = @import("../../root.zig");const calls = smg.calls;const graph_mod = smg.graph;const model = smg.model;const sample_max: usize = 3;const territory_max: usize = 8;const cycle_member_max: usize = 8;pub fn write( writer: *std.Io.Writer, graph: graph_mod.Graph, report: calls.Report, depth: u32,) !void { var out = pretty_json.Writer.init(writer, .minified); try out.beginObject(); try out.objectField("symbol"); try writeSymbol(&out, graph, report); try out.objectField("semantics"); try writeSemantics(&out, depth); try out.objectField("graph"); try out.beginObject(); try field(&out, "nodes", report.graph_nodes); try field(&out, "edges", report.graph_edges); try out.endObject(); try out.objectField("callers"); try writeReach(&out, graph, report.callers, depth); try out.objectField("calls"); try writeReach(&out, graph, report.calls, depth); try out.objectField("cycle"); try writeCycle(&out, graph, report.cycle); try out.objectField("resolution"); try writeResolution(&out, report.resolution); try out.endObject(); try writer.writeByte('\n');}fn writeSymbol( out: *pretty_json.Writer, graph: graph_mod.Graph, report: calls.Report,) !void { try out.beginObject(); try out.objectField("declaration"); try writeNode(out, graph.nodes.items[report.focus]); try out.objectField("territory"); try writeNodeIdentity(out, graph.nodes.items[report.focus_territory]); try out.endObject();}fn writeSemantics(out: *pretty_json.Writer, depth: u32) !void { try out.beginObject(); try field(out, "relationship", model.RelType.calls); try field(out, "source", "last_scan"); try field(out, "traversal", "complete_loaded_graph"); try field(out, "depth_horizon", depth); try field(out, "depth", "minimum_call_distance"); try field(out, "depth_horizon_is_display_only", true); try field(out, "deduplicated", true); try field(out, "locations", "declarations_not_call_sites"); try field(out, "runtime_evidence", false); try field(out, "resolution_counts", "distinct_target_names"); try field(out, "resolution_null", "not_recorded"); try out.endObject();}fn writeReach( out: *pretty_json.Writer, graph: graph_mod.Graph, reach: calls.Reach, depth: u32,) !void { try out.beginObject(); try field(out, "total", reach.total); try field(out, "test_marked", reach.test_marked); try field(out, "other", reach.total - reach.test_marked); try field(out, "max_depth", reach.max_depth); try field(out, "beyond_horizon", reach.beyond(depth)); try out.objectField("strata"); try out.beginArray(); const shown_depth = @min(depth, reach.max_depth); for (reach.strata[0..shown_depth]) |stratum| { try writeStratum(out, graph, reach, stratum); } try out.endArray(); try out.endObject();}fn writeStratum( out: *pretty_json.Writer, graph: graph_mod.Graph, reach: calls.Reach, stratum: calls.Stratum,) !void { try out.beginObject(); try field(out, "depth", stratum.depth); try field(out, "total", stratum.count); try field(out, "test_marked", stratum.test_marked); try field(out, "other", stratum.count - stratum.test_marked); try out.objectField("territories"); try writeTerritories(out, graph, reach, stratum); try out.objectField("samples"); try writeSamples(out, graph, reach, stratum); try out.endObject();}fn writeTerritories( out: *pretty_json.Writer, graph: graph_mod.Graph, reach: calls.Reach, stratum: calls.Stratum,) !void { const start: usize = @intCast(stratum.territory_start); const total: usize = @intCast(stratum.territory_count); const displayed = @min(total, territory_max); try out.beginObject(); try field(out, "total", total); try field(out, "displayed", displayed); try field(out, "truncated", displayed < total); try out.objectField("items"); try out.beginArray(); for (reach.territories[start..][0..displayed]) |territory| { try out.beginObject(); try field(out, "name", graph.nodes.items[territory.node].name); try field(out, "type", graph.nodes.items[territory.node].type); try field(out, "count", territory.count); try out.endObject(); } try out.endArray(); try out.endObject();}fn writeSamples( out: *pretty_json.Writer, graph: graph_mod.Graph, reach: calls.Reach, stratum: calls.Stratum,) !void { try out.beginObject(); const displayed: usize = @min(stratum.count, sample_max); try field(out, "displayed", displayed); try field(out, "truncated", displayed < stratum.count); try out.objectField("items"); try out.beginArray(); var count: usize = 0; for (reach.entries) |entry| { if (entry.depth != stratum.depth) continue; if (count == displayed) break; try out.beginObject(); try out.objectField("declaration"); try writeNode(out, graph.nodes.items[entry.node]); try out.objectField("territory"); try writeNodeIdentity(out, graph.nodes.items[entry.territory]); try field(out, "test_marked", entry.test_marked); try field(out, "cycle", entry.cycle); try out.endObject(); count += 1; } try out.endArray(); try out.endObject();}fn writeCycle( out: *pretty_json.Writer, graph: graph_mod.Graph, cycle: calls.Cycle,) !void { const displayed = @min(cycle.members.len, cycle_member_max); try out.beginObject(); try field(out, "self_recursive", cycle.recursive); try field(out, "other_members_total", cycle.members.len); try field(out, "members_displayed", displayed); try field(out, "members_truncated", displayed < cycle.members.len); try out.objectField("members"); try out.beginArray(); for (cycle.members[0..displayed]) |node_index| { try writeNode(out, graph.nodes.items[node_index]); } try out.endArray(); try out.endObject();}fn writeResolution( out: *pretty_json.Writer, resolution: calls.Resolution,) !void { try out.beginObject(); try out.objectField("unresolved_call_targets"); try writeOptional(out, resolution.unresolved_targets); try out.objectField("external_call_targets"); try writeOptional(out, resolution.external_targets); try out.endObject();}fn writeOptional(out: *pretty_json.Writer, value: ?u32) !void { if (value) |count| { try out.write(count); } else { try out.write(null); }}fn writeNodeIdentity( out: *pretty_json.Writer, node: model.Node,) !void { try out.beginObject(); try field(out, "name", node.name); try field(out, "type", node.type); try out.endObject();}fn writeNode(out: *pretty_json.Writer, node: model.Node) !void { try out.beginObject(); try field(out, "name", node.name); try field(out, "type", node.type); try out.objectField("file"); if (node.file) |file_name| { try out.write(file_name); } else { try out.write(null); } try out.objectField("line"); if (node.line) |line| { try out.write(line); } else { try out.write(null); } try out.endObject();}fn field(out: *pretty_json.Writer, name: []const u8, value: anytype) !void { try out.objectField(name); try out.write(value);}test "call architecture json preserves semantics and exact totals" { const fixture = @import("fixture.zig"); var arena = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena.deinit(); const allocator = arena.allocator(); const graph = try fixture.small(allocator); const report = try calls.build(allocator, graph, "app.focus"); var out: std.Io.Writer.Allocating = .init(allocator); try write(&out.writer, graph, report, 1); const parsed = try std.json.parseFromSlice( std.json.Value, allocator, out.written(), .{}, ); defer parsed.deinit(); const root = parsed.value.object; try std.testing.expectEqual( @as(i64, 2), root.get("callers").?.object.get("total").?.integer, ); try std.testing.expectEqual( @as(i64, 2), root.get("resolution").?.object .get("unresolved_call_targets").?.integer, ); try std.testing.expect( root.get("semantics").?.object.get("deduplicated").?.bool, ); try std.testing.expect( root.get("semantics").?.object .get("depth_horizon_is_display_only").?.bool, );}test "call architecture caps samples without losing 600 caller total" { const fixture = @import("fixture.zig"); var arena = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena.deinit(); const allocator = arena.allocator(); const graph = try fixture.manyCallers(allocator, 600); const report = try calls.build(allocator, graph, "app.focus"); try std.testing.expectEqual(@as(u32, 600), report.callers.total); var out: std.Io.Writer.Allocating = .init(allocator); try write(&out.writer, graph, report, 1); const parsed = try std.json.parseFromSlice( std.json.Value, allocator, out.written(), .{}, ); defer parsed.deinit(); const root = parsed.value.object; const callers = root.get("callers").?.object; try std.testing.expectEqual( @as(i64, 600), callers.get("total").?.integer, ); const stratum = callers.get("strata").?.array.items[0].object; try std.testing.expectEqual( @as(i64, sample_max), stratum.get("samples").?.object.get("displayed").?.integer, ); try std.testing.expect( stratum.get("samples").?.object.get("truncated").?.bool, ); try std.testing.expect(switch (root.get("resolution").?.object .get("unresolved_call_targets").?) { .null => true, else => false, });}Source: tools/smg/src/command/calls/root.zig:2
zig
pub const json = @import("json.zig");Audit
| Definitions | 2 |
|---|---|
| Public names | 3 |
| Members | 0 |
| Version | 26.7.0 |
| Revision | daab053ee433 |