diff --git a/lib/docs/main.js b/lib/docs/main.js index 2eb6e1918a..b6edaa9787 100644 --- a/lib/docs/main.js +++ b/lib/docs/main.js @@ -80,7 +80,7 @@ var rootIsStd = detectRootIsStd(); // map of decl index to list of non-generic fn indexes - var nodesToFnsMap = indexNodesToFns(); + // var nodesToFnsMap = indexNodesToFns(); // map of decl index to list of comptime fn calls var nodesToCallsMap = indexNodesToCalls(); @@ -160,7 +160,7 @@ console.assert(false); } - function resolveDeclValueTypeId(decl){ + function typeOfDecl(decl){ var i = 0; while(i < 1000) { i += 1; @@ -186,7 +186,12 @@ return resolveTypeRefToTypeId(decl.value.struct.typeRef); } - console.log("TODO: handle in `resolveDeclValueTypeId` more cases: ", decl); + if ("comptimeExpr" in decl.value) { + const cte = zigAnalysis.comptimeExprs[decl.value.comptimeExpr]; + return resolveTypeRefToTypeId(cte.typeRef); + } + + console.log("TODO: handle in `typeOfDecl` more cases: ", decl); console.assert(false); } console.assert(false); @@ -199,7 +204,7 @@ } if ("declRef" in ref) { - return resolveDeclValueTypeId(ref.declRef); + return typeOfDecl(ref.declRef); } if ("type" in ref) { @@ -265,7 +270,11 @@ var childDeclValue = resolveValue(childDecl.value); if ("type" in childDeclValue) { - childDecl = zigAnalysis.types[childDeclValue.type]; + + const t = zigAnalysis.types[childDeclValue.type]; + if (t.kind != typeKinds.Fn) { + childDecl = t; + } } currentType = childDecl; @@ -280,21 +289,28 @@ var lastIsContainerType = isContainerType(last); if (lastIsContainerType) { - renderContainer(last); + return renderContainer(last); } + if (!lastIsDecl && !lastIsType) { return renderUnknownDecl(last); - } else if (lastIsDecl && last.kind === 'var') { + } + + if (lastIsType) { + return renderType(last); + } + + if (lastIsDecl && last.kind === 'var') { return renderVar(last); - } else if (lastIsDecl && last.kind === 'const' && !(declContainsType(last))) { + } + + if (lastIsDecl && last.kind === 'const') { var typeObj = zigAnalysis.types[resolveValue(last.value).type]; - if (typeObj.kind === typeKinds.Fn) { + if (typeObj && typeObj.kind === typeKinds.Fn) { return renderFn(last); - } else { - return renderValue(last); } - } else { - renderType(last); + + return renderValue(last); } } @@ -1102,7 +1118,7 @@ function renderValue(decl) { - var declTypeId = resolveDeclValueTypeId(decl); + var declTypeId = typeOfDecl(decl); var declValueText = ""; switch(Object.keys(decl.value)[0]) { case "int": @@ -1111,6 +1127,9 @@ case "float": declValueText += decl.value.float.value; break; + case "comptimeExpr": + declValueText += "[ComptimeExpr]"; + break; default: console.log("TODO: renderValue for ", Object.keys(decl.value)[0]); declValueText += "#TODO#"; @@ -1130,7 +1149,7 @@ } function renderVar(decl) { - var declTypeId = resolveDeclValueTypeId(decl); + var declTypeId = typeOfDecl(decl); domFnProtoCode.innerHTML = 'var ' + escapeHtml(decl.name) + ': ' + typeIndexName(declTypeId, true, true); @@ -1324,7 +1343,7 @@ tdNameA.setAttribute('href', navLinkDecl(decl.name)); tdNameA.textContent = decl.name; - tdType.innerHTML = typeIndexName(resolveDeclValueTypeId(decl), true, true); + tdType.innerHTML = typeIndexName(typeOfDecl(decl), true, true); var docs = zigAnalysis.astNodes[decl.src].docs; if (docs != null) { @@ -1351,7 +1370,7 @@ tdNameA.setAttribute('href', navLinkDecl(decl.name)); tdNameA.textContent = decl.name; - tdType.innerHTML = typeIndexName(resolveDeclValueTypeId(decl), true, true); + tdType.innerHTML = typeIndexName(typeOfDecl(decl), true, true); var docs = zigAnalysis.astNodes[decl.src].docs; if (docs != null) { @@ -2106,19 +2125,7 @@ function renderSearchCursor() { } } -function indexNodesToFns() { - var map = {}; - for (var i = 0; i < zigAnalysis.fns.length; i += 1) { - var fn = zigAnalysis.fns[i]; - if (typeIsGenericFn(fn.type)) continue; - if (map[fn.src] == null) { - map[fn.src] = [i]; - } else { - map[fn.src].push(i); - } - } - return map; -} + function indexNodesToCalls() { var map = {}; diff --git a/src/Autodoc.zig b/src/Autodoc.zig index 45473b4409..c9e0315583 100644 --- a/src/Autodoc.zig +++ b/src/Autodoc.zig @@ -12,6 +12,7 @@ arena: std.mem.Allocator, types: std.ArrayListUnmanaged(DocData.Type) = .{}, decls: std.ArrayListUnmanaged(DocData.Decl) = .{}, ast_nodes: std.ArrayListUnmanaged(DocData.AstNode) = .{}, +comptimeExprs: std.ArrayListUnmanaged(DocData.ComptimeExpr) = .{}, var arena_allocator: std.heap.ArenaAllocator = undefined; pub fn init(m: *Module, doc_location: Compilation.EmitLoc) Autodoc { @@ -48,9 +49,11 @@ pub fn generateZirData(self: *Autodoc) !void { // append all the types in Zir.Inst.Ref { - - // TODO: we don't want to add .none, but the index math has to check out - var i: u32 = 0; + try self.types.append(self.arena, .{ + .ComptimeExpr = .{ .name = "ComptimeExpr" }, + }); + // this skipts Ref.none but it's ok becuse we replaced it with ComptimeExpr + var i: u32 = 1; while (i <= @enumToInt(Ref.anyerror_void_error_union_type)) : (i += 1) { var tmpbuf = std.ArrayList(u8).init(self.arena); try Ref.typed_value_map[i].val.format("", .{}, tmpbuf.writer()); @@ -128,6 +131,7 @@ pub fn generateZirData(self: *Autodoc) !void { .types = self.types.items, .decls = self.decls.items, .astNodes = self.ast_nodes.items, + .comptimeExprs = self.comptimeExprs.items, }; data.packages[0].main = main_type_index.type; @@ -196,7 +200,7 @@ const Scope = struct { }; const DocData = struct { - typeKinds: []const []const u8 = std.meta.fieldNames(std.builtin.TypeId), + typeKinds: []const []const u8 = std.meta.fieldNames(DocTypeKinds), rootPkg: u32 = 0, params: struct { zigId: []const u8 = "arst", @@ -208,7 +212,6 @@ const DocData = struct { }, } = .{}, packages: [1]Package = .{.{}}, - fns: []struct {} = &.{}, errors: []struct {} = &.{}, calls: []struct {} = &.{}, @@ -217,11 +220,27 @@ const DocData = struct { files: []const []const u8, types: []Type, decls: []Decl, + comptimeExprs: []ComptimeExpr, + const DocTypeKinds = blk: { + var info = @typeInfo(std.builtin.TypeId); + info.Enum.fields = info.Enum.fields ++ [1]std.builtin.TypeInfo.EnumField{ + .{ + .name = "ComptimeExpr", + .value = info.Enum.fields.len, + }, + }; + break :blk @Type(info); + }; + + const ComptimeExpr = struct { + code: []const u8, + typeRef: TypeRef, + }; const Package = struct { name: []const u8 = "root", - file: usize = 0, // index into files - main: usize = 0, // index into decls + file: usize = 0, // index into `files` + main: usize = 0, // index into `decls` table: struct { root: usize } = .{ .root = 0, }, @@ -244,7 +263,7 @@ const DocData = struct { fields: ?[]usize = null, // index into astNodes }; - const Type = union(std.builtin.TypeId) { + const Type = union(DocTypeKinds) { Type: struct { name: []const u8 }, Void: struct { name: []const u8 }, Bool: struct { name: []const u8 }, @@ -260,6 +279,7 @@ const DocData = struct { pubDecls: ?[]usize = null, // index into decls fields: ?[]TypeRef = null, // (use src->fields to find names) }, + ComptimeExpr: struct { name: []const u8 }, ComptimeFloat: struct { name: []const u8 }, ComptimeInt: struct { name: []const u8 }, Undefined: struct { name: []const u8 }, @@ -309,6 +329,7 @@ const DocData = struct { .Array => |v| try printTypeBody(v, options, w), .Bool => |v| try printTypeBody(v, options, w), .Void => |v| try printTypeBody(v, options, w), + .ComptimeExpr => |v| try printTypeBody(v, options, w), .ComptimeInt => |v| try printTypeBody(v, options, w), .ComptimeFloat => |v| try printTypeBody(v, options, w), .Null => |v| try printTypeBody(v, options, w), @@ -355,6 +376,7 @@ const DocData = struct { unspecified, declRef: usize, // index in `decls` type: usize, // index in `types` + comptimeExpr: usize, // index in `comptimeExprs` pub fn fromWalkResult(wr: WalkResult) TypeRef { return switch (wr) { @@ -376,7 +398,7 @@ const DocData = struct { , .{}); }, - .declRef, .type => |v| { + .declRef, .type, .comptimeExpr => |v| { try w.print( \\{{ "{s}":{} }} , .{ @tagName(self), v }); @@ -386,6 +408,7 @@ const DocData = struct { }; const WalkResult = union(enum) { + comptimeExpr: usize, // index in `comptimeExprs` void, @"unreachable", @"null": TypeRef, @@ -421,7 +444,7 @@ const DocData = struct { \\{{ "{s}":{{}} }} , .{@tagName(self)}); }, - .type, .declRef => |v| { + .type, .declRef, .comptimeExpr => |v| { try w.print( \\{{ "{s}":{} }} , .{ @tagName(self), v }); @@ -493,6 +516,14 @@ fn walkInstruction( var new_scope = Scope{ .parent = null }; return self.walkInstruction(new_file.file, &new_scope, Zir.main_struct_inst); }, + .block => { + const res = DocData.WalkResult{ .comptimeExpr = self.comptimeExprs.items.len }; + try self.comptimeExprs.append(self.arena, .{ + .code = "if(banana) 1 else 0", + .typeRef = .{ .type = 0 }, + }); + return res; + }, .int => { const int = data[inst_index].int; return DocData.WalkResult{ @@ -545,7 +576,9 @@ fn walkInstruction( // and we don't want to toss away the // decl_val information (eg by replacing it with // a WalkResult.type). - + .comptimeExpr => { + self.comptimeExprs.items[operand.comptimeExpr].typeRef = dest_type_ref; + }, .int => operand.int.typeRef = dest_type_ref, .@"struct" => operand.@"struct".typeRef = dest_type_ref, .@"undefined" => operand.@"undefined" = dest_type_ref,