From 2b55484f3f6cf336f54efb9ded25663fe0e1374a Mon Sep 17 00:00:00 2001 From: Vexu <15308111+Vexu@users.noreply.github.com> Date: Thu, 10 Oct 2019 10:27:12 +0300 Subject: [PATCH 1/9] implement doc generation for union and enum --- lib/std/special/docs/main.js | 7 +- src/dump_analysis.cpp | 157 +++++++++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+), 1 deletion(-) diff --git a/lib/std/special/docs/main.js b/lib/std/special/docs/main.js index 879b75872c..5a44259229 100644 --- a/lib/std/special/docs/main.js +++ b/lib/std/special/docs/main.js @@ -780,8 +780,13 @@ var field = container.fields[i]; var divDom = domListFields.children[i]; - var html = '
' + escapeHtml(field.name) + ": " +
+                var html = '
' + escapeHtml(field.name);
+                if (field.type) {
+                    html += ": " +
                     typeIndexName(field.type, true, true) + ',
'; + } else { + html += " = " + field.value + ",
"; + } var docs = zigAnalysis.astNodes[field.src].docs; if (docs != null) { diff --git a/src/dump_analysis.cpp b/src/dump_analysis.cpp index 35a249c92a..fc8afd8da4 100644 --- a/src/dump_analysis.cpp +++ b/src/dump_analysis.cpp @@ -216,6 +216,19 @@ static void jw_int(JsonWriter *jw, int64_t x) { jw_pop_state(jw); } +static void jw_bigint(JsonWriter *jw, const BigInt *x) { + assert(jw->state[jw->state_index] == JsonWriterStateValue); + Buf *str = buf_alloc(); + bigint_append_buf(str, x, 10); + + if (bigint_fits_in_bits(x, 52, true)) { + fprintf(jw->f, "%s", buf_ptr(str)); + } else { + fprintf(jw->f, "\"%s\"", buf_ptr(str)); + } + jw_pop_state(jw); +} + static void jw_string(JsonWriter *jw, const char *s) { assert(jw->state[jw->state_index] == JsonWriterStateValue); jw_write_escaped_string(jw, s); @@ -749,6 +762,40 @@ static void anal_dump_struct_field(AnalDumpCtx *ctx, const TypeStructField *stru jw_end_object(jw); } +static void anal_dump_union_field(AnalDumpCtx *ctx, const TypeUnionField *union_field) { + JsonWriter *jw = &ctx->jw; + + jw_begin_object(jw); + + jw_object_field(jw, "name"); + jw_string(jw, buf_ptr(union_field->name)); + + jw_object_field(jw, "type"); + anal_dump_type_ref(ctx, union_field->type_entry); + + jw_object_field(jw, "src"); + anal_dump_node_ref(ctx, union_field->decl_node); + + jw_end_object(jw); +} + +static void anal_dump_enum_field(AnalDumpCtx *ctx, const TypeEnumField *enum_field) { + JsonWriter *jw = &ctx->jw; + + jw_begin_object(jw); + + jw_object_field(jw, "name"); + jw_string(jw, buf_ptr(enum_field->name)); + + jw_object_field(jw, "value"); + jw_bigint(jw, &enum_field->value); + + jw_object_field(jw, "src"); + anal_dump_node_ref(ctx, enum_field->decl_node); + + jw_end_object(jw); +} + static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) { JsonWriter *jw = &ctx->jw; jw_array_elem(jw); @@ -831,6 +878,116 @@ static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) { } break; } + case ZigTypeIdUnion: { + jw_object_field(jw, "name"); + jw_string(jw, buf_ptr(&ty->name)); + { + jw_object_field(jw, "pubDecls"); + jw_begin_array(jw); + + ScopeDecls *decls_scope = ty->data.unionation.decls_scope; + auto it = decls_scope->decl_table.entry_iterator(); + for (;;) { + auto *entry = it.next(); + if (!entry) + break; + + Tld *tld = entry->value; + if (tld->visib_mod == VisibModPub) { + jw_array_elem(jw); + anal_dump_decl_ref(ctx, tld); + } + } + jw_end_array(jw); + } + + { + jw_object_field(jw, "privDecls"); + jw_begin_array(jw); + + ScopeDecls *decls_scope = ty->data.unionation.decls_scope; + auto it = decls_scope->decl_table.entry_iterator(); + for (;;) { + auto *entry = it.next(); + if (!entry) + break; + + Tld *tld = entry->value; + if (tld->visib_mod == VisibModPrivate) { + jw_array_elem(jw); + anal_dump_decl_ref(ctx, tld); + } + } + jw_end_array(jw); + } + + if (ty->data.unionation.src_field_count != 0) { + jw_object_field(jw, "fields"); + jw_begin_array(jw); + + for(size_t i = 0; i < ty->data.unionation.src_field_count; i += 1) { + jw_array_elem(jw); + anal_dump_union_field(ctx, &ty->data.unionation.fields[i]); + } + jw_end_array(jw); + } + break; + } + case ZigTypeIdEnum: { + jw_object_field(jw, "name"); + jw_string(jw, buf_ptr(&ty->name)); + { + jw_object_field(jw, "pubDecls"); + jw_begin_array(jw); + + ScopeDecls *decls_scope = ty->data.enumeration.decls_scope; + auto it = decls_scope->decl_table.entry_iterator(); + for (;;) { + auto *entry = it.next(); + if (!entry) + break; + + Tld *tld = entry->value; + if (tld->visib_mod == VisibModPub) { + jw_array_elem(jw); + anal_dump_decl_ref(ctx, tld); + } + } + jw_end_array(jw); + } + + { + jw_object_field(jw, "privDecls"); + jw_begin_array(jw); + + ScopeDecls *decls_scope = ty->data.enumeration.decls_scope; + auto it = decls_scope->decl_table.entry_iterator(); + for (;;) { + auto *entry = it.next(); + if (!entry) + break; + + Tld *tld = entry->value; + if (tld->visib_mod == VisibModPrivate) { + jw_array_elem(jw); + anal_dump_decl_ref(ctx, tld); + } + } + jw_end_array(jw); + } + + if (ty->data.enumeration.src_field_count != 0) { + jw_object_field(jw, "fields"); + jw_begin_array(jw); + + for(size_t i = 0; i < ty->data.enumeration.src_field_count; i += 1) { + jw_array_elem(jw); + anal_dump_enum_field(ctx, &ty->data.enumeration.fields[i]); + } + jw_end_array(jw); + } + break; + } case ZigTypeIdFloat: { jw_object_field(jw, "bits"); jw_int(jw, ty->data.floating.bit_count); From 4250d27fe500cf16701066277fd6643491e7ab09 Mon Sep 17 00:00:00 2001 From: Timon Kruiper Date: Thu, 10 Oct 2019 14:21:35 +0200 Subject: [PATCH 2/9] Generated docs: store static container info in a containerDecl astNode And then get the struct field astNodes through the containerDecl astNode. The type of a struct field is still stored in the types array, but the static information is in the astNodes. --- lib/std/special/docs/main.js | 11 ++++--- src/dump_analysis.cpp | 56 ++++++++++++++++++++++++------------ 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/lib/std/special/docs/main.js b/lib/std/special/docs/main.js index 879b75872c..681d36319f 100644 --- a/lib/std/special/docs/main.js +++ b/lib/std/special/docs/main.js @@ -776,14 +776,17 @@ if (container.fields != null && container.fields.length !== 0) { resizeDomList(domListFields, container.fields.length, '
'); + + var containerNode = zigAnalysis.astNodes[container.src]; for (var i = 0; i < container.fields.length; i += 1) { - var field = container.fields[i]; + var fieldTypeIndex = container.fields[i]; + var fieldNode = zigAnalysis.astNodes[containerNode.fields[i]]; var divDom = domListFields.children[i]; - var html = '
' + escapeHtml(field.name) + ": " +
-                    typeIndexName(field.type, true, true) + ',
'; + var html = '
' + escapeHtml(fieldNode.name) + ": " +
+                    typeIndexName(fieldTypeIndex, true, true) + ',
'; - var docs = zigAnalysis.astNodes[field.src].docs; + var docs = fieldNode.docs; if (docs != null) { html += markdown(docs); } diff --git a/src/dump_analysis.cpp b/src/dump_analysis.cpp index 35a249c92a..29a04b2d48 100644 --- a/src/dump_analysis.cpp +++ b/src/dump_analysis.cpp @@ -732,23 +732,6 @@ static void anal_dump_pointer_attrs(AnalDumpCtx *ctx, ZigType *ty) { anal_dump_type_ref(ctx, ty->data.pointer.child_type); } -static void anal_dump_struct_field(AnalDumpCtx *ctx, const TypeStructField *struct_field) { - JsonWriter *jw = &ctx->jw; - - jw_begin_object(jw); - - jw_object_field(jw, "name"); - jw_string(jw, buf_ptr(struct_field->name)); - - jw_object_field(jw, "type"); - anal_dump_type_ref(ctx, struct_field->type_entry); - - jw_object_field(jw, "src"); - anal_dump_node_ref(ctx, struct_field->decl_node); - - jw_end_object(jw); -} - static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) { JsonWriter *jw = &ctx->jw; jw_array_elem(jw); @@ -811,13 +794,16 @@ static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) { jw_end_array(jw); } + jw_object_field(jw, "src"); + anal_dump_node_ref(ctx, ty->data.structure.decl_node); + if (ty->data.structure.src_field_count != 0) { jw_object_field(jw, "fields"); jw_begin_array(jw); for(size_t i = 0; i < ty->data.structure.src_field_count; i += 1) { jw_array_elem(jw); - anal_dump_struct_field(ctx, &ty->data.structure.fields[i]); + anal_dump_type_ref(ctx, ty->data.structure.fields[i].type_entry); } jw_end_array(jw); } @@ -827,7 +813,6 @@ static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) { jw_object_field(jw, "file"); anal_dump_file_ref(ctx, path_buf); - } break; } @@ -974,6 +959,39 @@ static void anal_dump_node(AnalDumpCtx *ctx, const AstNode *node) { jw_string(jw, buf_ptr(doc_comments_buf)); } + const Buf *name_buf; + switch (node->type) { + case NodeTypeStructField: + name_buf = node->data.struct_field.name; + break; + default: + name_buf = nullptr; + break; + } + if (name_buf != nullptr) { + jw_object_field(jw, "name"); + jw_string(jw, buf_ptr(name_buf)); + } + + const ZigList *fieldNodes; + switch (node->type) { + case NodeTypeContainerDecl: + fieldNodes = &node->data.container_decl.fields; + break; + default: + fieldNodes = nullptr; + break; + } + if (fieldNodes != nullptr) { + jw_object_field(jw, "fields"); + jw_begin_array(jw); + for (size_t i = 0; i < fieldNodes->length; i += 1) { + jw_array_elem(jw); + anal_dump_node_ref(ctx, fieldNodes->at(i)); + } + jw_end_array(jw); + } + jw_end_object(jw); } From e34e3344d4ac5c50a008905fe5cba25629cafa1c Mon Sep 17 00:00:00 2001 From: Timon Kruiper Date: Thu, 10 Oct 2019 15:23:24 +0200 Subject: [PATCH 3/9] Generated docs: Add function paramater names --- lib/std/special/docs/main.js | 10 ++++++++++ src/dump_analysis.cpp | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/lib/std/special/docs/main.js b/lib/std/special/docs/main.js index 681d36319f..cc21767191 100644 --- a/lib/std/special/docs/main.js +++ b/lib/std/special/docs/main.js @@ -554,6 +554,16 @@ if (i != 0) { payloadHtml += ', '; } + + if (fnDecl != null && zigAnalysis.astNodes[fnDecl.src].fields != null) { + var paramDeclIndex = zigAnalysis.astNodes[fnDecl.src].fields[i]; + var paramName = zigAnalysis.astNodes[paramDeclIndex].name; + + if (paramName != null) { + payloadHtml += paramName + ': '; + } + } + var argTypeIndex = typeObj.args[i]; if (argTypeIndex != null) { payloadHtml += typeIndexName(argTypeIndex, wantHtml, wantSubLink); diff --git a/src/dump_analysis.cpp b/src/dump_analysis.cpp index 29a04b2d48..ddf59097d7 100644 --- a/src/dump_analysis.cpp +++ b/src/dump_analysis.cpp @@ -964,6 +964,9 @@ static void anal_dump_node(AnalDumpCtx *ctx, const AstNode *node) { case NodeTypeStructField: name_buf = node->data.struct_field.name; break; + case NodeTypeParamDecl: + name_buf = node->data.param_decl.name; + break; default: name_buf = nullptr; break; @@ -978,6 +981,9 @@ static void anal_dump_node(AnalDumpCtx *ctx, const AstNode *node) { case NodeTypeContainerDecl: fieldNodes = &node->data.container_decl.fields; break; + case NodeTypeFnProto: + fieldNodes = &node->data.fn_proto.params; + break; default: fieldNodes = nullptr; break; From fd94d78ffc60f61db0990c18d24a24ef3c56fd4e Mon Sep 17 00:00:00 2001 From: Michael Dusan Date: Thu, 10 Oct 2019 07:00:29 -0400 Subject: [PATCH 4/9] cleanup: unused imports in test --- test/stage1/behavior/bugs/3367.zig | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/stage1/behavior/bugs/3367.zig b/test/stage1/behavior/bugs/3367.zig index 06b633df67..3df3adbff7 100644 --- a/test/stage1/behavior/bugs/3367.zig +++ b/test/stage1/behavior/bugs/3367.zig @@ -1,6 +1,3 @@ -const std = @import("std"); -const expect = std.testing.expect; - const Foo = struct { usingnamespace Mixin; }; From 3464351d1e0a1e840d0b1a6267d0a5bf4113cfcc Mon Sep 17 00:00:00 2001 From: Michael Dusan Date: Thu, 10 Oct 2019 04:55:09 -0400 Subject: [PATCH 5/9] stage1: fix ir_resolve_str() to return slice `ir_resolve_str()` bug returns array expression even when when sliced to a lesser length. Fix is to return array if slice.len == array.len, otherwise return slice. Bug report use-case is based on one builtin function. However, at least the following builtins were exposed to the bug: `@byteOffsetOf` `@cDefine` `@cImport` `@cInclude` `@cUndef` `@compileError` `@embedFile` `@export` `@fieldParentPtr` `@hasDecl` `@hasField` `@import` `@unionInit` closes #3384 --- src/ir.cpp | 7 +++---- test/stage1/behavior.zig | 1 + test/stage1/behavior/bugs/3384.zig | 11 +++++++++++ 3 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 test/stage1/behavior/bugs/3384.zig diff --git a/src/ir.cpp b/src/ir.cpp index 0e6153ebcd..8fecbf7a18 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -13122,7 +13122,6 @@ static bool ir_resolve_float_mode(IrAnalyze *ira, IrInstruction *value, FloatMod return true; } - static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { if (type_is_invalid(value->value.type)) return nullptr; @@ -13143,11 +13142,11 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray); ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val; - if (array_val->data.x_array.special == ConstArraySpecialBuf) { - return array_val->data.x_array.data.s_buf; - } expand_undef_array(ira->codegen, array_val); size_t len = bigint_as_usize(&len_field->data.x_bigint); + if (array_val->data.x_array.special == ConstArraySpecialBuf && len == buf_len(array_val->data.x_array.data.s_buf)) { + return array_val->data.x_array.data.s_buf; + } Buf *result = buf_alloc(); buf_resize(result, len); for (size_t i = 0; i < len; i += 1) { diff --git a/test/stage1/behavior.zig b/test/stage1/behavior.zig index 95cb98f8eb..95d2dbac93 100644 --- a/test/stage1/behavior.zig +++ b/test/stage1/behavior.zig @@ -35,6 +35,7 @@ comptime { _ = @import("behavior/bugs/3046.zig"); _ = @import("behavior/bugs/3112.zig"); _ = @import("behavior/bugs/3367.zig"); + _ = @import("behavior/bugs/3384.zig"); _ = @import("behavior/bugs/394.zig"); _ = @import("behavior/bugs/421.zig"); _ = @import("behavior/bugs/529.zig"); diff --git a/test/stage1/behavior/bugs/3384.zig b/test/stage1/behavior/bugs/3384.zig new file mode 100644 index 0000000000..789b0be516 --- /dev/null +++ b/test/stage1/behavior/bugs/3384.zig @@ -0,0 +1,11 @@ +const std = @import("std"); +const expect = std.testing.expect; + +test "resolve array slice using builtin" { + expect(@hasDecl(@This(), "std") == true); + expect(@hasDecl(@This(), "std"[0..0]) == false); + expect(@hasDecl(@This(), "std"[0..1]) == false); + expect(@hasDecl(@This(), "std"[0..2]) == false); + expect(@hasDecl(@This(), "std"[0..3]) == true); + expect(@hasDecl(@This(), "std"[0..]) == true); +} From 6330dfbea6d5434dc694aebd0203ea13e2511a0e Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 10 Oct 2019 11:03:16 -0400 Subject: [PATCH 6/9] generated docs: better listing of functions --- lib/std/special/docs/main.js | 37 ++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/lib/std/special/docs/main.js b/lib/std/special/docs/main.js index cc21767191..5ecc2c0545 100644 --- a/lib/std/special/docs/main.js +++ b/lib/std/special/docs/main.js @@ -376,24 +376,24 @@ } } - function typeIndexName(typeIndex, wantHtml, wantLink, fnDecl, skipFnName) { + function typeIndexName(typeIndex, wantHtml, wantLink, fnDecl, linkFnNameDecl) { var typeObj = zigAnalysis.types[typeIndex]; if (wantLink) { var declIndex = getCanonTypeDecl(typeIndex); var declPath = getCanonDeclPath(declIndex); var haveLink = declPath != null; - var typeNameHtml = typeName(typeObj, true, !haveLink, fnDecl, skipFnName); + var typeNameHtml = typeName(typeObj, true, !haveLink, fnDecl, linkFnNameDecl); if (haveLink) { return '' + typeNameHtml + ''; } else { return typeNameHtml; } } else { - return typeName(typeObj, wantHtml, false, fnDecl, skipFnName); + return typeName(typeObj, wantHtml, false, fnDecl, linkFnNameDecl); } } - function typeName(typeObj, wantHtml, wantSubLink, fnDecl, skipFnName) { + function typeName(typeObj, wantHtml, wantSubLink, fnDecl, linkFnNameDecl) { switch (typeObj.kind) { case typeKinds.Array: var name = "["; @@ -542,8 +542,15 @@ var payloadHtml = ""; if (wantHtml) { payloadHtml += 'fn'; - if (fnDecl != null && !skipFnName) { - payloadHtml += ' ' + escapeHtml(fnDecl.name) + ''; + if (fnDecl != null) { + payloadHtml += ' '; + if (linkFnNameDecl != null) { + payloadHtml += '' + + escapeHtml(fnDecl.name) + ''; + } else { + payloadHtml += escapeHtml(fnDecl.name); + } + payloadHtml += ''; } } else { payloadHtml += 'fn' @@ -655,7 +662,7 @@ } function renderValue(decl) { - domFnProtoCode.innerHTML = 'pub const ' + + domFnProtoCode.innerHTML = 'const ' + escapeHtml(decl.name) + ': ' + typeIndexName(decl.type, true, true); var docs = zigAnalysis.astNodes[decl.src].docs; @@ -668,7 +675,7 @@ } function renderVar(decl) { - domFnProtoCode.innerHTML = 'pub var ' + + domFnProtoCode.innerHTML = 'var ' + escapeHtml(decl.name) + ': ' + typeIndexName(decl.type, true, true); var docs = zigAnalysis.astNodes[decl.src].docs; @@ -758,21 +765,15 @@ } if (fnsList.length !== 0) { - resizeDomList(domListFns, fnsList.length, - ''); + resizeDomList(domListFns, fnsList.length, ''); for (var i = 0; i < fnsList.length; i += 1) { var decl = fnsList[i]; var trDom = domListFns.children[i]; - var tdName = trDom.children[0]; - var tdNameA = tdName.children[0]; - var tdType = trDom.children[1]; - var tdDesc = trDom.children[2]; + var tdFnCode = trDom.children[0]; + var tdDesc = trDom.children[1]; - tdNameA.setAttribute('href', navLinkDecl(decl.name)); - tdNameA.textContent = decl.name; - - tdType.innerHTML = typeIndexName(decl.type, true, true, decl, true); + tdFnCode.innerHTML = typeIndexName(decl.type, true, true, decl, navLinkDecl(decl.name)); var docs = zigAnalysis.astNodes[decl.src].docs; if (docs != null) { From 4e81df12c3dae2ae67ef25fcfe65e8db724e84f3 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 10 Oct 2019 13:40:17 -0400 Subject: [PATCH 7/9] generated docs: css: wider tables --- lib/std/special/docs/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/special/docs/index.html b/lib/std/special/docs/index.html index ec226f220b..181b101e0e 100644 --- a/lib/std/special/docs/index.html +++ b/lib/std/special/docs/index.html @@ -160,7 +160,7 @@ vertical-align: top; margin: 0; padding: 0.5em; - max-width: 20em; + max-width: 27em; text-overflow: ellipsis; overflow-x: hidden; } From 6cbb732b59d1ded92c7272a8b06f645e1c8acfd2 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 10 Oct 2019 10:47:59 +0200 Subject: [PATCH 8/9] Extern unions should not trigger active field check Fixes #3378 --- src/ir.cpp | 2 +- test/stage1/behavior/union.zig | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/ir.cpp b/src/ir.cpp index 8fecbf7a18..7dd141423c 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -17951,7 +17951,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ union_val->special = ConstValSpecialStatic; bigint_init_bigint(&union_val->data.x_union.tag, &field->enum_field->value); union_val->data.x_union.payload = payload_val; - } else { + } else if (bare_type->data.unionation.layout != ContainerLayoutExtern) { TypeUnionField *actual_field = find_union_field_by_tag(bare_type, &union_val->data.x_union.tag); if (actual_field == nullptr) zig_unreachable(); diff --git a/test/stage1/behavior/union.zig b/test/stage1/behavior/union.zig index d340a52d1e..f5e9ec09a8 100644 --- a/test/stage1/behavior/union.zig +++ b/test/stage1/behavior/union.zig @@ -511,3 +511,13 @@ test "union with comptime_int tag" { }; comptime expect(@TagType(@TagType(Union)) == comptime_int); } + +test "extern union doesn't trigger field check at comptime" { + const U = extern union { + x: u32, + y: u8, + }; + + const x = U{ .x = 0x55AAAA55 }; + comptime expect(x.y == 0x55); +} From d15a71afc95f148966be2f5fd9f66b8396e8293d Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 10 Oct 2019 15:42:40 -0400 Subject: [PATCH 9/9] generated docs: clean up type names and param names closes #3410 --- lib/std/special/docs/main.js | 44 +++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/lib/std/special/docs/main.js b/lib/std/special/docs/main.js index 4c8fd389f7..7e5a9c4c0e 100644 --- a/lib/std/special/docs/main.js +++ b/lib/std/special/docs/main.js @@ -43,6 +43,7 @@ var typeKinds = indexTypeKinds(); var typeTypeId = findTypeTypeId(); + var pointerSizeEnum = { One: 0, Many: 1, Slice: 2, C: 3 }; // for each package, is an array with packages to get to this one var canonPkgPaths = computeCanonicalPackagePaths(); @@ -378,21 +379,38 @@ function typeIndexName(typeIndex, wantHtml, wantLink, fnDecl, linkFnNameDecl) { var typeObj = zigAnalysis.types[typeIndex]; + var declNameOk = declCanRepresentTypeKind(typeObj.kind); if (wantLink) { var declIndex = getCanonTypeDecl(typeIndex); var declPath = getCanonDeclPath(declIndex); - var haveLink = declPath != null; - var typeNameHtml = typeName(typeObj, true, !haveLink, fnDecl, linkFnNameDecl); - if (haveLink) { - return '' + typeNameHtml + ''; + if (declPath == null) { + return typeName(typeObj, wantHtml, wantLink, fnDecl, linkFnNameDecl); + } + var name = (wantLink && declCanRepresentTypeKind(typeObj.kind)) ? + declPath.declNames[declPath.declNames.length - 1] : + typeName(typeObj, wantHtml, false, fnDecl, linkFnNameDecl); + if (wantLink && wantHtml) { + return '' + name + ''; } else { - return typeNameHtml; + return name; } } else { return typeName(typeObj, wantHtml, false, fnDecl, linkFnNameDecl); } } + function shouldSkipParamName(typeIndex, paramName) { + var typeObj = zigAnalysis.types[typeIndex]; + if (typeObj.kind === typeKinds.Pointer && getPtrSize(typeObj) === pointerSizeEnum.One) { + typeIndex = typeObj.elem; + } + return typeIndexName(typeIndex, false, true).toLowerCase() === paramName; + } + + function getPtrSize(typeObj) { + return (typeObj.len == null) ? pointerSizeEnum.One : typeObj.len; + } + function typeName(typeObj, wantHtml, wantSubLink, fnDecl, linkFnNameDecl) { switch (typeObj.kind) { case typeKinds.Array: @@ -408,17 +426,17 @@ case typeKinds.Pointer: var name = ""; switch (typeObj.len) { - case 0: + case pointerSizeEnum.One: default: name += "*"; break; - case 1: + case pointerSizeEnum.Many: name += "[*]"; break; - case 2: + case pointerSizeEnum.Slice: name += "[]"; break; - case 3: + case pointerSizeEnum.C: name += "[*c]"; break; } @@ -562,16 +580,20 @@ payloadHtml += ', '; } + var argTypeIndex = typeObj.args[i]; + if (fnDecl != null && zigAnalysis.astNodes[fnDecl.src].fields != null) { var paramDeclIndex = zigAnalysis.astNodes[fnDecl.src].fields[i]; var paramName = zigAnalysis.astNodes[paramDeclIndex].name; if (paramName != null) { - payloadHtml += paramName + ': '; + // skip if it matches the type name + if (argTypeIndex == null || !shouldSkipParamName(argTypeIndex, paramName)) { + payloadHtml += paramName + ': '; + } } } - var argTypeIndex = typeObj.args[i]; if (argTypeIndex != null) { payloadHtml += typeIndexName(argTypeIndex, wantHtml, wantSubLink); } else if (wantHtml) {