Skip to documentation
SLOP

tiny.smg.scan.clike

Reference tiny.smg scan clike

Defined in scan.

API (3)

Actions

Public operations.

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

Source

Called byCallsprivate; no linktools.smg.src.scan.pipeline.scanscanCLikeLanguageprivate; no linktools.smg.src.scan.clikeenhanceMetadataFromTextprivate; no linktools.smg.src.scan.clikeenhanceNodescan.cliketreeParseCandidatescan.clikeusesCppParserscan.clikeenhanceMetadata
Static calls · unresolved targets: 0 · external targets: 4.
Called byCallsNo direct callsscan.clikeenhanceMetadatatest; no linktools.smg.src.scan.testtest: tree parser gates current compa...test; no linktools.smg.src.scan.testtest: tree parser gates minified and ...scan.cliketreeParseCandidate
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsscan.clikeenhanceMetadataprivate; no linktools.smg.src.scan.pipeline.scanscanCLikeLanguageprivate; no linktools.smg.src.scan.clikecHeaderLooksLikeCppscan.clikeusesCppParser
Static calls · unresolved targets: 0 · external targets: 0.

Source: tools/smg/src/scan/clike.zig

zig
const std = @import("std");const smg = @import("../root.zig");const core = @import("core/root.zig");const scan_metrics = @import("metrics.zig");const graph_mod = smg.graph;const lines_mod = smg.lines;const model = smg.model;const spans = smg.span;const tree = smg.tree;const SourceLines = lines_mod.SourceLines;const Context = struct {    allocator: std.mem.Allocator,    scratch: std.mem.Allocator,    metric_inputs: std.mem.Allocator,    graph: *graph_mod.Graph,    path: []const u8,    source: []const u8,    is_cpp: bool,};pub fn enhanceMetadata(allocator: std.mem.Allocator, scratch: std.mem.Allocator, metric_inputs: std.mem.Allocator, graph: *graph_mod.Graph, path: []const u8, source: []const u8, source_lines: SourceLines, lang: []const u8, limits: smg.ParserLimits) !void {    const is_cpp = usesCppParser(source, lang);    if (!treeParseCandidate(source)) return try enhanceMetadataFromText(allocator, metric_inputs, graph, path, source_lines, is_cpp);    const parsed = if (is_cpp)        try tree.parseCpp(scratch, source, limits)    else        try tree.parseC(scratch, source, limits);    const parsed_value = parsed orelse return try enhanceMetadataFromText(allocator, metric_inputs, graph, path, source_lines, is_cpp);    defer tree.deinit(parsed_value);    const context: Context = .{ .allocator = allocator, .scratch = scratch, .metric_inputs = metric_inputs, .graph = graph, .path = path, .source = source, .is_cpp = is_cpp };    try enhanceNode(context, tree.root(parsed_value));}pub fn usesCppParser(source: []const u8, lang: []const u8) bool {    if (std.mem.eql(u8, lang, "cpp") or std.mem.eql(u8, lang, "cpp_header")) return true;    if (std.mem.eql(u8, lang, "c_header")) return cHeaderLooksLikeCpp(source);    return false;}pub fn treeParseCandidate(source: []const u8) bool {    return core.compactParseCandidateAny(source, &.{"int "});}fn enhanceMetadataFromText(allocator: std.mem.Allocator, metric_inputs: std.mem.Allocator, graph: *graph_mod.Graph, path: []const u8, source_lines: SourceLines, is_cpp: bool) !void {    for (graph.nodes.items) |*node| {        const file = node.file orelse continue;        if (!std.mem.eql(u8, file, path)) continue;        const line = node.line orelse continue;        const end_line = node.end_line orelse line;        if (std.mem.eql(u8, node.type, model.NodeType.function) or std.mem.eql(u8, node.type, model.NodeType.method)) {            if (spans.startsWith(source_lines, line, end_line, "#define ")) {                node.metadata = try model.mergePairs(allocator, node.metadata, try scan_metrics.textMacroMetadata(allocator, source_lines, line, end_line));            } else {                node.metadata = try model.mergePairs(allocator, node.metadata, try scan_metrics.textFunctionMetadata(allocator, metric_inputs, source_lines, line, end_line, .c));            }        } else if (std.mem.eql(u8, node.type, model.NodeType.class) or std.mem.eql(u8, node.type, model.NodeType.type)) {            const c_kind = if (is_cpp) null else model.pairValue(node.metadata, "c_kind");            node.metadata = try model.mergePairs(allocator, node.metadata, try scan_metrics.textSpanMetadata(allocator, source_lines, line, end_line, c_kind));        }    }}fn cHeaderLooksLikeCpp(source: []const u8) bool {    const markers = [_][]const u8{ "class ", "namespace ", "template ", "public:", "private:", "protected:", "virtual ", "override", "::" };    for (markers) |marker| if (std.mem.indexOf(u8, source, marker) != null) return true;    return false;}fn enhanceNode(context: Context, node: tree.Node) anyerror!void {    if (try enhanceNodeMetadata(context, node)) return;    const children = tree.childCount(node);    for (0..children) |raw_index| try enhanceNode(context, tree.child(node, @intCast(raw_index)));}fn enhanceNodeMetadata(context: Context, node: tree.Node) !bool {    const node_kind = tree.kind(node);    if (std.mem.eql(u8, node_kind, "type_definition")) {        try enhanceTypeDefinition(context, node);        return true;    }    if (try enhanceFunctionNode(context, node_kind, node)) return false;    if (try enhanceRecordNode(context, node_kind, node)) return false;    try enhanceMethodDeclarationNode(context, node_kind, node);    return false;}fn enhanceFunctionNode(context: Context, node_kind: []const u8, node: tree.Node) !bool {    if (std.mem.eql(u8, node_kind, "function_definition")) {        try enhanceFunctionDefinition(context, node);        return true;    }    if (std.mem.eql(u8, node_kind, "preproc_function_def")) {        try enhanceMacroDefinition(context, node);        return true;    }    return false;}fn enhanceFunctionDefinition(context: Context, node: tree.Node) !void {    const types = [_][]const u8{ model.NodeType.function, model.NodeType.method };    try replaceNodeMetadata(context, node, &types, try scan_metrics.cFunctionMetadata(context.allocator, context.scratch, context.metric_inputs, context.source, node));}fn enhanceMacroDefinition(context: Context, node: tree.Node) !void {    const types = [_][]const u8{model.NodeType.function};    try replaceNodeMetadata(context, node, &types, try scan_metrics.cMacroMetadata(context.allocator, context.scratch, context.source, node));}fn enhanceRecordNode(context: Context, node_kind: []const u8, node: tree.Node) !bool {    if (std.mem.eql(u8, node_kind, "class_specifier")) {        try enhanceClassSpecifier(context, node);        return true;    }    if (std.mem.eql(u8, node_kind, "struct_specifier")) {        try enhanceAggregateSpecifier(context, node, model.NodeType.class, "struct");        return true;    }    if (std.mem.eql(u8, node_kind, "union_specifier")) {        try enhanceAggregateSpecifier(context, node, model.NodeType.class, "union");        return true;    }    if (std.mem.eql(u8, node_kind, "enum_specifier")) {        try enhanceAggregateSpecifier(context, node, model.NodeType.type, "enum");        return true;    }    return false;}fn enhanceClassSpecifier(context: Context, node: tree.Node) !void {    const types = [_][]const u8{model.NodeType.class};    try replaceNodeMetadata(context, node, &types, try scan_metrics.cDeclarationMetadata(context.allocator, context.scratch, context.source, node));}fn enhanceAggregateSpecifier(context: Context, node: tree.Node, node_type: []const u8, c_kind: []const u8) !void {    const types = [_][]const u8{node_type};    const metadata = if (context.is_cpp and !std.mem.eql(u8, c_kind, "enum")) try scan_metrics.cDeclarationMetadata(context.allocator, context.scratch, context.source, node) else try scan_metrics.cRecordMetadata(context.allocator, context.scratch, context.source, node, c_kind);    try replaceNodeMetadata(context, node, &types, metadata);}fn enhanceMethodDeclarationNode(context: Context, node_kind: []const u8, node: tree.Node) !void {    if (!std.mem.eql(u8, node_kind, "declaration") and !std.mem.eql(u8, node_kind, "field_declaration")) return;    if (!core.hasDescendant(node, "function_declarator")) return;    const types = [_][]const u8{model.NodeType.method};    try replaceNodeMetadata(context, node, &types, try scan_metrics.cDeclarationMetadata(context.allocator, context.scratch, context.source, node));}fn enhanceTypeDefinition(context: Context, node: tree.Node) !void {    const type_node = core.findChild(node, "struct_specifier") orelse core.findChild(node, "union_specifier") orelse core.findChild(node, "enum_specifier") orelse return;    const type_kind = tree.kind(type_node);    const node_type = if (std.mem.eql(u8, type_kind, "enum_specifier")) model.NodeType.type else model.NodeType.class;    const c_kind = if (std.mem.eql(u8, type_kind, "struct_specifier"))        "struct"    else if (std.mem.eql(u8, type_kind, "union_specifier"))        "union"    else        "enum";    const types = [_][]const u8{node_type};    try replaceNodeMetadata(context, node, &types, try scan_metrics.cRecordMetadata(context.allocator, context.scratch, context.source, node, c_kind));}fn replaceNodeMetadata(context: Context, node: tree.Node, node_types: []const []const u8, metadata: []const model.Pair) !void {    replaceUniqueNodeMetadata(context.graph, context.path, tree.startLine(node), tree.endLine(node), node_types, metadata);}fn replaceUniqueNodeMetadata(graph: *graph_mod.Graph, path: []const u8, line: i64, end_line: i64, node_types: []const []const u8, metadata: []const model.Pair) void {    var found: ?usize = null;    var matches: usize = 0;    for (graph.nodes.items, 0..) |node, index| {        if (!nodeMatchesRange(node, path, line, end_line, node_types)) continue;        found = index;        matches += 1;    }    if (matches != 1) return;    graph.nodes.items[found.?].metadata = metadata;}fn nodeMatchesRange(node: model.Node, path: []const u8, line: i64, end_line: i64, node_types: []const []const u8) bool {    const file = node.file orelse return false;    if (!std.mem.eql(u8, file, path)) return false;    if (node.line == null or node.line.? != line) return false;    if (node.end_line == null or node.end_line.? != end_line) return false;    for (node_types) |node_type| if (std.mem.eql(u8, node.type, node_type)) return true;    return false;}

Source: tools/smg/src/scan/root.zig:8

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

Audit

Definitions4
Public names4
Members0
Version26.7.0
Revisiondaab053ee433