astgen: fix firstToken for container_decl, switch_case, asm, while/for, assign_destructure
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
106
astgen.c
106
astgen.c
@@ -601,6 +601,7 @@ static void advanceSourceCursor(AstGenCtx* ag, uint32_t end) {
|
||||
// Mirrors tree.firstToken (Ast.zig:596).
|
||||
// Recurse through nodes to find the first token.
|
||||
static uint32_t firstToken(const Ast* tree, uint32_t node) {
|
||||
uint32_t end_offset = 0;
|
||||
uint32_t n = node;
|
||||
while (1) {
|
||||
AstNodeTag tag = tree->nodes.tags[n];
|
||||
@@ -654,7 +655,7 @@ static uint32_t firstToken(const Ast* tree, uint32_t node) {
|
||||
case AST_NODE_PTR_TYPE_SENTINEL:
|
||||
case AST_NODE_PTR_TYPE:
|
||||
case AST_NODE_PTR_TYPE_BIT_RANGE:
|
||||
return tree->nodes.main_tokens[n];
|
||||
return tree->nodes.main_tokens[n] - end_offset;
|
||||
|
||||
// Return main_token - 1: dot-prefixed inits and enum_literal
|
||||
// (Ast.zig:645-654).
|
||||
@@ -667,7 +668,7 @@ static uint32_t firstToken(const Ast* tree, uint32_t node) {
|
||||
case AST_NODE_STRUCT_INIT_DOT_TWO:
|
||||
case AST_NODE_STRUCT_INIT_DOT_TWO_COMMA:
|
||||
case AST_NODE_ENUM_LITERAL:
|
||||
return tree->nodes.main_tokens[n] - 1;
|
||||
return tree->nodes.main_tokens[n] - 1 - end_offset;
|
||||
|
||||
// Recurse into LHS: all binary ops and compound expressions
|
||||
// (Ast.zig:656-733).
|
||||
@@ -767,7 +768,7 @@ static uint32_t firstToken(const Ast* tree, uint32_t node) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
return i - end_offset;
|
||||
}
|
||||
// Fn decls: scan backwards for modifiers (Ast.zig:737-759).
|
||||
case AST_NODE_FN_DECL:
|
||||
@@ -788,7 +789,7 @@ static uint32_t firstToken(const Ast* tree, uint32_t node) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
return i - end_offset;
|
||||
}
|
||||
// Container fields: check for preceding comptime (Ast.zig:761-769).
|
||||
case AST_NODE_CONTAINER_FIELD_INIT:
|
||||
@@ -796,8 +797,8 @@ static uint32_t firstToken(const Ast* tree, uint32_t node) {
|
||||
case AST_NODE_CONTAINER_FIELD: {
|
||||
uint32_t mt = tree->nodes.main_tokens[n];
|
||||
if (mt > 0 && tree->tokens.tags[mt - 1] == TOKEN_KEYWORD_COMPTIME)
|
||||
return mt - 1;
|
||||
return mt;
|
||||
end_offset++;
|
||||
return mt - end_offset;
|
||||
}
|
||||
// Blocks: check for label (Ast.zig:794-805).
|
||||
case AST_NODE_BLOCK:
|
||||
@@ -807,12 +808,99 @@ static uint32_t firstToken(const Ast* tree, uint32_t node) {
|
||||
uint32_t lbrace = tree->nodes.main_tokens[n];
|
||||
if (lbrace >= 2 && tree->tokens.tags[lbrace - 1] == TOKEN_COLON
|
||||
&& tree->tokens.tags[lbrace - 2] == TOKEN_IDENTIFIER)
|
||||
return lbrace - 2;
|
||||
return lbrace;
|
||||
end_offset += 2;
|
||||
return lbrace - end_offset;
|
||||
}
|
||||
// Container decls: check for packed/extern (Ast.zig:807-826).
|
||||
case AST_NODE_CONTAINER_DECL:
|
||||
case AST_NODE_CONTAINER_DECL_TRAILING:
|
||||
case AST_NODE_CONTAINER_DECL_TWO:
|
||||
case AST_NODE_CONTAINER_DECL_TWO_TRAILING:
|
||||
case AST_NODE_CONTAINER_DECL_ARG:
|
||||
case AST_NODE_CONTAINER_DECL_ARG_TRAILING:
|
||||
case AST_NODE_TAGGED_UNION:
|
||||
case AST_NODE_TAGGED_UNION_TRAILING:
|
||||
case AST_NODE_TAGGED_UNION_TWO:
|
||||
case AST_NODE_TAGGED_UNION_TWO_TRAILING:
|
||||
case AST_NODE_TAGGED_UNION_ENUM_TAG:
|
||||
case AST_NODE_TAGGED_UNION_ENUM_TAG_TRAILING: {
|
||||
uint32_t mt = tree->nodes.main_tokens[n];
|
||||
if (mt > 0) {
|
||||
TokenizerTag prev = tree->tokens.tags[mt - 1];
|
||||
if (prev == TOKEN_KEYWORD_PACKED
|
||||
|| prev == TOKEN_KEYWORD_EXTERN)
|
||||
end_offset++;
|
||||
}
|
||||
return mt - end_offset;
|
||||
}
|
||||
|
||||
// Switch cases: check for inline/else/values (Ast.zig:834-847).
|
||||
case AST_NODE_SWITCH_CASE_ONE:
|
||||
if (tree->nodes.datas[n].lhs == 0)
|
||||
return tree->nodes.main_tokens[n] - 1 - end_offset;
|
||||
n = tree->nodes.datas[n].lhs;
|
||||
continue;
|
||||
case AST_NODE_SWITCH_CASE_INLINE_ONE:
|
||||
if (tree->nodes.datas[n].lhs == 0)
|
||||
return tree->nodes.main_tokens[n] - 2;
|
||||
end_offset += 1;
|
||||
n = tree->nodes.datas[n].lhs;
|
||||
continue;
|
||||
case AST_NODE_SWITCH_CASE: {
|
||||
uint32_t extra_idx = tree->nodes.datas[n].lhs;
|
||||
uint32_t items_start = tree->extra_data.arr[extra_idx];
|
||||
uint32_t items_end = tree->extra_data.arr[extra_idx + 1];
|
||||
if (items_start == items_end)
|
||||
return tree->nodes.main_tokens[n] - 1 - end_offset;
|
||||
n = tree->extra_data.arr[items_start];
|
||||
continue;
|
||||
}
|
||||
case AST_NODE_SWITCH_CASE_INLINE: {
|
||||
uint32_t extra_idx = tree->nodes.datas[n].lhs;
|
||||
uint32_t items_start = tree->extra_data.arr[extra_idx];
|
||||
uint32_t items_end = tree->extra_data.arr[extra_idx + 1];
|
||||
if (items_start == items_end)
|
||||
return tree->nodes.main_tokens[n] - 2;
|
||||
end_offset += 1;
|
||||
n = tree->extra_data.arr[items_start];
|
||||
continue;
|
||||
}
|
||||
|
||||
// Asm output/input: first token is '[' before main_token
|
||||
// (Ast.zig:849-852).
|
||||
case AST_NODE_ASM_OUTPUT:
|
||||
case AST_NODE_ASM_INPUT:
|
||||
return tree->nodes.main_tokens[n] - 1 - end_offset;
|
||||
|
||||
// While/for: check for inline and label (Ast.zig:854-870).
|
||||
case AST_NODE_WHILE_SIMPLE:
|
||||
case AST_NODE_WHILE_CONT:
|
||||
case AST_NODE_WHILE:
|
||||
case AST_NODE_FOR_SIMPLE:
|
||||
case AST_NODE_FOR: {
|
||||
uint32_t result = tree->nodes.main_tokens[n];
|
||||
if (result > 0
|
||||
&& tree->tokens.tags[result - 1] == TOKEN_KEYWORD_INLINE)
|
||||
result--;
|
||||
if (result >= 2 && tree->tokens.tags[result - 1] == TOKEN_COLON
|
||||
&& tree->tokens.tags[result - 2] == TOKEN_IDENTIFIER)
|
||||
result -= 2;
|
||||
return result - end_offset;
|
||||
}
|
||||
|
||||
// Assign destructure: recurse into first variable
|
||||
// (Ast.zig:735).
|
||||
case AST_NODE_ASSIGN_DESTRUCTURE: {
|
||||
uint32_t extra_start = tree->nodes.datas[n].lhs;
|
||||
// extra_data[extra_start] = variable_count
|
||||
// extra_data[extra_start + 1 .. +1+count] = variables
|
||||
n = tree->extra_data.arr[extra_start + 1];
|
||||
continue;
|
||||
}
|
||||
|
||||
// Fallback for any remaining node types.
|
||||
default:
|
||||
return tree->nodes.main_tokens[n];
|
||||
return tree->nodes.main_tokens[n] - end_offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user