authorgravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2022-02-15 20:45:07+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-19 19:10:11-07:00
log5d4c88c7419040e38f7c3b8850f7c8a5c6b31fd5
treeb764206c616dabb97a138cef2c0da45be3191a38
parentee16eddecfc700e37d1acc5393bc2a2ac4e72250

autodoc: added basic support for unresolved comptime expressions


2 files changed, 81 insertions(+), 41 deletions(-)

lib/docs/main.js+37-30
......@@ -80,7 +80,7 @@
8080 var rootIsStd = detectRootIsStd();
8181
8282 // map of decl index to list of non-generic fn indexes
83 var nodesToFnsMap = indexNodesToFns();
83 // var nodesToFnsMap = indexNodesToFns();
8484 // map of decl index to list of comptime fn calls
8585 var nodesToCallsMap = indexNodesToCalls();
8686
......@@ -160,7 +160,7 @@
160160 console.assert(false);
161161 }
162162
163 function resolveDeclValueTypeId(decl){
163 function typeOfDecl(decl){
164164 var i = 0;
165165 while(i < 1000) {
166166 i += 1;
......@@ -186,7 +186,12 @@
186186 return resolveTypeRefToTypeId(decl.value.struct.typeRef);
187187 }
188188
189 console.log("TODO: handle in `resolveDeclValueTypeId` more cases: ", decl);
189 if ("comptimeExpr" in decl.value) {
190 const cte = zigAnalysis.comptimeExprs[decl.value.comptimeExpr];
191 return resolveTypeRefToTypeId(cte.typeRef);
192 }
193
194 console.log("TODO: handle in `typeOfDecl` more cases: ", decl);
190195 console.assert(false);
191196 }
192197 console.assert(false);
......@@ -199,7 +204,7 @@
199204 }
200205
201206 if ("declRef" in ref) {
202 return resolveDeclValueTypeId(ref.declRef);
207 return typeOfDecl(ref.declRef);
203208 }
204209
205210 if ("type" in ref) {
......@@ -265,7 +270,11 @@
265270
266271 var childDeclValue = resolveValue(childDecl.value);
267272 if ("type" in childDeclValue) {
268 childDecl = zigAnalysis.types[childDeclValue.type];
273
274 const t = zigAnalysis.types[childDeclValue.type];
275 if (t.kind != typeKinds.Fn) {
276 childDecl = t;
277 }
269278 }
270279
271280 currentType = childDecl;
......@@ -280,21 +289,28 @@
280289 var lastIsContainerType = isContainerType(last);
281290
282291 if (lastIsContainerType) {
283 renderContainer(last);
292 return renderContainer(last);
284293 }
294
285295 if (!lastIsDecl && !lastIsType) {
286296 return renderUnknownDecl(last);
287 } else if (lastIsDecl && last.kind === 'var') {
297 }
298
299 if (lastIsType) {
300 return renderType(last);
301 }
302
303 if (lastIsDecl && last.kind === 'var') {
288304 return renderVar(last);
289 } else if (lastIsDecl && last.kind === 'const' && !(declContainsType(last))) {
305 }
306
307 if (lastIsDecl && last.kind === 'const') {
290308 var typeObj = zigAnalysis.types[resolveValue(last.value).type];
291 if (typeObj.kind === typeKinds.Fn) {
309 if (typeObj && typeObj.kind === typeKinds.Fn) {
292310 return renderFn(last);
293 } else {
294 return renderValue(last);
295311 }
296 } else {
297 renderType(last);
312
313 return renderValue(last);
298314 }
299315 }
300316
......@@ -1102,7 +1118,7 @@
11021118
11031119 function renderValue(decl) {
11041120
1105 var declTypeId = resolveDeclValueTypeId(decl);
1121 var declTypeId = typeOfDecl(decl);
11061122 var declValueText = "";
11071123 switch(Object.keys(decl.value)[0]) {
11081124 case "int":
......@@ -1111,6 +1127,9 @@
11111127 case "float":
11121128 declValueText += decl.value.float.value;
11131129 break;
1130 case "comptimeExpr":
1131 declValueText += "[ComptimeExpr]";
1132 break;
11141133 default:
11151134 console.log("TODO: renderValue for ", Object.keys(decl.value)[0]);
11161135 declValueText += "#TODO#";
......@@ -1130,7 +1149,7 @@
11301149 }
11311150
11321151 function renderVar(decl) {
1133 var declTypeId = resolveDeclValueTypeId(decl);
1152 var declTypeId = typeOfDecl(decl);
11341153 domFnProtoCode.innerHTML = '<span class="tok-kw">var</span> ' +
11351154 escapeHtml(decl.name) + ': ' + typeIndexName(declTypeId, true, true);
11361155
......@@ -1324,7 +1343,7 @@
13241343 tdNameA.setAttribute('href', navLinkDecl(decl.name));
13251344 tdNameA.textContent = decl.name;
13261345
1327 tdType.innerHTML = typeIndexName(resolveDeclValueTypeId(decl), true, true);
1346 tdType.innerHTML = typeIndexName(typeOfDecl(decl), true, true);
13281347
13291348 var docs = zigAnalysis.astNodes[decl.src].docs;
13301349 if (docs != null) {
......@@ -1351,7 +1370,7 @@
13511370 tdNameA.setAttribute('href', navLinkDecl(decl.name));
13521371 tdNameA.textContent = decl.name;
13531372
1354 tdType.innerHTML = typeIndexName(resolveDeclValueTypeId(decl), true, true);
1373 tdType.innerHTML = typeIndexName(typeOfDecl(decl), true, true);
13551374
13561375 var docs = zigAnalysis.astNodes[decl.src].docs;
13571376 if (docs != null) {
......@@ -2106,19 +2125,7 @@ function renderSearchCursor() {
21062125 }
21072126}
21082127
2109function indexNodesToFns() {
2110 var map = {};
2111 for (var i = 0; i < zigAnalysis.fns.length; i += 1) {
2112 var fn = zigAnalysis.fns[i];
2113 if (typeIsGenericFn(fn.type)) continue;
2114 if (map[fn.src] == null) {
2115 map[fn.src] = [i];
2116 } else {
2117 map[fn.src].push(i);
2118 }
2119 }
2120 return map;
2121}
2128
21222129
21232130function indexNodesToCalls() {
21242131 var map = {};
src/Autodoc.zig+44-11
......@@ -12,6 +12,7 @@ arena: std.mem.Allocator,
1212types: std.ArrayListUnmanaged(DocData.Type) = .{},
1313decls: std.ArrayListUnmanaged(DocData.Decl) = .{},
1414ast_nodes: std.ArrayListUnmanaged(DocData.AstNode) = .{},
15comptimeExprs: std.ArrayListUnmanaged(DocData.ComptimeExpr) = .{},
1516
1617var arena_allocator: std.heap.ArenaAllocator = undefined;
1718pub fn init(m: *Module, doc_location: Compilation.EmitLoc) Autodoc {
......@@ -48,9 +49,11 @@ pub fn generateZirData(self: *Autodoc) !void {
4849
4950 // append all the types in Zir.Inst.Ref
5051 {
51
52 // TODO: we don't want to add .none, but the index math has to check out
53 var i: u32 = 0;
52 try self.types.append(self.arena, .{
53 .ComptimeExpr = .{ .name = "ComptimeExpr" },
54 });
55 // this skipts Ref.none but it's ok becuse we replaced it with ComptimeExpr
56 var i: u32 = 1;
5457 while (i <= @enumToInt(Ref.anyerror_void_error_union_type)) : (i += 1) {
5558 var tmpbuf = std.ArrayList(u8).init(self.arena);
5659 try Ref.typed_value_map[i].val.format("", .{}, tmpbuf.writer());
......@@ -128,6 +131,7 @@ pub fn generateZirData(self: *Autodoc) !void {
128131 .types = self.types.items,
129132 .decls = self.decls.items,
130133 .astNodes = self.ast_nodes.items,
134 .comptimeExprs = self.comptimeExprs.items,
131135 };
132136
133137 data.packages[0].main = main_type_index.type;
......@@ -196,7 +200,7 @@ const Scope = struct {
196200};
197201
198202const DocData = struct {
199 typeKinds: []const []const u8 = std.meta.fieldNames(std.builtin.TypeId),
203 typeKinds: []const []const u8 = std.meta.fieldNames(DocTypeKinds),
200204 rootPkg: u32 = 0,
201205 params: struct {
202206 zigId: []const u8 = "arst",
......@@ -208,7 +212,6 @@ const DocData = struct {
208212 },
209213 } = .{},
210214 packages: [1]Package = .{.{}},
211 fns: []struct {} = &.{},
212215 errors: []struct {} = &.{},
213216 calls: []struct {} = &.{},
214217
......@@ -217,11 +220,27 @@ const DocData = struct {
217220 files: []const []const u8,
218221 types: []Type,
219222 decls: []Decl,
223 comptimeExprs: []ComptimeExpr,
224
225 const DocTypeKinds = blk: {
226 var info = @typeInfo(std.builtin.TypeId);
227 info.Enum.fields = info.Enum.fields ++ [1]std.builtin.TypeInfo.EnumField{
228 .{
229 .name = "ComptimeExpr",
230 .value = info.Enum.fields.len,
231 },
232 };
233 break :blk @Type(info);
234 };
220235
236 const ComptimeExpr = struct {
237 code: []const u8,
238 typeRef: TypeRef,
239 };
221240 const Package = struct {
222241 name: []const u8 = "root",
223 file: usize = 0, // index into files
224 main: usize = 0, // index into decls
242 file: usize = 0, // index into `files`
243 main: usize = 0, // index into `decls`
225244 table: struct { root: usize } = .{
226245 .root = 0,
227246 },
......@@ -244,7 +263,7 @@ const DocData = struct {
244263 fields: ?[]usize = null, // index into astNodes
245264 };
246265
247 const Type = union(std.builtin.TypeId) {
266 const Type = union(DocTypeKinds) {
248267 Type: struct { name: []const u8 },
249268 Void: struct { name: []const u8 },
250269 Bool: struct { name: []const u8 },
......@@ -260,6 +279,7 @@ const DocData = struct {
260279 pubDecls: ?[]usize = null, // index into decls
261280 fields: ?[]TypeRef = null, // (use src->fields to find names)
262281 },
282 ComptimeExpr: struct { name: []const u8 },
263283 ComptimeFloat: struct { name: []const u8 },
264284 ComptimeInt: struct { name: []const u8 },
265285 Undefined: struct { name: []const u8 },
......@@ -309,6 +329,7 @@ const DocData = struct {
309329 .Array => |v| try printTypeBody(v, options, w),
310330 .Bool => |v| try printTypeBody(v, options, w),
311331 .Void => |v| try printTypeBody(v, options, w),
332 .ComptimeExpr => |v| try printTypeBody(v, options, w),
312333 .ComptimeInt => |v| try printTypeBody(v, options, w),
313334 .ComptimeFloat => |v| try printTypeBody(v, options, w),
314335 .Null => |v| try printTypeBody(v, options, w),
......@@ -355,6 +376,7 @@ const DocData = struct {
355376 unspecified,
356377 declRef: usize, // index in `decls`
357378 type: usize, // index in `types`
379 comptimeExpr: usize, // index in `comptimeExprs`
358380
359381 pub fn fromWalkResult(wr: WalkResult) TypeRef {
360382 return switch (wr) {
......@@ -376,7 +398,7 @@ const DocData = struct {
376398 , .{});
377399 },
378400
379 .declRef, .type => |v| {
401 .declRef, .type, .comptimeExpr => |v| {
380402 try w.print(
381403 \\{{ "{s}":{} }}
382404 , .{ @tagName(self), v });
......@@ -386,6 +408,7 @@ const DocData = struct {
386408 };
387409
388410 const WalkResult = union(enum) {
411 comptimeExpr: usize, // index in `comptimeExprs`
389412 void,
390413 @"unreachable",
391414 @"null": TypeRef,
......@@ -421,7 +444,7 @@ const DocData = struct {
421444 \\{{ "{s}":{{}} }}
422445 , .{@tagName(self)});
423446 },
424 .type, .declRef => |v| {
447 .type, .declRef, .comptimeExpr => |v| {
425448 try w.print(
426449 \\{{ "{s}":{} }}
427450 , .{ @tagName(self), v });
......@@ -493,6 +516,14 @@ fn walkInstruction(
493516 var new_scope = Scope{ .parent = null };
494517 return self.walkInstruction(new_file.file, &new_scope, Zir.main_struct_inst);
495518 },
519 .block => {
520 const res = DocData.WalkResult{ .comptimeExpr = self.comptimeExprs.items.len };
521 try self.comptimeExprs.append(self.arena, .{
522 .code = "if(banana) 1 else 0",
523 .typeRef = .{ .type = 0 },
524 });
525 return res;
526 },
496527 .int => {
497528 const int = data[inst_index].int;
498529 return DocData.WalkResult{
......@@ -545,7 +576,9 @@ fn walkInstruction(
545576 // and we don't want to toss away the
546577 // decl_val information (eg by replacing it with
547578 // a WalkResult.type).
548
579 .comptimeExpr => {
580 self.comptimeExprs.items[operand.comptimeExpr].typeRef = dest_type_ref;
581 },
549582 .int => operand.int.typeRef = dest_type_ref,
550583 .@"struct" => operand.@"struct".typeRef = dest_type_ref,
551584 .@"undefined" => operand.@"undefined" = dest_type_ref,