authorgravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2022-05-30 21:48:46+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-19 19:10:12-07:00
log413cfd4066c547ec1cf3c7b81b0ca34e9eddb82a
treef3b07b2f7b29f34731a32e72d4faf70454c434f7
parent51647c305eea1c38da47e3c20b39418ce3a7689f

autodoc: init generic function support


2 files changed, 73 insertions(+), 11 deletions(-)

lib/docs/main.js+27-8
...@@ -724,7 +724,7 @@ var zigAnalysis;...@@ -724,7 +724,7 @@ var zigAnalysis;
724 if (typeObj.kind !== typeKinds.Fn) {724 if (typeObj.kind !== typeKinds.Fn) {
725 return false;725 return false;
726 }726 }
727 return /** @type {Fn} */(typeObj).generic;727 return /** @type {Fn} */(typeObj).generic_ret != null;
728 }728 }
729729
730 /** @param {Decl} fnDecl */730 /** @param {Decl} fnDecl */
...@@ -772,7 +772,26 @@ var zigAnalysis;...@@ -772,7 +772,26 @@ var zigAnalysis;
772772
773 let protoSrcIndex = fnDecl.src;773 let protoSrcIndex = fnDecl.src;
774 if (typeIsGenericFn(value.expr.type)) {774 if (typeIsGenericFn(value.expr.type)) {
775 throw "TODO";775 // does the generic_ret contain a container?
776 var resolvedGenericRet = resolveValue({expr: typeObj.generic_ret});
777 // TODO: see if unwrapping the `as` here is a good idea or not.
778 if ("as" in resolvedGenericRet.expr) {
779 resolvedGenericRet = {
780 expr: zigAnalysis.exprs[resolvedGenericRet.expr.as.exprArg]
781 };
782 }
783
784 if (!("type" in resolvedGenericRet.expr)) return;
785 const genericType = zigAnalysis.types[resolvedGenericRet.expr.type];
786 if (isContainerType(genericType)) {
787 renderContainer(genericType)
788 }
789
790
791
792
793
794 // old code
776 // let instantiations = nodesToFnsMap[protoSrcIndex];795 // let instantiations = nodesToFnsMap[protoSrcIndex];
777 // let calls = nodesToCallsMap[protoSrcIndex];796 // let calls = nodesToCallsMap[protoSrcIndex];
778 // if (instantiations == null && calls == null) {797 // if (instantiations == null && calls == null) {
...@@ -1530,7 +1549,7 @@ var zigAnalysis;...@@ -1530,7 +1549,7 @@ var zigAnalysis;
1530 return html;1549 return html;
1531 }1550 }
1532 }1551 }
1533 1552
1534 case typeKinds.ErrorUnion:1553 case typeKinds.ErrorUnion:
1535 {1554 {
1536 let errUnionObj = /** @type {ErrUnionType} */(typeObj);1555 let errUnionObj = /** @type {ErrUnionType} */(typeObj);
...@@ -1614,7 +1633,7 @@ var zigAnalysis;...@@ -1614,7 +1633,7 @@ var zigAnalysis;
16141633
1615 if (isVarArgs && i === fnObj.params.length - 1) {1634 if (isVarArgs && i === fnObj.params.length - 1) {
1616 payloadHtml += '...';1635 payloadHtml += '...';
1617 } 1636 }
1618 else if ("typeOf" in value) {1637 else if ("typeOf" in value) {
1619 if (opts.wantHtml) {1638 if (opts.wantHtml) {
1620 payloadHtml += '<a href="">';1639 payloadHtml += '<a href="">';
...@@ -1626,7 +1645,7 @@ var zigAnalysis;...@@ -1626,7 +1645,7 @@ var zigAnalysis;
1626 payloadHtml += exprName(value, opts);1645 payloadHtml += exprName(value, opts);
1627 }1646 }
16281647
1629 } 1648 }
1630 else if ("typeOf_peer" in value) {1649 else if ("typeOf_peer" in value) {
1631 if (opts.wantHtml) {1650 if (opts.wantHtml) {
1632 payloadHtml += '<a href="">';1651 payloadHtml += '<a href="">';
...@@ -1638,7 +1657,7 @@ var zigAnalysis;...@@ -1638,7 +1657,7 @@ var zigAnalysis;
1638 payloadHtml += exprName(value, opts);1657 payloadHtml += exprName(value, opts);
1639 }1658 }
16401659
1641 } 1660 }
1642 else if ("declRef" in value) {1661 else if ("declRef" in value) {
1643 if (opts.wantHtml) {1662 if (opts.wantHtml) {
1644 payloadHtml += '<a href="">';1663 payloadHtml += '<a href="">';
...@@ -1650,7 +1669,7 @@ var zigAnalysis;...@@ -1650,7 +1669,7 @@ var zigAnalysis;
1650 payloadHtml += exprName(value, opts);1669 payloadHtml += exprName(value, opts);
1651 }1670 }
16521671
1653 } 1672 }
1654 else if ("call" in value) {1673 else if ("call" in value) {
1655 if (opts.wantHtml) {1674 if (opts.wantHtml) {
1656 payloadHtml += '<a href="">';1675 payloadHtml += '<a href="">';
...@@ -1661,7 +1680,7 @@ var zigAnalysis;...@@ -1661,7 +1680,7 @@ var zigAnalysis;
1661 } else {1680 } else {
1662 payloadHtml += exprName(value, opts);1681 payloadHtml += exprName(value, opts);
1663 }1682 }
1664 } 1683 }
1665 else if ("refPath" in value) {1684 else if ("refPath" in value) {
1666 if (opts.wantHtml) {1685 if (opts.wantHtml) {
1667 payloadHtml += '<a href="">';1686 payloadHtml += '<a href="">';
src/Autodoc.zig+46-3
...@@ -476,8 +476,9 @@ const DocData = struct {...@@ -476,8 +476,9 @@ const DocData = struct {
476 },476 },
477 Fn: struct {477 Fn: struct {
478 name: []const u8,478 name: []const u8,
479 src: ?usize = null, // index into astNodes479 src: ?usize = null, // index into `astNodes`
480 ret: Expr,480 ret: Expr,
481 generic_ret: ?Expr = null,
481 params: ?[]Expr = null, // (use src->fields to find names)482 params: ?[]Expr = null, // (use src->fields to find names)
482 lib_name: []const u8 = "",483 lib_name: []const u8 = "",
483 is_var_args: bool = false,484 is_var_args: bool = false,
...@@ -522,7 +523,6 @@ const DocData = struct {...@@ -522,7 +523,6 @@ const DocData = struct {
522 .ComptimeFloat => |v| try printTypeBody(v, options, w),523 .ComptimeFloat => |v| try printTypeBody(v, options, w),
523 .Null => |v| try printTypeBody(v, options, w),524 .Null => |v| try printTypeBody(v, options, w),
524 .Optional => |v| try printTypeBody(v, options, w),525 .Optional => |v| try printTypeBody(v, options, w),
525
526 .Struct => |v| try printTypeBody(v, options, w),526 .Struct => |v| try printTypeBody(v, options, w),
527 .Fn => |v| try printTypeBody(v, options, w),527 .Fn => |v| try printTypeBody(v, options, w),
528 .Union => |v| try printTypeBody(v, options, w),528 .Union => |v| try printTypeBody(v, options, w),
...@@ -886,6 +886,10 @@ fn walkInstruction(...@@ -886,6 +886,10 @@ fn walkInstruction(
886 );886 );
887 return self.cteTodo(@tagName(tags[inst_index]));887 return self.cteTodo(@tagName(tags[inst_index]));
888 },888 },
889 .ret_node => {
890 const un_node = data[inst_index].un_node;
891 return self.walkRef(file, parent_scope, un_node.operand, false);
892 },
889 .closure_get => {893 .closure_get => {
890 const inst_node = data[inst_index].inst_node;894 const inst_node = data[inst_index].inst_node;
891 return try self.walkInstruction(file, parent_scope, inst_node.inst, need_type);895 return try self.walkInstruction(file, parent_scope, inst_node.inst, need_type);
...@@ -3882,7 +3886,20 @@ fn analyzeFunctionExtended(...@@ -3882,7 +3886,20 @@ fn analyzeFunctionExtended(
3882 }3886 }
38833887
3884 self.types.items[type_slot_index] = .{3888 self.types.items[type_slot_index] = .{
3885 .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 },3889 .Fn = .{
3890 .name = "todo_name func",
3891 .src = self_ast_node_index,
3892 .params = param_type_refs.items,
3893 .ret = ret_type_ref.expr,
3894 .is_extern = extra.data.bits.is_extern,
3895 .has_cc = extra.data.bits.has_cc,
3896 .has_align = extra.data.bits.has_align,
3897 .has_lib_name = extra.data.bits.has_lib_name,
3898 .lib_name = lib_name,
3899 .is_inferred_error = extra.data.bits.is_inferred_error,
3900 .cc = cc_index,
3901 .@"align" = align_index,
3902 },
3886 };3903 };
38873904
3888 return DocData.WalkResult{3905 return DocData.WalkResult{
...@@ -3974,6 +3991,21 @@ fn analyzeFunction(...@@ -3974,6 +3991,21 @@ fn analyzeFunction(
3974 break :blk wr;3991 break :blk wr;
3975 };3992 };
39763993
3994 // TODO: a complete version of this will probably need a scope
3995 // in order to evaluate correctly closures around funcion
3996 // parameters etc.
3997 const generic_ret: ?DocData.Expr = switch (ret_type_ref.expr) {
3998 .type => |t| if (t == @enumToInt(Ref.type_type))
3999 try self.getGenericReturnType(
4000 file,
4001 scope,
4002 fn_info.body[fn_info.body.len - 1],
4003 )
4004 else
4005 null,
4006 else => null,
4007 };
4008
3977 self.ast_nodes.items[self_ast_node_index].fields = param_ast_indexes.items;4009 self.ast_nodes.items[self_ast_node_index].fields = param_ast_indexes.items;
3978 self.types.items[type_slot_index] = .{4010 self.types.items[type_slot_index] = .{
3979 .Fn = .{4011 .Fn = .{
...@@ -3981,6 +4013,7 @@ fn analyzeFunction(...@@ -3981,6 +4013,7 @@ fn analyzeFunction(
3981 .src = self_ast_node_index,4013 .src = self_ast_node_index,
3982 .params = param_type_refs.items,4014 .params = param_type_refs.items,
3983 .ret = ret_type_ref.expr,4015 .ret = ret_type_ref.expr,
4016 .generic_ret = generic_ret,
3984 },4017 },
3985 };4018 };
39864019
...@@ -3990,6 +4023,16 @@ fn analyzeFunction(...@@ -3990,6 +4023,16 @@ fn analyzeFunction(
3990 };4023 };
3991}4024}
39924025
4026fn getGenericReturnType(
4027 self: *Autodoc,
4028 file: *File,
4029 scope: *Scope,
4030 body_end: usize,
4031) !DocData.Expr {
4032 const wr = try self.walkInstruction(file, scope, body_end, false);
4033 return wr.expr;
4034}
4035
3993fn collectUnionFieldInfo(4036fn collectUnionFieldInfo(
3994 self: *Autodoc,4037 self: *Autodoc,
3995 file: *File,4038 file: *File,