From a04045c709b6b9a8df830e9b270505663164a89e Mon Sep 17 00:00:00 2001 From: Loris Cro Date: Fri, 4 Feb 2022 19:28:12 +0100 Subject: [PATCH] autodocs: fix rendering of non-type decls --- lib/docs/main.js | 243 +++++++++++++++++++++++++++++++---------------- src/Autodoc.zig | 28 +++++- 2 files changed, 185 insertions(+), 86 deletions(-) diff --git a/lib/docs/main.js b/lib/docs/main.js index 80ba13c537..2301f7c89d 100644 --- a/lib/docs/main.js +++ b/lib/docs/main.js @@ -1,3 +1,5 @@ +//'use strict'; + (function() { var domStatus = document.getElementById("status"); var domSectNav = document.getElementById("sectNav"); @@ -101,6 +103,98 @@ } } + function isDecl(x) { + return "value" in x; + } + + function isType(x) { + return "kind" in x && !("value" in x); + } + + function isContainerType(x) { + return isType(x) && typeKindIsContainer(x.kind) ; + } + + function declContainsType(x){ + console.assert("value" in x); + + } + + function typeKindIsContainer(typeKind) { + return typeKind === typeKinds.Struct || + typeKind === typeKinds.Union || + typeKind === typeKinds.Enum; + } + + function declCanRepresentTypeKind(typeKind) { + return typeKind === typeKinds.ErrorSet || typeKindIsContainer(typeKind); + } + + function resolveDeclValue(decl) { + var i = 0; + while(i < 1000) { + i += 1; + + if ("declRef" in decl.value) { + decl = zigAnalysis.decls[decl.value.declRef]; + continue; + } + + return decl.value; + + } + console.assert(false); + } + + function resolveDeclValueTypeId(decl){ + var i = 0; + while(i < 1000) { + i += 1; + console.assert(isDecl(decl)); + if ("type" in decl.value) { + return typeTypeId; + } + + if ("declRef" in decl.value) { + decl = zigAnalysis.decls[decl.value.declRef]; + continue; + } + + if ("int" in decl.value) { + return resolveTypeRefToTypeId(decl.value.int.typeRef); + } + + if ("float" in decl.value) { + return resolveTypeRefToTypeId(decl.value.float.typeRef); + } + + if ("struct" in decl.value) { + return resolveTypeRefToTypeId(decl.value.struct.typeRef); + } + + console.log("TODO: handle in `resolveDeclValueTypeId` more cases: ", decl); + console.assert(false); + } + console.assert(false); + } + + function resolveTypeRefToTypeId(ref) { + if ("unspecified" in ref) { + console.log("found an unspecified type!") + return -1; + } + + if ("declRef" in ref) { + return resolveDeclValueTypeId(ref.declRef); + } + + if ("type" in ref) { + return ref.type; + } + + console.assert(false); + } + function render() { domStatus.classList.add("hidden"); domFnProto.classList.add("hidden"); @@ -154,38 +248,43 @@ if (childDecl == null) { return render404(); } - var container = getDeclContainerType(childDecl); - if (container == null) { + + var childDeclValue = resolveDeclValue(childDecl); + if ("type" in childDeclValue){ if (i + 1 === curNav.declNames.length) { - curNav.declObjs.push(childDecl); + curNav.declObjs.push(zigAnalysis.types[childDeclValue.type]); break; } else { return render404(); } } - currentType = container; + currentType = childDecl; curNav.declObjs.push(currentType); } renderNav(); - var lastDeclOrType = curNav.declObjs[curNav.declObjs.length - 1]; - if (lastDeclOrType.pubDecls != null) { - renderContainer(lastDeclOrType); + var last = curNav.declObjs[curNav.declObjs.length - 1]; + var lastIsDecl = isDecl(last); + var lastIsType = isType(last); + var lastIsContainerType = isContainerType(last); + + if (lastIsContainerType) { + renderContainer(last); } - if (lastDeclOrType.kind == null) { - return renderUnknownDecl(lastDeclOrType); - } else if (lastDeclOrType.kind === 'var') { - return renderVar(lastDeclOrType); - } else if (lastDeclOrType.kind === 'const' && "value" in lastDeclOrType && !("type" in lastDeclOrType.value)) { - var typeObj = zigAnalysis.types[getDeclValTypeId(lastDeclOrType)]; + if (!lastIsDecl && !lastIsType) { + return renderUnknownDecl(last); + } else if (lastIsDecl && last.kind === 'var') { + return renderVar(last); + } else if (lastIsDecl && last.kind === 'const' && !(declContainsType(last))) { + var typeObj = zigAnalysis.types[resolveDeclValueTypeId(last)]; if (typeObj.kind === typeKinds.Fn) { - return renderFn(lastDeclOrType); + return renderFn(last); } else { - return renderValue(lastDeclOrType); + return renderValue(last); } } else { - renderType(lastDeclOrType); + renderType(last); } } @@ -210,7 +309,7 @@ var typeObj = zigAnalysis.types[typeIndex]; if (typeObj.kind !== typeKinds.Struct) return false; - return typeObj.fields == null || typeObj.fields.length === 0; + return !typeObj.fields; } function typeIsGenericFn(typeIndex) { @@ -642,14 +741,16 @@ return "f" + typeObj.bits; } case typeKinds.Int: - return '' + typeObj.name + ''; - // var signed = (typeObj.i != null) ? 'i' : 'u'; - // var bits = typeObj[signed]; - // if (wantHtml) { - // return '' + signed + bits + ''; - // } else { - // return signed + bits; - // } + var signed = (typeObj.i != null) ? 'i' : 'u'; + var bits = typeObj[signed] || typeObj.name; + + var name = typeObj.name ? typeObj.name : signed + bits; + + if (wantHtml) { + return '' + name + ''; + } else { + return name; + } case typeKinds.ComptimeInt: if (wantHtml) { return 'comptime_int'; @@ -960,12 +1061,15 @@ function renderValue(decl) { - var declTypeId = getDeclValTypeId(decl); + var declTypeId = resolveDeclValueTypeId(decl); var declValueText = ""; switch(Object.keys(decl.value)[0]) { case "int": declValueText += decl.value.int.value; break; + case "float": + declValueText += decl.value.float.value; + break; default: console.log("TODO: renderValue for ", Object.keys(decl.value)[0]); declValueText += "#TODO#"; @@ -985,7 +1089,7 @@ } function renderVar(decl) { - var declTypeId = getDeclValTypeId(decl); + var declTypeId = resolveDeclValueTypeId(decl); domFnProtoCode.innerHTML = 'var ' + escapeHtml(decl.name) + ': ' + typeIndexName(declTypeId, true, true); @@ -1006,27 +1110,28 @@ var varsList = []; var valsList = []; - for (var i = 0; i < container.pubDecls.length; i += 1) { + var declLen = container.pubDecls ? container.pubDecls.length : 0; + for (var i = 0; i < declLen; i += 1) { var decl = zigAnalysis.decls[container.pubDecls[i]]; - var declValTypeId = getDeclValTypeId(decl); + var declTypeId = resolveDeclValueTypeId(decl); if (decl.kind === 'var') { varsList.push(decl); continue; - } else if (decl.kind === 'const' && "value" in decl) { - if (declValTypeId === typeTypeId) { - if (typeIsErrSet(declValTypeId)) { + } else if (decl.kind === 'const') { + if (declTypeId === typeTypeId) { + if (typeIsErrSet(declTypeId)) { errSetsList.push(decl); - } else if (typeIsStructWithNoFields(declValTypeId)) { + } else if (typeIsStructWithNoFields(declTypeId)) { namespacesList.push(decl); } else { typesList.push(decl); } } else { - var typeKind = zigAnalysis.types[declValTypeId].kind; + var typeKind = zigAnalysis.types[declTypeId].kind; if (typeKind === typeKinds.Fn) { // TODO: this is broken but I don't understand functions yet - if (allCompTimeFnCallsHaveTypeResult(decl.type, declValTypeId)) { + if (allCompTimeFnCallsHaveTypeResult(decl.type, declTypeId)) { typesList.push(decl); } else { fnsList.push(decl); @@ -1108,7 +1213,7 @@ domSectFns.classList.remove("hidden"); } - if (container.fields != null && container.fields.length !== 0) { + if (container.fields) { resizeDomList(domListFields, container.fields.length, '
'); var containerNode = zigAnalysis.astNodes[container.src]; @@ -1128,7 +1233,10 @@ html += '#FAILURE#'; } else if ("declRef" in field) { var decl = zigAnalysis.decls[field.declRef]; - var valType = zigAnalysis.types[getDeclValTypeId(decl)]; + var val = resolveDeclValue(decl); + console.assert("type" in val); + var valType = zigAnalysis.types[val.type]; + var valTypeName = valType.name; if (valType.kind === typeKinds.Struct) { valTypeName = "struct"; @@ -1175,7 +1283,7 @@ tdNameA.setAttribute('href', navLinkDecl(decl.name)); tdNameA.textContent = decl.name; - tdType.innerHTML = typeIndexName(getDeclValTypeId(decl), true, true); + tdType.innerHTML = typeIndexName(resolveDeclValueTypeId(decl), true, true); var docs = zigAnalysis.astNodes[decl.src].docs; if (docs != null) { @@ -1202,7 +1310,7 @@ tdNameA.setAttribute('href', navLinkDecl(decl.name)); tdNameA.textContent = decl.name; - tdType.innerHTML = typeIndexName(getDeclValTypeId(decl), true, true); + tdType.innerHTML = typeIndexName(resolveDeclValueTypeId(decl), true, true); var docs = zigAnalysis.astNodes[decl.src].docs; if (docs != null) { @@ -1304,7 +1412,7 @@ } function findSubDecl(parentType, childName) { - if (parentType.pubDecls == null) throw new Error("parent object has no public decls"); + if (!parentType.pubDecls) throw new Error("parent object has no public decls"); for (var i = 0; i < parentType.pubDecls.length; i += 1) { var declIndex = parentType.pubDecls[i]; var childDecl = zigAnalysis.decls[declIndex]; @@ -1315,12 +1423,8 @@ return null; } - function getDeclContainerType(decl) { - if (decl.type === typeTypeId) { - return zigAnalysis.types[getDeclValTypeId(decl)]; - } - return null; - } + + function computeCanonicalPackagePaths() { var list = new Array(zigAnalysis.packages.length); @@ -1350,37 +1454,6 @@ return list; } - function typeKindIsContainer(typeKind) { - return typeKind === typeKinds.Struct || - typeKind === typeKinds.Union || - typeKind === typeKinds.Enum; - } - - function declCanRepresentTypeKind(typeKind) { - return typeKind === typeKinds.ErrorSet || typeKindIsContainer(typeKind); - } - - // Handles both WalkResult and TypeRef - function getDeclValTypeId(decl) { - var val = decl.value; - while (true) { - if ( "declRef" in val) { - val = zigAnalysis.decls[val.declRef].value; - continue; - } - - if ("int" in val) { - val = val.int.typeRef; - } - - if ("type" in val) { - return val.type; - } - - console.assert("type" in val); - } - return val.type; - } function computeCanonDeclPaths() { var list = new Array(zigAnalysis.decls.length); @@ -1397,14 +1470,15 @@ while (stack.length !== 0) { var item = stack.shift(); - if (item.type.pubDecls != null) { - for (var declI = 0; declI < item.type.pubDecls.length; declI += 1) { + if (isContainerType(item.type)) { + var len = item.type.pubDecls ? item.type.pubDecls.length : 0; + for (var declI = 0; declI < len; declI += 1) { var mainDeclIndex = item.type.pubDecls[declI]; if (list[mainDeclIndex] != null) continue; var decl = zigAnalysis.decls[mainDeclIndex]; - var declValTypeId = getDeclValTypeId(decl); - if (decl.type === typeTypeId && + var declValTypeId = resolveDeclValueTypeId(decl); + if (declValTypeId === typeTypeId && declCanRepresentTypeKind(zigAnalysis.types[declValTypeId].kind)) { canonTypeDecls[declValTypeId] = mainDeclIndex; @@ -1414,11 +1488,12 @@ pkgNames: pkgNames, declNames: declNames, }; - var containerType = getDeclContainerType(decl); - if (containerType != null) { + + var declType = zigAnalysis.types[declValTypeId]; + if (isContainerType(declType)) { stack.push({ declNames: declNames, - type: containerType, + type: declType, }); } } diff --git a/src/Autodoc.zig b/src/Autodoc.zig index 21aff1f36b..46c01e43a1 100644 --- a/src/Autodoc.zig +++ b/src/Autodoc.zig @@ -88,13 +88,14 @@ pub fn generateZirData(self: *Autodoc) !void { .c_longlong_type, .c_ulonglong_type, .c_longdouble_type, - .comptime_int_type, => @enumToInt(std.builtin.TypeId.Int), .f16_type, .f32_type, .f64_type, .f128_type, => @enumToInt(std.builtin.TypeId.Float), + .comptime_int_type => @enumToInt(std.builtin.TypeId.ComptimeInt), + .comptime_float_type => @enumToInt(std.builtin.TypeId.ComptimeFloat), .bool_type => @enumToInt(std.builtin.TypeId.Bool), .void_type => @enumToInt(std.builtin.TypeId.Void), .type_type => @enumToInt(std.builtin.TypeId.Type), @@ -275,7 +276,11 @@ const DocData = struct { value: usize, // direct value negated: bool = false, }, - + float: struct { + typeRef: TypeRef, + value: f64, // direct value + negated: bool = false, + }, pub fn jsonStringify( self: WalkResult, options: std.json.StringifyOptions, @@ -304,6 +309,16 @@ const DocData = struct { \\, "value": {s}{} }} }} , .{ neg, v.value }); }, + .float => |v| { + const neg = if (v.negated) "-" else ""; + try w.print( + \\{{ "float": {{ "typeRef": + , .{}); + try v.typeRef.jsonStringify(options, w); + try w.print( + \\, "value": {s}{} }} }} + , .{ neg, v.value }); + }, .bool => |v| { try w.print( \\{{ "bool":{} }} @@ -350,6 +365,15 @@ fn walkInstruction( }, }; }, + .float => { + const float = data[inst_index].float; + return DocData.WalkResult{ + .float = .{ + .typeRef = .{ .type = @enumToInt(Ref.comptime_float_type) }, + .value = float, + }, + }; + }, .negate => { const un_node = data[inst_index].un_node; var operand = try self.walkRef(zir, parent_scope, un_node.operand);