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 @@...@@ -80,7 +80,7 @@
80 var rootIsStd = detectRootIsStd();80 var rootIsStd = detectRootIsStd();
8181
82 // map of decl index to list of non-generic fn indexes82 // map of decl index to list of non-generic fn indexes
83 var nodesToFnsMap = indexNodesToFns();83 // var nodesToFnsMap = indexNodesToFns();
84 // map of decl index to list of comptime fn calls84 // map of decl index to list of comptime fn calls
85 var nodesToCallsMap = indexNodesToCalls();85 var nodesToCallsMap = indexNodesToCalls();
8686
...@@ -160,7 +160,7 @@...@@ -160,7 +160,7 @@
160 console.assert(false);160 console.assert(false);
161 }161 }
162162
163 function resolveDeclValueTypeId(decl){163 function typeOfDecl(decl){
164 var i = 0;164 var i = 0;
165 while(i < 1000) {165 while(i < 1000) {
166 i += 1;166 i += 1;
...@@ -186,7 +186,12 @@...@@ -186,7 +186,12 @@
186 return resolveTypeRefToTypeId(decl.value.struct.typeRef);186 return resolveTypeRefToTypeId(decl.value.struct.typeRef);
187 }187 }
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);
190 console.assert(false);195 console.assert(false);
191 }196 }
192 console.assert(false);197 console.assert(false);
...@@ -199,7 +204,7 @@...@@ -199,7 +204,7 @@
199 }204 }
200205
201 if ("declRef" in ref) {206 if ("declRef" in ref) {
202 return resolveDeclValueTypeId(ref.declRef);207 return typeOfDecl(ref.declRef);
203 }208 }
204209
205 if ("type" in ref) {210 if ("type" in ref) {
...@@ -265,7 +270,11 @@...@@ -265,7 +270,11 @@
265270
266 var childDeclValue = resolveValue(childDecl.value);271 var childDeclValue = resolveValue(childDecl.value);
267 if ("type" in childDeclValue) {272 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 }
269 }278 }
270279
271 currentType = childDecl;280 currentType = childDecl;
...@@ -280,21 +289,28 @@...@@ -280,21 +289,28 @@
280 var lastIsContainerType = isContainerType(last);289 var lastIsContainerType = isContainerType(last);
281290
282 if (lastIsContainerType) {291 if (lastIsContainerType) {
283 renderContainer(last);292 return renderContainer(last);
284 }293 }
294
285 if (!lastIsDecl && !lastIsType) {295 if (!lastIsDecl && !lastIsType) {
286 return renderUnknownDecl(last);296 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') {
288 return renderVar(last);304 return renderVar(last);
289 } else if (lastIsDecl && last.kind === 'const' && !(declContainsType(last))) {305 }
306
307 if (lastIsDecl && last.kind === 'const') {
290 var typeObj = zigAnalysis.types[resolveValue(last.value).type];308 var typeObj = zigAnalysis.types[resolveValue(last.value).type];
291 if (typeObj.kind === typeKinds.Fn) {309 if (typeObj && typeObj.kind === typeKinds.Fn) {
292 return renderFn(last);310 return renderFn(last);
293 } else {
294 return renderValue(last);
295 }311 }
296 } else {312
297 renderType(last);313 return renderValue(last);
298 }314 }
299 }315 }
300316
...@@ -1102,7 +1118,7 @@...@@ -1102,7 +1118,7 @@
11021118
1103 function renderValue(decl) {1119 function renderValue(decl) {
11041120
1105 var declTypeId = resolveDeclValueTypeId(decl);1121 var declTypeId = typeOfDecl(decl);
1106 var declValueText = "";1122 var declValueText = "";
1107 switch(Object.keys(decl.value)[0]) {1123 switch(Object.keys(decl.value)[0]) {
1108 case "int":1124 case "int":
...@@ -1111,6 +1127,9 @@...@@ -1111,6 +1127,9 @@
1111 case "float":1127 case "float":
1112 declValueText += decl.value.float.value;1128 declValueText += decl.value.float.value;
1113 break;1129 break;
1130 case "comptimeExpr":
1131 declValueText += "[ComptimeExpr]";
1132 break;
1114 default:1133 default:
1115 console.log("TODO: renderValue for ", Object.keys(decl.value)[0]);1134 console.log("TODO: renderValue for ", Object.keys(decl.value)[0]);
1116 declValueText += "#TODO#";1135 declValueText += "#TODO#";
...@@ -1130,7 +1149,7 @@...@@ -1130,7 +1149,7 @@
1130 }1149 }
11311150
1132 function renderVar(decl) {1151 function renderVar(decl) {
1133 var declTypeId = resolveDeclValueTypeId(decl);1152 var declTypeId = typeOfDecl(decl);
1134 domFnProtoCode.innerHTML = '<span class="tok-kw">var</span> ' +1153 domFnProtoCode.innerHTML = '<span class="tok-kw">var</span> ' +
1135 escapeHtml(decl.name) + ': ' + typeIndexName(declTypeId, true, true);1154 escapeHtml(decl.name) + ': ' + typeIndexName(declTypeId, true, true);
11361155
...@@ -1324,7 +1343,7 @@...@@ -1324,7 +1343,7 @@
1324 tdNameA.setAttribute('href', navLinkDecl(decl.name));1343 tdNameA.setAttribute('href', navLinkDecl(decl.name));
1325 tdNameA.textContent = decl.name;1344 tdNameA.textContent = decl.name;
13261345
1327 tdType.innerHTML = typeIndexName(resolveDeclValueTypeId(decl), true, true);1346 tdType.innerHTML = typeIndexName(typeOfDecl(decl), true, true);
13281347
1329 var docs = zigAnalysis.astNodes[decl.src].docs;1348 var docs = zigAnalysis.astNodes[decl.src].docs;
1330 if (docs != null) {1349 if (docs != null) {
...@@ -1351,7 +1370,7 @@...@@ -1351,7 +1370,7 @@
1351 tdNameA.setAttribute('href', navLinkDecl(decl.name));1370 tdNameA.setAttribute('href', navLinkDecl(decl.name));
1352 tdNameA.textContent = decl.name;1371 tdNameA.textContent = decl.name;
13531372
1354 tdType.innerHTML = typeIndexName(resolveDeclValueTypeId(decl), true, true);1373 tdType.innerHTML = typeIndexName(typeOfDecl(decl), true, true);
13551374
1356 var docs = zigAnalysis.astNodes[decl.src].docs;1375 var docs = zigAnalysis.astNodes[decl.src].docs;
1357 if (docs != null) {1376 if (docs != null) {
...@@ -2106,19 +2125,7 @@ function renderSearchCursor() {...@@ -2106,19 +2125,7 @@ function renderSearchCursor() {
2106 }2125 }
2107}2126}
21082127
2109function indexNodesToFns() {2128
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}
21222129
2123function indexNodesToCalls() {2130function indexNodesToCalls() {
2124 var map = {};2131 var map = {};
src/Autodoc.zig+44-11
...@@ -12,6 +12,7 @@ arena: std.mem.Allocator,...@@ -12,6 +12,7 @@ arena: std.mem.Allocator,
12types: std.ArrayListUnmanaged(DocData.Type) = .{},12types: std.ArrayListUnmanaged(DocData.Type) = .{},
13decls: std.ArrayListUnmanaged(DocData.Decl) = .{},13decls: std.ArrayListUnmanaged(DocData.Decl) = .{},
14ast_nodes: std.ArrayListUnmanaged(DocData.AstNode) = .{},14ast_nodes: std.ArrayListUnmanaged(DocData.AstNode) = .{},
15comptimeExprs: std.ArrayListUnmanaged(DocData.ComptimeExpr) = .{},
1516
16var arena_allocator: std.heap.ArenaAllocator = undefined;17var arena_allocator: std.heap.ArenaAllocator = undefined;
17pub fn init(m: *Module, doc_location: Compilation.EmitLoc) Autodoc {18pub fn init(m: *Module, doc_location: Compilation.EmitLoc) Autodoc {
...@@ -48,9 +49,11 @@ pub fn generateZirData(self: *Autodoc) !void {...@@ -48,9 +49,11 @@ pub fn generateZirData(self: *Autodoc) !void {
4849
49 // append all the types in Zir.Inst.Ref50 // append all the types in Zir.Inst.Ref
50 {51 {
5152 try self.types.append(self.arena, .{
52 // TODO: we don't want to add .none, but the index math has to check out53 .ComptimeExpr = .{ .name = "ComptimeExpr" },
53 var i: u32 = 0;54 });
55 // this skipts Ref.none but it's ok becuse we replaced it with ComptimeExpr
56 var i: u32 = 1;
54 while (i <= @enumToInt(Ref.anyerror_void_error_union_type)) : (i += 1) {57 while (i <= @enumToInt(Ref.anyerror_void_error_union_type)) : (i += 1) {
55 var tmpbuf = std.ArrayList(u8).init(self.arena);58 var tmpbuf = std.ArrayList(u8).init(self.arena);
56 try Ref.typed_value_map[i].val.format("", .{}, tmpbuf.writer());59 try Ref.typed_value_map[i].val.format("", .{}, tmpbuf.writer());
...@@ -128,6 +131,7 @@ pub fn generateZirData(self: *Autodoc) !void {...@@ -128,6 +131,7 @@ pub fn generateZirData(self: *Autodoc) !void {
128 .types = self.types.items,131 .types = self.types.items,
129 .decls = self.decls.items,132 .decls = self.decls.items,
130 .astNodes = self.ast_nodes.items,133 .astNodes = self.ast_nodes.items,
134 .comptimeExprs = self.comptimeExprs.items,
131 };135 };
132136
133 data.packages[0].main = main_type_index.type;137 data.packages[0].main = main_type_index.type;
...@@ -196,7 +200,7 @@ const Scope = struct {...@@ -196,7 +200,7 @@ const Scope = struct {
196};200};
197201
198const DocData = struct {202const DocData = struct {
199 typeKinds: []const []const u8 = std.meta.fieldNames(std.builtin.TypeId),203 typeKinds: []const []const u8 = std.meta.fieldNames(DocTypeKinds),
200 rootPkg: u32 = 0,204 rootPkg: u32 = 0,
201 params: struct {205 params: struct {
202 zigId: []const u8 = "arst",206 zigId: []const u8 = "arst",
...@@ -208,7 +212,6 @@ const DocData = struct {...@@ -208,7 +212,6 @@ const DocData = struct {
208 },212 },
209 } = .{},213 } = .{},
210 packages: [1]Package = .{.{}},214 packages: [1]Package = .{.{}},
211 fns: []struct {} = &.{},
212 errors: []struct {} = &.{},215 errors: []struct {} = &.{},
213 calls: []struct {} = &.{},216 calls: []struct {} = &.{},
214217
...@@ -217,11 +220,27 @@ const DocData = struct {...@@ -217,11 +220,27 @@ const DocData = struct {
217 files: []const []const u8,220 files: []const []const u8,
218 types: []Type,221 types: []Type,
219 decls: []Decl,222 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 };
221 const Package = struct {240 const Package = struct {
222 name: []const u8 = "root",241 name: []const u8 = "root",
223 file: usize = 0, // index into files242 file: usize = 0, // index into `files`
224 main: usize = 0, // index into decls243 main: usize = 0, // index into `decls`
225 table: struct { root: usize } = .{244 table: struct { root: usize } = .{
226 .root = 0,245 .root = 0,
227 },246 },
...@@ -244,7 +263,7 @@ const DocData = struct {...@@ -244,7 +263,7 @@ const DocData = struct {
244 fields: ?[]usize = null, // index into astNodes263 fields: ?[]usize = null, // index into astNodes
245 };264 };
246265
247 const Type = union(std.builtin.TypeId) {266 const Type = union(DocTypeKinds) {
248 Type: struct { name: []const u8 },267 Type: struct { name: []const u8 },
249 Void: struct { name: []const u8 },268 Void: struct { name: []const u8 },
250 Bool: struct { name: []const u8 },269 Bool: struct { name: []const u8 },
...@@ -260,6 +279,7 @@ const DocData = struct {...@@ -260,6 +279,7 @@ const DocData = struct {
260 pubDecls: ?[]usize = null, // index into decls279 pubDecls: ?[]usize = null, // index into decls
261 fields: ?[]TypeRef = null, // (use src->fields to find names)280 fields: ?[]TypeRef = null, // (use src->fields to find names)
262 },281 },
282 ComptimeExpr: struct { name: []const u8 },
263 ComptimeFloat: struct { name: []const u8 },283 ComptimeFloat: struct { name: []const u8 },
264 ComptimeInt: struct { name: []const u8 },284 ComptimeInt: struct { name: []const u8 },
265 Undefined: struct { name: []const u8 },285 Undefined: struct { name: []const u8 },
...@@ -309,6 +329,7 @@ const DocData = struct {...@@ -309,6 +329,7 @@ const DocData = struct {
309 .Array => |v| try printTypeBody(v, options, w),329 .Array => |v| try printTypeBody(v, options, w),
310 .Bool => |v| try printTypeBody(v, options, w),330 .Bool => |v| try printTypeBody(v, options, w),
311 .Void => |v| try printTypeBody(v, options, w),331 .Void => |v| try printTypeBody(v, options, w),
332 .ComptimeExpr => |v| try printTypeBody(v, options, w),
312 .ComptimeInt => |v| try printTypeBody(v, options, w),333 .ComptimeInt => |v| try printTypeBody(v, options, w),
313 .ComptimeFloat => |v| try printTypeBody(v, options, w),334 .ComptimeFloat => |v| try printTypeBody(v, options, w),
314 .Null => |v| try printTypeBody(v, options, w),335 .Null => |v| try printTypeBody(v, options, w),
...@@ -355,6 +376,7 @@ const DocData = struct {...@@ -355,6 +376,7 @@ const DocData = struct {
355 unspecified,376 unspecified,
356 declRef: usize, // index in `decls`377 declRef: usize, // index in `decls`
357 type: usize, // index in `types`378 type: usize, // index in `types`
379 comptimeExpr: usize, // index in `comptimeExprs`
358380
359 pub fn fromWalkResult(wr: WalkResult) TypeRef {381 pub fn fromWalkResult(wr: WalkResult) TypeRef {
360 return switch (wr) {382 return switch (wr) {
...@@ -376,7 +398,7 @@ const DocData = struct {...@@ -376,7 +398,7 @@ const DocData = struct {
376 , .{});398 , .{});
377 },399 },
378400
379 .declRef, .type => |v| {401 .declRef, .type, .comptimeExpr => |v| {
380 try w.print(402 try w.print(
381 \\{{ "{s}":{} }}403 \\{{ "{s}":{} }}
382 , .{ @tagName(self), v });404 , .{ @tagName(self), v });
...@@ -386,6 +408,7 @@ const DocData = struct {...@@ -386,6 +408,7 @@ const DocData = struct {
386 };408 };
387409
388 const WalkResult = union(enum) {410 const WalkResult = union(enum) {
411 comptimeExpr: usize, // index in `comptimeExprs`
389 void,412 void,
390 @"unreachable",413 @"unreachable",
391 @"null": TypeRef,414 @"null": TypeRef,
...@@ -421,7 +444,7 @@ const DocData = struct {...@@ -421,7 +444,7 @@ const DocData = struct {
421 \\{{ "{s}":{{}} }}444 \\{{ "{s}":{{}} }}
422 , .{@tagName(self)});445 , .{@tagName(self)});
423 },446 },
424 .type, .declRef => |v| {447 .type, .declRef, .comptimeExpr => |v| {
425 try w.print(448 try w.print(
426 \\{{ "{s}":{} }}449 \\{{ "{s}":{} }}
427 , .{ @tagName(self), v });450 , .{ @tagName(self), v });
...@@ -493,6 +516,14 @@ fn walkInstruction(...@@ -493,6 +516,14 @@ fn walkInstruction(
493 var new_scope = Scope{ .parent = null };516 var new_scope = Scope{ .parent = null };
494 return self.walkInstruction(new_file.file, &new_scope, Zir.main_struct_inst);517 return self.walkInstruction(new_file.file, &new_scope, Zir.main_struct_inst);
495 },518 },
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 },
496 .int => {527 .int => {
497 const int = data[inst_index].int;528 const int = data[inst_index].int;
498 return DocData.WalkResult{529 return DocData.WalkResult{
...@@ -545,7 +576,9 @@ fn walkInstruction(...@@ -545,7 +576,9 @@ fn walkInstruction(
545 // and we don't want to toss away the576 // and we don't want to toss away the
546 // decl_val information (eg by replacing it with577 // decl_val information (eg by replacing it with
547 // a WalkResult.type).578 // a WalkResult.type).
548579 .comptimeExpr => {
580 self.comptimeExprs.items[operand.comptimeExpr].typeRef = dest_type_ref;
581 },
549 .int => operand.int.typeRef = dest_type_ref,582 .int => operand.int.typeRef = dest_type_ref,
550 .@"struct" => operand.@"struct".typeRef = dest_type_ref,583 .@"struct" => operand.@"struct".typeRef = dest_type_ref,
551 .@"undefined" => operand.@"undefined" = dest_type_ref,584 .@"undefined" => operand.@"undefined" = dest_type_ref,