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>
This commit is contained in:
2026-02-13 23:48:40 +00:00
parent 6703c40f48
commit 1fd8dace86

179
astgen.c
View File

@@ -7639,6 +7639,23 @@ static uint32_t lastToken(const Ast* tree, uint32_t node) {
return tree->tokens.len - 1; return tree->tokens.len - 1;
// Binary ops: recurse into RHS (Ast.zig:893-948). // 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_ASSIGN:
case AST_NODE_ADD: case AST_NODE_ADD:
case AST_NODE_SUB: case AST_NODE_SUB:
@@ -7774,7 +7791,7 @@ static uint32_t lastToken(const Ast* tree, uint32_t node) {
continue; 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_BOOL_NOT:
case AST_NODE_BIT_NOT: case AST_NODE_BIT_NOT:
case AST_NODE_NEGATION: 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_TRY:
case AST_NODE_AWAIT: case AST_NODE_AWAIT:
case AST_NODE_OPTIONAL_TYPE: case AST_NODE_OPTIONAL_TYPE:
case AST_NODE_SUSPEND:
case AST_NODE_COMPTIME: case AST_NODE_COMPTIME:
case AST_NODE_NOSUSPEND: case AST_NODE_NOSUSPEND:
case AST_NODE_RESUME: 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; 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: 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: 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: case AST_NODE_FOR_RANGE:
if (nd.rhs != 0) { if (nd.rhs != 0) {
n = nd.rhs; n = nd.rhs;
} else { } else {
// Unbounded range: last token is the '..' operator. return tree->nodes.main_tokens[n] + end_offset;
// main_token + 1 (the second dot of ..)
return tree->nodes.main_tokens[n] + 1 + end_offset;
} }
continue; continue;
@@ -7831,22 +7848,19 @@ static uint32_t lastToken(const Ast* tree, uint32_t node) {
case AST_NODE_ANYFRAME_LITERAL: case AST_NODE_ANYFRAME_LITERAL:
return tree->nodes.main_tokens[n] + end_offset; 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: case AST_NODE_CALL_ONE:
end_offset += 1; // rparen end_offset += 1; // rparen
if (nd.rhs != 0) { if (nd.rhs != 0) {
n = nd.rhs; n = nd.rhs;
} else { } else {
n = nd.lhs; return tree->nodes.main_tokens[n] + end_offset;
} }
continue; continue;
case AST_NODE_CALL_ONE_COMMA: case AST_NODE_CALL_ONE_COMMA:
end_offset += 2; // comma + rparen end_offset += 2; // comma + rparen
if (nd.rhs != 0) { n = nd.rhs;
n = nd.rhs;
} else {
n = nd.lhs;
}
continue; continue;
// array_access: end_offset += 1 (rbracket), recurse rhs. // array_access: end_offset += 1 (rbracket), recurse rhs.
@@ -7878,25 +7892,38 @@ static uint32_t lastToken(const Ast* tree, uint32_t node) {
continue; continue;
// local_var_decl (Ast.zig:1209-1217). // local_var_decl (Ast.zig:1209-1217).
// extra[lhs] = LocalVarDecl { type_node, align_node }
case AST_NODE_LOCAL_VAR_DECL: case AST_NODE_LOCAL_VAR_DECL:
if (nd.rhs != 0) { if (nd.rhs != 0) {
n = nd.rhs; // init expr n = nd.rhs; // init expr
} else { } else {
// extra[lhs] has align_node
end_offset += 1; // rparen end_offset += 1; // rparen
n = tree->extra_data.arr[nd.lhs]; // align_node n = tree->extra_data.arr[nd.lhs + 1]; // align_node
} }
continue; continue;
// global_var_decl (Ast.zig:1189-1207). // global_var_decl (Ast.zig:1189-1207).
// extra[lhs] = GlobalVarDecl { type_node, align_node,
// addrspace_node, section_node }
case AST_NODE_GLOBAL_VAR_DECL: case AST_NODE_GLOBAL_VAR_DECL:
if (nd.rhs != 0) { if (nd.rhs != 0) {
n = nd.rhs; // init expr n = nd.rhs; // init expr
} else { } else {
// extra[lhs] = {type_node, align_node, ...} uint32_t section_node = tree->extra_data.arr[nd.lhs + 3];
// complex; approximate by using main_token uint32_t align_node = tree->extra_data.arr[nd.lhs + 1];
end_offset += 1; uint32_t type_node = tree->extra_data.arr[nd.lhs];
return tree->nodes.main_tokens[n] + end_offset; 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; continue;
@@ -7907,11 +7934,9 @@ static uint32_t lastToken(const Ast* tree, uint32_t node) {
n = nd.rhs; n = nd.rhs;
continue; continue;
// grouped_expression: end_offset += 1 (rparen), recurse lhs. // grouped_expression (Ast.zig:983): return rhs token + end_offset.
case AST_NODE_GROUPED_EXPRESSION: case AST_NODE_GROUPED_EXPRESSION:
end_offset += 1; return nd.rhs + end_offset;
n = nd.lhs;
continue;
// if_simple: recurse into body (rhs) (Ast.zig:942). // if_simple: recurse into body (rhs) (Ast.zig:942).
case AST_NODE_IF_SIMPLE: 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]; n = tree->extra_data.arr[nd.rhs - 1];
continue; 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_CONTAINER_DECL_TWO:
case AST_NODE_TAGGED_UNION_TWO: case AST_NODE_TAGGED_UNION_TWO:
if (nd.rhs != 0) { if (nd.rhs != 0) {
@@ -8095,7 +8120,20 @@ static uint32_t lastToken(const Ast* tree, uint32_t node) {
end_offset += 1; end_offset += 1;
n = nd.lhs; n = nd.lhs;
} else { } 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; return tree->nodes.main_tokens[n] + end_offset;
} }
continue; continue;
@@ -8281,6 +8319,91 @@ static uint32_t lastToken(const Ast* tree, uint32_t node) {
continue; 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: default:
// Fallback: return main_token + end_offset. // Fallback: return main_token + end_offset.
return tree->nodes.main_tokens[n] + end_offset; return tree->nodes.main_tokens[n] + end_offset;