feature. See also
. The project being documented here (as the example) is the Zig library itself.
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) {
} 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,
.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);
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));
},
.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,
}
}