"use strict"; var zigAnalysis = { typeKinds, rootMod, modules, astNodes, calls, files, decls, exprs, types, comptimeExprs, guideSections }; let skipNextHashChange = null; const NAV_MODES = { API: "#A;", GUIDES: "#G;", }; var scrollHistory = {}; (function() { const domBanner = document.getElementById("banner"); const domMain = document.getElementById("main"); const domStatus = document.getElementById("status"); const domSectNavAPI = document.getElementById("sectNavAPI"); const domListNavAPI = document.getElementById("listNavAPI"); const domSectNavGuides = document.getElementById("sectNavGuides"); const domListNavGuides = document.getElementById("listNavGuides"); const domApiSwitch = document.getElementById("ApiSwitch"); const domGuideSwitch = document.getElementById("guideSwitch"); const domGuidesMenu = document.getElementById("guidesMenu"); const domGuidesMenuTitle = document.getElementById("guidesMenuTitle"); const domGuideTocList = document.getElementById("guideTocList"); const domGuideTocListEmtpy = document.getElementById("guideTocListEmpty"); const domListMods = document.getElementById("listMods"); const domSectTypes = document.getElementById("sectTypes"); const domListTypesLeft = document.getElementById("listTypesLeft"); const domListTypesRight = document.getElementById("listTypesRight"); const domSectTests = document.getElementById("sectTests"); const domListTests = document.getElementById("listTests"); const domSectDocTests = document.getElementById("sectDocTests"); const domDocTestsCode = document.getElementById("docTestsCode"); const domSectNamespaces = document.getElementById("sectNamespaces"); const domListNamespacesLeft = document.getElementById("listNamespacesLeft"); const domListNamespacesRight = document.getElementById("listNamespacesRight"); const domNoDocsNamespaces = document.getElementById("noDocsNamespaces"); const domSectErrSets = document.getElementById("sectErrSets"); const domListErrSets = document.getElementById("listErrSets"); const domSectFns = document.getElementById("sectFns"); const domListFns = document.getElementById("listFns"); const domSectFields = document.getElementById("sectFields"); const domListFields = document.getElementById("listFields"); const domSectGlobalVars = document.getElementById("sectGlobalVars"); const domListGlobalVars = document.getElementById("listGlobalVars"); const domSectValues = document.getElementById("sectValues"); const domListValues = document.getElementById("listValues"); const domFnProto = document.getElementById("fnProto"); const domFnProtoCode = document.getElementById("fnProtoCode"); const domFnSourceLink = document.getElementById("fnSourceLink"); const domSectParams = document.getElementById("sectParams"); const domListParams = document.getElementById("listParams"); const domTldDocs = document.getElementById("tldDocs"); const domSectFnErrors = document.getElementById("sectFnErrors"); const domListFnErrors = document.getElementById("listFnErrors"); const domTableFnErrors = document.getElementById("tableFnErrors"); const domFnErrorsAnyError = document.getElementById("fnErrorsAnyError"); const domFnExamples = document.getElementById("fnExamples"); // const domListFnExamples = (document.getElementById("listFnExamples")); const domFnNoExamples = document.getElementById("fnNoExamples"); const domDeclNoRef = document.getElementById("declNoRef"); const domSearch = document.getElementById("search"); const domSearchHelp = document.getElementById("searchHelp"); const domSearchHelpSummary = document.getElementById("searchHelpSummary"); const domSectSearchResults = document.getElementById("sectSearchResults"); const domSectSearchAllResultsLink = document.getElementById("sectSearchAllResultsLink"); const domDocs = document.getElementById("docs"); const domDocsScroll = document.getElementById("docs-scroll"); const domGuidesSection = document.getElementById("guides"); const domActiveGuide = document.getElementById("activeGuide"); const domListSearchResults = document.getElementById("listSearchResults"); const domSectSearchNoResults = document.getElementById("sectSearchNoResults"); // const domTdTarget = (document.getElementById("tdTarget")); const domTdZigVer = document.getElementById("tdZigVer"); const domHdrName = document.getElementById("hdrName"); const domHelpModal = document.getElementById("helpModal"); const domSearchKeys = document.getElementById("searchKeys"); const domPrefsModal = document.getElementById("prefsModal"); const domSearchPlaceholder = document.getElementById("searchPlaceholder"); const domSearchPlaceholderText = document.getElementById("searchPlaceholderText"); const sourceFileUrlTemplate = "src/{{mod}}/{{file}}.html#L{{line}}" const domLangRefLink = document.getElementById("langRefLink"); const domPrefSlashSearch = document.getElementById("prefSlashSearch"); const prefs = getLocalStorage(); loadPrefs(); domPrefSlashSearch.addEventListener("change", () => setPrefSlashSearch(domPrefSlashSearch.checked)); const scrollMonitor = [ domActiveGuide, domGuideTocList, domDocsScroll, domSectSearchResults, ]; computeGuideHashes(); let searchTimer = null; let searchTrimResults = true; let escapeHtmlReplacements = { "&": "&", '"': """, "<": "<", ">": ">", }; let typeKinds = indexTypeKinds(); let typeTypeId = findTypeTypeId(); let pointerSizeEnum = { One: 0, Many: 1, Slice: 2, C: 3 }; let declSearchIndex = new RadixTree(); window.search = declSearchIndex; // for each module, is an array with modules to get to this one let canonModPaths = computeCanonicalModulePaths(); // for each decl, is an array with {declNames, modNames} to get to this one let canonDeclPaths = null; // lazy; use getCanonDeclPath // for each type, is an array with {declNames, modNames} to get to this one let canonTypeDecls = null; // lazy; use getCanonTypeDecl let curNav = { hash: "", mode: NAV_MODES.API, activeGuide: "", activeGuideScrollTo: null, // each element is a module name, e.g. @import("a") then within there @import("b") // starting implicitly from root module modNames: [], // same as above except actual modules, not names modObjs: [], // Each element is a decl name, `a.b.c`, a is 0, b is 1, c is 2, etc. // empty array means refers to the module itself declNames: [], // these will be all types, except the last one may be a type or a decl declObjs: [], // (a, b, c, d) comptime call; result is the value the docs refer to callName: null, }; let curNavSearch = ""; let curSearchIndex = -1; let imFeelingLucky = false; let rootIsStd = detectRootIsStd(); // map of decl index to list of non-generic fn indexes // let nodesToFnsMap = indexNodesToFns(); // map of decl index to list of comptime fn calls // let nodesToCallsMap = indexNodesToCalls(); let guidesSearchIndex = {}; window.guideSearch = guidesSearchIndex; parseGuides(); // identifiers can contain modal trigger characters so we want to allow typing // such characters when the search is focused instead of toggling the modal let canToggleModal = true; domSearch.disabled = false; domSearch.addEventListener("keydown", onSearchKeyDown, false); domSearch.addEventListener("input", onSearchInput, false); domSearch.addEventListener("focus", ev => { domSearchPlaceholder.classList.add("hidden"); canToggleModal = false; }); domSearch.addEventListener("blur", ev => { if (domSearch.value.length == 0) domSearchPlaceholder.classList.remove("hidden"); canToggleModal = true; }); domSectSearchAllResultsLink.addEventListener('click', onClickSearchShowAllResults, false); function onClickSearchShowAllResults(ev) { ev.preventDefault(); ev.stopPropagation(); searchTrimResults = false; onHashChange(); } if (location.hash == "") { location.hash = "#A;"; } // make the modal disappear if you click outside it function handleModalClick(ev) { if (ev.target.classList.contains("modal-container")) { hideModal(this); } } domHelpModal.addEventListener("click", handleModalClick); domPrefsModal.addEventListener("click", handleModalClick); window.addEventListener("hashchange", onHashChange, false); window.addEventListener("keydown", onWindowKeyDown, false); onHashChange(); // TODO: fix this once langref becomes part of autodoc let langRefVersion = "master"; domLangRefLink.href = `https://ziglang.org/documentation/${langRefVersion}/`; function renderTitle() { let suffix = " - Zig"; switch (curNav.mode) { case NAV_MODES.API: let list = curNav.modNames.concat(curNav.declNames); if (list.length === 0) { document.title = zigAnalysis.modules[zigAnalysis.rootMod].name + suffix; } else { document.title = list.join(".") + suffix; } return; case NAV_MODES.GUIDES: document.title = "[G] " + curNav.activeGuide + suffix; return; } } 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 typeShorthandName(expr) { let resolvedExpr = resolveValue({ expr: expr }); if (!("type" in resolvedExpr)) { return null; } let type = getType(resolvedExpr.type); outer: for (let i = 0; i < 10000; i += 1) { switch (type.kind) { case typeKinds.Optional: case typeKinds.Pointer: let child = type.child; let resolvedChild = resolveValue(child); if ("type" in resolvedChild) { type = getType(resolvedChild.type); continue; } else { return null; } default: break outer; } if (i == 9999) throw "Exhausted typeShorthandName quota"; } let name = undefined; if (type.kind === typeKinds.Struct) { name = "struct"; } else if (type.kind === typeKinds.Enum) { name = "enum"; } else if (type.kind === typeKinds.Union) { name = "union"; } else { console.log("TODO: unhandled case in typeShortName"); return null; } return escapeHtml(name); } function typeKindIsContainer(typeKind) { return ( typeKind === typeKinds.Struct || typeKind === typeKinds.Union || typeKind === typeKinds.Enum || typeKind === typeKinds.Opaque ); } function declCanRepresentTypeKind(typeKind) { return typeKind === typeKinds.ErrorSet || typeKindIsContainer(typeKind); } // // function findCteInRefPath(path) { // for (let i = path.length - 1; i >= 0; i -= 1) { // 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; // } function resolveValue(value, trackDecls) { let seenDecls = []; let i = 0; while (true) { i += 1; if (i >= 10000) { throw "resolveValue quota exceeded" } if ("refPath" in value.expr) { value = { expr: value.expr.refPath[value.expr.refPath.length - 1] }; continue; } if ("declRef" in value.expr) { seenDecls.push(value.expr.declRef); value = getDecl(value.expr.declRef).value; continue; } if ("as" in value.expr) { value = { typeRef: zigAnalysis.exprs[value.expr.as.typeRefArg], expr: zigAnalysis.exprs[value.expr.as.exprArg], }; continue; } if (trackDecls) return { value, seenDecls }; return value; } } function resolveGenericRet(genericFunc) { if (genericFunc.generic_ret == null) return null; let result = resolveValue({ expr: genericFunc.generic_ret }); let i = 0; while (true) { i += 1; if (i >= 10000) { throw "resolveGenericRet quota exceeded" } if ("call" in result.expr) { let call = zigAnalysis.calls[result.expr.call]; let resolvedFunc = resolveValue({ expr: call.func }); if (!("type" in resolvedFunc.expr)) return null; let callee = getType(resolvedFunc.expr.type); if (!callee.generic_ret) return null; result = resolveValue({ expr: callee.generic_ret }); continue; } return result; } } // function typeOfDecl(decl){ // return decl.value.typeRef; // // let i = 0; // while(i < 1000) { // i += 1; // console.assert(isDecl(decl)); // if ("type" in decl.value) { // return ({ type: typeTypeId }); // } // //// if ("string" in decl.value) { //// return ({ type: { //// kind: typeKinds.Pointer, //// size: pointerSizeEnum.One, //// child: }); //// } // // 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; // } // // if ("int" in decl.value) { // return decl.value.int.typeRef; // } // // if ("float" in decl.value) { // return decl.value.float.typeRef; // } // // if ("array" in decl.value) { // return decl.value.array.typeRef; // } // // if ("struct" in decl.value) { // return decl.value.struct.typeRef; // } // // if ("comptimeExpr" in decl.value) { // const cte = zigAnalysis.comptimeExprs[decl.value.comptimeExpr]; // return cte.typeRef; // } // // if ("call" in decl.value) { // const fn_call = zigAnalysis.calls[decl.value.call]; // let 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]; // } 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]); // console.assert(fn_type.kind === typeKinds.Fn); // return fn_type.ret; // } // // if ("void" in decl.value) { // return ({ type: typeTypeId }); // } // // if ("bool" in decl.value) { // return ({ type: typeKinds.Bool }); // } // // console.log("TODO: handle in `typeOfDecl` more cases: ", decl); // console.assert(false); // throw {}; // } // console.assert(false); // return ({}); // } function detectDeclPath(text, context) { let result = ""; let separator = ":"; const components = text.split("."); let curDeclOrType = undefined; let curContext = context; let limit = 10000; while (curContext) { limit -= 1; if (limit == 0) { throw "too many iterations"; } curDeclOrType = findSubDecl(curContext, components[0]); if (!curDeclOrType) { if (curContext.parent_container == null) break; curContext = getType(curContext.parent_container); continue; } if (curContext == context) { separator = '.'; result = location.hash + separator + components[0]; } else { // We had to go up, which means we need a new path! const canonPath = getCanonDeclPath(curDeclOrType.find_subdecl_idx); if (!canonPath) return; let lastModName = canonPath.modNames[canonPath.modNames.length - 1]; let fullPath = lastModName + ":" + canonPath.declNames.join("."); separator = '.'; result = "#A;" + fullPath; } break; } if (!curDeclOrType) { for (let i = 0; i < zigAnalysis.modules.length; i += 1){ const p = zigAnalysis.modules[i]; if (p.name == components[0]) { curDeclOrType = getType(p.main); result += "#A;" + components[0]; break; } } } if (!curDeclOrType) return null; for (let i = 1; i < components.length; i += 1) { curDeclOrType = findSubDecl(curDeclOrType, components[i]); if (!curDeclOrType) return null; result += separator + components[i]; separator = '.'; } return result; } function renderGuides() { renderTitle(); // set guide mode domGuideSwitch.classList.add("active"); domApiSwitch.classList.remove("active"); domDocs.classList.add("hidden"); domSectNavAPI.classList.add("hidden"); domSectNavGuides.classList.remove("hidden"); domGuidesSection.classList.remove("hidden"); domActiveGuide.classList.add("hidden"); domSectSearchResults.classList.add("hidden"); domSectSearchAllResultsLink.classList.add("hidden"); domSectSearchNoResults.classList.add("hidden"); if (curNavSearch !== "") { return renderSearchGuides(); } let activeGuide = undefined; outer: for (let i = 0; i < zigAnalysis.guideSections.length; i += 1) { const section = zigAnalysis.guideSections[i]; for (let j = 0; j < section.guides.length; j += 1) { const guide = section.guides[j]; if (guide.name == curNav.activeGuide) { activeGuide = guide; break outer; } } } // navigation bar const guideIndexDom = domListNavGuides.children[0].children[0]; const guideDom = domListNavGuides.children[1].children[0]; if (activeGuide){ guideDom.textContent = activeGuide.title; guideDom.setAttribute("href", location.hash); guideDom.classList.remove("hidden"); guideIndexDom.classList.remove("active"); } else { guideDom.classList.add("hidden"); guideIndexDom.classList.add("active"); } // main content domGuidesMenuTitle.textContent = "Table of Contents"; if (activeGuide) { if (activeGuide.toc != "") { domGuideTocList.innerHTML = activeGuide.toc; // add js callbacks to all links function onLinkClick(ev) { const link = ev.target.getAttribute("href"); skipNextHashChange = link; location.replace(link); scrollToHeading(":" + link.split(":")[1], true); ev.preventDefault(); ev.stopPropagation(); } for (let a of domGuideTocList.querySelectorAll("a")) { a.addEventListener('click', onLinkClick, false); } domGuideTocList.classList.remove("hidden"); domGuideTocListEmtpy.classList.add("hidden"); } else { domGuideTocListEmtpy.classList.remove("hidden"); domGuideTocList.classList.add("hidden"); } let reader = new commonmark.Parser({ smart: true, autoDoc: { detectDeclPath: detectDeclPath, } }); let ast = reader.parse(activeGuide.body); let writer = new commonmark.HtmlRenderer(); let result = writer.render(ast); domActiveGuide.innerHTML = result; if (curNav.activeGuideScrollTo !== null) { scrollToHeading(curNav.activeGuideScrollTo, false); } } else { domGuideTocList.classList.add("hidden"); domGuideTocListEmtpy.classList.remove("hidden"); if (zigAnalysis.guideSections.length > 1 || (zigAnalysis.guideSections[0].guides.length > 0)) { renderGuidesIndex(); } else { noGuidesAtAll(); } } domGuidesMenu.classList.remove("hidden"); domActiveGuide.classList.remove("hidden"); } // TODO: ensure unique hashes // TODO: hash also guides and their headings function computeGuideHashes() { for (let i = 1; i < zigAnalysis.guideSections.length; i += 1) { const section = zigAnalysis.guideSections[i]; section.hash = "section-" + slugify(section.name || i); } } function renderGuidesIndex() { // main content { let html = ""; for (let i = 0; i < zigAnalysis.guideSections.length; i += 1) { const section = zigAnalysis.guideSections[i]; if (i != 0) { // first section is the default section html += "
There are no doc comments for this declaration.
"; } domTldDocs.classList.remove("hidden"); } function typeIsErrSet(typeIndex) { let typeObj = getType(typeIndex); return typeObj.kind === typeKinds.ErrorSet; } function typeIsStructWithNoFields(typeIndex) { let typeObj = getType(typeIndex); if (typeObj.kind !== typeKinds.Struct) return false; return typeObj.field_types.length == 0; } function typeIsGenericFn(typeIndex) { let typeObj = getType(typeIndex); if (typeObj.kind !== typeKinds.Fn) { return false; } return typeObj.generic_ret != null; } function renderFn(fnDecl) { if ("refPath" in fnDecl.value.expr) { let last = fnDecl.value.expr.refPath.length - 1; let lastExpr = fnDecl.value.expr.refPath[last]; console.assert("declRef" in lastExpr); fnDecl = getDecl(lastExpr.declRef); } let value = resolveValue(fnDecl.value); console.assert("type" in value.expr); let typeObj = getType(value.expr.type); domFnProtoCode.innerHTML = renderTokens(ex(value.expr, { fnDecl: fnDecl })); domFnSourceLink.classList.remove("hidden"); domFnSourceLink.innerHTML = "[src]"; let docsSource = null; let srcNode = getAstNode(fnDecl.src); if (srcNode.docs != null) { docsSource = srcNode.docs; } renderFnParamDocs(fnDecl, typeObj); let retExpr = resolveValue({ expr: typeObj.ret }).expr; if ("type" in retExpr) { let retIndex = retExpr.type; let errSetTypeIndex = null; let retType = getType(retIndex); if (retType.kind === typeKinds.ErrorSet) { errSetTypeIndex = retIndex; } else if (retType.kind === typeKinds.ErrorUnion) { errSetTypeIndex = retType.err.type; } if (errSetTypeIndex != null) { let errSetType = getType(errSetTypeIndex); renderErrorSet(errSetType); } } let protoSrcIndex = fnDecl.src; if (typeIsGenericFn(value.expr.type)) { // does the generic_ret contain a container? var resolvedGenericRet = resolveValue({ expr: typeObj.generic_ret }); if ("call" in resolvedGenericRet.expr) { let call = zigAnalysis.calls[resolvedGenericRet.expr.call]; let resolvedFunc = resolveValue({ expr: call.func }); if (!("type" in resolvedFunc.expr)) return; let callee = getType(resolvedFunc.expr.type); if (!callee.generic_ret) return; resolvedGenericRet = resolveValue({ expr: callee.generic_ret }); } // TODO: see if unwrapping the `as` here is a good idea or not. if ("as" in resolvedGenericRet.expr) { resolvedGenericRet = { expr: zigAnalysis.exprs[resolvedGenericRet.expr.as.exprArg], }; } if (!("type" in resolvedGenericRet.expr)) return; const genericType = getType(resolvedGenericRet.expr.type); if (isContainerType(genericType)) { renderContainer(genericType); } // old code // let instantiations = nodesToFnsMap[protoSrcIndex]; // let calls = nodesToCallsMap[protoSrcIndex]; // if (instantiations == null && calls == null) { // domFnNoExamples.classList.remove("hidden"); // } else if (calls != null) { // // if (fnObj.combined === undefined) fnObj.combined = allCompTimeFnCallsResult(calls); // if (fnObj.combined != null) renderContainer(fnObj.combined); // resizeDomList(domListFnExamples, calls.length, ''); // for (let callI = 0; callI < calls.length; callI += 1) { // let liDom = domListFnExamples.children[callI]; // liDom.innerHTML = getCallHtml(fnDecl, calls[callI]); // } // domFnExamples.classList.remove("hidden"); // } else if (instantiations != null) { // // TODO // } } else { domFnExamples.classList.add("hidden"); domFnNoExamples.classList.add("hidden"); } let protoSrcNode = getAstNode(protoSrcIndex); if ( docsSource == null && protoSrcNode != null && protoSrcNode.docs != null ) { docsSource = protoSrcNode.docs; } if (docsSource != null) { domTldDocs.innerHTML = markdown(docsSource, fnDecl); domTldDocs.classList.remove("hidden"); } domFnProto.classList.remove("hidden"); } function renderFnParamDocs(fnDecl, typeObj) { let docCount = 0; let fnNode = getAstNode(fnDecl.src); let fields = fnNode.fields; if (fields === null) { fields = getAstNode(typeObj.src).fields; } let isVarArgs = typeObj.is_var_args; for (let i = 0; i < fields.length; i += 1) { let field = fields[i]; let fieldNode = getAstNode(field); if (fieldNode.docs != null) { docCount += 1; } } if (docCount == 0) { return; } resizeDomList(domListParams, docCount, ""); let domIndex = 0; for (let i = 0; i < fields.length; i += 1) { let field = fields[i]; let fieldNode = getAstNode(field); let docs = fieldNode.docs; if (fieldNode.docs == null) { continue; } let docsNonEmpty = docs !== ""; let divDom = domListParams.children[domIndex]; domIndex += 1; let value = typeObj.params[i]; let preClass = docsNonEmpty ? ' class="fieldHasDocs"' : ""; let html = "" + renderTokens((function*() { yield Tok.identifier(fieldNode.name); yield Tok.colon; yield Tok.space; if (isVarArgs && i === typeObj.params.length - 1) { yield Tok.period; yield Tok.period; yield Tok.period; } else { yield* ex(value, {}); } yield Tok.comma; }())); html += ""; if (docsNonEmpty) { html += '
" + name + "(" + zigAnalysis.typeKinds[typeObj.kind] + ")"; domHdrName.classList.remove("hidden"); } if (typeObj.kind == typeKinds.ErrorSet) { renderErrorSet(typeObj); } } function renderErrorSet(errSetType) { if (errSetType.fields == null) { domFnErrorsAnyError.classList.remove("hidden"); } else { let errorList = []; for (let i = 0; i < errSetType.fields.length; i += 1) { let errObj = errSetType.fields[i]; //let srcObj = zigAnalysis.astNodes[errObj.src]; errorList.push(errObj); } errorList.sort(function(a, b) { return operatorCompare(a.name.toLowerCase(), b.name.toLowerCase()); }); resizeDomListDl(domListFnErrors, errorList.length); for (let i = 0; i < errorList.length; i += 1) { let nameTdDom = domListFnErrors.children[i * 2 + 0]; let descTdDom = domListFnErrors.children[i * 2 + 1]; nameTdDom.textContent = errorList[i].name; let docs = errorList[i].docs; if (docs != null) { descTdDom.innerHTML = markdown(docs); } else { descTdDom.textContent = ""; } } domTableFnErrors.classList.remove("hidden"); } domSectFnErrors.classList.remove("hidden"); } // function allCompTimeFnCallsHaveTypeResult(typeIndex, value) { // let srcIndex = zigAnalysis.fns[value].src; // let calls = nodesToCallsMap[srcIndex]; // if (calls == null) return false; // for (let i = 0; i < calls.length; i += 1) { // let call = zigAnalysis.calls[calls[i]]; // if (call.result.type !== typeTypeId) return false; // } // return true; // } // // function allCompTimeFnCallsResult(calls) { // let firstTypeObj = null; // let containerObj = { // privDecls: [], // }; // for (let callI = 0; callI < calls.length; callI += 1) { // let call = zigAnalysis.calls[calls[callI]]; // if (call.result.type !== typeTypeId) return null; // let 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 (let fieldI = 0; fieldI < typeObj.fields.length; fieldI += 1) { // let prev = containerObj.fields[fieldI]; // let 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 (let declI = 0; declI < typeObj.pubDecls.length; declI += 1) { // let prev = containerObj.pubDecls[declI]; // let 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') { // // let 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 (let declI = 0; declI < containerObj.pubDecls.length; declI += 1) { // let decl = containerObj.pubDecls[declI]; // if (typeof(decl) === 'object') { // containerObj.pubDecls[declI] = containerObj.pubDecls[declI].id; // } // } // return containerObj; // } function renderValue(decl) { let resolvedValue = resolveValue(decl.value); if (resolvedValue.expr.fieldRef) { const declRef = decl.value.expr.refPath[0].declRef; const type = getDecl(declRef); domFnProtoCode.innerHTML = renderTokens( (function*() { yield Tok.const; yield Tok.space; yield Tok.identifier(decl.name); yield Tok.colon; yield Tok.space; yield Tok.identifier(type.name); yield Tok.space; yield Tok.eql; yield Tok.space; yield* ex(decl.value.expr, {}); yield Tok.semi; })()); } else if ( resolvedValue.expr.string !== undefined || resolvedValue.expr.call !== undefined || resolvedValue.expr.comptimeExpr !== undefined ) { // TODO: we're using the resolved value but // not keeping track of how we got there // that's important context that should // be shown to the user! domFnProtoCode.innerHTML = renderTokens( (function*() { yield Tok.const; yield Tok.space; yield Tok.identifier(decl.name); if (decl.value.typeRef) { yield Tok.colon; yield Tok.space; yield* ex(decl.value.typeRef, {}); } yield Tok.space; yield Tok.eql; yield Tok.space; yield* ex(resolvedValue.expr, {}); yield Tok.semi; })()); } else if (resolvedValue.expr.compileError) { domFnProtoCode.innerHTML = renderTokens( (function*() { yield Tok.const; yield Tok.space; yield Tok.identifier(decl.name); yield Tok.space; yield Tok.eql; yield Tok.space; yield* ex(decl.value.expr, {}); yield Tok.semi; })()); } else { const parent = getType(decl.parent_container); domFnProtoCode.innerHTML = renderTokens( (function*() { yield Tok.const; yield Tok.space; yield Tok.identifier(decl.name); if (decl.value.typeRef !== null) { yield Tok.colon; yield Tok.space; yield* ex(decl.value.typeRef, {}); } yield Tok.space; yield Tok.eql; yield Tok.space; yield* ex(decl.value.expr, {}); yield Tok.semi; })()); } let docs = getAstNode(decl.src).docs; if (docs != null) { // TODO: it shouldn't just be decl.parent_container, but rather // the type that the decl holds (if the value is a type) domTldDocs.innerHTML = markdown(docs, decl); domTldDocs.classList.remove("hidden"); } domFnProto.classList.remove("hidden"); } function renderVar(decl) { let resolvedVar = resolveValue(decl.value); if (resolvedVar.expr.fieldRef) { const declRef = decl.value.expr.refPath[0].declRef; const type = getDecl(declRef); domFnProtoCode.innerHTML = renderTokens( (function*() { yield Tok.var; yield Tok.space; yield Tok.identifier(decl.name); yield Tok.colon; yield Tok.space; yield Tok.identifier(type.name); yield Tok.space; yield Tok.eql; yield Tok.space; yield* ex(decl.value.expr, {}); yield Tok.semi; })()); } else if ( resolvedVar.expr.string !== undefined || resolvedVar.expr.call !== undefined || resolvedVar.expr.comptimeExpr !== undefined ) { domFnProtoCode.innerHTML = renderTokens( (function*() { yield Tok.var; yield Tok.space; yield Tok.identifier(decl.name); if (decl.value.typeRef) { yield Tok.colon; yield Tok.space; yield* ex(decl.value.typeRef, {}); } yield Tok.space; yield Tok.eql; yield Tok.space; yield* ex(decl.value.expr, {}); yield Tok.semi; })()); } else if (resolvedVar.expr.compileError) { domFnProtoCode.innerHTML = renderTokens( (function*() { yield Tok.var; yield Tok.space; yield Tok.identifier(decl.name); yield Tok.space; yield Tok.eql; yield Tok.space; yield* ex(decl.value.expr, {}); yield Tok.semi; })()); } else { domFnProtoCode.innerHTML = renderTokens( (function*() { yield Tok.var; yield Tok.space; yield Tok.identifier(decl.name); yield Tok.colon; yield Tok.space; yield* ex(resolvedVar.typeRef, {}); yield Tok.space; yield Tok.eql; yield Tok.space; yield* ex(decl.value.expr, {}); yield Tok.semi; })()); } let docs = getAstNode(decl.src).docs; if (docs != null) { domTldDocs.innerHTML = markdown(docs); domTldDocs.classList.remove("hidden"); } domFnProto.classList.remove("hidden"); } function categorizeDecls( decls, typesList, namespacesWithDocsList, namespacesNoDocsList, errSetsList, fnsList, varsList, valsList, testsList, unsList ) { for (let i = 0; i < decls.length; i += 1) { let decl = getDecl(decls[i]); let declValue = resolveValue(decl.value); // if (decl.isTest) { // testsList.push(decl); // continue; // } if (decl.kind === "var") { varsList.push(decl); continue; } if (decl.kind === "const") { if ("type" in declValue.expr) { // We have the actual type expression at hand. const typeExpr = getType(declValue.expr.type); if (typeExpr.kind == typeKinds.Fn) { const funcRetExpr = resolveValue({ expr: typeExpr.ret, }); if ( "type" in funcRetExpr.expr && funcRetExpr.expr.type == typeTypeId ) { if (typeIsErrSet(declValue.expr.type)) { errSetsList.push(decl); } else if (typeIsStructWithNoFields(declValue.expr.type)) { let docs = getAstNode(decl.src).docs; if (!docs) { // If this is a re-export, try to fetch docs from the actual definition const { value, seenDecls } = resolveValue(decl.value, true); if (seenDecls.length > 0) { const definitionDecl = getDecl(seenDecls[seenDecls.length - 1]); docs = getAstNode(definitionDecl.src).docs; } else { docs = getAstNode(getType(value.expr.type).src).docs; } } if (docs) { namespacesWithDocsList.push({decl, docs}); } else { namespacesNoDocsList.push(decl); } } else { typesList.push(decl); } } else { fnsList.push(decl); } } else { if (typeIsErrSet(declValue.expr.type)) { errSetsList.push(decl); } else if (typeIsStructWithNoFields(declValue.expr.type)) { let docs = getAstNode(decl.src).docs; if (!docs) { // If this is a re-export, try to fetch docs from the actual definition const { value, seenDecls } = resolveValue(decl.value, true); if (seenDecls.length > 0) { const definitionDecl = getDecl(seenDecls[seenDecls.length - 1]); docs = getAstNode(definitionDecl.src).docs; } else { docs = getAstNode(getType(value.expr.type).src).docs; } } if (docs) { namespacesWithDocsList.push({decl, docs}); } else { namespacesNoDocsList.push(decl); } } else { typesList.push(decl); } } } else if (declValue.typeRef) { if ("type" in declValue.typeRef && declValue.typeRef == typeTypeId) { // We don't know what the type expression is, but we know it's a type. typesList.push(decl); } else { valsList.push(decl); } } else { valsList.push(decl); } } if (decl.is_uns) { unsList.push(decl); } } } function sourceFileLink(decl) { const srcNode = getAstNode(decl.src); const srcFile = getFile(srcNode.file); return sourceFileUrlTemplate. replace("{{mod}}", zigAnalysis.modules[srcFile.modIndex].name). replace("{{file}}", srcFile.name). replace("{{line}}", srcNode.line + 1); } function renderContainer(container) { let typesList = []; let namespacesWithDocsList = []; let namespacesNoDocsList = []; let errSetsList = []; let fnsList = []; let varsList = []; let valsList = []; let testsList = []; let unsList = []; categorizeDecls( container.pubDecls, typesList, namespacesWithDocsList, namespacesNoDocsList, errSetsList, fnsList, varsList, valsList, testsList, unsList ); if (curNav.showPrivDecls) categorizeDecls( container.privDecls, typesList, namespacesWithDocsList, namespacesNoDocsList, errSetsList, fnsList, varsList, valsList, testsList, unsList ); while (unsList.length > 0) { let uns = unsList.shift(); let declValue = resolveValue(uns.value); if (!("type" in declValue.expr)) continue; let uns_container = getType(declValue.expr.type); if (!isContainerType(uns_container)) continue; categorizeDecls( uns_container.pubDecls, typesList, namespacesWithDocsList, namespacesNoDocsList, errSetsList, fnsList, varsList, valsList, testsList, unsList ); if (curNav.showPrivDecls) categorizeDecls( uns_container.privDecls, typesList, namespacesWithDocsList, namespacesNoDocsList, errSetsList, fnsList, varsList, valsList, testsList, unsList ); } typesList.sort(byNameProperty); namespacesWithDocsList.sort(byNameProperty); namespacesNoDocsList.sort(byNameProperty); errSetsList.sort(byNameProperty); fnsList.sort(byNameProperty); varsList.sort(byNameProperty); valsList.sort(byNameProperty); testsList.sort(byNameProperty); if (container.src != null) { let docs = getAstNode(container.src).docs; if (docs != null) { domTldDocs.innerHTML = markdown(docs, container); domTldDocs.classList.remove("hidden"); } } if (typesList.length !== 0) { const splitPoint = Math.ceil(typesList.length / 2); const template = '
No documentation provided.
"; } if (i == splitPoint - 1) { activeList = domListTypesRight; offset = splitPoint; } } domSectTypes.classList.remove("hidden"); } if (namespacesWithDocsList.length !== 0) { const splitPoint = Math.ceil(namespacesWithDocsList.length / 2); const template = '