Skip to documentation
SLOP

tiny.smg.zig

Reference tiny.smg zig

Defined in tiny.smg.

API (10)

Actions

Public operations.

Types and contracts

Public types and contracts.

No direct callersNo direct callstiny.smgzig
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallsprivate; no linktools.smg.src.scan.pipeline.scanzigAstFunctionRecordprivate; no linktools.smg.src.scan.pipeline.scanzigAstVariableDecltest; no linktools.smg.src.zigtest: ast documentation and signature...private; no linktools.smg.src.zigdocstringzigdeclarationDocstring
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallsNo direct callsprivate; no linktools.smg.src.scan.pipeline.scanzigAstDeclarationSpanprivate; no linktools.smg.src.zigexpectDeclarationBytestest; no linktools.smg.src.zigtest: ast documentation and signature...zigdeclarationSourceSpan
Static calls · unresolved targets: 0 · external targets: 5.
Called byCallsprivate; no linktools.smg.src.scan.pipeline.scanzigAstFunctionRecordtest; no linktools.smg.src.zigtest: ast documentation and signature...private; no linktools.smg.src.zigcopyTrimmedSignaturezigfunctionSignature
Static calls · unresolved targets: 0 · external targets: 3.
Called byCallsprivate; no linktools.smg.src.scan.pipeline.scanscanZigtest; no linktools.smg.src.zigtest: ast documentation and signature...private; no linktools.smg.src.zigdocstringzigmoduleDocstring
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsprivate; no linktools.smg.src.scan.pipeline.scanzigAstFunctionRecordprivate; no linktools.smg.src.scan.pipeline.scanzigAstTestRecordprivate; no linktools.smg.src.scan.pipeline.scanzigAstVariableDecltest; no linktools.smg.src.zigtest: ast nodes map to source lineszigtokenLinezignodeEndLine
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsprivate; no linktools.smg.src.scan.pipeline.scanzigAstFunctionRecordprivate; no linktools.smg.src.scan.pipeline.scanzigAstTestRecordprivate; no linktools.smg.src.scan.pipeline.scanzigAstVariableDecltest; no linktools.smg.src.zigtest: ast nodes map to source lineszigtokenLinezignodeLine
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsprivate; no linktools.smg.src.scan.pipeline.scanscanZigAstErrorMembersprivate; no linktools.smg.src.scan.pipeline.scanzigAstMemberGapRecordprivate; no linktools.smg.src.scan.pipeline.scanzigAstMemberRecordprivate; no linktools.smg.src.scan.pipeline.scanzigAstUnsupportedMemberGapprivate; no linktools.smg.src.zigdocstringzigtokenDocstring
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallszignodeEndLinezignodeLinelineslineForBytezigtokenLine
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsprivate; no linktools.smg.src.scan.pipeline.scanzigAstVariableDecltest; no linktools.smg.src.zigtest: ast documentation and signature...private; no linktools.smg.src.zigcopyTrimmedprivate; no linktools.smg.src.zigcopyTrimmedSignaturezigvariableSignature
Static calls · unresolved targets: 0 · external targets: 3.

Source: tools/smg/src/root.zig:39

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

Source: tools/smg/src/zig.zig

zig
const std = @import("std");const lines = @import("lines.zig");/// An exact half-open declaration range in parsed Zig source.pub const SourceSpan = struct {    start_byte: u32,    end_byte: u32,};pub fn tokenLine(source_lines: lines.SourceLines, ast: *const std.zig.Ast, token: std.zig.Ast.TokenIndex) i64 {    return lines.lineForByte(source_lines, @intCast(ast.tokenStart(token)));}pub fn nodeLine(source_lines: lines.SourceLines, ast: *const std.zig.Ast, node: std.zig.Ast.Node.Index) i64 {    return tokenLine(source_lines, ast, ast.firstToken(node));}pub fn nodeEndLine(source_lines: lines.SourceLines, ast: *const std.zig.Ast, node: std.zig.Ast.Node.Index) i64 {    return tokenLine(source_lines, ast, ast.lastToken(node));}/// Extracts leading file documentation from //! tokens.pub fn moduleDocstring(    allocator: std.mem.Allocator,    ast: *const std.zig.Ast,) !?[]const u8 {    var end: std.zig.Ast.TokenIndex = 0;    while (end < ast.tokens.len and ast.tokenTag(end) == .container_doc_comment) {        end += 1;    }    return try docstring(allocator, ast, 0, end, .container_doc_comment);}/// Extracts the contiguous /// tokens attached before a declaration.pub fn declarationDocstring(    allocator: std.mem.Allocator,    ast: *const std.zig.Ast,    node: std.zig.Ast.Node.Index,) !?[]const u8 {    var start = ast.firstToken(node);    const end = start;    while (start > 0 and ast.tokenTag(start - 1) == .doc_comment) start -= 1;    return try docstring(allocator, ast, start, end, .doc_comment);}/// Returns attached documentation and the complete declaration terminator.pub fn declarationSourceSpan(    ast: *const std.zig.Ast,    node: std.zig.Ast.Node.Index,) SourceSpan {    var first = ast.firstToken(node);    while (first > 0 and ast.tokenTag(first - 1) == .doc_comment) first -= 1;    const last = ast.lastToken(node);    var end = ast.tokenStart(last) + ast.tokenSlice(last).len;    if (last + 1 < ast.tokens.len and ast.tokenTag(last + 1) == .semicolon) {        const terminator = last + 1;        end = ast.tokenStart(terminator) + ast.tokenSlice(terminator).len;    }    const start = ast.tokenStart(first);    std.debug.assert(start < end);    std.debug.assert(end <= ast.source.len);    return .{ .start_byte = @intCast(start), .end_byte = @intCast(end) };}/// Extracts the contiguous /// tokens attached before a source token.pub fn tokenDocstring(    allocator: std.mem.Allocator,    ast: *const std.zig.Ast,    token: std.zig.Ast.TokenIndex,) !?[]const u8 {    var start = token;    while (start > 0 and ast.tokenTag(start - 1) == .doc_comment) start -= 1;    return try docstring(allocator, ast, start, token, .doc_comment);}/// Copies a function prototype without its body.pub fn functionSignature(    allocator: std.mem.Allocator,    ast: *const std.zig.Ast,    proto: std.zig.Ast.full.FnProto,) ![]const u8 {    const node = proto.ast.proto_node;    const last = ast.lastToken(node);    const has_semicolon = last + 1 < ast.tokens.len and        ast.tokenTag(last + 1) == .semicolon;    return try copyTrimmedSignature(        allocator,        ast.getNodeSource(node),        has_semicolon,    );}/// Copies a value declaration or the header of a container declaration.pub fn variableSignature(    allocator: std.mem.Allocator,    ast: *const std.zig.Ast,    node: std.zig.Ast.Node.Index,    container: bool,) ![]const u8 {    var raw = ast.getNodeSource(node);    if (container) {        const brace = std.mem.indexOfScalar(u8, raw, '{') orelse raw.len;        raw = raw[0..brace];        return try copyTrimmed(allocator, raw);    }    const last = ast.lastToken(node);    const has_semicolon = last + 1 < ast.tokens.len and        ast.tokenTag(last + 1) == .semicolon;    return try copyTrimmedSignature(allocator, raw, has_semicolon);}fn docstring(    allocator: std.mem.Allocator,    ast: *const std.zig.Ast,    start: std.zig.Ast.TokenIndex,    end: std.zig.Ast.TokenIndex,    expected: std.zig.Token.Tag,) !?[]const u8 {    if (start == end) return null;    var size: usize = end - start - 1;    for (start..end) |raw_index| {        const index: std.zig.Ast.TokenIndex = @intCast(raw_index);        std.debug.assert(ast.tokenTag(index) == expected);        size = try std.math.add(usize, size, docLine(ast.tokenSlice(index)).len);    }    const out = try allocator.alloc(u8, size);    var offset: usize = 0;    for (start..end, 0..) |raw_index, line_index| {        const index: std.zig.Ast.TokenIndex = @intCast(raw_index);        const line = docLine(ast.tokenSlice(index));        if (line_index != 0) {            out[offset] = '\n';            offset += 1;        }        @memcpy(out[offset .. offset + line.len], line);        offset += line.len;    }    std.debug.assert(offset == out.len);    return out;}fn docLine(raw: []const u8) []const u8 {    std.debug.assert(raw.len >= 3);    var line = raw[3..];    if (std.mem.startsWith(u8, line, " ")) line = line[1..];    return std.mem.trimEnd(u8, line, "\r");}fn copyTrimmed(allocator: std.mem.Allocator, raw: []const u8) ![]const u8 {    return try allocator.dupe(u8, std.mem.trim(u8, raw, " \t\r\n"));}fn copyTrimmedSignature(    allocator: std.mem.Allocator,    raw: []const u8,    semicolon: bool,) ![]const u8 {    const trimmed = std.mem.trim(u8, raw, " \t\r\n");    const size = try std.math.add(usize, trimmed.len, @intFromBool(semicolon));    const out = try allocator.alloc(u8, size);    @memcpy(out[0..trimmed.len], trimmed);    if (semicolon) out[trimmed.len] = ';';    return out;}test "ast nodes map to source lines" {    const source: [:0]const u8 = "const alpha = 1;\n\nfn beta() void {}\n";    var source_lines = try lines.SourceLines.init(std.testing.allocator, .{ .source = source });    defer source_lines.deinit(std.testing.allocator);    source_lines.fill();    source_lines.activate();    var ast = try std.zig.Ast.parse(std.testing.allocator, source, .{});    defer ast.deinit(std.testing.allocator);    const root_decls = ast.rootDecls();    try std.testing.expectEqual(@as(i64, 1), nodeLine(source_lines, &ast, root_decls[0]));    try std.testing.expectEqual(@as(i64, 3), nodeLine(source_lines, &ast, root_decls[1]));    try std.testing.expectEqual(@as(i64, 3), nodeEndLine(source_lines, &ast, root_decls[1]));}test "ast documentation and signatures preserve source meaning" {    const source: [:0]const u8 =        \\//! Module summary.        \\//!        \\//! More detail.        \\/// Builds a value.        \\pub fn build(        \\    input: u32,        \\) u32 {        \\    return input;        \\}        \\/// Stores state.        \\pub const State = struct {        \\    value: u32,        \\};        \\pub const default_state = State{ .value = 1 };        \\/// Calls an external implementation.        \\pub extern fn external() void;        \\    ;    var ast = try std.zig.Ast.parse(std.testing.allocator, source, .{});    defer ast.deinit(std.testing.allocator);    try std.testing.expectEqual(@as(usize, 0), ast.errors.len);    const module_doc = (try moduleDocstring(std.testing.allocator, &ast)).?;    defer std.testing.allocator.free(module_doc);    try std.testing.expectEqualStrings("Module summary.\n\nMore detail.", module_doc);    const declarations = ast.rootDecls();    var buffer: [1]std.zig.Ast.Node.Index = undefined;    const proto = ast.fullFnProto(&buffer, declarations[0]).?;    const function_doc = (try declarationDocstring(std.testing.allocator, &ast, declarations[0])).?;    defer std.testing.allocator.free(function_doc);    try std.testing.expectEqualStrings("Builds a value.", function_doc);    const function_signature = try functionSignature(std.testing.allocator, &ast, proto);    defer std.testing.allocator.free(function_signature);    try std.testing.expectEqualStrings("pub fn build(\n    input: u32,\n) u32", function_signature);    const container_signature = try variableSignature(std.testing.allocator, &ast, declarations[1], true);    defer std.testing.allocator.free(container_signature);    try std.testing.expectEqualStrings("pub const State = struct", container_signature);    const value_signature = try variableSignature(std.testing.allocator, &ast, declarations[2], false);    defer std.testing.allocator.free(value_signature);    try std.testing.expectEqualStrings("pub const default_state = State{ .value = 1 };", value_signature);    const external_proto = ast.fullFnProto(&buffer, declarations[3]).?;    const external_signature = try functionSignature(std.testing.allocator, &ast, external_proto);    defer std.testing.allocator.free(external_signature);    try std.testing.expectEqualStrings("pub extern fn external() void;", external_signature);    const expected = [_][]const u8{        "/// Builds a value.\npub fn build(\n    input: u32,\n) u32 {\n    return input;\n}",        "/// Stores state.\npub const State = struct {\n    value: u32,\n};",        "pub const default_state = State{ .value = 1 };",        "/// Calls an external implementation.\npub extern fn external() void;",    };    for (declarations, expected) |declaration, exact| {        const span = declarationSourceSpan(&ast, declaration);        try std.testing.expectEqualStrings(            exact,            source[span.start_byte..span.end_byte],        );    }}test "declaration spans preserve every public declaration form" {    const source: [:0]const u8 =        \\/// Stores one value.        \\pub const Box = struct {        \\    value: u8,        \\    /// Reads the value.        \\    pub fn read(self: Box) u8 {        \\        return self.value;        \\    }        \\};        \\/// Names the container.        \\pub const Alias = Box;        \\/// Builds a value.        \\pub fn build() Box {        \\    return .{ .value = 1 };        \\}        \\/// Calls an external implementation.        \\pub extern fn external() void;        \\    ;    var ast = try std.zig.Ast.parse(std.testing.allocator, source, .{});    defer ast.deinit(std.testing.allocator);    try std.testing.expectEqual(@as(usize, 0), ast.errors.len);    const declarations = ast.rootDecls();    const expected = [_][]const u8{        "/// Stores one value.\npub const Box = struct {\n    value: u8,\n    /// Reads the value.\n    pub fn read(self: Box) u8 {\n        return self.value;\n    }\n};",        "/// Names the container.\npub const Alias = Box;",        "/// Builds a value.\npub fn build() Box {\n    return .{ .value = 1 };\n}",        "/// Calls an external implementation.\npub extern fn external() void;",    };    for (declarations, expected) |declaration, exact| {        try expectDeclarationBytes(&ast, declaration, exact);    }    var buffer: [2]std.zig.Ast.Node.Index = undefined;    const variable = ast.fullVarDecl(declarations[0]).?;    const initializer = variable.ast.init_node.unwrap().?;    const container = ast.fullContainerDecl(&buffer, initializer).?;    var method: ?std.zig.Ast.Node.Index = null;    for (container.ast.members) |member| {        var proto_buffer: [1]std.zig.Ast.Node.Index = undefined;        if (ast.fullFnProto(&proto_buffer, member) != null) method = member;    }    try expectDeclarationBytes(        &ast,        method.?,        "/// Reads the value.\n    pub fn read(self: Box) u8 {\n        return self.value;\n    }",    );}fn expectDeclarationBytes(    ast: *const std.zig.Ast,    declaration: std.zig.Ast.Node.Index,    expected: []const u8,) !void {    const span = declarationSourceSpan(ast, declaration);    try std.testing.expectEqualStrings(        expected,        ast.source[span.start_byte..span.end_byte],    );}

Audit

Definitions11
Public names11
Members2
Version26.7.0
Revisiondaab053ee433