From 919b8e400ca7b2885221a4a93ba5ab3192046480 Mon Sep 17 00:00:00 2001 From: Loris Cro Date: Thu, 31 Mar 2022 19:07:57 +0200 Subject: [PATCH] autodoc: more typechecking in main.js --- lib/docs/main.js | 341 ++++++++++++++++++++++++++++------------------- 1 file changed, 204 insertions(+), 137 deletions(-) diff --git a/lib/docs/main.js b/lib/docs/main.js index 1966beb7a9..7247c43276 100644 --- a/lib/docs/main.js +++ b/lib/docs/main.js @@ -56,32 +56,40 @@ */ /** - * @typedef { - | { kind: number, name: string; src: number; privDecls: number[]; pubDecls: number[]; fields: WalkResult[] } // Struct, Enum, Union - } ContainerType -*/ - -/** - * @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; fields: { name: string; docs: string }[] } // ErrorSet - | { kind: number, size: "One" | "Many" | "Slice" | "C"; child: TypeRef } // Pointer - | ContainerType - | { kind: number, name: string; src: number; ret: WalkResult; params: WalkResult[] } // Fn - } Type + * @typedef {{ + kind: number, + name: string, + src: number, + privDecls: number[], + pubDecls: number[], + fields: WalkResult[] +}} ContainerType */ /** * @typedef {{ - name: string, - src: number | null, - ret: WalkResult, - params: WalkResult[] | null, - }} Fn + 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: 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: WalkResult } // Pointer + | ContainerType + | Fn + } Type +*/ + + /** * @typedef {{ func: WalkResult, @@ -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, }} Package */ @@ -225,17 +234,34 @@ var zigAnalysis; /** @type Object */ var escapeHtmlReplacements = { "&": "&", '"': """, "<": "<", ">": ">" }; - var typeKinds = indexTypeKinds(); - var typeTypeId = findTypeTypeId(); + var typeKinds = /** @type {Record} */(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, '
  • '); @@ -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 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 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 = 'var ' + @@ -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 = '
    ' + escapeHtml(fieldNode.name);
    +                var html = '
    ' + escapeHtml(fieldName);
     
                     if (container.kind === typeKinds.Enum) {
    -                    html += ' = ' + field + '';
    +                    html += ' = ' + fieldName + '';
                     } else {
                         var field = container.fields[i];
                         html += ": ";
    -                    if (field.failure === true) {
    -                        html += '#FAILURE#';
    -                    } else {
    -                        var name = typeValueName(field);
    -                        html += ''+ name +'';
    -                    }
    +                    var name = typeValueName(field);
    +                    html += ''+ name +'';
                     }
     
                     html += ',
    '; @@ -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} */({}); 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 */