Commit 36c4b1aac9

Loris Cro <kappaloris@gmail.com>
2022-03-24 18:52:07
autodoc: improve rendering and add "show priv decls" checkbox
1 parent df3074a
Changed files (3)
lib/docs/index.html
@@ -26,17 +26,17 @@
         --search-sh-color: rgba(0, 0, 0, 0.18);
         --help-sh-color: rgba(0, 0, 0, 0.75);
       }
-      
+
       html, body { margin: 0; padding:0; height: 100%; }
 
       a {
         text-decoration: none;
       }
-      
+
       a:hover {
         text-decoration: underline;
       }
-      
+
       .hidden {
         display: none;
       }
@@ -58,7 +58,7 @@
         width: 100%;
         height: 100%;
         justify-content: center;
-        
+
         z-index: 100;
       }
 
@@ -76,7 +76,7 @@
         overflow-wrap: break-word;
         flex-shrink: 0;
         flex-grow: 0;
-        
+
         z-index: 300;
       }
 
@@ -86,7 +86,7 @@
         -webkit-overflow-scrolling: touch;
         flex-grow: 1;
         flex-shrink: 1;
-        
+
         z-index: 200;
       }
 
@@ -95,44 +95,44 @@
         max-width: 85vw;
         flex-shrink: 1;
       }
-      
+
       .help-modal {
         z-index: 400;
       }
-      
+
       /* sidebar */
       .sidebar {
         font-size: 1rem;
         background-color: var(--bg-color);
         box-shadow: 0 0 1rem var(--sidebar-sh-color);
       }
-      
+
       .sidebar .logo {
         padding: 1rem 0.35rem 0.35rem 0.35rem;
       }
-      
+
       .sidebar .logo > svg {
         display: block;
         overflow: visible;
       }
-      
+
       .sidebar h2 {
         margin: 0.5rem;
         padding: 0;
         font-size: 1.2rem;
       }
-      
+
       .sidebar h2 > span {
         border-bottom: 0.125rem dotted var(--tx-color);
       }
-      
+
       .sidebar .packages {
         list-style-type: none;
         margin: 0;
         padding: 0;
         background-color: var(--sidebar-pkg-bg-color);
       }
-      
+
       .sidebar .packages > li > a {
         display: block;
         padding: 0.5rem 1rem;
@@ -140,17 +140,17 @@
         background-color: var(--sidebar-pkglnk-bg-color);
         text-decoration: none;
       }
-      
+
       .sidebar .packages > li > a:hover {
         color: var(--sidebar-pkglnk-tx-color-hover);
         background-color: var(--sidebar-pkglnk-bg-color-hover);
       }
-      
+
       .sidebar .packages > li > a.active {
         color: var(--sidebar-pkglnk-tx-color-active);
         background-color: var(--sidebar-pkglnk-bg-color-active);
       }
-      
+
       .sidebar p.str {
         margin: 0.5rem;
         font-family: var(--mono);
@@ -183,28 +183,28 @@
         border-radius: 0;
         -webkit-appearance: none;
       }
-      
+
       .docs .search:focus {
         background-color: var(--search-bg-color-focus);
         border-bottom-color: #ffbb4d;
         box-shadow: 0 0.3em 1em 0.125em var(--search-sh-color);
       }
-      
+
       .docs .search::placeholder {
         font-size: 1rem;
         font-family: var(--ui);
         color: var(--tx-color);
         opacity: 0.5;
       }
-      
+
       .docs a {
         color: var(--link-color);
       }
-      
+
       .docs p {
         margin: 0.8rem 0;
       }
-      
+
       .docs pre {
         font-family: var(--mono);
         font-size:1em;
@@ -212,19 +212,19 @@
         padding:1em;
         overflow-x: auto;
       }
-      
+
       .docs code {
         font-family: var(--mono);
         font-size: 1em;
       }
-      
+
       .docs h1 {
         font-size: 1.4em;
         margin: 0.8em 0;
         padding: 0;
         border-bottom: 0.0625rem dashed;
       }
-      
+
       .docs  h2 {
         font-size: 1.3em;
         margin: 0.5em 0;
@@ -264,7 +264,7 @@
       #tableFnErrors dt {
         font-weight: bold;
       }
-      
+
       .examples {
         list-style-type: none;
         margin: 0;
@@ -275,7 +275,7 @@
         white-space: nowrap;
         overflow-x: auto;
       }
-      
+
       .docs td {
         margin: 0;
         padding: 0.5em;
@@ -283,7 +283,7 @@
         text-overflow: ellipsis;
         overflow-x: hidden;
       }
-      
+
       /* help dialog */
       .help-modal {
         display: flex;
@@ -308,23 +308,23 @@
         border: 0.125rem solid #000;
         box-shadow: 0 0.5rem 2.5rem 0.3rem var(--help-sh-color);
       }
-      
+
       .help-modal h1 {
         margin: 0.75em 2.5em 1em 2.5em;
         font-size: 1.5em;
         text-align: center;
       }
-      
+
       .help-modal dt, .help-modal dd {
         display: inline;
         margin: 0 0.2em;
       }
-      
+
       .help-modal dl {
         margin-left: 0.5em;
         margin-right: 0.5em;
       }
-      
+
       .help-modal kbd {
         display: inline-block;
         padding: 0.3em 0.2em;
@@ -341,7 +341,7 @@
         box-shadow: inset 0 -0.0625em 0 #c6cbd1;
         cursor: default;
       }
-      
+
       /* tokens */
       .tok-kw {
           color: #333;
@@ -371,10 +371,10 @@
           color: #458;
           font-weight: bold;
       }
-      
+
       /* dark mode */
       @media (prefers-color-scheme: dark) {
-      
+
         :root {
           --tx-color: #bbb;
           --bg-color: #111;
@@ -392,7 +392,7 @@
           --search-sh-color: rgba(255, 255, 255, 0.28);
           --help-sh-color: rgba(142, 142, 142, 0.5);
         }
-        
+
         .docs pre {
           background-color:#2A2A2A;
         }
@@ -440,7 +440,7 @@
         .tok-type {
             color: #68f;
         }
-        
+
       }
 
       @media only screen and (max-width: 750px) {
@@ -545,6 +545,9 @@
             <h2><span>Target</span></h2>
             <p class="str" id="tdTarget"></p>
           </div>
+		  <div>
+			<input id="privDeclsBox" type="checkbox"/> Show Private Decls
+		  </div>
         </nav>
       </div>
       <div class="flex-right">
lib/docs/main.js
@@ -32,18 +32,6 @@
    } TypeKind
 */
 
-/**
- * @typedef {
-    | WalkResult
-    | { unspecified: {} }
-    | { anytype: {} }
-    | { type: number }
-    | { comptimeExpr: number }
-    | { call: number }
-    | { hasCte: boolean; declPath: number[] }
-   } TypeRef
-*/
-
 /**
  * @typedef {
     | { void: {} }
@@ -52,16 +40,16 @@
     | { type: number }
     | { comptimeExpr: number }
     | { call: number }
-    | { int: { typeRef: TypeRef; value: number } }
-    | { float: { typeRef: TypeRef; value: number } }
+    | { int: { typeRef: WalkResult; value: number } }
+    | { float: { typeRef: WalkResult; value: number } }
     | { bool: boolean }
-    | { undefined: TypeRef }
-    | { null: TypeRef }
+    | { undefined: WalkResult }
+    | { null: WalkResult }
     | { typeOf: WalkResult }
     | { compileError: string }
     | { string: string }
     | { struct: Struct }
-    | { hasCte: boolean; declPath: number[] }
+    | { refPath: WalkResult[] }
     | { array: ZigArray }
     | { enumLiteral: string }
    } WalkResult
@@ -75,8 +63,8 @@
         | { len: WalkResult; child: TypeRef } // Array
         | { name: string; fields: { name: string; docs: string }[] } // ErrorSet
         | { size: "One" | "Many" | "Slice" | "C"; child: TypeRef } // Pointer
-        | { name: string; src?: number; privDecls: number[]; pubDecls: number[]; fields?: TypeRef[] } // Struct, Enum, Union
-        | { name: string; src?: number; ret: TypeRef; params?: TypeRef[] } // Fn
+        | { name: string; src: number; privDecls: number[]; pubDecls: number[]; fields: WalkResult[] } // Struct, Enum, Union
+        | { name: string; src: number; ret: WalkResult; params: WalkResult[] } // Fn
      )
    } Type
 */
@@ -85,14 +73,14 @@
  * @typedef {{
        name: string,
        src: number | null,
-       ret: TypeRef,
-       params: TypeRef[] | null,
+       ret: WalkResult,
+       params: WalkResult[] | null,
    }} Fn
 */
 
 /**
  * @typedef {{
-       func: TypeRef,
+       func: WalkResult,
        args: WalkResult[],
        ret: WalkResult,
    }} Call
@@ -135,21 +123,21 @@
       src?: number,
       privDecls: number[],
       pubDecls: number[],
-      fields?: TypeRef[],
+      fields?: WalkResult[],
    }} Struct
 */
 
 /**
  * @typedef {{
       len: WalkResult,
-      child: TypeRef,
+      child: WalkResult,
   }} ZigArray
 */
 
 /**
  * @typedef {{
       code: string,
-      typeRef: TypeRef,
+      typeRef: WalkResult,
    }} ComptimeExpr
 */
 
@@ -219,6 +207,7 @@ var zigAnalysis;
     var domSectSearchNoResults = document.getElementById("sectSearchNoResults");
     var domSectInfo = document.getElementById("sectInfo");
     var domTdTarget = document.getElementById("tdTarget");
+    var domPrivDeclsBox = document.getElementById("privDeclsBox");
     var domTdZigVer = document.getElementById("tdZigVer");
     var domHdrName = document.getElementById("hdrName");
     var domHelpModal = document.getElementById("helpDialog");
@@ -238,6 +227,7 @@ var zigAnalysis;
     var canonTypeDecls = null; // lazy; use getCanonTypeDecl
 
     var curNav = {
+        showPrivDecls: false,
         // each element is a package name, e.g. @import("a") then within there @import("b")
         // starting implicitly from root package
         pkgNames: [],
@@ -264,6 +254,18 @@ var zigAnalysis;
     // var nodesToCallsMap = indexNodesToCalls();
 
     domSearch.addEventListener('keydown', onSearchKeyDown, false);
+    domPrivDeclsBox.addEventListener('change', function() {
+        if (this.checked != curNav.showPrivDecls) {
+            if (this.checked && location.hash.length > 1 && location.hash[1] != '*'){
+                location.hash = "#*" + location.hash.substring(1);
+                return;
+            }
+            if (!this.checked && location.hash.length > 1 && location.hash[1] == '*') {
+                location.hash = "#" + location.hash.substring(2);
+                return;
+            }
+        }
+    }, false);
     window.addEventListener('hashchange', onHashChange, false);
     window.addEventListener('keydown', onWindowKeyDown, false);
     onHashChange();
@@ -323,19 +325,13 @@ var zigAnalysis;
         return typeKind === typeKinds.ErrorSet || typeKindIsContainer(typeKind);
     }
 
-    function findCteInDeclPath(path) {
+    function findCteInRefPath(path) {
         for (var i = path.length - 1; i >= 0; i -= 1) {
-            const decl = zigAnalysis.decls[path[i]];
-            if ("comptimeExpr" in decl.value) {
-                return decl;
-            }
-
-            if ("declPath" in decl.value) {
-                const res = findCteInDeclPath(decl.value.declPath);
-                if (res !== null) {
-                    return res;
-                }
-            }
+            const ref = path[i];
+            if ("string" in ref) continue;
+            if ("comptimeExpr" in ref) return ref;
+            if ("refPath" in ref) return findCteinRefPath(ref.refPath);
+            return null;
         }
 
         return null;
@@ -346,14 +342,15 @@ var zigAnalysis;
         while(i < 1000) {
             i += 1;
 
-            if ("declPath" in value) {
-                if (value.hasCte) {
-                    return findCteInDeclPath(value.declPath).value;
-                }
-                value = zigAnalysis.decls[value.declPath[0]].value;
+            if ("refPath" in value) {
+                value = value.refPath[value.refPath.length -1];
                 continue;
             }
 
+            if ("declRef" in value) {
+                value = zigAnalysis.decls[value.declRef].value;
+            }
+
             return value;
 
         }
@@ -369,13 +366,15 @@ var zigAnalysis;
                 return { type: typeTypeId };
             }
 
-            if ("declPath" in decl.value) {
-                if (decl.value.hasCte) {
-                    decl = findCteInDeclPath(decl.value.declPath);
-                } else {
-                    decl = zigAnalysis.decls[decl.value.declPath[0]];
-                }
+            if ("refPath" in decl.value) {
+                decl =  {
+                  value: decl.value.refPath[decl.value.refPath.length -1]
+                };
+                continue;
+            }
 
+            if ("declRef" in decl.value) {
+                decl = zigAnalysis.decls[decl.value.declRef];
                 continue;
             }
 
@@ -402,8 +401,14 @@ var zigAnalysis;
 
             if ("call" in decl.value) {
                 const fn_call = zigAnalysis.calls[decl.value.call];
-                console.assert("declPath" in fn_call.func);
-                const fn_decl = zigAnalysis.decls[fn_call.func.declPath[0]];
+                var fn_decl = undefined;
+                if ("declRef" in fn_call.func) {
+                    fn_decl = zigAnalysis.decls[fn_call.func.declRef];
+                } else if ("refPath" in fn_call.func) {
+                    console.assert("declRef" in fn_call.func.refPath[fn_call.func.refPath.length -1]);
+                    fn_decl = zigAnalysis.decls[fn_call.func.refPath[fn_call.func.refPath.length -1].declRef.value];
+                } else throw {};
+
                 const fn_decl_value = resolveValue(fn_decl.value);
                 console.assert("type" in fn_decl_value); //TODO handle comptimeExpr
                 const fn_type = zigAnalysis.types[fn_decl_value.type];
@@ -456,6 +461,8 @@ var zigAnalysis;
         renderInfo();
         renderPkgList();
 
+        domPrivDeclsBox.checked = curNav.showPrivDecls;
+
         if (curNavSearch !== "") {
             return renderSearch();
         }
@@ -547,7 +554,7 @@ var zigAnalysis;
         var typeObj = zigAnalysis.types[typeIndex];
         if (typeObj.kind !== typeKinds.Struct)
             return false;
-        return !typeObj.fields;
+        return typeObj.fields.length == 0;
     }
 
     function typeIsGenericFn(typeIndex) {
@@ -850,22 +857,14 @@ var zigAnalysis;
         if ("comptimeExpr" in typeValue) {
             return "[ComptimeExpr]";
         }
-        if ("declPath" in typeValue) {
+        if ("refPath" in typeValue) {
               var result = "";
-              for (var j = typeValue.declPath.length - 1; j >= 0; j--) {
-                  var decl = zigAnalysis.decls[typeValue.declPath[j]];
-
-                  // TODO: handle nested decl paths properly!
-                  if (typeValue.hasCte) {
-                      if (wantHtml)
-                          result += "<a href=\"\">[ComptimeExpr]</a>";
-                      else
-                          result += "[ComptimeExpr]";
-                      break;
-                  }
-                  var name = escapeHtml(decl.name);
+              for (var j = 0; j < typeValue.refPath.length; j++) {
+
+                  var name = "[RefPath]";
                   if (wantHtml) {
-                      result += '<a href="'+navLinkDecl(decl.name)+'">';
+                      //result += '<a href="'+navLinkDecl(decl.name)+'">';
+                      result += '<a href="">';
                       result += '<span class="tok-kw" style="color:lightblue;">' +
                            name + '</span>';
                       result += '</a>';
@@ -1182,24 +1181,11 @@ var zigAnalysis;
 
                             if (isVarArgs && i === typeObj.params.length - 1) {
                                 payloadHtml += '...';
-                            } else if ("declPath" in value) {
-                                if (value.hasCte) {
-                                    var cte = findCteInDeclPath(value.declPath);
-                                    payloadHtml += "[ComptimeExpr]";
-                                } else {
-                                    var decl = zigAnalysis.decls[value.declPath[0]];
-                                    var val = resolveValue(decl.value);
-                                    if ("comptimeExpr" in val) {
-                                        payloadHtml += "[ComptimeExpr]";
-                                    } else {
-                                      console.assert("type" in val);
-                                      var valType = zigAnalysis.types[val.type];
-                                      var valTypeName = typeShorthandName(valType);
-                                      payloadHtml += '<a href="'+navLinkDecl(decl.name)+'">';
-                                      payloadHtml += '<span class="tok-kw" style="color:lightblue;">' + escapeHtml(decl.name) + '</span>';
-                                      payloadHtml += '</a>';
-                                    }
-                                }
+                            } else if ("refPath" in value) {
+                                payloadHtml += '<a href="">';
+                                payloadHtml += '<span class="tok-kw" style="color:lightblue;">[Ref Path]</span>';
+                                payloadHtml += '</a>';
+
                             } else if ("type" in value) {
                                 var name = typeValueName(value, false);
                                 payloadHtml += '<span class="tok-kw">' + escapeHtml(name) + '</span>';
@@ -1422,17 +1408,13 @@ var zigAnalysis;
         domFnProto.classList.remove("hidden");
     }
 
-    function renderContainer(container) {
-        var typesList = [];
-        var namespacesList = [];
-        var errSetsList = [];
-        var fnsList = [];
-        var varsList = [];
-        var valsList = [];
 
-        var declLen = container.pubDecls ? container.pubDecls.length : 0;
-        for (var i = 0; i < declLen; i += 1) {
-            var decl = zigAnalysis.decls[container.pubDecls[i]];
+    function categorizeDecls(decls,
+        typesList, namespacesList, errSetsList,
+        fnsList, varsList, valsList) {
+
+        for (var i = 0; i < decls.length; i += 1) {
+            var decl = zigAnalysis.decls[decls[i]];
             var declValue = resolveValue(decl.value);
 
             if (decl.kind === 'var') {
@@ -1441,7 +1423,19 @@ var zigAnalysis;
             }
 
             if (decl.kind === 'const') {
-                if (!("type" in declValue)){
+                if ("call" in declValue) {
+                    let c  = zigAnalysis.calls[declValue.call];
+                    console.assert("comptimeExpr" in c.ret);
+                    let fDecl = resolveValue(c.func);
+                    console.assert("type" in fDecl);
+                    let fType = zigAnalysis.types[fDecl.type];
+                    console.assert("type" in fType.ret);
+                    if (fType.ret.type === typeTypeId) {
+                        typesList.push(decl);
+                    } else {
+                        valsList.push(decl);
+                    }
+                } else if (!("type" in declValue)){
                     valsList.push(decl);
                 } else {
                     var value = zigAnalysis.types[declValue.type];
@@ -1465,42 +1459,23 @@ var zigAnalysis;
                 }
             }
         }
+    }
 
-        declLen = container.privDecls ? container.privDecls.length : 0;
-        for (var i = 0; i < declLen; i += 1) {
-            var decl = zigAnalysis.decls[container.privDecls[i]];
-            var declValue = resolveValue(decl.value);
-
-            if (decl.kind === 'var') {
-                varsList.push(decl);
-                continue;
-            }
+    function renderContainer(container) {
+        var typesList = [];
+        var namespacesList = [];
+        var errSetsList = [];
+        var fnsList = [];
+        var varsList = [];
+        var valsList = [];
 
-            if (decl.kind === 'const') {
-                if (!("type" in declValue)){
-                    valsList.push(decl);
-                } else {
-                    var value = zigAnalysis.types[declValue.type];
-                    var kind = value.kind;
-                    if (kind === typeKinds.Fn) {
-                        // TODO: handle CTE return types when we know their type.
-                        const resVal = resolveValue(value.ret);
-                        if ("type" in resVal && resVal.type == typeTypeId) {
-                            typesList.push(decl);
-                        } else {
-                            fnsList.push(decl);
-                        }
+        categorizeDecls(container.pubDecls,
+            typesList, namespacesList, errSetsList,
+            fnsList, varsList, valsList);
+        if (curNav.showPrivDecls) categorizeDecls(container.privDecls,
+            typesList, namespacesList, errSetsList,
+            fnsList, varsList, valsList);
 
-                    } else  if (typeIsErrSet(declValue.type)) {
-                        errSetsList.push(decl);
-                    } else if (typeIsStructWithNoFields(declValue.type)) {
-                        namespacesList.push(decl);
-                    } else {
-                        typesList.push(decl);
-                    }
-                }
-            }
-        }
 
         typesList.sort(byNameProperty);
         namespacesList.sort(byNameProperty);
@@ -1712,6 +1687,7 @@ var zigAnalysis;
 
     function updateCurNav() {
         curNav = {
+            showPrivDecls: false,
             pkgNames: [],
             pkgObjs: [],
             declNames: [],
@@ -1721,6 +1697,11 @@ var zigAnalysis;
 
         if (location.hash[0] === '#' && location.hash.length > 1) {
             var query = location.hash.substring(1);
+            if (query[0] === '*') {
+              curNav.showPrivDecls = true;
+              query = query.substring(1);
+            }
+
             var qpos = query.indexOf("?");
             var nonSearchPart;
             if (qpos === -1) {
src/Autodoc.zig
@@ -608,6 +608,7 @@ const DocData = struct {
                         \\, "value": {s}1 }} }}
                     , .{neg});
                     // TODO: uncomment once float panic is fixed in stdlib
+                    //       See: https://github.com/ziglang/zig/issues/11283
                     // try w.print(
                     //     \\, "value": {s}{e} }} }}
                     // , .{ neg, v.value });
@@ -621,7 +622,6 @@ const DocData = struct {
                 .@"null" => |v| try std.json.stringify(v, options, w),
                 .typeOf, .sizeOf => |v| try std.json.stringify(v, options, w),
                 .compileError => |v| try std.json.stringify(v, options, w),
-                .string => |v| try std.json.stringify(v, options, w),
                 .fieldRef => |v| try std.json.stringify(
                     struct { fieldRef: FieldRef }{ .fieldRef = v },
                     options,
@@ -645,6 +645,11 @@ const DocData = struct {
                     options,
                     w,
                 ),
+                .string => |v| try std.json.stringify(
+                    struct { string: []const u8 }{ .string = v },
+                    options,
+                    w,
+                ),
                 .enumLiteral => |v| try std.json.stringify(
                     struct { @"enumLiteral": []const u8 }{ .@"enumLiteral" = v },
                     options,