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.

parseFnProto

Parse.parseFnProto
fn parseFnProto(p: *Parse) !?Node.Index

File

lib/std/zig/Parse.zig:715

Code

fn parseFnProto(p: *Parse) !?Node.Index {
    const fn_token = p.eatToken(.keyword_fn) orelse return null;

    // We want the fn proto node to be before its children in the array.
    const fn_proto_index = try p.reserveNode(.fn_proto);
    errdefer p.unreserveNode(fn_proto_index);

    _ = p.eatToken(.identifier);
    const params = try p.parseParamDeclList();
    const align_expr = try p.parseByteAlign();
    const addrspace_expr = try p.parseAddrSpace();
    const section_expr = try p.parseLinkSection();
    const callconv_expr = try p.parseCallconv();
    _ = p.eatToken(.bang);

    const return_type_expr = try p.parseTypeExpr();
    if (return_type_expr == null) {
        // most likely the user forgot to specify the return type.
        // Mark return type as invalid and try to continue.
        try p.warn(.expected_return_type);
    }

    if (align_expr == null and section_expr == null and callconv_expr == null and addrspace_expr == null) {
        switch (params) {
            .zero_or_one => |param| return p.setNode(fn_proto_index, .{
                .tag = .fn_proto_simple,
                .main_token = fn_token,
                .data = .{ .opt_node_and_opt_node = .{
                    param,
                    .fromOptional(return_type_expr),
                } },
            }),
            .multi => |span| {
                return p.setNode(fn_proto_index, .{
                    .tag = .fn_proto_multi,
                    .main_token = fn_token,
                    .data = .{ .extra_and_opt_node = .{
                        try p.addExtra(Node.SubRange{
                            .start = span.start,
                            .end = span.end,
                        }),
                        .fromOptional(return_type_expr),
                    } },
                });
            },
        }
    }
    switch (params) {
        .zero_or_one => |param| return p.setNode(fn_proto_index, .{
            .tag = .fn_proto_one,
            .main_token = fn_token,
            .data = .{ .extra_and_opt_node = .{
                try p.addExtra(Node.FnProtoOne{
                    .param = param,
                    .align_expr = .fromOptional(align_expr),
                    .addrspace_expr = .fromOptional(addrspace_expr),
                    .section_expr = .fromOptional(section_expr),
                    .callconv_expr = .fromOptional(callconv_expr),
                }),
                .fromOptional(return_type_expr),
            } },
        }),
        .multi => |span| {
            return p.setNode(fn_proto_index, .{
                .tag = .fn_proto,
                .main_token = fn_token,
                .data = .{ .extra_and_opt_node = .{
                    try p.addExtra(Node.FnProto{
                        .params_start = span.start,
                        .params_end = span.end,
                        .align_expr = .fromOptional(align_expr),
                        .addrspace_expr = .fromOptional(addrspace_expr),
                        .section_expr = .fromOptional(section_expr),
                        .callconv_expr = .fromOptional(callconv_expr),
                    }),
                    .fromOptional(return_type_expr),
                } },
            });
        },
    }
}