Function firstToken [src]

Prototype

pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex

Parameters

tree: Astnode: Node.Index

Source

pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex { var end_offset: u32 = 0; var n = node; while (true) switch (tree.nodeTag(n)) { .root => return 0, .test_decl, .@"errdefer", .@"defer", .bool_not, .negation, .bit_not, .negation_wrap, .address_of, .@"try", .@"await", .optional_type, .@"switch", .switch_comma, .if_simple, .@"if", .@"suspend", .@"resume", .@"continue", .@"break", .@"return", .anyframe_type, .identifier, .anyframe_literal, .char_literal, .number_literal, .unreachable_literal, .string_literal, .multiline_string_literal, .grouped_expression, .builtin_call_two, .builtin_call_two_comma, .builtin_call, .builtin_call_comma, .error_set_decl, .@"comptime", .@"nosuspend", .asm_simple, .@"asm", .array_type, .array_type_sentinel, .error_value, => return tree.nodeMainToken(n) - end_offset, .array_init_dot, .array_init_dot_comma, .array_init_dot_two, .array_init_dot_two_comma, .struct_init_dot, .struct_init_dot_comma, .struct_init_dot_two, .struct_init_dot_two_comma, .enum_literal, => return tree.nodeMainToken(n) - 1 - end_offset, .@"catch", .equal_equal, .bang_equal, .less_than, .greater_than, .less_or_equal, .greater_or_equal, .assign_mul, .assign_div, .assign_mod, .assign_add, .assign_sub, .assign_shl, .assign_shl_sat, .assign_shr, .assign_bit_and, .assign_bit_xor, .assign_bit_or, .assign_mul_wrap, .assign_add_wrap, .assign_sub_wrap, .assign_mul_sat, .assign_add_sat, .assign_sub_sat, .assign, .merge_error_sets, .mul, .div, .mod, .array_mult, .mul_wrap, .mul_sat, .add, .sub, .array_cat, .add_wrap, .sub_wrap, .add_sat, .sub_sat, .shl, .shl_sat, .shr, .bit_and, .bit_xor, .bit_or, .@"orelse", .bool_and, .bool_or, .slice_open, .array_access, .array_init_one, .array_init_one_comma, .switch_range, .error_union, => n = tree.nodeData(n).node_and_node[0], .for_range, .call_one, .call_one_comma, .struct_init_one, .struct_init_one_comma, => n = tree.nodeData(n).node_and_opt_node[0], .field_access, .unwrap_optional, => n = tree.nodeData(n).node_and_token[0], .slice, .slice_sentinel, .array_init, .array_init_comma, .struct_init, .struct_init_comma, .call, .call_comma, => n = tree.nodeData(n).node_and_extra[0], .deref => n = tree.nodeData(n).node, .assign_destructure => n = tree.assignDestructure(n).ast.variables[0], .fn_decl, .fn_proto_simple, .fn_proto_multi, .fn_proto_one, .fn_proto, => { var i = tree.nodeMainToken(n); // fn token while (i > 0) { i -= 1; switch (tree.tokenTag(i)) { .keyword_extern, .keyword_export, .keyword_pub, .keyword_inline, .keyword_noinline, .string_literal, => continue, else => return i + 1 - end_offset, } } return i - end_offset; }, .@"usingnamespace" => { const main_token: TokenIndex = tree.nodeMainToken(n); const has_visib_token = tree.isTokenPrecededByTags(main_token, &.{.keyword_pub}); end_offset += @intFromBool(has_visib_token); return main_token - end_offset; }, .async_call_one, .async_call_one_comma, => { end_offset += 1; // async token n = tree.nodeData(n).node_and_opt_node[0]; }, .async_call, .async_call_comma, => { end_offset += 1; // async token n = tree.nodeData(n).node_and_extra[0]; }, .container_field_init, .container_field_align, .container_field, => { const name_token = tree.nodeMainToken(n); const has_comptime_token = tree.isTokenPrecededByTags(name_token, &.{.keyword_comptime}); end_offset += @intFromBool(has_comptime_token); return name_token - end_offset; }, .global_var_decl, .local_var_decl, .simple_var_decl, .aligned_var_decl, => { var i = tree.nodeMainToken(n); // mut token while (i > 0) { i -= 1; switch (tree.tokenTag(i)) { .keyword_extern, .keyword_export, .keyword_comptime, .keyword_pub, .keyword_threadlocal, .string_literal, => continue, else => return i + 1 - end_offset, } } return i - end_offset; }, .block, .block_semicolon, .block_two, .block_two_semicolon, => { // Look for a label. const lbrace = tree.nodeMainToken(n); if (tree.isTokenPrecededByTags(lbrace, &.{ .identifier, .colon })) { end_offset += 2; } return lbrace - end_offset; }, .container_decl, .container_decl_trailing, .container_decl_two, .container_decl_two_trailing, .container_decl_arg, .container_decl_arg_trailing, .tagged_union, .tagged_union_trailing, .tagged_union_two, .tagged_union_two_trailing, .tagged_union_enum_tag, .tagged_union_enum_tag_trailing, => { const main_token = tree.nodeMainToken(n); switch (tree.tokenTag(main_token -| 1)) { .keyword_packed, .keyword_extern => end_offset += 1, else => {}, } return main_token - end_offset; }, .ptr_type_aligned, .ptr_type_sentinel, .ptr_type, .ptr_type_bit_range, => return tree.nodeMainToken(n) - end_offset, .switch_case_one, .switch_case_inline_one, .switch_case, .switch_case_inline, => { const full_switch = tree.fullSwitchCase(n).?; if (full_switch.inline_token) |inline_token| { return inline_token; } else if (full_switch.ast.values.len == 0) { return full_switch.ast.arrow_token - 1 - end_offset; // else token } else { n = full_switch.ast.values[0]; } }, .asm_output, .asm_input => { assert(tree.tokenTag(tree.nodeMainToken(n) - 1) == .l_bracket); return tree.nodeMainToken(n) - 1 - end_offset; }, .while_simple, .while_cont, .@"while", .for_simple, .@"for", => { // Look for a label and inline. const main_token = tree.nodeMainToken(n); var result = main_token; if (tree.isTokenPrecededByTags(result, &.{.keyword_inline})) { result = result - 1; } if (tree.isTokenPrecededByTags(result, &.{ .identifier, .colon })) { result = result - 2; } return result - end_offset; }, }; }