diff --git a/lib/docs/main.js b/lib/docs/main.js index dec6bf85cc..088a974316 100644 --- a/lib/docs/main.js +++ b/lib/docs/main.js @@ -281,7 +281,8 @@ const NAV_MODES = { // return null; // } - function resolveValue(value) { + function resolveValue(value, trackDecls) { + let seenDecls = []; let i = 0; while (true) { i += 1; @@ -295,6 +296,7 @@ const NAV_MODES = { } if ("declRef" in value.expr) { + seenDecls.push(value.expr.declRef); value = getDecl(value.expr.declRef).value; continue; } @@ -307,6 +309,7 @@ const NAV_MODES = { continue; } + if (trackDecls) return { value, seenDecls }; return value; } } @@ -1134,9 +1137,8 @@ Happy writing! } case "declRef": { const name = getDecl(expr.declRef).name; - const canonPath = getCanonDeclPath(expr.declRef); - if (canonPath) { - const link = navLink(canonPath.modNames, canonPath.declNames); + const link = declLinkOrSrcLink(expr.declRef); + if (link) { yield { src: name, tag: Tag.identifier, link }; } else { yield { src: name, tag: Tag.identifier }; @@ -2028,7 +2030,6 @@ Happy writing! let linkFnNameDecl = opts.linkFnNameDecl; opts.fnDecl = null; opts.linkFnNameDecl = null; - let payloadHtml = ""; if (opts.addParensIfFnSignature && fnObj.src == 0) { yield Tok.l_paren; } @@ -2108,6 +2109,7 @@ Happy writing! } } + // TODO: most of this seems redundant if (isVarArgs && i === fnObj.params.length - 1) { yield Tok.period; yield Tok.period; @@ -3234,7 +3236,7 @@ Happy writing! } function addDeclToSearchResults(decl, declIndex, modNames, item, list, stack) { - let declVal = resolveValue(decl.value); + let {value: declVal, seenDecls} = resolveValue(decl.value, true); let declNames = item.declNames.concat([decl.name]); let declIndexes = item.declIndexes.concat([declIndex]); @@ -3245,6 +3247,15 @@ Happy writing! declIndexes: declIndexes, }; + for (let sd of seenDecls) { + if (list[sd] != null) continue; + list[sd] = { + modNames: modNames, + declNames: declNames, + declIndexes: declIndexes, + }; + } + // add to search index { declSearchIndex.add(decl.name, { declIndex }); @@ -3282,12 +3293,60 @@ Happy writing! } } + function declLinkOrSrcLink(index) { + + let match = getCanonDeclPath(index); + if (match) return navLink(match.modNames, match.declNames); + + // could not find a precomputed decl path + const decl = getDecl(index); + + // try to find a public decl by scanning declRefs and declPaths + let value = decl.value; + let i = 0; + while (true) { + i += 1; + if (i >= 10000) { + throw "getCanonDeclPath quota exceeded" + } + + if ("refPath" in value.expr) { + value = { expr: value.expr.refPath[value.expr.refPath.length - 1] }; + continue; + } + + if ("declRef" in value.expr) { + let cp = canonDeclPaths[value.expr.declRef]; + if (cp) return navLink(cp.modNames, cp.declNames); + + 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 we got here it means that we failed + // produce a link to source code instead + return sourceFileLink(decl); + + } + + } + function getCanonDeclPath(index) { if (canonDeclPaths == null) { canonDeclPaths = computeCanonDeclPaths(); } - //let cd = (canonDeclPaths); + return canonDeclPaths[index]; + + } function getCanonTypeDecl(index) { @@ -3395,6 +3454,8 @@ Happy writing! } + + function detectDeclPath(text, context) { let result = ""; let separator = ":"; @@ -3888,109 +3949,7 @@ Happy writing! domSectSearchResults.classList.remove("hidden"); } - function renderSearchAPIOld() { - let matchedItems = []; - let ignoreCase = curNavSearch.toLowerCase() === curNavSearch; - let terms = getSearchTerms(); - - decl_loop: for ( - let declIndex = 0; - declIndex < zigAnalysis.decls.length; - declIndex += 1 - ) { - let canonPath = getCanonDeclPath(declIndex); - if (canonPath == null) continue; - - let decl = getDecl(declIndex); - let lastModName = canonPath.modNames[canonPath.modNames.length - 1]; - let fullPathSearchText = - lastModName + "." + canonPath.declNames.join("."); - let astNode = getAstNode(decl.src); - let fileAndDocs = ""; //zigAnalysis.files[astNode.file]; - // TODO: understand what this piece of code is trying to achieve - // also right now `files` are expressed as a hashmap. - if (astNode.docs != null) { - fileAndDocs += "\n" + astNode.docs; - } - let fullPathSearchTextLower = fullPathSearchText; - if (ignoreCase) { - fullPathSearchTextLower = fullPathSearchTextLower.toLowerCase(); - fileAndDocs = fileAndDocs.toLowerCase(); - } - - let points = 0; - for (let termIndex = 0; termIndex < terms.length; termIndex += 1) { - let term = terms[termIndex]; - - // exact, case sensitive match of full decl path - if (fullPathSearchText === term) { - points += 4; - continue; - } - // exact, case sensitive match of just decl name - if (decl.name == term) { - points += 3; - continue; - } - // substring, case insensitive match of full decl path - if (fullPathSearchTextLower.indexOf(term) >= 0) { - points += 2; - continue; - } - if (fileAndDocs.indexOf(term) >= 0) { - points += 1; - continue; - } - - continue decl_loop; - } - - matchedItems.push({ - decl: decl, - path: canonPath, - points: points, - }); - } - - if (matchedItems.length !== 0) { - matchedItems.sort(function(a, b) { - let cmp = operatorCompare(b.points, a.points); - if (cmp != 0) return cmp; - return operatorCompare(a.decl.name, b.decl.name); - }); - - let searchTrimmed = false; - const searchTrimResultsMaxItems = 60; - if (searchTrimResults && matchedItems.length > searchTrimResultsMaxItems) { - matchedItems = matchedItems.slice(0, searchTrimResultsMaxItems); - searchTrimmed = true; - } - - // Build up the list of search results - let matchedItemsHTML = ""; - - for (let i = 0; i < matchedItems.length; i += 1) { - const match = matchedItems[i]; - const lastModName = match.path.modNames[match.path.modNames.length - 1]; - - const text = lastModName + "." + match.path.declNames.join("."); - const href = navLink(match.path.modNames, match.path.declNames); - - matchedItemsHTML += "