Commit 919b8e400c

Loris Cro <kappaloris@gmail.com>
2022-03-31 19:07:57
autodoc: more typechecking in main.js
1 parent 72e5b4f
Changed files (1)
lib
docs
lib/docs/main.js
@@ -56,31 +56,39 @@
 */
 
 /**
- * @typedef {
-    | { kind: number, name: string; src: number; privDecls: number[]; pubDecls: number[]; fields: WalkResult[] } // Struct, Enum, Union
-   } ContainerType
+ * @typedef {{
+      kind: number,
+      name: string,
+      src: number,
+      privDecls: number[],
+      pubDecls: number[],
+      fields: WalkResult[]
+}} ContainerType
+*/
+
+/**
+ * @typedef {{
+      kind: number,
+      name: string,
+      src: number,
+      ret: WalkResult,
+      params: WalkResult[]
+ }} Fn
 */
 
+
 /**
  * @typedef {
     | { kind: number, name: string } // Type, Void, Bool, NoReturn, Int, Float, ComptimeExpr, ComptimeFloat, ComptimeInt, Undefined, Null, ErrorUnion, BoundFn, Opaque, Frame, AnyFrame, Vector, EnumLiteral
-    | { kind: number, name: string; child: TypeRef } // Optional
-    | { kind: number, len: WalkResult; child: TypeRef } // Array
+    | { kind: number, name: string; child: WalkResult } // Optional
+    | { kind: number, len: WalkResult; child: WalkResult } // Array
     | { kind: number, name: string; fields: { name: string; docs: string }[] } // ErrorSet
-    | { kind: number, size: "One" | "Many" | "Slice" | "C"; child: TypeRef } // Pointer
+    | { kind: number, size: "One" | "Many" | "Slice" | "C"; child: WalkResult } // Pointer
     | ContainerType
-    | { kind: number, name: string; src: number; ret: WalkResult; params: WalkResult[] } // Fn
+    | Fn
    } Type
 */
 
-/**
- * @typedef {{
-       name: string,
-       src: number | null,
-       ret: WalkResult,
-       params: WalkResult[] | null,
-   }} Fn
-*/
 
 /**
  * @typedef {{
@@ -109,6 +117,7 @@
       src: number,
       value: WalkResult,
       decltest?: number,
+      isTest: bool,
    }} Decl
 */
 
@@ -117,7 +126,7 @@
       name: string,
       file: number,
       main: number,
-      table: { root: number },
+      table: Record<string, number>,
    }} Package
 */
 
@@ -225,17 +234,34 @@ var zigAnalysis;
     /** @type Object<string, string> */
     var escapeHtmlReplacements = { "&": "&amp;", '"': "&quot;", "<": "&lt;", ">": "&gt;" };
 
-    var typeKinds = indexTypeKinds();
-    var typeTypeId = findTypeTypeId();
+    var typeKinds = /** @type {Record<string, number>} */(indexTypeKinds());
+    var typeTypeId = /** @type {number} */ (findTypeTypeId());
     var pointerSizeEnum = { One: 0, Many: 1, Slice: 2, C: 3 };
 
     // for each package, is an array with packages to get to this one
     var canonPkgPaths = computeCanonicalPackagePaths();
+
+    /** @typedef {{declNames: string[], pkgNames: string[]}} CanonDecl */
+
     // for each decl, is an array with {declNames, pkgNames} to get to this one
+    /** @type CanonDecl[] | null */
     var canonDeclPaths = null; // lazy; use getCanonDeclPath
+
     // for each type, is an array with {declNames, pkgNames} to get to this one
+    /** @type  number[] | null */
     var canonTypeDecls = null; // lazy; use getCanonTypeDecl
 
+    /** @typedef {{
+    *       showPrivDecls: bool,
+    *       pkgNames: string[],
+    *       pkgObjs: Package[],
+    *       declNames: string[],
+    *       declObjs: Decl[],
+    *       callName: any,
+    *   }} CurNav
+    */
+
+    /** @type {CurNav} */
     var curNav = {
         showPrivDecls: false,
         // each element is a package name, e.g. @import("a") then within there @import("b")
@@ -252,6 +278,7 @@ var zigAnalysis;
         // (a, b, c, d) comptime call; result is the value the docs refer to
         callName: null,
     };
+
     var curNavSearch = "";
     var curSearchIndex = -1;
     var imFeelingLucky = false;
@@ -606,7 +633,7 @@ var zigAnalysis;
             if (instantiations == null && calls == null) {
                 domFnNoExamples.classList.remove("hidden");
             } else if (calls != null) {
-                if (fnObj.combined === undefined) fnObj.combined = allCompTimeFnCallsResult(calls);
+                // if (fnObj.combined === undefined) fnObj.combined = allCompTimeFnCallsResult(calls);
                 if (fnObj.combined != null) renderContainer(fnObj.combined);
 
                 resizeDomList(domListFnExamples, calls.length, '<li></li>');
@@ -848,6 +875,14 @@ var zigAnalysis;
         }
     }
 
+    /**
+    * @param {WalkResult} typeValue,
+    * @param {boolean} wantHtml,
+    * @param {boolean} wantLink,
+    * @param {number} [fnDecl],
+    * @param {string} [linkFnNameDecl],
+    * @return {string}
+    */
     function typeValueName(typeValue, wantHtml, wantLink, fnDecl, linkFnNameDecl) {
 
         if ("int" in typeValue) {
@@ -984,6 +1019,14 @@ var zigAnalysis;
         }
     }
 
+    /**
+    * @param {Type} typeObj,
+    * @param {boolean} wantHtml,
+    * @param {boolean} wantSubLink,
+    * @param {number} [fnDecl],
+    * @param {string} [linkFnNameDecl],
+    * @return {string}
+    */
     function typeName(typeObj, wantHtml, wantSubLink, fnDecl, linkFnNameDecl) {
         switch (typeObj.kind) {
             case typeKinds.Array:
@@ -1294,111 +1337,113 @@ var zigAnalysis;
         domSectFnErrors.classList.remove("hidden");
     }
 
-    function allCompTimeFnCallsHaveTypeResult(typeIndex, value) {
-        var srcIndex = zigAnalysis.fns[value].src;
-        var calls = nodesToCallsMap[srcIndex];
-        if (calls == null) return false;
-        for (var i = 0; i < calls.length; i += 1) {
-            var call = zigAnalysis.calls[calls[i]];
-            if (call.result.type !== typeTypeId) return false;
-        }
-        return true;
-    }
-
-    function allCompTimeFnCallsResult(calls) {
-        var firstTypeObj = null;
-        var containerObj = {
-            privDecls: [],
-        };
-        for (var callI = 0; callI < calls.length; callI += 1) {
-            var call = zigAnalysis.calls[calls[callI]];
-            if (call.result.type !== typeTypeId) return null;
-            var typeObj = zigAnalysis.types[call.result.value];
-            if (!typeKindIsContainer(typeObj.kind)) return null;
-            if (firstTypeObj == null) {
-                firstTypeObj = typeObj;
-                containerObj.src = typeObj.src;
-            } else if (firstTypeObj.src !== typeObj.src) {
-                return null;
-            }
-
-            if (containerObj.fields == null) {
-                containerObj.fields = (typeObj.fields || []).concat([]);
-            } else for (var fieldI = 0; fieldI < typeObj.fields.length; fieldI += 1) {
-                var prev = containerObj.fields[fieldI];
-                var next = typeObj.fields[fieldI];
-                if (prev === next) continue;
-                if (typeof(prev) === 'object') {
-                    if (prev[next] == null) prev[next] = typeObj;
-                } else {
-                    containerObj.fields[fieldI] = {};
-                    containerObj.fields[fieldI][prev] = firstTypeObj;
-                    containerObj.fields[fieldI][next] = typeObj;
-                }
-            }
-
-            if (containerObj.pubDecls == null) {
-                containerObj.pubDecls = (typeObj.pubDecls || []).concat([]);
-            } else for (var declI = 0; declI < typeObj.pubDecls.length; declI += 1) {
-                var prev = containerObj.pubDecls[declI];
-                var next = typeObj.pubDecls[declI];
-                if (prev === next) continue;
-                // TODO instead of showing "examples" as the public declarations,
-                    // do logic like this:
-                //if (typeof(prev) !== 'object') {
-                    //    var newDeclId = zigAnalysis.decls.length;
-                    //    prev = clone(zigAnalysis.decls[prev]);
-                    //    prev.id = newDeclId;
-                    //    zigAnalysis.decls.push(prev);
-                    //    containerObj.pubDecls[declI] = prev;
-                    //}
-                //mergeDecls(prev, next, firstTypeObj, typeObj);
-            }
-        }
-        for (var declI = 0; declI < containerObj.pubDecls.length; declI += 1) {
-            var decl = containerObj.pubDecls[declI];
-            if (typeof(decl) === 'object') {
-                containerObj.pubDecls[declI] = containerObj.pubDecls[declI].id;
-            }
-        }
-        return containerObj;
-    }
+//     function allCompTimeFnCallsHaveTypeResult(typeIndex, value) {
+//         var srcIndex = zigAnalysis.fns[value].src;
+//         var calls = nodesToCallsMap[srcIndex];
+//         if (calls == null) return false;
+//         for (var i = 0; i < calls.length; i += 1) {
+//             var call = zigAnalysis.calls[calls[i]];
+//             if (call.result.type !== typeTypeId) return false;
+//         }
+//         return true;
+//     }
+//
+//     function allCompTimeFnCallsResult(calls) {
+//         var firstTypeObj = null;
+//         var containerObj = {
+//             privDecls: [],
+//         };
+//         for (var callI = 0; callI < calls.length; callI += 1) {
+//             var call = zigAnalysis.calls[calls[callI]];
+//             if (call.result.type !== typeTypeId) return null;
+//             var typeObj = zigAnalysis.types[call.result.value];
+//             if (!typeKindIsContainer(typeObj.kind)) return null;
+//             if (firstTypeObj == null) {
+//                 firstTypeObj = typeObj;
+//                 containerObj.src = typeObj.src;
+//             } else if (firstTypeObj.src !== typeObj.src) {
+//                 return null;
+//             }
+//
+//             if (containerObj.fields == null) {
+//                 containerObj.fields = (typeObj.fields || []).concat([]);
+//             } else for (var fieldI = 0; fieldI < typeObj.fields.length; fieldI += 1) {
+//                 var prev = containerObj.fields[fieldI];
+//                 var next = typeObj.fields[fieldI];
+//                 if (prev === next) continue;
+//                 if (typeof(prev) === 'object') {
+//                     if (prev[next] == null) prev[next] = typeObj;
+//                 } else {
+//                     containerObj.fields[fieldI] = {};
+//                     containerObj.fields[fieldI][prev] = firstTypeObj;
+//                     containerObj.fields[fieldI][next] = typeObj;
+//                 }
+//             }
+//
+//             if (containerObj.pubDecls == null) {
+//                 containerObj.pubDecls = (typeObj.pubDecls || []).concat([]);
+//             } else for (var declI = 0; declI < typeObj.pubDecls.length; declI += 1) {
+//                 var prev = containerObj.pubDecls[declI];
+//                 var next = typeObj.pubDecls[declI];
+//                 if (prev === next) continue;
+//                 // TODO instead of showing "examples" as the public declarations,
+//                     // do logic like this:
+//                 //if (typeof(prev) !== 'object') {
+//                     //    var newDeclId = zigAnalysis.decls.length;
+//                     //    prev = clone(zigAnalysis.decls[prev]);
+//                     //    prev.id = newDeclId;
+//                     //    zigAnalysis.decls.push(prev);
+//                     //    containerObj.pubDecls[declI] = prev;
+//                     //}
+//                 //mergeDecls(prev, next, firstTypeObj, typeObj);
+//             }
+//         }
+//         for (var declI = 0; declI < containerObj.pubDecls.length; declI += 1) {
+//             var decl = containerObj.pubDecls[declI];
+//             if (typeof(decl) === 'object') {
+//                 containerObj.pubDecls[declI] = containerObj.pubDecls[declI].id;
+//             }
+//         }
+//         return containerObj;
+//     }
 
-    function mergeDecls(declObj, nextDeclIndex, firstTypeObj, typeObj) {
-        var nextDeclObj = zigAnalysis.decls[nextDeclIndex];
-        if (declObj.type != null && nextDeclObj.type != null && declObj.type !== nextDeclObj.type) {
-            if (typeof(declObj.type) !== 'object') {
-                var prevType = declObj.type;
-                declObj.type = {};
-                declObj.type[prevType] = firstTypeObj;
-                declObj.value = null;
-            }
-            declObj.type[nextDeclObj.type] = typeObj;
-        } else if (declObj.type == null && nextDeclObj != null) {
-            declObj.type = nextDeclObj.type;
-        }
-        if (declObj.value != null && nextDeclObj.value != null && declObj.value !== nextDeclObj.value) {
-            if (typeof(declObj.value) !== 'object') {
-                var prevValue = declObj.value;
-                declObj.value = {};
-                declObj.value[prevValue] = firstTypeObj;
-            }
-            declObj.value[nextDeclObj.value] = typeObj;
-        } else if (declObj.value == null && nextDeclObj.value != null) {
-            declObj.value = nextDeclObj.value;
-        }
-    }
 
+    // function mergeDecls(declObj, nextDeclIndex, firstTypeObj, typeObj) {
+    //     var nextDeclObj = zigAnalysis.decls[nextDeclIndex];
+    //     if (declObj.type != null && nextDeclObj.type != null && declObj.type !== nextDeclObj.type) {
+    //         if (typeof(declObj.type) !== 'object') {
+    //             var prevType = declObj.type;
+    //             declObj.type = {};
+    //             declObj.type[prevType] = firstTypeObj;
+    //             declObj.value = null;
+    //         }
+    //         declObj.type[nextDeclObj.type] = typeObj;
+    //     } else if (declObj.type == null && nextDeclObj != null) {
+    //         declObj.type = nextDeclObj.type;
+    //     }
+    //     if (declObj.value != null && nextDeclObj.value != null && declObj.value !== nextDeclObj.value) {
+    //         if (typeof(declObj.value) !== 'object') {
+    //             var prevValue = declObj.value;
+    //             declObj.value = {};
+    //             declObj.value[prevValue] = firstTypeObj;
+    //         }
+    //         declObj.value[nextDeclObj.value] = typeObj;
+    //     } else if (declObj.value == null && nextDeclObj.value != null) {
+    //         declObj.value = nextDeclObj.value;
+    //     }
+    // }
+
+    /** @param {Decl} decl */
     function renderValue(decl) {
 
         var declTypeRef = typeOfDecl(decl);
         var declValueText = "";
         switch(Object.keys(decl.value)[0]) {
             case "int":
-                declValueText += decl.value.int.value;
+                declValueText += /** @type {{int: {value: number}}} */(decl.value).int.value;
                 break;
             case "float":
-                declValueText += decl.value.float.value;
+                declValueText += /** @type {{float: {value: number}}} */(decl.value).float.value;
                 break;
             case "comptimeExpr":
                 declValueText += "[ComptimeExpr]";
@@ -1421,6 +1466,7 @@ var zigAnalysis;
         domFnProto.classList.remove("hidden");
     }
 
+    /** @param {Decl} decl */
     function renderVar(decl) {
         var declTypeRef = typeOfDecl(decl);
         domFnProtoCode.innerHTML = '<span class="tok-kw">var</span> ' +
@@ -1438,7 +1484,13 @@ var zigAnalysis;
 
     /**
     * @param {number[]} decls
-    * @param {Decl[]} typesList, namespacesList, errSetsList, fnsList, varsList, valsList, testsList
+    * @param {Decl[]} typesList
+    * @param {Decl[]} namespacesList,
+    * @param {Decl[]} errSetsList,
+    * @param {Decl[]} fnsList,
+    * @param {Decl[]} varsList,
+    * @param {Decl[]} valsList,
+    * @param {Decl[]} testsList
     */
     function categorizeDecls(decls,
         typesList, namespacesList, errSetsList,
@@ -1482,7 +1534,7 @@ var zigAnalysis;
                     var kind = value.kind;
                     if (kind === typeKinds.Fn) {
                         // TODO: handle CTE return types when we know their type.
-                        const resVal = resolveValue(value.ret);
+                        const resVal = resolveValue(/** @type {Fn} */(value).ret);
                         if ("type" in resVal && resVal.type == typeTypeId) {
                             typesList.push(decl);
                         } else {
@@ -1610,20 +1662,17 @@ var zigAnalysis;
             for (var i = 0; i < containerNode.fields.length; i += 1) {
                 var fieldNode = zigAnalysis.astNodes[containerNode.fields[i]];
                 var divDom = domListFields.children[i];
+                let fieldName = /** @type {string} */(fieldNode.name);
 
-                var html = '<div class="mobile-scroll-container"><pre class="scroll-item">' + escapeHtml(fieldNode.name);
+                var html = '<div class="mobile-scroll-container"><pre class="scroll-item">' + escapeHtml(fieldName);
 
                 if (container.kind === typeKinds.Enum) {
-                    html += ' = <span class="tok-number">' + field + '</span>';
+                    html += ' = <span class="tok-number">' + fieldName + '</span>';
                 } else {
                     var field = container.fields[i];
                     html += ": ";
-                    if (field.failure === true) {
-                        html += '<span class="tok-kw" style="color:red;">#FAILURE#</span>';
-                    } else {
-                        var name = typeValueName(field);
-                        html += '<span class="tok-kw">'+ name +'</span>';
-                    }
+                    var name = typeValueName(field);
+                    html += '<span class="tok-kw">'+ name +'</span>';
                 }
 
                 html += ',</pre></div>';
@@ -1719,6 +1768,11 @@ var zigAnalysis;
         }
     }
 
+
+    /**
+    * @param {string | number} a
+    * @param {string | number} b
+    */
     function operatorCompare(a, b) {
         if (a === b) {
             return 0;
@@ -1741,7 +1795,7 @@ var zigAnalysis;
     }
 
     function indexTypeKinds() {
-        var map = {};
+        var map = /** @type {Record<string, number>} */({});
         for (var i = 0; i < zigAnalysis.typeKinds.length; i += 1) {
             map[zigAnalysis.typeKinds[i]] = i;
         }
@@ -1765,12 +1819,14 @@ var zigAnalysis;
     }
 
     function updateCurNav() {
+
         curNav = {
             showPrivDecls: false,
             pkgNames: [],
             pkgObjs: [],
             declNames: [],
             declObjs: [],
+            callName: null,
         };
         curNavSearch = "";
 
@@ -1814,6 +1870,10 @@ var zigAnalysis;
         }
     }
 
+    /**
+    * @param {ContainerType} parentType
+    * @param {string} childName
+    */
     function findSubDecl(parentType, childName) {
         if (!parentType.pubDecls) return null;
         for (var i = 0; i < parentType.pubDecls.length; i += 1) {
@@ -1843,11 +1903,11 @@ var zigAnalysis;
             var rootPkg = zigAnalysis.packages[zigAnalysis.rootPkg];
         // Breadth-first to keep the path shortest possible.
             var stack = [{
-                path: [],
+                path: /** @type {string[]} */([]),
                 pkg: rootPkg,
             }];
         while (stack.length !== 0) {
-            var item = stack.shift();
+            var item = /** @type {{path: string[], pkg: Package}} */(stack.shift());
             for (var key in item.pkg.table) {
                 var childPkgIndex = item.pkg.table[key];
                 if (list[childPkgIndex] != null) continue;
@@ -1866,6 +1926,7 @@ var zigAnalysis;
     }
 
 
+    /** @return {CanonDecl[]} */
     function computeCanonDeclPaths() {
         var list = new Array(zigAnalysis.decls.length);
         canonTypeDecls = new Array(zigAnalysis.types.length);
@@ -1875,16 +1936,18 @@ var zigAnalysis;
             var pkg = zigAnalysis.packages[pkgI];
             var pkgNames = canonPkgPaths[pkgI];
             var stack = [{
-                declNames: [],
+                declNames: /** @type {string[]} */([]),
                 type: zigAnalysis.types[pkg.main],
             }];
             while (stack.length !== 0) {
-                var item = stack.shift();
+                var item = /** @type {{declNames: string[], type: Type}} */(stack.shift());
 
                 if (isContainerType(item.type)) {
-                    var len = item.type.pubDecls ? item.type.pubDecls.length : 0;
+                    let t = /** @type {ContainerType} */(item.type);
+
+                    var len = t.pubDecls ? t.pubDecls.length : 0;
                     for (var declI = 0; declI < len; declI += 1) {
-                        var mainDeclIndex = item.type.pubDecls[declI];
+                        var mainDeclIndex = t.pubDecls[declI];
                         if (list[mainDeclIndex] != null) continue;
 
                         var decl = zigAnalysis.decls[mainDeclIndex];
@@ -1915,16 +1978,20 @@ var zigAnalysis;
         return list;
     }
 
+    /** @param {number} index */
     function getCanonDeclPath(index) {
         if (canonDeclPaths == null) {
             canonDeclPaths = computeCanonDeclPaths();
         }
-        return canonDeclPaths[index];
+        let cd = /** @type {CanonDecl[]}*/(canonDeclPaths);
+        return cd[index];
     }
 
+    /** @param {number} index */
     function getCanonTypeDecl(index) {
         getCanonDeclPath(0);
-        return canonTypeDecls[index];
+        let ct = /** @type {number[]}*/(canonTypeDecls);
+        return ct[index];
     }
 
     /** @param {string} text */