structstd.zig.Ast.full.FnProto[src]

Fields

visib_token: ?TokenIndex
extern_export_inline_token: ?TokenIndex
lib_name: ?TokenIndex
name_token: ?TokenIndex
lparen: TokenIndex
ast: Components

Functions

FunctionfirstToken[src]

pub fn firstToken(fn_proto: FnProto) TokenIndex

Parameters

fn_proto: FnProto

Source Code

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

Functioniterate[src]

pub fn iterate(fn_proto: *const FnProto, tree: *const Ast) Iterator

Parameters

fn_proto: *const FnProto
tree: *const Ast

Source Code

Source code
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,
    };
}

Source Code

Source code
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.Index,
        params: []const Node.Index,
        align_expr: Node.Index,
        addrspace_expr: Node.Index,
        section_expr: Node.Index,
        callconv_expr: Node.Index,
    };

    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 token_tags = it.tree.tokens.items(.tag);
            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 = it.tree.firstToken(param_type) - 1;
                    while (true) : (tok_i -= 1) switch (token_tags[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 = it.tree.lastToken(param_type) + 1;
                    // Look for anytype and ... params afterwards.
                    if (token_tags[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 (token_tags[it.tok_i] == .comma) {
                    it.tok_i += 1;
                }
                if (token_tags[it.tok_i] == .r_paren) {
                    return null;
                }
                if (token_tags[it.tok_i] == .doc_comment) {
                    first_doc_comment = it.tok_i;
                    while (token_tags[it.tok_i] == .doc_comment) {
                        it.tok_i += 1;
                    }
                }
                switch (token_tags[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 = 0,
                        };
                    },
                    .keyword_noalias, .keyword_comptime => {
                        comptime_noalias = it.tok_i;
                        it.tok_i += 1;
                    },
                    else => {},
                }
                if (token_tags[it.tok_i] == .identifier and
                    token_tags[it.tok_i + 1] == .colon)
                {
                    name_token = it.tok_i;
                    it.tok_i += 2;
                }
                if (token_tags[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 = 0,
                    };
                }
                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,
        };
    }
}