autodoc: init generic function support

This commit is contained in:
Loris Cro 2022-05-30 21:48:46 +02:00 committed by Andrew Kelley
parent 51647c305e
commit 413cfd4066
2 changed files with 73 additions and 11 deletions

View File

@ -724,7 +724,7 @@ var zigAnalysis;
if (typeObj.kind !== typeKinds.Fn) {
return false;
}
return /** @type {Fn} */(typeObj).generic;
return /** @type {Fn} */(typeObj).generic_ret != null;
}
/** @param {Decl} fnDecl */
@ -772,7 +772,26 @@ var zigAnalysis;
let protoSrcIndex = fnDecl.src;
if (typeIsGenericFn(value.expr.type)) {
throw "TODO";
// does the generic_ret contain a container?
var resolvedGenericRet = resolveValue({expr: typeObj.generic_ret});
// TODO: see if unwrapping the `as` here is a good idea or not.
if ("as" in resolvedGenericRet.expr) {
resolvedGenericRet = {
expr: zigAnalysis.exprs[resolvedGenericRet.expr.as.exprArg]
};
}
if (!("type" in resolvedGenericRet.expr)) return;
const genericType = zigAnalysis.types[resolvedGenericRet.expr.type];
if (isContainerType(genericType)) {
renderContainer(genericType)
}
// old code
// let instantiations = nodesToFnsMap[protoSrcIndex];
// let calls = nodesToCallsMap[protoSrcIndex];
// if (instantiations == null && calls == null) {
@ -1530,7 +1549,7 @@ var zigAnalysis;
return html;
}
}
case typeKinds.ErrorUnion:
{
let errUnionObj = /** @type {ErrUnionType} */(typeObj);
@ -1614,7 +1633,7 @@ var zigAnalysis;
if (isVarArgs && i === fnObj.params.length - 1) {
payloadHtml += '...';
}
}
else if ("typeOf" in value) {
if (opts.wantHtml) {
payloadHtml += '<a href="">';
@ -1626,7 +1645,7 @@ var zigAnalysis;
payloadHtml += exprName(value, opts);
}
}
}
else if ("typeOf_peer" in value) {
if (opts.wantHtml) {
payloadHtml += '<a href="">';
@ -1638,7 +1657,7 @@ var zigAnalysis;
payloadHtml += exprName(value, opts);
}
}
}
else if ("declRef" in value) {
if (opts.wantHtml) {
payloadHtml += '<a href="">';
@ -1650,7 +1669,7 @@ var zigAnalysis;
payloadHtml += exprName(value, opts);
}
}
}
else if ("call" in value) {
if (opts.wantHtml) {
payloadHtml += '<a href="">';
@ -1661,7 +1680,7 @@ var zigAnalysis;
} else {
payloadHtml += exprName(value, opts);
}
}
}
else if ("refPath" in value) {
if (opts.wantHtml) {
payloadHtml += '<a href="">';

View File

@ -476,8 +476,9 @@ const DocData = struct {
},
Fn: struct {
name: []const u8,
src: ?usize = null, // index into astNodes
src: ?usize = null, // index into `astNodes`
ret: Expr,
generic_ret: ?Expr = null,
params: ?[]Expr = null, // (use src->fields to find names)
lib_name: []const u8 = "",
is_var_args: bool = false,
@ -522,7 +523,6 @@ const DocData = struct {
.ComptimeFloat => |v| try printTypeBody(v, options, w),
.Null => |v| try printTypeBody(v, options, w),
.Optional => |v| try printTypeBody(v, options, w),
.Struct => |v| try printTypeBody(v, options, w),
.Fn => |v| try printTypeBody(v, options, w),
.Union => |v| try printTypeBody(v, options, w),
@ -886,6 +886,10 @@ fn walkInstruction(
);
return self.cteTodo(@tagName(tags[inst_index]));
},
.ret_node => {
const un_node = data[inst_index].un_node;
return self.walkRef(file, parent_scope, un_node.operand, false);
},
.closure_get => {
const inst_node = data[inst_index].inst_node;
return try self.walkInstruction(file, parent_scope, inst_node.inst, need_type);
@ -3882,7 +3886,20 @@ fn analyzeFunctionExtended(
}
self.types.items[type_slot_index] = .{
.Fn = .{ .name = "todo_name func", .src = self_ast_node_index, .params = param_type_refs.items, .ret = ret_type_ref.expr, .is_extern = extra.data.bits.is_extern, .has_cc = extra.data.bits.has_cc, .has_align = extra.data.bits.has_align, .has_lib_name = extra.data.bits.has_lib_name, .lib_name = lib_name, .is_inferred_error = extra.data.bits.is_inferred_error, .cc = cc_index, .@"align" = align_index },
.Fn = .{
.name = "todo_name func",
.src = self_ast_node_index,
.params = param_type_refs.items,
.ret = ret_type_ref.expr,
.is_extern = extra.data.bits.is_extern,
.has_cc = extra.data.bits.has_cc,
.has_align = extra.data.bits.has_align,
.has_lib_name = extra.data.bits.has_lib_name,
.lib_name = lib_name,
.is_inferred_error = extra.data.bits.is_inferred_error,
.cc = cc_index,
.@"align" = align_index,
},
};
return DocData.WalkResult{
@ -3974,6 +3991,21 @@ fn analyzeFunction(
break :blk wr;
};
// TODO: a complete version of this will probably need a scope
// in order to evaluate correctly closures around funcion
// parameters etc.
const generic_ret: ?DocData.Expr = switch (ret_type_ref.expr) {
.type => |t| if (t == @enumToInt(Ref.type_type))
try self.getGenericReturnType(
file,
scope,
fn_info.body[fn_info.body.len - 1],
)
else
null,
else => null,
};
self.ast_nodes.items[self_ast_node_index].fields = param_ast_indexes.items;
self.types.items[type_slot_index] = .{
.Fn = .{
@ -3981,6 +4013,7 @@ fn analyzeFunction(
.src = self_ast_node_index,
.params = param_type_refs.items,
.ret = ret_type_ref.expr,
.generic_ret = generic_ret,
},
};
@ -3990,6 +4023,16 @@ fn analyzeFunction(
};
}
fn getGenericReturnType(
self: *Autodoc,
file: *File,
scope: *Scope,
body_end: usize,
) !DocData.Expr {
const wr = try self.walkInstruction(file, scope, body_end, false);
return wr.expr;
}
fn collectUnionFieldInfo(
self: *Autodoc,
file: *File,