authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-10-07 23:53:17-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-10-08 00:15:16-04:00
loga55db08a7b6326ea0d84f13acd9312d435c10136
treea04a39fa2ca8c185a697707bb0324a4a188556c5
parentffc0c26b27b14fbaedc0def018fd962a93e420bc
signaturelock-open Commit is signed but in an unrecognized format.

generated docs contain generic instantiations and comptime calls


7 files changed, 295 insertions(+), 61 deletions(-)

lib/std/debug.zig+5
......@@ -2439,3 +2439,8 @@ pub fn dumpStackPointerAddr(prefix: []const u8) void {
24392439 );
24402440 std.debug.warn("{} sp = 0x{x}\n", prefix, sp);
24412441}
2442
2443// Reference everything so it gets tested.
2444test "" {
2445 _ = leb;
2446}
lib/std/special/docs/index.html+4
......@@ -210,6 +210,10 @@
210210 </div>
211211 <h1 id="hdrName" class="hidden"></h1>
212212 <div id="fnDocs" class="hidden"></div>
213 <div id="fnExamples" class="hidden"></div>
214 <div id="fnNoExamples" class="hidden">
215 <p>This function is not tested or referenced.</p>
216 </div>
213217 <div id="sectSearchResults" class="hidden">
214218 <h2>Search Results</h2>
215219 <ul id="listSearchResults"></ul>
lib/std/special/docs/main.js+91-3
......@@ -11,6 +11,8 @@
1111 var domFnProto = document.getElementById("fnProto");
1212 var domFnProtoCode = document.getElementById("fnProtoCode");
1313 var domFnDocs = document.getElementById("fnDocs");
14 var domFnExamples = document.getElementById("fnExamples");
15 var domFnNoExamples = document.getElementById("fnNoExamples");
1416 var domSearch = document.getElementById("search");
1517 var domSectSearchResults = document.getElementById("sectSearchResults");
1618 var domListSearchResults = document.getElementById("listSearchResults");
......@@ -50,6 +52,12 @@
5052
5153 var rootIsStd = detectRootIsStd();
5254 var typeTypeId = findTypeTypeId();
55
56 // map of decl index to list of non-generic fn indexes
57 var nodesToFnsMap = indexNodesToFns();
58 // map of decl index to list of comptime fn calls
59 var nodesToCallsMap = indexNodesToCalls();
60
5361 domSearch.addEventListener('keydown', onSearchKeyDown, false);
5462 window.addEventListener('hashchange', onHashChange, false);
5563 window.addEventListener('keydown', onWindowKeyDown, false);
......@@ -81,6 +89,8 @@
8189 domSectInfo.classList.add("hidden");
8290 domHdrName.classList.add("hidden");
8391 domSectNav.classList.add("hidden");
92 domFnExamples.classList.add("hidden");
93 domFnNoExamples.classList.add("hidden");
8494
8595 renderTitle();
8696 renderInfo();
......@@ -138,16 +148,51 @@
138148 }
139149 }
140150
151 function typeIsGenericFn(typeIndex) {
152 var typeObj = zigAnalysis.types[typeIndex];
153 if (typeObj.kind !== typeKindFnId) {
154 return false;
155 }
156 return typeObj.generic;
157 }
158
141159 function renderFn(fnDecl) {
142160 var typeObj = zigAnalysis.types[fnDecl.type];
143161 domFnProtoCode.textContent = "fn " + fnDecl.name + typeObj.name.substring(2);
144162
163 var docsSource = null;
145164 var srcNode = zigAnalysis.astNodes[fnDecl.src];
146165 if (srcNode.docs != null) {
147 domFnDocs.innerHTML = markdown(srcNode.docs);
148 domFnDocs.classList.remove("hidden");
166 docsSource = srcNode.docs;
167 }
168
169 var protoSrcIndex;
170 if (typeIsGenericFn(fnDecl.type)) {
171 protoSrcIndex = fnDecl.value;
172
173 var instantiations = nodesToFnsMap[protoSrcIndex];
174 var calls = nodesToCallsMap[protoSrcIndex];
175 if (instantiations == null && calls == null) {
176 domFnNoExamples.classList.remove("hidden");
177 } else {
178 // TODO show examples
179 domFnExamples.classList.remove("hidden");
180 }
181 } else {
182 protoSrcIndex = zigAnalysis.fns[fnDecl.value].src;
183
184 domFnExamples.classList.add("hidden");
185 domFnNoExamples.classList.add("hidden");
149186 }
150187
188 var protoSrcNode = zigAnalysis.astNodes[protoSrcIndex];
189 if (docsSource == null && protoSrcNode.docs != null) {
190 docsSource = protoSrcNode.docs;
191 }
192 if (docsSource != null) {
193 domFnDocs.innerHTML = markdown(docsSource);
194 domFnDocs.classList.remove("hidden");
195 }
151196 domFnProto.classList.remove("hidden");
152197 }
153198
......@@ -268,6 +313,17 @@
268313 }
269314 }
270315
316 function allCompTimeFnCallsHaveTypeResult(typeIndex, value) {
317 var srcIndex = typeIsGenericFn(typeIndex) ? value : zigAnalysis.fns[value].src;
318 var calls = nodesToCallsMap[srcIndex];
319 if (calls == null) return false;
320 for (var i = 0; i < calls.length; i += 1) {
321 var call = zigAnalysis.calls[calls[i]];
322 if (call.result.type !== typeTypeId) return false;
323 }
324 return true;
325 }
326
271327 function renderContainer(container) {
272328 var typesList = [];
273329 var fnsList = [];
......@@ -279,7 +335,11 @@
279335 } else {
280336 var typeKind = zigAnalysis.types[decl.type].kind;
281337 if (typeKind === typeKindFnId) {
282 fnsList.push(decl);
338 if (allCompTimeFnCallsHaveTypeResult(decl.type, decl.value)) {
339 typesList.push(decl);
340 } else {
341 fnsList.push(decl);
342 }
283343 }
284344 }
285345 }
......@@ -688,4 +748,32 @@
688748 }
689749 }
690750 }
751
752 function indexNodesToFns() {
753 var map = {};
754 for (var i = 0; i < zigAnalysis.fns.length; i += 1) {
755 var fn = zigAnalysis.fns[i];
756 if (typeIsGenericFn(fn.type)) continue;
757 if (map[fn.src] == null) {
758 map[fn.src] = [i];
759 } else {
760 map[fn.src].push(i);
761 }
762 }
763 return map;
764 }
765
766 function indexNodesToCalls() {
767 var map = {};
768 for (var i = 0; i < zigAnalysis.calls.length; i += 1) {
769 var call = zigAnalysis.calls[i];
770 var fn = zigAnalysis.fns[call.fn];
771 if (map[fn.src] == null) {
772 map[fn.src] = [i];
773 } else {
774 map[fn.src].push(i);
775 }
776 }
777 return map;
778 }
691779})();
lib/std/std.zig+64-56
......@@ -62,61 +62,69 @@ pub const unicode = @import("unicode.zig");
6262pub const valgrind = @import("valgrind.zig");
6363pub const zig = @import("zig.zig");
6464
65test "std" {
66 // run tests from these
67 _ = @import("array_list.zig");
68 _ = @import("atomic.zig");
69 _ = @import("bloom_filter.zig");
70 _ = @import("buf_map.zig");
71 _ = @import("buf_set.zig");
72 _ = @import("buffer.zig");
73 _ = @import("hash_map.zig");
74 _ = @import("linked_list.zig");
75 _ = @import("mutex.zig");
76 _ = @import("statically_initialized_mutex.zig");
77 _ = @import("segmented_list.zig");
78 _ = @import("spinlock.zig");
79 _ = @import("child_process.zig");
65// Reference everything so it gets tested.
66test "" {
67 _ = AlignedArrayList;
68 _ = ArrayList;
69 _ = AutoHashMap;
70 _ = BloomFilter;
71 _ = BufMap;
72 _ = BufSet;
73 _ = Buffer;
74 _ = BufferOutStream;
75 _ = DynLib;
76 _ = HashMap;
77 _ = Mutex;
78 _ = PackedIntArrayEndian;
79 _ = PackedIntArray;
80 _ = PackedIntSliceEndian;
81 _ = PackedIntSlice;
82 _ = PriorityQueue;
83 _ = SinglyLinkedList;
84 _ = StaticallyInitializedMutex;
85 _ = SegmentedList;
86 _ = SpinLock;
87 _ = StringHashMap;
88 _ = ChildProcess;
89 _ = TailQueue;
90 _ = Thread;
8091
81 _ = @import("ascii.zig");
82 _ = @import("base64.zig");
83 _ = @import("build.zig");
84 _ = @import("c.zig");
85 _ = @import("coff.zig");
86 _ = @import("crypto.zig");
87 _ = @import("cstr.zig");
88 _ = @import("debug.zig");
89 _ = @import("dwarf.zig");
90 _ = @import("dynamic_library.zig");
91 _ = @import("elf.zig");
92 _ = @import("event.zig");
93 _ = @import("fmt.zig");
94 _ = @import("fs.zig");
95 _ = @import("hash.zig");
96 _ = @import("heap.zig");
97 _ = @import("http.zig");
98 _ = @import("io.zig");
99 _ = @import("json.zig");
100 _ = @import("lazy_init.zig");
101 _ = @import("macho.zig");
102 _ = @import("math.zig");
103 _ = @import("mem.zig");
104 _ = @import("meta.zig");
105 _ = @import("net.zig");
106 _ = @import("os.zig");
107 _ = @import("pdb.zig");
108 _ = @import("process.zig");
109 _ = @import("packed_int_array.zig");
110 _ = @import("priority_queue.zig");
111 _ = @import("rand.zig");
112 _ = @import("rb.zig");
113 _ = @import("sort.zig");
114 _ = @import("testing.zig");
115 _ = @import("thread.zig");
116 _ = @import("time.zig");
117 _ = @import("unicode.zig");
118 _ = @import("valgrind.zig");
119 _ = @import("zig.zig");
120
121 _ = @import("debug/leb128.zig");
92 _ = atomic;
93 _ = base64;
94 _ = build;
95 _ = c;
96 _ = coff;
97 _ = crypto;
98 _ = cstr;
99 _ = debug;
100 _ = dwarf;
101 _ = elf;
102 _ = event;
103 _ = fmt;
104 _ = fs;
105 _ = hash;
106 _ = hash_map;
107 _ = heap;
108 _ = http;
109 _ = io;
110 _ = json;
111 _ = lazyInit;
112 _ = macho;
113 _ = math;
114 _ = mem;
115 _ = meta;
116 _ = net;
117 _ = os;
118 _ = packed_int_array;
119 _ = pdb;
120 _ = process;
121 _ = rand;
122 _ = rb;
123 _ = sort;
124 _ = ascii;
125 _ = testing;
126 _ = time;
127 _ = unicode;
128 _ = valgrind;
129 _ = zig;
122130}
src/all_types.hpp+3
......@@ -1325,6 +1325,9 @@ bool tld_ptr_eql(const Tld *a, const Tld *b);
13251325uint32_t node_ptr_hash(const AstNode *ptr);
13261326bool node_ptr_eql(const AstNode *a, const AstNode *b);
13271327
1328uint32_t fn_ptr_hash(const ZigFn *ptr);
1329bool fn_ptr_eql(const ZigFn *a, const ZigFn *b);
1330
13281331struct ZigTypeUnion {
13291332 AstNode *decl_node;
13301333 TypeUnionField *fields;
src/analyze.cpp+8
......@@ -7328,6 +7328,14 @@ bool node_ptr_eql(const AstNode *a, const AstNode *b) {
73287328 return a == b;
73297329}
73307330
7331uint32_t fn_ptr_hash(const ZigFn *ptr) {
7332 return hash_ptr((void*)ptr);
7333}
7334
7335bool fn_ptr_eql(const ZigFn *a, const ZigFn *b) {
7336 return a == b;
7337}
7338
73317339ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name) {
73327340 Tld *tld = get_container_scope(codegen->compile_var_import)->decl_table.get(buf_create_from_str(name));
73337341 resolve_top_level_decl(codegen, tld, nullptr, false);
src/dump_analysis.cpp+120-2
......@@ -352,6 +352,9 @@ struct AnalDumpCtx {
352352 ZigList<Tld *> decl_list;
353353 HashMap<const Tld *, uint32_t, tld_ptr_hash, tld_ptr_eql> decl_map;
354354
355 ZigList<ZigFn *> fn_list;
356 HashMap<const ZigFn *, uint32_t, fn_ptr_hash, fn_ptr_eql> fn_map;
357
355358 ZigList<AstNode *> node_list;
356359 HashMap<const AstNode *, uint32_t, node_ptr_hash, node_ptr_eql> node_map;
357360};
......@@ -430,6 +433,17 @@ static uint32_t anal_dump_get_node_id(AnalDumpCtx *ctx, AstNode *node) {
430433 return node_id;
431434}
432435
436static uint32_t anal_dump_get_fn_id(AnalDumpCtx *ctx, ZigFn *fn) {
437 uint32_t fn_id = ctx->fn_list.length;
438 auto existing_entry = ctx->fn_map.put_unique(fn, fn_id);
439 if (existing_entry == nullptr) {
440 ctx->fn_list.append(fn);
441 } else {
442 fn_id = existing_entry->value;
443 }
444 return fn_id;
445}
446
433447static uint32_t anal_dump_get_decl_id(AnalDumpCtx *ctx, Tld *tld) {
434448 uint32_t decl_id = ctx->decl_list.length;
435449 auto existing_entry = ctx->decl_map.put_unique(tld, decl_id);
......@@ -494,6 +508,11 @@ static void anal_dump_node_ref(AnalDumpCtx *ctx, AstNode *node) {
494508 jw_int(&ctx->jw, node_id);
495509}
496510
511static void anal_dump_fn_ref(AnalDumpCtx *ctx, ZigFn *fn) {
512 uint32_t fn_id = anal_dump_get_fn_id(ctx, fn);
513 jw_int(&ctx->jw, fn_id);
514}
515
497516static void anal_dump_decl_ref(AnalDumpCtx *ctx, Tld *tld) {
498517 uint32_t decl_id = anal_dump_get_decl_id(ctx, tld);
499518 jw_int(&ctx->jw, decl_id);
......@@ -600,8 +619,10 @@ static void anal_dump_decl(AnalDumpCtx *ctx, Tld *tld) {
600619
601620 jw_object_field(jw, "type");
602621 anal_dump_type_ref(ctx, fn->type_entry);
603 }
604622
623 jw_object_field(jw, "value");
624 anal_dump_fn_ref(ctx, fn);
625 }
605626 break;
606627 }
607628 default:
......@@ -642,6 +663,19 @@ static void anal_dump_value(AnalDumpCtx *ctx, AstNode *source_node, ZigType *ty,
642663 anal_dump_type_ref(ctx, val_ty);
643664 return;
644665 }
666 case ZigTypeIdFn: {
667 if (value->data.x_ptr.special == ConstPtrSpecialFunction) {
668 ZigFn *val_fn = value->data.x_ptr.data.fn.fn_entry;
669 if (val_fn->type_entry->data.fn.is_generic) {
670 anal_dump_node_ref(ctx, val_fn->proto_node);
671 } else {
672 anal_dump_fn_ref(ctx, val_fn);
673 }
674 } else {
675 jw_null(&ctx->jw);
676 }
677 return;
678 }
645679 default:
646680 jw_null(&ctx->jw);
647681 return;
......@@ -721,6 +755,11 @@ static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) {
721755 jw_int(jw, ty->data.floating.bit_count);
722756 break;
723757 }
758 case ZigTypeIdFn: {
759 jw_object_field(jw, "generic");
760 jw_bool(jw, ty->data.fn.is_generic);
761 break;
762 }
724763 default:
725764 // TODO
726765 break;
......@@ -763,7 +802,7 @@ void anal_dump_node(AnalDumpCtx *ctx, const AstNode *node) {
763802 doc_comments_buf = nullptr;
764803 break;
765804 }
766 if (doc_comments_buf->list.length != 0) {
805 if (doc_comments_buf != nullptr && doc_comments_buf->list.length != 0) {
767806 jw_object_field(jw, "docs");
768807 jw_string(jw, buf_ptr(doc_comments_buf));
769808 }
......@@ -771,6 +810,19 @@ void anal_dump_node(AnalDumpCtx *ctx, const AstNode *node) {
771810 jw_end_object(jw);
772811}
773812
813void anal_dump_fn(AnalDumpCtx *ctx, ZigFn *fn) {
814 JsonWriter *jw = &ctx->jw;
815
816 jw_begin_object(jw);
817
818 jw_object_field(jw, "src");
819 anal_dump_node_ref(ctx, fn->proto_node);
820
821 jw_object_field(jw, "type");
822 anal_dump_type_ref(ctx, fn->type_entry);
823
824 jw_end_object(jw);
825}
774826
775827void zig_print_analysis_dump(CodeGen *g, FILE *f, const char *one_indent, const char *nl) {
776828 Error err;
......@@ -783,6 +835,7 @@ void zig_print_analysis_dump(CodeGen *g, FILE *f, const char *one_indent, const
783835 ctx.file_map.init(16);
784836 ctx.decl_map.init(16);
785837 ctx.node_map.init(16);
838 ctx.fn_map.init(16);
786839
787840 jw_begin_object(jw);
788841
......@@ -822,6 +875,71 @@ void zig_print_analysis_dump(CodeGen *g, FILE *f, const char *one_indent, const
822875 jw_object_field(jw, "rootPkg");
823876 anal_dump_pkg_ref(&ctx, g->root_package);
824877
878 // Poke the functions
879 for (size_t i = 0; i < g->fn_defs.length; i += 1) {
880 ZigFn *fn = g->fn_defs.at(i);
881 (void)anal_dump_get_fn_id(&ctx, fn);
882 }
883
884 jw_object_field(jw, "calls");
885 jw_begin_array(jw);
886 {
887 auto it = g->memoized_fn_eval_table.entry_iterator();
888 for (;;) {
889 auto *entry = it.next();
890 if (!entry)
891 break;
892
893 jw_array_elem(jw);
894 jw_begin_object(jw);
895
896 jw_object_field(jw, "args");
897 jw_begin_object(jw);
898
899 Scope *scope = entry->key;
900 while (scope != nullptr) {
901 if (scope->id == ScopeIdVarDecl) {
902 ZigVar *var = reinterpret_cast<ScopeVarDecl *>(scope)->var;
903 jw_object_field(jw, var->name);
904 jw_begin_object(jw);
905 jw_object_field(jw, "type");
906 anal_dump_type_ref(&ctx, var->var_type);
907 jw_object_field(jw, "value");
908 anal_dump_value(&ctx, scope->source_node, var->var_type, var->const_value);
909 jw_end_object(jw);
910 } else if (scope->id == ScopeIdFnDef) {
911 jw_end_object(jw);
912
913 jw_object_field(jw, "fn");
914 ZigFn *fn = reinterpret_cast<ScopeFnDef *>(scope)->fn_entry;
915 anal_dump_fn_ref(&ctx, fn);
916
917 ConstExprValue *result = entry->value;
918 jw_object_field(jw, "result");
919 jw_begin_object(jw);
920 jw_object_field(jw, "type");
921 anal_dump_type_ref(&ctx, result->type);
922 jw_object_field(jw, "value");
923 anal_dump_value(&ctx, scope->source_node, result->type, result);
924 jw_end_object(jw);
925 break;
926 }
927 scope = scope->parent;
928 }
929 jw_end_object(jw);
930 }
931 }
932 jw_end_array(jw);
933
934 jw_object_field(jw, "fns");
935 jw_begin_array(jw);
936 for (uint32_t i = 0; i < ctx.fn_list.length; i += 1) {
937 ZigFn *fn = ctx.fn_list.at(i);
938 jw_array_elem(jw);
939 anal_dump_fn(&ctx, fn);
940 }
941 jw_end_array(jw);
942
825943 jw_object_field(jw, "packages");
826944 jw_begin_array(jw);
827945 for (uint32_t i = 0; i < ctx.pkg_list.length; i += 1) {