Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 56 additions & 9 deletions lib/std/zig/Ast.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1184,14 +1184,7 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex {
n = extra.sentinel;
},

.@"continue" => {
if (datas[n].lhs != 0) {
return datas[n].lhs + end_offset;
} else {
return main_tokens[n] + end_offset;
}
},
.@"break" => {
.@"continue", .@"break" => {
if (datas[n].rhs != 0) {
n = datas[n].rhs;
} else if (datas[n].lhs != 0) {
Expand Down Expand Up @@ -1895,6 +1888,25 @@ pub fn taggedUnionEnumTag(tree: Ast, node: Node.Index) full.ContainerDecl {
});
}

pub fn switchFull(tree: Ast, node: Node.Index) full.Switch {
const data = &tree.nodes.items(.data)[node];
const main_token = tree.nodes.items(.main_token)[node];
const switch_token: TokenIndex, const label_token: ?TokenIndex = switch (tree.tokens.items(.tag)[main_token]) {
.identifier => .{ main_token + 2, main_token },
.keyword_switch => .{ main_token, null },
else => unreachable,
};
const extra = tree.extraData(data.rhs, Ast.Node.SubRange);
return .{
.ast = .{
.switch_token = switch_token,
.condition = data.lhs,
.cases = tree.extra_data[extra.start..extra.end],
},
.label_token = label_token,
};
}

pub fn switchCaseOne(tree: Ast, node: Node.Index) full.SwitchCase {
const data = &tree.nodes.items(.data)[node];
const values: *[1]Node.Index = &data.lhs;
Expand Down Expand Up @@ -2206,6 +2218,21 @@ fn fullContainerDeclComponents(tree: Ast, info: full.ContainerDecl.Components) f
return result;
}

fn fullSwitchComponents(tree: Ast, info: full.Switch.Components) full.Switch {
const token_tags = tree.tokens.items(.tag);
const tok_i = info.switch_token -| 1;
var result: full.Switch = .{
.ast = info,
.label_token = null,
};
if (token_tags[tok_i] == .colon and
token_tags[tok_i -| 1] == .identifier)
{
result.label_token = tok_i - 1;
}
return result;
}

fn fullSwitchCaseComponents(tree: Ast, info: full.SwitchCase.Components, node: Node.Index) full.SwitchCase {
const token_tags = tree.tokens.items(.tag);
const node_tags = tree.nodes.items(.tag);
Expand Down Expand Up @@ -2477,6 +2504,13 @@ pub fn fullContainerDecl(tree: Ast, buffer: *[2]Ast.Node.Index, node: Node.Index
};
}

pub fn fullSwitch(tree: Ast, node: Node.Index) ?full.Switch {
return switch (tree.nodes.items(.tag)[node]) {
.@"switch", .switch_comma => tree.switchFull(node),
else => null,
};
}

pub fn fullSwitchCase(tree: Ast, node: Node.Index) ?full.SwitchCase {
return switch (tree.nodes.items(.tag)[node]) {
.switch_case_one, .switch_case_inline_one => tree.switchCaseOne(node),
Expand Down Expand Up @@ -2829,6 +2863,17 @@ pub const full = struct {
};
};

pub const Switch = struct {
ast: Components,
label_token: ?TokenIndex,

pub const Components = struct {
switch_token: TokenIndex,
condition: Node.Index,
cases: []const Node.Index,
};
};

pub const SwitchCase = struct {
inline_token: ?TokenIndex,
/// Points to the first token after the `|`. Will either be an identifier or
Expand Down Expand Up @@ -3243,6 +3288,7 @@ pub const Node = struct {
/// main_token is the `(`.
async_call_comma,
/// `switch(lhs) {}`. `SubRange[rhs]`.
/// `main_token` is the identifier of a preceding label, if any; otherwise `switch`.
@"switch",
/// Same as switch except there is known to be a trailing comma
/// before the final rbrace
Expand Down Expand Up @@ -3287,7 +3333,8 @@ pub const Node = struct {
@"suspend",
/// `resume lhs`. rhs is unused.
@"resume",
/// `continue`. lhs is token index of label if any. rhs is unused.
/// `continue :lhs rhs`
/// both lhs and rhs may be omitted.
@"continue",
/// `break :lhs rhs`
/// both lhs and rhs may be omitted.
Expand Down
Loading