struct Iterator [src]
Abstracts over the fact that anytype and ... are not included
in the params slice, since they are simple identifiers and
not sub-expressions.
Fields
tree: *const Ast
fn_proto: *const FnProto
param_i: usize
tok_i: TokenIndex
tok_flag: bool
Members
- next (Function)
Source
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;
}
}
}