Commit a04045c709

Loris Cro <kappaloris@gmail.com>
2022-02-04 19:28:12
autodocs: fix rendering of non-type decls
1 parent ce40f34
Changed files (2)
lib
docs
src
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 '<span class="tok-type">' + typeObj.name + '</span>';
-                // var signed = (typeObj.i != null) ? 'i' : 'u';
-                // var bits = typeObj[signed];
-                // if (wantHtml) {
-                //     return '<span class="tok-type">' + signed + bits + '</span>';
-                // } 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 '<span class="tok-type">' + name + '</span>';
+                } else {
+                    return name;
+                }
             case typeKinds.ComptimeInt:
                 if (wantHtml) {
                     return '<span class="tok-type">comptime_int</span>';
@@ -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 = '<span class="tok-kw">var</span> ' +
             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, '<div></div>');
 
             var containerNode = zigAnalysis.astNodes[container.src];
@@ -1128,7 +1233,10 @@
                             html += '<span class="tok-kw" style="color:red;">#FAILURE#</span>';
                         } 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,
                             });
                         }
                     }
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);