Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

renderFunc

ast.renderFunc
fn renderFunc(c: *Context, node: Node) !NodeIndex

File

Code

fn renderFunc(c: *Context, node: Node) !NodeIndex {
    const payload = node.castTag(.func).?.data;
    if (payload.is_pub) _ = try c.addToken(.keyword_pub, "pub");
    if (payload.is_extern) _ = try c.addToken(.keyword_extern, "extern");
    if (payload.is_export) _ = try c.addToken(.keyword_export, "export");
    if (payload.is_inline) _ = try c.addToken(.keyword_inline, "inline");
    const fn_token = try c.addToken(.keyword_fn, "fn");
    if (payload.name) |some| _ = try c.addIdentifier(some);

    var params = try renderParams(c, payload.params, payload.is_var_args);
    defer params.deinit(c.gpa);
    var span: NodeSubRange = undefined;
    if (params.items.len > 1) span = try c.listToSpan(params.items);

    const align_expr_opt = if (payload.alignment) |some| blk: {
        _ = try c.addToken(.keyword_align, "align");
        _ = try c.addToken(.l_paren, "(");
        const res = try c.addNode(.{
            .tag = .number_literal,
            .main_token = try c.addTokenFmt(.number_literal, "{d}", .{some}),
            .data = undefined,
        });
        _ = try c.addToken(.r_paren, ")");
        break :blk res;
    } else null;

    const section_expr_opt = if (payload.linksection_string) |some| blk: {
        _ = try c.addToken(.keyword_linksection, "linksection");
        _ = try c.addToken(.l_paren, "(");
        const res = try c.addNode(.{
            .tag = .string_literal,
            .main_token = try c.addTokenFmt(.string_literal, "\"{f}\"", .{std.zig.fmtString(some)}),
            .data = undefined,
        });
        _ = try c.addToken(.r_paren, ")");
        break :blk res;
    } else null;

    const callconv_expr_opt = if (payload.explicit_callconv) |some| blk: {
        _ = try c.addToken(.keyword_callconv, "callconv");
        _ = try c.addToken(.l_paren, "(");
        const cc_node = switch (some) {
            .c => cc_node: {
                _ = try c.addToken(.period, ".");
                break :cc_node try c.addNode(.{
                    .tag = .enum_literal,
                    .main_token = try c.addToken(.identifier, "c"),
                    .data = undefined,
                });
            },
            .x86_64_sysv,
            .x86_64_win,
            .x86_stdcall,
            .x86_fastcall,
            .x86_thiscall,
            .x86_vectorcall,
            .x86_regcall,
            .aarch64_vfabi,
            .aarch64_sve_pcs,
            .arm_aapcs,
            .arm_aapcs_vfp,
            .m68k_rtd,
            .riscv_vector,
            => cc_node: {
                // .{ .foo = .{} }
                _ = try c.addToken(.period, ".");
                const outer_lbrace = try c.addToken(.l_brace, "{");
                _ = try c.addToken(.period, ".");
                _ = try c.addToken(.identifier, @tagName(some));
                _ = try c.addToken(.equal, "=");
                _ = try c.addToken(.period, ".");
                const inner_lbrace = try c.addToken(.l_brace, "{");
                _ = try c.addToken(.r_brace, "}");
                _ = try c.addToken(.r_brace, "}");
                break :cc_node try c.addNode(.{
                    .tag = .struct_init_dot_two,
                    .main_token = outer_lbrace,
                    .data = .{ .opt_node_and_opt_node = .{
                        (try c.addNode(.{
                            .tag = .struct_init_dot_two,
                            .main_token = inner_lbrace,
                            .data = .{ .opt_node_and_opt_node = .{
                                .none, .none,
                            } },
                        })).toOptional(),
                        .none,
                    } },
                });
            },
        };
        _ = try c.addToken(.r_paren, ")");
        break :blk cc_node;
    } else null;

    const return_type_expr = try renderNode(c, payload.return_type);

    const fn_proto = try blk: {
        if (align_expr_opt == null and section_expr_opt == null and callconv_expr_opt == null) {
            if (params.items.len < 2)
                break :blk c.addNode(.{
                    .tag = .fn_proto_simple,
                    .main_token = fn_token,
                    .data = .{ .opt_node_and_opt_node = .{
                        if (params.items.len == 1) params.items[0].toOptional() else .none,
                        return_type_expr.toOptional(),
                    } },
                })
            else
                break :blk c.addNode(.{
                    .tag = .fn_proto_multi,
                    .main_token = fn_token,
                    .data = .{ .extra_and_opt_node = .{
                        try c.addExtra(span),
                        return_type_expr.toOptional(),
                    } },
                });
        }
        if (params.items.len < 2)
            break :blk c.addNode(.{
                .tag = .fn_proto_one,
                .main_token = fn_token,
                .data = .{
                    .extra_and_opt_node = .{
                        try c.addExtra(std.zig.Ast.Node.FnProtoOne{
                            .param = if (params.items.len == 1) params.items[0].toOptional() else .none,
                            .align_expr = .fromOptional(align_expr_opt),
                            .addrspace_expr = .none, // TODO
                            .section_expr = .fromOptional(section_expr_opt),
                            .callconv_expr = .fromOptional(callconv_expr_opt),
                        }),
                        return_type_expr.toOptional(),
                    },
                },
            })
        else
            break :blk c.addNode(.{
                .tag = .fn_proto,
                .main_token = fn_token,
                .data = .{
                    .extra_and_opt_node = .{
                        try c.addExtra(std.zig.Ast.Node.FnProto{
                            .params_start = span.start,
                            .params_end = span.end,
                            .align_expr = .fromOptional(align_expr_opt),
                            .addrspace_expr = .none, // TODO
                            .section_expr = .fromOptional(section_expr_opt),
                            .callconv_expr = .fromOptional(callconv_expr_opt),
                        }),
                        return_type_expr.toOptional(),
                    },
                },
            });
    };

    const payload_body = payload.body orelse {
        if (payload.is_extern) {
            _ = try c.addToken(.semicolon, ";");
        }
        return fn_proto;
    };
    const body = try renderNode(c, payload_body);
    return c.addNode(.{
        .tag = .fn_decl,
        .main_token = fn_token,
        .data = .{ .node_and_node = .{
            fn_proto, body,
        } },
    });
}