commit 1fd8dace86be40f05cdeb89fc99c9ada1e658cd8 (tree)
parent 6703c40f482d455f46d2e018f61ab6cbbd0a6db5
Author: Motiejus Jakštys <motiejus@jakstys.lt>
Date: Fri, 13 Feb 2026 23:48:40 +0000
astgen: fix lastToken for deref, compound assigns, call_one, container_decl, for_range, var_decl, asm, and more
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat:
| M | astgen.c | | | 179 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------- |
1 file changed, 151 insertions(+), 28 deletions(-)
diff --git a/astgen.c b/astgen.c
@@ -7639,6 +7639,23 @@ static uint32_t lastToken(const Ast* tree, uint32_t node) {
return tree->tokens.len - 1;
// Binary ops: recurse into RHS (Ast.zig:893-948).
+ case AST_NODE_ASSIGN_MUL:
+ case AST_NODE_ASSIGN_DIV:
+ case AST_NODE_ASSIGN_MOD:
+ case AST_NODE_ASSIGN_ADD:
+ case AST_NODE_ASSIGN_SUB:
+ case AST_NODE_ASSIGN_SHL:
+ case AST_NODE_ASSIGN_SHL_SAT:
+ case AST_NODE_ASSIGN_SHR:
+ case AST_NODE_ASSIGN_BIT_AND:
+ case AST_NODE_ASSIGN_BIT_XOR:
+ case AST_NODE_ASSIGN_BIT_OR:
+ case AST_NODE_ASSIGN_MUL_WRAP:
+ case AST_NODE_ASSIGN_ADD_WRAP:
+ case AST_NODE_ASSIGN_SUB_WRAP:
+ case AST_NODE_ASSIGN_MUL_SAT:
+ case AST_NODE_ASSIGN_ADD_SAT:
+ case AST_NODE_ASSIGN_SUB_SAT:
case AST_NODE_ASSIGN:
case AST_NODE_ADD:
case AST_NODE_SUB:
@@ -7774,7 +7791,7 @@ static uint32_t lastToken(const Ast* tree, uint32_t node) {
continue;
}
- // Unary ops: recurse into lhs (Ast.zig:895-910).
+ // Unary ops: recurse into lhs (Ast.zig:880-891).
case AST_NODE_BOOL_NOT:
case AST_NODE_BIT_NOT:
case AST_NODE_NEGATION:
@@ -7783,6 +7800,7 @@ static uint32_t lastToken(const Ast* tree, uint32_t node) {
case AST_NODE_TRY:
case AST_NODE_AWAIT:
case AST_NODE_OPTIONAL_TYPE:
+ case AST_NODE_SUSPEND:
case AST_NODE_COMPTIME:
case AST_NODE_NOSUSPEND:
case AST_NODE_RESUME:
@@ -7797,22 +7815,21 @@ static uint32_t lastToken(const Ast* tree, uint32_t node) {
}
return tree->nodes.main_tokens[n] + end_offset;
- // deref: main_token is the dot, +1 for '*' (Ast.zig:974).
+ // deref: main_token is the `.*` token (Ast.zig:993).
case AST_NODE_DEREF:
- return tree->nodes.main_tokens[n] + 1 + end_offset;
+ return tree->nodes.main_tokens[n] + end_offset;
- // unwrap_optional: +1 for '?' (Ast.zig:971).
+ // unwrap_optional (Ast.zig:980): return rhs token + end_offset.
case AST_NODE_UNWRAP_OPTIONAL:
- return tree->nodes.main_tokens[n] + 1 + end_offset;
+ return nd.rhs + end_offset;
- // for_range: recurse into rhs if present, else lhs.
+ // for_range (Ast.zig:973-977): recurse into rhs if present, else
+ // main_token + end_offset.
case AST_NODE_FOR_RANGE:
if (nd.rhs != 0) {
n = nd.rhs;
} else {
- // Unbounded range: last token is the '..' operator.
- // main_token + 1 (the second dot of ..)
- return tree->nodes.main_tokens[n] + 1 + end_offset;
+ return tree->nodes.main_tokens[n] + end_offset;
}
continue;
@@ -7831,22 +7848,19 @@ static uint32_t lastToken(const Ast* tree, uint32_t node) {
case AST_NODE_ANYFRAME_LITERAL:
return tree->nodes.main_tokens[n] + end_offset;
- // call_one: recurse into lhs, +1 for ')'.
+ // call_one (Ast.zig:1107-1114): +1 for rparen, recurse into
+ // first_param if present.
case AST_NODE_CALL_ONE:
end_offset += 1; // rparen
if (nd.rhs != 0) {
n = nd.rhs;
} else {
- n = nd.lhs;
+ return tree->nodes.main_tokens[n] + end_offset;
}
continue;
case AST_NODE_CALL_ONE_COMMA:
end_offset += 2; // comma + rparen
- if (nd.rhs != 0) {
- n = nd.rhs;
- } else {
- n = nd.lhs;
- }
+ n = nd.rhs;
continue;
// array_access: end_offset += 1 (rbracket), recurse rhs.
@@ -7878,25 +7892,38 @@ static uint32_t lastToken(const Ast* tree, uint32_t node) {
continue;
// local_var_decl (Ast.zig:1209-1217).
+ // extra[lhs] = LocalVarDecl { type_node, align_node }
case AST_NODE_LOCAL_VAR_DECL:
if (nd.rhs != 0) {
n = nd.rhs; // init expr
} else {
- // extra[lhs] has align_node
end_offset += 1; // rparen
- n = tree->extra_data.arr[nd.lhs]; // align_node
+ n = tree->extra_data.arr[nd.lhs + 1]; // align_node
}
continue;
// global_var_decl (Ast.zig:1189-1207).
+ // extra[lhs] = GlobalVarDecl { type_node, align_node,
+ // addrspace_node, section_node }
case AST_NODE_GLOBAL_VAR_DECL:
if (nd.rhs != 0) {
n = nd.rhs; // init expr
} else {
- // extra[lhs] = {type_node, align_node, ...}
- // complex; approximate by using main_token
- end_offset += 1;
- return tree->nodes.main_tokens[n] + end_offset;
+ uint32_t section_node = tree->extra_data.arr[nd.lhs + 3];
+ uint32_t align_node = tree->extra_data.arr[nd.lhs + 1];
+ uint32_t type_node = tree->extra_data.arr[nd.lhs];
+ if (section_node != 0) {
+ end_offset += 1; // rparen
+ n = section_node;
+ } else if (align_node != 0) {
+ end_offset += 1; // rparen
+ n = align_node;
+ } else if (type_node != 0) {
+ n = type_node;
+ } else {
+ end_offset += 1; // from mut token to name
+ return tree->nodes.main_tokens[n] + end_offset;
+ }
}
continue;
@@ -7907,11 +7934,9 @@ static uint32_t lastToken(const Ast* tree, uint32_t node) {
n = nd.rhs;
continue;
- // grouped_expression: end_offset += 1 (rparen), recurse lhs.
+ // grouped_expression (Ast.zig:983): return rhs token + end_offset.
case AST_NODE_GROUPED_EXPRESSION:
- end_offset += 1;
- n = nd.lhs;
- continue;
+ return nd.rhs + end_offset;
// if_simple: recurse into body (rhs) (Ast.zig:942).
case AST_NODE_IF_SIMPLE:
@@ -8085,7 +8110,7 @@ static uint32_t lastToken(const Ast* tree, uint32_t node) {
n = tree->extra_data.arr[nd.rhs - 1];
continue;
- // container_decl_two: like block_two.
+ // container_decl_two / tagged_union_two (Ast.zig:1120-1151).
case AST_NODE_CONTAINER_DECL_TWO:
case AST_NODE_TAGGED_UNION_TWO:
if (nd.rhs != 0) {
@@ -8095,7 +8120,20 @@ static uint32_t lastToken(const Ast* tree, uint32_t node) {
end_offset += 1;
n = nd.lhs;
} else {
- end_offset += 2; // lbrace + rbrace
+ if (tag == AST_NODE_CONTAINER_DECL_TWO) {
+ uint32_t i = 2; // lbrace + rbrace
+ while (tree->tokens.tags[tree->nodes.main_tokens[n] + i]
+ == TOKEN_CONTAINER_DOC_COMMENT)
+ i += 1;
+ end_offset += i;
+ } else {
+ // tagged_union_two: (enum) {}
+ uint32_t i = 5;
+ while (tree->tokens.tags[tree->nodes.main_tokens[n] + i]
+ == TOKEN_CONTAINER_DOC_COMMENT)
+ i += 1;
+ end_offset += i;
+ }
return tree->nodes.main_tokens[n] + end_offset;
}
continue;
@@ -8281,6 +8319,91 @@ static uint32_t lastToken(const Ast* tree, uint32_t node) {
continue;
}
+ // anyframe_type (Ast.zig:952): recurse into rhs.
+ case AST_NODE_ANYFRAME_TYPE:
+ n = nd.rhs;
+ continue;
+
+ // assign_destructure (Ast.zig:960-965): recurse into rhs.
+ case AST_NODE_ASSIGN_DESTRUCTURE:
+ n = nd.rhs;
+ continue;
+
+ // asm_simple (Ast.zig:981): return nd.rhs + end_offset.
+ case AST_NODE_ASM_SIMPLE:
+ return nd.rhs + end_offset;
+
+ // asm_input (Ast.zig:983): return nd.rhs + end_offset.
+ case AST_NODE_ASM_INPUT:
+ return nd.rhs + end_offset;
+
+ // asm_output (Ast.zig:985): return nd.rhs + end_offset.
+ case AST_NODE_ASM_OUTPUT:
+ return nd.rhs + end_offset;
+
+ // asm_legacy (Ast.zig:1053-1057): read rparen from extra data.
+ case AST_NODE_ASM_LEGACY: {
+ // extra[rhs] = AsmLegacy { items_start, items_end, rparen }
+ uint32_t rparen = tree->extra_data.arr[nd.rhs + 2];
+ return rparen + end_offset;
+ }
+
+ // asm (Ast.zig:1058-1062): read rparen from extra data.
+ case AST_NODE_ASM: {
+ // extra[rhs] = Asm { items_start, items_end, clobbers, rparen }
+ uint32_t rparen = tree->extra_data.arr[nd.rhs + 3];
+ return rparen + end_offset;
+ }
+
+ // container_field_init (Ast.zig:1219-1222): recurse into
+ // value_expr or type_expr.
+ case AST_NODE_CONTAINER_FIELD_INIT:
+ if (nd.rhs != 0) {
+ n = nd.rhs; // value_expr
+ } else {
+ n = nd.lhs; // type_expr
+ }
+ continue;
+
+ // container_field_align (Ast.zig:1224-1231): +1 for rparen,
+ // recurse rhs.
+ case AST_NODE_CONTAINER_FIELD_ALIGN:
+ end_offset += 1;
+ n = nd.rhs;
+ continue;
+
+ // container_field (Ast.zig:1232-1236): read value_expr from
+ // extra data.
+ case AST_NODE_CONTAINER_FIELD: {
+ // extra[rhs] = ContainerField { align_expr, value_expr }
+ uint32_t value_expr = tree->extra_data.arr[nd.rhs + 1];
+ n = value_expr;
+ continue;
+ }
+
+ // tagged_union_enum_tag (Ast.zig:1011-1021): SubRange handling.
+ case AST_NODE_TAGGED_UNION_ENUM_TAG: {
+ uint32_t si = tree->extra_data.arr[nd.rhs];
+ uint32_t se = tree->extra_data.arr[nd.rhs + 1];
+ if (si == se) {
+ end_offset += 4; // rparen + rparen + lbrace + rbrace
+ n = nd.lhs;
+ } else {
+ end_offset += 1; // rbrace
+ n = tree->extra_data.arr[se - 1];
+ }
+ continue;
+ }
+ // tagged_union_enum_tag_trailing (Ast.zig:1022-1030).
+ case AST_NODE_TAGGED_UNION_ENUM_TAG_TRAILING: {
+ uint32_t si = tree->extra_data.arr[nd.rhs];
+ uint32_t se = tree->extra_data.arr[nd.rhs + 1];
+ assert(si != se);
+ end_offset += 2; // comma/semicolon + rbrace
+ n = tree->extra_data.arr[se - 1];
+ continue;
+ }
+
default:
// Fallback: return main_token + end_offset.
return tree->nodes.main_tokens[n] + end_offset;