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.

walkExpression

Walk.walkExpression
fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void

File

Code

fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void {
    const ast = w.ast;
    switch (ast.nodeTag(node)) {
        .identifier => {
            const name_ident = ast.nodeMainToken(node);
            assert(ast.tokenTag(name_ident) == .identifier);
            const name_bytes = ast.tokenSlice(name_ident);
            _ = w.unreferenced_globals.swapRemove(name_bytes);
            if (w.replace_names.get(name_bytes)) |index| {
                try w.transformations.items[index].delete_var_decl.references.append(w.arena, node);
            }
        },

        .number_literal,
        .char_literal,
        .unreachable_literal,
        .anyframe_literal,
        .string_literal,
        => {},

        .multiline_string_literal => {},

        .error_value => {},

        .block_two,
        .block_two_semicolon,
        .block,
        .block_semicolon,
        => {
            var buf: [2]Ast.Node.Index = undefined;
            const statements = ast.blockStatements(&buf, node).?;
            return walkBlock(w, node, statements);
        },

        .@"defer",
        .@"errdefer",
        .@"comptime",
        .@"nosuspend",
        .@"suspend",
        => {
            return walkExpression(w, ast.nodeData(node).node);
        },

        .field_access => {
            try walkExpression(w, ast.nodeData(node).node_and_token[0]);
        },

        .for_range => {
            const start, const opt_end = ast.nodeData(node).node_and_opt_node;
            try walkExpression(w, start);
            if (opt_end.unwrap()) |end| {
                return walkExpression(w, end);
            }
        },

        .add,
        .add_wrap,
        .add_sat,
        .array_cat,
        .assign,
        .assign_bit_and,
        .assign_bit_or,
        .assign_shl,
        .assign_shl_sat,
        .assign_shr,
        .assign_bit_xor,
        .assign_div,
        .assign_sub,
        .assign_sub_wrap,
        .assign_sub_sat,
        .assign_mod,
        .assign_add,
        .assign_add_wrap,
        .assign_add_sat,
        .assign_mul,
        .assign_mul_wrap,
        .assign_mul_sat,
        .bang_equal,
        .bit_and,
        .bit_or,
        .shl,
        .shl_sat,
        .shr,
        .bit_xor,
        .bool_and,
        .bool_or,
        .div,
        .equal_equal,
        .greater_or_equal,
        .greater_than,
        .less_or_equal,
        .less_than,
        .merge_error_sets,
        .mod,
        .mul,
        .mul_wrap,
        .mul_sat,
        .sub,
        .sub_wrap,
        .sub_sat,
        .@"catch",
        .error_union,
        .switch_range,
        .@"orelse",
        .array_access,
        => {
            const lhs, const rhs = ast.nodeData(node).node_and_node;
            try walkExpression(w, lhs);
            try walkExpression(w, rhs);
        },

        .assign_destructure => {
            const full = ast.assignDestructure(node);
            for (full.ast.variables) |variable_node| {
                switch (ast.nodeTag(variable_node)) {
                    .global_var_decl,
                    .local_var_decl,
                    .simple_var_decl,
                    .aligned_var_decl,
                    => try walkLocalVarDecl(w, ast.fullVarDecl(variable_node).?),

                    else => try walkExpression(w, variable_node),
                }
            }
            return walkExpression(w, full.ast.value_expr);
        },

        .bit_not,
        .bool_not,
        .negation,
        .negation_wrap,
        .optional_type,
        .address_of,
        .@"try",
        .@"resume",
        .deref,
        => {
            return walkExpression(w, ast.nodeData(node).node);
        },

        .array_type,
        .array_type_sentinel,
        => {},

        .ptr_type_aligned,
        .ptr_type_sentinel,
        .ptr_type,
        .ptr_type_bit_range,
        => {},

        .array_init_one,
        .array_init_one_comma,
        .array_init_dot_two,
        .array_init_dot_two_comma,
        .array_init_dot,
        .array_init_dot_comma,
        .array_init,
        .array_init_comma,
        => {
            var elements: [2]Ast.Node.Index = undefined;
            return walkArrayInit(w, ast.fullArrayInit(&elements, node).?);
        },

        .struct_init_one,
        .struct_init_one_comma,
        .struct_init_dot_two,
        .struct_init_dot_two_comma,
        .struct_init_dot,
        .struct_init_dot_comma,
        .struct_init,
        .struct_init_comma,
        => {
            var buf: [2]Ast.Node.Index = undefined;
            return walkStructInit(w, node, ast.fullStructInit(&buf, node).?);
        },

        .call_one,
        .call_one_comma,
        .call,
        .call_comma,
        => {
            var buf: [1]Ast.Node.Index = undefined;
            return walkCall(w, ast.fullCall(&buf, node).?);
        },

        .slice_open, .slice, .slice_sentinel => return walkSlice(w, node, ast.fullSlice(node).?),

        .unwrap_optional => {
            try walkExpression(w, ast.nodeData(node).node_and_token[0]);
        },

        .@"break" => {
            const label_token, const target = ast.nodeData(node).opt_token_and_opt_node;
            if (label_token == .none and target == .none) {
                // no expressions
            } else if (label_token == .none and target != .none) {
                try walkExpression(w, target.unwrap().?);
            } else if (label_token != .none and target == .none) {
                try walkIdentifier(w, label_token.unwrap().?);
            } else if (label_token != .none and target != .none) {
                try walkExpression(w, target.unwrap().?);
            }
        },

        .@"continue" => {
            const opt_label = ast.nodeData(node).opt_token_and_opt_node[0];
            if (opt_label.unwrap()) |label| {
                return walkIdentifier(w, label);
            }
        },

        .@"return" => {
            if (ast.nodeData(node).opt_node.unwrap()) |lhs| {
                try walkExpression(w, lhs);
            }
        },

        .grouped_expression => {
            try walkExpression(w, ast.nodeData(node).node_and_token[0]);
        },

        .container_decl,
        .container_decl_trailing,
        .container_decl_arg,
        .container_decl_arg_trailing,
        .container_decl_two,
        .container_decl_two_trailing,
        .tagged_union,
        .tagged_union_trailing,
        .tagged_union_enum_tag,
        .tagged_union_enum_tag_trailing,
        .tagged_union_two,
        .tagged_union_two_trailing,
        => {
            var buf: [2]Ast.Node.Index = undefined;
            return walkContainerDecl(w, node, ast.fullContainerDecl(&buf, node).?);
        },

        .error_set_decl => {
            const lbrace, const rbrace = ast.nodeData(node).token_and_token;

            var i = lbrace + 1;
            while (i < rbrace) : (i += 1) {
                switch (ast.tokenTag(i)) {
                    .doc_comment => unreachable, // TODO
                    .identifier => try walkIdentifier(w, i),
                    .comma => {},
                    else => unreachable,
                }
            }
        },

        .builtin_call_two,
        .builtin_call_two_comma,
        .builtin_call,
        .builtin_call_comma,
        => {
            var buf: [2]Ast.Node.Index = undefined;
            const params = ast.builtinCallParams(&buf, node).?;
            return walkBuiltinCall(w, node, params);
        },

        .fn_proto_simple,
        .fn_proto_multi,
        .fn_proto_one,
        .fn_proto,
        => {
            var buf: [1]Ast.Node.Index = undefined;
            return walkFnProto(w, ast.fullFnProto(&buf, node).?);
        },

        .anyframe_type => {
            _, const child_type = ast.nodeData(node).token_and_node;
            return walkExpression(w, child_type);
        },

        .@"switch",
        .switch_comma,
        => {
            const full = ast.fullSwitch(node).?;
            try walkExpression(w, full.ast.condition); // condition expression
            try walkExpressions(w, full.ast.cases);
        },

        .switch_case_one,
        .switch_case_inline_one,
        .switch_case,
        .switch_case_inline,
        => return walkSwitchCase(w, ast.fullSwitchCase(node).?),

        .while_simple,
        .while_cont,
        .@"while",
        => return walkWhile(w, node, ast.fullWhile(node).?),

        .for_simple,
        .@"for",
        => return walkFor(w, ast.fullFor(node).?),

        .if_simple,
        .@"if",
        => return walkIf(w, node, ast.fullIf(node).?),

        .asm_simple,
        .@"asm",
        => return walkAsm(w, ast.fullAsm(node).?),

        .enum_literal => {
            return walkIdentifier(w, ast.nodeMainToken(node)); // name
        },

        .fn_decl => unreachable,
        .container_field => unreachable,
        .container_field_init => unreachable,
        .container_field_align => unreachable,
        .root => unreachable,
        .global_var_decl => unreachable,
        .local_var_decl => unreachable,
        .simple_var_decl => unreachable,
        .aligned_var_decl => unreachable,
        .test_decl => unreachable,
        .asm_output => unreachable,
        .asm_input => unreachable,
    }
}