Skip to documentation
SLOP

tiny.smg.command.analyze.support

Reference tiny.smg command analyze support

Defined in command.analyze.

API (2)

Actions

Public operations.

No direct callersNo direct callscommand.analyzesupport
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallsprivate; no linktools.smg.src.command.analyze.commanddeltaFiltertest; no linktools.smg.src.command.analyze.supporttest: delta names preserve first occu...private; no linktools.smg.src.command.analyze.supportappendUniqueDeltaNamecommand.analyze.supportdeltaNames
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallscommand.analyze.commandruncli.outputwriteErrprivate; no linktools.smg.src.command.analyze.supportcandidatescommand.analyze.supportwriteScopeWarning
Static calls · unresolved targets: 1 · external targets: 4.

Source: tools/smg/src/command/analyze/root.zig:3

zig
pub const support = @import("support.zig");

Source: tools/smg/src/command/analyze/support.zig

zig
const std = @import("std");const smg = @import("../../root.zig");const diff = smg.diff;const graph_mod = smg.graph;const model = smg.model;const output = smg.cli.output;const text = smg.text;pub fn deltaNames(allocator: std.mem.Allocator, result: diff.Result) ![]const []const u8 {    var out: std.ArrayList([]const u8) = .empty;    for (result.added_nodes) |node| try appendUniqueDeltaName(allocator, &out, node.name);    for (result.changed_nodes) |node| try appendUniqueDeltaName(allocator, &out, node.node.name);    for (result.added_edges) |edge| {        try appendUniqueDeltaName(allocator, &out, edge.source);        try appendUniqueDeltaName(allocator, &out, edge.target);    }    return try out.toOwnedSlice(allocator);}pub fn writeScopeWarning(allocator: std.mem.Allocator, graph: graph_mod.Graph, filter: []const u8) !void {    const candidate_names = try candidates(allocator, graph, filter);    var out: std.Io.Writer.Allocating = .init(allocator);    errdefer out.deinit();    try out.writer.print("Warning: no nodes matching {s}", .{filter});    if (candidate_names.len != 0) {        try out.writer.writeAll(". Did you mean:");        for (candidate_names[0..@min(candidate_names.len, 5)]) |candidate| try out.writer.print("\n  {s}", .{candidate});    }    try out.writer.writeByte('\n');    try output.writeErr(out.written());}fn candidates(allocator: std.mem.Allocator, graph: graph_mod.Graph, filter: []const u8) ![]const []const u8 {    const suffix = if (std.mem.lastIndexOfScalar(u8, filter, '.')) |index| filter[index + 1 ..] else filter;    const middle = try std.fmt.allocPrint(allocator, ".{s}.", .{suffix});    const end = try std.fmt.allocPrint(allocator, ".{s}", .{suffix});    var out: std.ArrayList([]const u8) = .empty;    for (graph.nodes.items) |node| {        if (std.mem.indexOf(u8, node.name, middle) == null and !std.mem.endsWith(u8, node.name, end)) continue;        const index = std.mem.lastIndexOf(u8, node.name, end) orelse continue;        const candidate = try std.fmt.allocPrint(allocator, "{s}.{s}", .{ node.name[0..index], suffix });        if (!text.list.containsString(out.items, candidate)) try out.append(allocator, candidate);    }    std.mem.sort([]const u8, out.items, {}, stringLess);    return try out.toOwnedSlice(allocator);}fn stringLess(_: void, a: []const u8, b: []const u8) bool {    return std.mem.lessThan(u8, a, b);}fn appendUniqueDeltaName(allocator: std.mem.Allocator, list: *std.ArrayList([]const u8), name: []const u8) !void {    if (!text.list.containsString(list.items, name)) try list.append(allocator, name);}test "delta names preserve first occurrence order" {    const added_nodes = [_]model.Node{.{        .name = "new",        .type = model.NodeType.module,    }};    const changed_nodes = [_]diff.ChangedNode{.{        .node = .{ .name = "changed", .type = model.NodeType.function },        .changes = &.{},    }};    const added_edges = [_]model.Edge{        .{ .source = "new", .rel = model.RelType.calls, .target = "changed" },        .{ .source = "extra", .rel = model.RelType.imports, .target = "new" },    };    const names = try deltaNames(std.testing.allocator, .{        .added_nodes = &added_nodes,        .changed_nodes = &changed_nodes,        .added_edges = &added_edges,    });    defer std.testing.allocator.free(names);    try std.testing.expectEqual(@as(usize, 3), names.len);    try std.testing.expectEqualStrings("new", names[0]);    try std.testing.expectEqualStrings("changed", names[1]);    try std.testing.expectEqualStrings("extra", names[2]);}test "analyze scope candidates match python suffix suggestions" {    var arena = std.heap.ArenaAllocator.init(std.testing.allocator);    defer arena.deinit();    const allocator = arena.allocator();    var graph = graph_mod.init(allocator);    try graph_mod.addNode(&graph, .{ .name = "app.service", .type = model.NodeType.module });    try graph_mod.addNode(&graph, .{ .name = "app.service.Worker", .type = model.NodeType.class });    try graph_mod.addNode(&graph, .{ .name = "pkg.service", .type = model.NodeType.module });    try graph_mod.addNode(&graph, .{ .name = "pkg.service.Helper", .type = model.NodeType.class });    try graph_mod.addNode(&graph, .{ .name = "pkg.other", .type = model.NodeType.module });    const candidate_names = try candidates(allocator, graph, "service");    try std.testing.expectEqual(@as(usize, 2), candidate_names.len);    try std.testing.expectEqualStrings("app.service", candidate_names[0]);    try std.testing.expectEqualStrings("pkg.service", candidate_names[1]);    const none = try candidates(allocator, graph, "missing");    try std.testing.expectEqual(@as(usize, 0), none.len);}

Audit

Definitions3
Public names5
Members0
Version26.7.0
Revisiondaab053ee433