struct full [src]
Fully assembled AST node information.
Members
- ArrayInit (struct)
- ArrayType (struct)
- Asm (struct)
- AssignDestructure (struct)
- Call (struct)
- ContainerDecl (struct)
- ContainerField (struct)
- FnProto (struct)
- For (struct)
- If (struct)
- PtrType (struct)
- Slice (struct)
- StructInit (struct)
- Switch (struct)
- SwitchCase (struct)
- VarDecl (struct)
- While (struct)
Source
pub const full = struct {
pub const VarDecl = struct {
visib_token: ?TokenIndex,
extern_export_token: ?TokenIndex,
lib_name: ?TokenIndex,
threadlocal_token: ?TokenIndex,
comptime_token: ?TokenIndex,
ast: Components,
pub const Components = struct {
mut_token: TokenIndex,
type_node: Node.OptionalIndex,
align_node: Node.OptionalIndex,
addrspace_node: Node.OptionalIndex,
section_node: Node.OptionalIndex,
init_node: Node.OptionalIndex,
};
pub fn firstToken(var_decl: VarDecl) TokenIndex {
return var_decl.visib_token orelse
var_decl.extern_export_token orelse
var_decl.threadlocal_token orelse
var_decl.comptime_token orelse
var_decl.ast.mut_token;
}
};
pub const AssignDestructure = struct {
comptime_token: ?TokenIndex,
ast: Components,
pub const Components = struct {
variables: []const Node.Index,
equal_token: TokenIndex,
value_expr: Node.Index,
};
};
pub const If = struct {
/// Points to the first token after the `|`. Will either be an identifier or
/// a `*` (with an identifier immediately after it).
payload_token: ?TokenIndex,
/// Points to the identifier after the `|`.
error_token: ?TokenIndex,
/// Populated only if else_expr != .none.
else_token: TokenIndex,
ast: Components,
pub const Components = struct {
if_token: TokenIndex,
cond_expr: Node.Index,
then_expr: Node.Index,
else_expr: Node.OptionalIndex,
};
};
pub const While = struct {
ast: Components,
inline_token: ?TokenIndex,
label_token: ?TokenIndex,
payload_token: ?TokenIndex,
error_token: ?TokenIndex,
/// Populated only if else_expr != none.
else_token: TokenIndex,
pub const Components = struct {
while_token: TokenIndex,
cond_expr: Node.Index,
cont_expr: Node.OptionalIndex,
then_expr: Node.Index,
else_expr: Node.OptionalIndex,
};
};
pub const For = struct {
ast: Components,
inline_token: ?TokenIndex,
label_token: ?TokenIndex,
payload_token: TokenIndex,
/// Populated only if else_expr != .none.
else_token: ?TokenIndex,
pub const Components = struct {
for_token: TokenIndex,
inputs: []const Node.Index,
then_expr: Node.Index,
else_expr: Node.OptionalIndex,
};
};
pub const ContainerField = struct {
comptime_token: ?TokenIndex,
ast: Components,
pub const Components = struct {
main_token: TokenIndex,
/// Can only be `.none` after calling `convertToNonTupleLike`.
type_expr: Node.OptionalIndex,
align_expr: Node.OptionalIndex,
value_expr: Node.OptionalIndex,
tuple_like: bool,
};
pub fn firstToken(cf: ContainerField) TokenIndex {
return cf.comptime_token orelse cf.ast.main_token;
}
pub fn convertToNonTupleLike(cf: *ContainerField, tree: *const Ast) void {
if (!cf.ast.tuple_like) return;
if (tree.nodeTag(cf.ast.type_expr.unwrap().?) != .identifier) return;
cf.ast.type_expr = .none;
cf.ast.tuple_like = false;
}
};
pub const FnProto = struct {
visib_token: ?TokenIndex,
extern_export_inline_token: ?TokenIndex,
lib_name: ?TokenIndex,
name_token: ?TokenIndex,
lparen: TokenIndex,
ast: Components,
pub const Components = struct {
proto_node: Node.Index,
fn_token: TokenIndex,
return_type: Node.OptionalIndex,
params: []const Node.Index,
align_expr: Node.OptionalIndex,
addrspace_expr: Node.OptionalIndex,
section_expr: Node.OptionalIndex,
callconv_expr: Node.OptionalIndex,
};
pub const Param = struct {
first_doc_comment: ?TokenIndex,
name_token: ?TokenIndex,
comptime_noalias: ?TokenIndex,
anytype_ellipsis3: ?TokenIndex,
type_expr: ?Node.Index,
};
pub fn firstToken(fn_proto: FnProto) TokenIndex {
return fn_proto.visib_token orelse
fn_proto.extern_export_inline_token orelse
fn_proto.ast.fn_token;
}
/// Abstracts over the fact that anytype and ... are not included
/// in the params slice, since they are simple identifiers and
/// not sub-expressions.
pub const Iterator = struct {
tree: *const Ast,
fn_proto: *const FnProto,
param_i: usize,
tok_i: TokenIndex,
tok_flag: bool,
pub fn next(it: *Iterator) ?Param {
const tree = it.tree;
while (true) {
var first_doc_comment: ?TokenIndex = null;
var comptime_noalias: ?TokenIndex = null;
var name_token: ?TokenIndex = null;
if (!it.tok_flag) {
if (it.param_i >= it.fn_proto.ast.params.len) {
return null;
}
const param_type = it.fn_proto.ast.params[it.param_i];
var tok_i = tree.firstToken(param_type) - 1;
while (true) : (tok_i -= 1) switch (tree.tokenTag(tok_i)) {
.colon => continue,
.identifier => name_token = tok_i,
.doc_comment => first_doc_comment = tok_i,
.keyword_comptime, .keyword_noalias => comptime_noalias = tok_i,
else => break,
};
it.param_i += 1;
it.tok_i = tree.lastToken(param_type) + 1;
// Look for anytype and ... params afterwards.
if (tree.tokenTag(it.tok_i) == .comma) {
it.tok_i += 1;
}
it.tok_flag = true;
return Param{
.first_doc_comment = first_doc_comment,
.comptime_noalias = comptime_noalias,
.name_token = name_token,
.anytype_ellipsis3 = null,
.type_expr = param_type,
};
}
if (tree.tokenTag(it.tok_i) == .comma) {
it.tok_i += 1;
}
if (tree.tokenTag(it.tok_i) == .r_paren) {
return null;
}
if (tree.tokenTag(it.tok_i) == .doc_comment) {
first_doc_comment = it.tok_i;
while (tree.tokenTag(it.tok_i) == .doc_comment) {
it.tok_i += 1;
}
}
switch (tree.tokenTag(it.tok_i)) {
.ellipsis3 => {
it.tok_flag = false; // Next iteration should return null.
return Param{
.first_doc_comment = first_doc_comment,
.comptime_noalias = null,
.name_token = null,
.anytype_ellipsis3 = it.tok_i,
.type_expr = null,
};
},
.keyword_noalias, .keyword_comptime => {
comptime_noalias = it.tok_i;
it.tok_i += 1;
},
else => {},
}
if (tree.tokenTag(it.tok_i) == .identifier and
tree.tokenTag(it.tok_i + 1) == .colon)
{
name_token = it.tok_i;
it.tok_i += 2;
}
if (tree.tokenTag(it.tok_i) == .keyword_anytype) {
it.tok_i += 1;
return Param{
.first_doc_comment = first_doc_comment,
.comptime_noalias = comptime_noalias,
.name_token = name_token,
.anytype_ellipsis3 = it.tok_i - 1,
.type_expr = null,
};
}
it.tok_flag = false;
}
}
};
pub fn iterate(fn_proto: *const FnProto, tree: *const Ast) Iterator {
return .{
.tree = tree,
.fn_proto = fn_proto,
.param_i = 0,
.tok_i = fn_proto.lparen + 1,
.tok_flag = true,
};
}
};
pub const StructInit = struct {
ast: Components,
pub const Components = struct {
lbrace: TokenIndex,
fields: []const Node.Index,
type_expr: Node.OptionalIndex,
};
};
pub const ArrayInit = struct {
ast: Components,
pub const Components = struct {
lbrace: TokenIndex,
elements: []const Node.Index,
type_expr: Node.OptionalIndex,
};
};
pub const ArrayType = struct {
ast: Components,
pub const Components = struct {
lbracket: TokenIndex,
elem_count: Node.Index,
sentinel: Node.OptionalIndex,
elem_type: Node.Index,
};
};
pub const PtrType = struct {
size: std.builtin.Type.Pointer.Size,
allowzero_token: ?TokenIndex,
const_token: ?TokenIndex,
volatile_token: ?TokenIndex,
ast: Components,
pub const Components = struct {
main_token: TokenIndex,
align_node: Node.OptionalIndex,
addrspace_node: Node.OptionalIndex,
sentinel: Node.OptionalIndex,
bit_range_start: Node.OptionalIndex,
bit_range_end: Node.OptionalIndex,
child_type: Node.Index,
};
};
pub const Slice = struct {
ast: Components,
pub const Components = struct {
sliced: Node.Index,
lbracket: TokenIndex,
start: Node.Index,
end: Node.OptionalIndex,
sentinel: Node.OptionalIndex,
};
};
pub const ContainerDecl = struct {
layout_token: ?TokenIndex,
ast: Components,
pub const Components = struct {
main_token: TokenIndex,
/// Populated when main_token is Keyword_union.
enum_token: ?TokenIndex,
members: []const Node.Index,
arg: Node.OptionalIndex,
};
};
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
/// a `*` (with an identifier immediately after it).
payload_token: ?TokenIndex,
ast: Components,
pub const Components = struct {
/// If empty, this is an else case
values: []const Node.Index,
arrow_token: TokenIndex,
target_expr: Node.Index,
};
};
pub const Asm = struct {
ast: Components,
volatile_token: ?TokenIndex,
first_clobber: ?TokenIndex,
outputs: []const Node.Index,
inputs: []const Node.Index,
pub const Components = struct {
asm_token: TokenIndex,
template: Node.Index,
items: []const Node.Index,
rparen: TokenIndex,
};
};
pub const Call = struct {
ast: Components,
async_token: ?TokenIndex,
pub const Components = struct {
lparen: TokenIndex,
fn_expr: Node.Index,
params: []const Node.Index,
};
};
}