mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
autodoc: added support for error sets and extended functions
This commit is contained in:
parent
67f1d2b967
commit
63be9e65ed
2 changed files with 154 additions and 84 deletions
|
|
@ -236,6 +236,10 @@
|
||||||
return { type: typeTypeId };
|
return { type: typeTypeId };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ("bool" in decl.value) {
|
||||||
|
return { type: typeKinds.Bool };
|
||||||
|
}
|
||||||
|
|
||||||
console.log("TODO: handle in `typeOfDecl` more cases: ", decl);
|
console.log("TODO: handle in `typeOfDecl` more cases: ", decl);
|
||||||
console.assert(false);
|
console.assert(false);
|
||||||
throw {};
|
throw {};
|
||||||
|
|
|
||||||
234
src/Autodoc.zig
234
src/Autodoc.zig
|
|
@ -402,7 +402,10 @@ const DocData = struct {
|
||||||
child: TypeRef,
|
child: TypeRef,
|
||||||
},
|
},
|
||||||
ErrorUnion: struct { name: []const u8 },
|
ErrorUnion: struct { name: []const u8 },
|
||||||
ErrorSet: struct { name: []const u8 },
|
ErrorSet: struct {
|
||||||
|
name: []const u8,
|
||||||
|
fields: []const Field,
|
||||||
|
},
|
||||||
Enum: struct {
|
Enum: struct {
|
||||||
name: []const u8,
|
name: []const u8,
|
||||||
src: ?usize = null, // index into astNodes
|
src: ?usize = null, // index into astNodes
|
||||||
|
|
@ -430,6 +433,11 @@ const DocData = struct {
|
||||||
Vector: struct { name: []const u8 },
|
Vector: struct { name: []const u8 },
|
||||||
EnumLiteral: struct { name: []const u8 },
|
EnumLiteral: struct { name: []const u8 },
|
||||||
|
|
||||||
|
const Field = struct {
|
||||||
|
name: []const u8,
|
||||||
|
docs: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn jsonStringify(
|
pub fn jsonStringify(
|
||||||
self: Type,
|
self: Type,
|
||||||
opt: std.json.StringifyOptions,
|
opt: std.json.StringifyOptions,
|
||||||
|
|
@ -1167,6 +1175,37 @@ fn walkInstruction(
|
||||||
.fieldVals = field_vals,
|
.fieldVals = field_vals,
|
||||||
} };
|
} };
|
||||||
},
|
},
|
||||||
|
.error_set_decl => {
|
||||||
|
const pl_node = data[inst_index].pl_node;
|
||||||
|
const extra = file.zir.extraData(Zir.Inst.ErrorSetDecl, pl_node.payload_index);
|
||||||
|
const fields = try self.arena.alloc(
|
||||||
|
DocData.Type.Field,
|
||||||
|
extra.data.fields_len,
|
||||||
|
);
|
||||||
|
var idx = extra.end;
|
||||||
|
for (fields) |*f| {
|
||||||
|
const name = file.zir.nullTerminatedString(file.zir.extra[idx]);
|
||||||
|
idx += 1;
|
||||||
|
|
||||||
|
const docs = file.zir.nullTerminatedString(file.zir.extra[idx]);
|
||||||
|
idx += 1;
|
||||||
|
|
||||||
|
f.* = .{
|
||||||
|
.name = name,
|
||||||
|
.docs = docs,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const type_slot_index = self.types.items.len;
|
||||||
|
try self.types.append(self.arena, .{
|
||||||
|
.ErrorSet = .{
|
||||||
|
.name = "todo errset",
|
||||||
|
.fields = fields,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return DocData.WalkResult{ .type = type_slot_index };
|
||||||
|
},
|
||||||
.param_anytype => {
|
.param_anytype => {
|
||||||
// Analysis of anytype function params happens in `.func`.
|
// Analysis of anytype function params happens in `.func`.
|
||||||
// This switch case handles the case where an expression depends
|
// This switch case handles the case where an expression depends
|
||||||
|
|
@ -1228,88 +1267,12 @@ fn walkInstruction(
|
||||||
return DocData.WalkResult{ .call = call_slot_index };
|
return DocData.WalkResult{ .call = call_slot_index };
|
||||||
},
|
},
|
||||||
.func, .func_inferred => {
|
.func, .func_inferred => {
|
||||||
const fn_info = file.zir.getFnInfo(@intCast(u32, inst_index));
|
return self.analyzeFunction(
|
||||||
|
file,
|
||||||
try self.ast_nodes.ensureUnusedCapacity(self.arena, fn_info.total_params_len);
|
parent_scope,
|
||||||
var param_type_refs = try std.ArrayListUnmanaged(DocData.TypeRef).initCapacity(
|
inst_index,
|
||||||
self.arena,
|
self_ast_node_index,
|
||||||
fn_info.total_params_len,
|
|
||||||
);
|
);
|
||||||
var param_ast_indexes = try std.ArrayListUnmanaged(usize).initCapacity(
|
|
||||||
self.arena,
|
|
||||||
fn_info.total_params_len,
|
|
||||||
);
|
|
||||||
// TODO: handle scope rules for fn parameters
|
|
||||||
for (fn_info.param_body[0..fn_info.total_params_len]) |param_index| {
|
|
||||||
switch (tags[param_index]) {
|
|
||||||
else => panicWithContext(
|
|
||||||
file,
|
|
||||||
param_index,
|
|
||||||
"TODO: handle `{s}` in walkInstruction.func\n",
|
|
||||||
.{@tagName(tags[param_index])},
|
|
||||||
),
|
|
||||||
.param_anytype => {
|
|
||||||
// TODO: where are the doc comments?
|
|
||||||
const str_tok = data[param_index].str_tok;
|
|
||||||
|
|
||||||
const name = str_tok.get(file.zir);
|
|
||||||
|
|
||||||
param_ast_indexes.appendAssumeCapacity(self.ast_nodes.items.len);
|
|
||||||
self.ast_nodes.appendAssumeCapacity(.{
|
|
||||||
.name = name,
|
|
||||||
.docs = "",
|
|
||||||
.@"comptime" = true,
|
|
||||||
});
|
|
||||||
|
|
||||||
param_type_refs.appendAssumeCapacity(
|
|
||||||
DocData.TypeRef{ .@"anytype" = {} },
|
|
||||||
);
|
|
||||||
},
|
|
||||||
.param, .param_comptime => {
|
|
||||||
const pl_tok = data[param_index].pl_tok;
|
|
||||||
const extra = file.zir.extraData(Zir.Inst.Param, pl_tok.payload_index);
|
|
||||||
const doc_comment = if (extra.data.doc_comment != 0)
|
|
||||||
file.zir.nullTerminatedString(extra.data.doc_comment)
|
|
||||||
else
|
|
||||||
"";
|
|
||||||
const name = file.zir.nullTerminatedString(extra.data.name);
|
|
||||||
|
|
||||||
param_ast_indexes.appendAssumeCapacity(self.ast_nodes.items.len);
|
|
||||||
self.ast_nodes.appendAssumeCapacity(.{
|
|
||||||
.name = name,
|
|
||||||
.docs = doc_comment,
|
|
||||||
.@"comptime" = tags[param_index] == .param_comptime,
|
|
||||||
});
|
|
||||||
|
|
||||||
const break_index = file.zir.extra[extra.end..][extra.data.body_len - 1];
|
|
||||||
const break_operand = data[break_index].@"break".operand;
|
|
||||||
const param_type_ref = try self.walkRef(file, parent_scope, break_operand);
|
|
||||||
|
|
||||||
param_type_refs.appendAssumeCapacity(
|
|
||||||
walkResultToTypeRef(param_type_ref),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ret
|
|
||||||
const ret_type_ref = blk: {
|
|
||||||
const last_instr_index = fn_info.ret_ty_body[fn_info.ret_ty_body.len - 1];
|
|
||||||
const break_operand = data[last_instr_index].@"break".operand;
|
|
||||||
const wr = try self.walkRef(file, parent_scope, break_operand);
|
|
||||||
break :blk walkResultToTypeRef(wr);
|
|
||||||
};
|
|
||||||
|
|
||||||
self.ast_nodes.items[self_ast_node_index].fields = param_ast_indexes.items;
|
|
||||||
try self.types.append(self.arena, .{
|
|
||||||
.Fn = .{
|
|
||||||
.name = "todo_name func",
|
|
||||||
.src = self_ast_node_index,
|
|
||||||
.params = param_type_refs.items,
|
|
||||||
.ret = ret_type_ref,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return DocData.WalkResult{ .type = self.types.items.len - 1 };
|
|
||||||
},
|
},
|
||||||
.extended => {
|
.extended => {
|
||||||
// NOTE: this code + the subsequent defer block are working towards
|
// NOTE: this code + the subsequent defer block are working towards
|
||||||
|
|
@ -1338,11 +1301,21 @@ fn walkInstruction(
|
||||||
const extended = data[inst_index].extended;
|
const extended = data[inst_index].extended;
|
||||||
switch (extended.opcode) {
|
switch (extended.opcode) {
|
||||||
else => {
|
else => {
|
||||||
std.debug.panic(
|
panicWithContext(
|
||||||
"TODO: implement `walkinstruction.extended` for {s}\n\n",
|
file,
|
||||||
|
inst_index,
|
||||||
|
"TODO: implement `walkInstruction.extended` for {s}\n\n",
|
||||||
.{@tagName(extended.opcode)},
|
.{@tagName(extended.opcode)},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
.func => {
|
||||||
|
return try self.analyzeFunction(
|
||||||
|
file,
|
||||||
|
parent_scope,
|
||||||
|
inst_index,
|
||||||
|
self_ast_node_index,
|
||||||
|
);
|
||||||
|
},
|
||||||
.variable => {
|
.variable => {
|
||||||
const small = @bitCast(Zir.Inst.ExtendedVar.Small, extended.small);
|
const small = @bitCast(Zir.Inst.ExtendedVar.Small, extended.small);
|
||||||
var extra_index: usize = extended.operand;
|
var extra_index: usize = extended.operand;
|
||||||
|
|
@ -2105,6 +2078,99 @@ fn tryResolveDeclPath(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn analyzeFunction(
|
||||||
|
self: *Autodoc,
|
||||||
|
file: *File,
|
||||||
|
scope: *Scope,
|
||||||
|
inst_index: usize,
|
||||||
|
self_ast_node_index: usize,
|
||||||
|
) error{OutOfMemory}!DocData.WalkResult {
|
||||||
|
const tags = file.zir.instructions.items(.tag);
|
||||||
|
const data = file.zir.instructions.items(.data);
|
||||||
|
|
||||||
|
const fn_info = file.zir.getFnInfo(@intCast(u32, inst_index));
|
||||||
|
try self.ast_nodes.ensureUnusedCapacity(self.arena, fn_info.total_params_len);
|
||||||
|
var param_type_refs = try std.ArrayListUnmanaged(DocData.TypeRef).initCapacity(
|
||||||
|
self.arena,
|
||||||
|
fn_info.total_params_len,
|
||||||
|
);
|
||||||
|
var param_ast_indexes = try std.ArrayListUnmanaged(usize).initCapacity(
|
||||||
|
self.arena,
|
||||||
|
fn_info.total_params_len,
|
||||||
|
);
|
||||||
|
// TODO: handle scope rules for fn parameters
|
||||||
|
for (fn_info.param_body[0..fn_info.total_params_len]) |param_index| {
|
||||||
|
switch (tags[param_index]) {
|
||||||
|
else => panicWithContext(
|
||||||
|
file,
|
||||||
|
param_index,
|
||||||
|
"TODO: handle `{s}` in walkInstruction.func\n",
|
||||||
|
.{@tagName(tags[param_index])},
|
||||||
|
),
|
||||||
|
.param_anytype => {
|
||||||
|
// TODO: where are the doc comments?
|
||||||
|
const str_tok = data[param_index].str_tok;
|
||||||
|
|
||||||
|
const name = str_tok.get(file.zir);
|
||||||
|
|
||||||
|
param_ast_indexes.appendAssumeCapacity(self.ast_nodes.items.len);
|
||||||
|
self.ast_nodes.appendAssumeCapacity(.{
|
||||||
|
.name = name,
|
||||||
|
.docs = "",
|
||||||
|
.@"comptime" = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
param_type_refs.appendAssumeCapacity(
|
||||||
|
DocData.TypeRef{ .@"anytype" = {} },
|
||||||
|
);
|
||||||
|
},
|
||||||
|
.param, .param_comptime => {
|
||||||
|
const pl_tok = data[param_index].pl_tok;
|
||||||
|
const extra = file.zir.extraData(Zir.Inst.Param, pl_tok.payload_index);
|
||||||
|
const doc_comment = if (extra.data.doc_comment != 0)
|
||||||
|
file.zir.nullTerminatedString(extra.data.doc_comment)
|
||||||
|
else
|
||||||
|
"";
|
||||||
|
const name = file.zir.nullTerminatedString(extra.data.name);
|
||||||
|
|
||||||
|
param_ast_indexes.appendAssumeCapacity(self.ast_nodes.items.len);
|
||||||
|
self.ast_nodes.appendAssumeCapacity(.{
|
||||||
|
.name = name,
|
||||||
|
.docs = doc_comment,
|
||||||
|
.@"comptime" = tags[param_index] == .param_comptime,
|
||||||
|
});
|
||||||
|
|
||||||
|
const break_index = file.zir.extra[extra.end..][extra.data.body_len - 1];
|
||||||
|
const break_operand = data[break_index].@"break".operand;
|
||||||
|
const param_type_ref = try self.walkRef(file, scope, break_operand);
|
||||||
|
|
||||||
|
param_type_refs.appendAssumeCapacity(
|
||||||
|
walkResultToTypeRef(param_type_ref),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ret
|
||||||
|
const ret_type_ref = blk: {
|
||||||
|
const last_instr_index = fn_info.ret_ty_body[fn_info.ret_ty_body.len - 1];
|
||||||
|
const break_operand = data[last_instr_index].@"break".operand;
|
||||||
|
const wr = try self.walkRef(file, scope, break_operand);
|
||||||
|
break :blk walkResultToTypeRef(wr);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.ast_nodes.items[self_ast_node_index].fields = param_ast_indexes.items;
|
||||||
|
try self.types.append(self.arena, .{
|
||||||
|
.Fn = .{
|
||||||
|
.name = "todo_name func",
|
||||||
|
.src = self_ast_node_index,
|
||||||
|
.params = param_type_refs.items,
|
||||||
|
.ret = ret_type_ref,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return DocData.WalkResult{ .type = self.types.items.len - 1 };
|
||||||
|
}
|
||||||
|
|
||||||
fn collectUnionFieldInfo(
|
fn collectUnionFieldInfo(
|
||||||
self: *Autodoc,
|
self: *Autodoc,
|
||||||
file: *File,
|
file: *File,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue