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;
        }
    }
}