| ... | @@ -281,7 +281,8 @@ const NAV_MODES = { | ... | @@ -281,7 +281,8 @@ const NAV_MODES = { |
| 281 | // return null; | 281 | // return null; |
| 282 | // } | 282 | // } |
| 283 | | 283 | |
| 284 | function resolveValue(value) { | 284 | function resolveValue(value, trackDecls) { |
| | 285 | let seenDecls = []; |
| 285 | let i = 0; | 286 | let i = 0; |
| 286 | while (true) { | 287 | while (true) { |
| 287 | i += 1; | 288 | i += 1; |
| ... | @@ -295,6 +296,7 @@ const NAV_MODES = { | ... | @@ -295,6 +296,7 @@ const NAV_MODES = { |
| 295 | } | 296 | } |
| 296 | | 297 | |
| 297 | if ("declRef" in value.expr) { | 298 | if ("declRef" in value.expr) { |
| | 299 | seenDecls.push(value.expr.declRef); |
| 298 | value = getDecl(value.expr.declRef).value; | 300 | value = getDecl(value.expr.declRef).value; |
| 299 | continue; | 301 | continue; |
| 300 | } | 302 | } |
| ... | @@ -307,6 +309,7 @@ const NAV_MODES = { | ... | @@ -307,6 +309,7 @@ const NAV_MODES = { |
| 307 | continue; | 309 | continue; |
| 308 | } | 310 | } |
| 309 | | 311 | |
| | 312 | if (trackDecls) return { value, seenDecls }; |
| 310 | return value; | 313 | return value; |
| 311 | } | 314 | } |
| 312 | } | 315 | } |
| ... | @@ -1134,9 +1137,8 @@ Happy writing! | ... | @@ -1134,9 +1137,8 @@ Happy writing! |
| 1134 | } | 1137 | } |
| 1135 | case "declRef": { | 1138 | case "declRef": { |
| 1136 | const name = getDecl(expr.declRef).name; | 1139 | const name = getDecl(expr.declRef).name; |
| 1137 | const canonPath = getCanonDeclPath(expr.declRef); | 1140 | const link = declLinkOrSrcLink(expr.declRef); |
| 1138 | if (canonPath) { | 1141 | if (link) { |
| 1139 | const link = navLink(canonPath.modNames, canonPath.declNames); | | |
| 1140 | yield { src: name, tag: Tag.identifier, link }; | 1142 | yield { src: name, tag: Tag.identifier, link }; |
| 1141 | } else { | 1143 | } else { |
| 1142 | yield { src: name, tag: Tag.identifier }; | 1144 | yield { src: name, tag: Tag.identifier }; |
| ... | @@ -2028,7 +2030,6 @@ Happy writing! | ... | @@ -2028,7 +2030,6 @@ Happy writing! |
| 2028 | let linkFnNameDecl = opts.linkFnNameDecl; | 2030 | let linkFnNameDecl = opts.linkFnNameDecl; |
| 2029 | opts.fnDecl = null; | 2031 | opts.fnDecl = null; |
| 2030 | opts.linkFnNameDecl = null; | 2032 | opts.linkFnNameDecl = null; |
| 2031 | let payloadHtml = ""; | | |
| 2032 | if (opts.addParensIfFnSignature && fnObj.src == 0) { | 2033 | if (opts.addParensIfFnSignature && fnObj.src == 0) { |
| 2033 | yield Tok.l_paren; | 2034 | yield Tok.l_paren; |
| 2034 | } | 2035 | } |
| ... | @@ -2108,6 +2109,7 @@ Happy writing! | ... | @@ -2108,6 +2109,7 @@ Happy writing! |
| 2108 | } | 2109 | } |
| 2109 | } | 2110 | } |
| 2110 | | 2111 | |
| | 2112 | // TODO: most of this seems redundant |
| 2111 | if (isVarArgs && i === fnObj.params.length - 1) { | 2113 | if (isVarArgs && i === fnObj.params.length - 1) { |
| 2112 | yield Tok.period; | 2114 | yield Tok.period; |
| 2113 | yield Tok.period; | 2115 | yield Tok.period; |
| ... | @@ -3234,7 +3236,7 @@ Happy writing! | ... | @@ -3234,7 +3236,7 @@ Happy writing! |
| 3234 | } | 3236 | } |
| 3235 | | 3237 | |
| 3236 | function addDeclToSearchResults(decl, declIndex, modNames, item, list, stack) { | 3238 | function addDeclToSearchResults(decl, declIndex, modNames, item, list, stack) { |
| 3237 | let declVal = resolveValue(decl.value); | 3239 | let {value: declVal, seenDecls} = resolveValue(decl.value, true); |
| 3238 | let declNames = item.declNames.concat([decl.name]); | 3240 | let declNames = item.declNames.concat([decl.name]); |
| 3239 | let declIndexes = item.declIndexes.concat([declIndex]); | 3241 | let declIndexes = item.declIndexes.concat([declIndex]); |
| 3240 | | 3242 | |
| ... | @@ -3245,6 +3247,15 @@ Happy writing! | ... | @@ -3245,6 +3247,15 @@ Happy writing! |
| 3245 | declIndexes: declIndexes, | 3247 | declIndexes: declIndexes, |
| 3246 | }; | 3248 | }; |
| 3247 | | 3249 | |
| | 3250 | for (let sd of seenDecls) { |
| | 3251 | if (list[sd] != null) continue; |
| | 3252 | list[sd] = { |
| | 3253 | modNames: modNames, |
| | 3254 | declNames: declNames, |
| | 3255 | declIndexes: declIndexes, |
| | 3256 | }; |
| | 3257 | } |
| | 3258 | |
| 3248 | // add to search index | 3259 | // add to search index |
| 3249 | { | 3260 | { |
| 3250 | declSearchIndex.add(decl.name, { declIndex }); | 3261 | declSearchIndex.add(decl.name, { declIndex }); |
| ... | @@ -3282,12 +3293,60 @@ Happy writing! | ... | @@ -3282,12 +3293,60 @@ Happy writing! |
| 3282 | } | 3293 | } |
| 3283 | } | 3294 | } |
| 3284 | | 3295 | |
| | 3296 | function declLinkOrSrcLink(index) { |
| | 3297 | |
| | 3298 | let match = getCanonDeclPath(index); |
| | 3299 | if (match) return navLink(match.modNames, match.declNames); |
| | 3300 | |
| | 3301 | // could not find a precomputed decl path |
| | 3302 | const decl = getDecl(index); |
| | 3303 | |
| | 3304 | // try to find a public decl by scanning declRefs and declPaths |
| | 3305 | let value = decl.value; |
| | 3306 | let i = 0; |
| | 3307 | while (true) { |
| | 3308 | i += 1; |
| | 3309 | if (i >= 10000) { |
| | 3310 | throw "getCanonDeclPath quota exceeded" |
| | 3311 | } |
| | 3312 | |
| | 3313 | if ("refPath" in value.expr) { |
| | 3314 | value = { expr: value.expr.refPath[value.expr.refPath.length - 1] }; |
| | 3315 | continue; |
| | 3316 | } |
| | 3317 | |
| | 3318 | if ("declRef" in value.expr) { |
| | 3319 | let cp = canonDeclPaths[value.expr.declRef]; |
| | 3320 | if (cp) return navLink(cp.modNames, cp.declNames); |
| | 3321 | |
| | 3322 | value = getDecl(value.expr.declRef).value; |
| | 3323 | continue; |
| | 3324 | } |
| | 3325 | |
| | 3326 | if ("as" in value.expr) { |
| | 3327 | value = { |
| | 3328 | typeRef: zigAnalysis.exprs[value.expr.as.typeRefArg], |
| | 3329 | expr: zigAnalysis.exprs[value.expr.as.exprArg], |
| | 3330 | }; |
| | 3331 | continue; |
| | 3332 | } |
| | 3333 | |
| | 3334 | // if we got here it means that we failed |
| | 3335 | // produce a link to source code instead |
| | 3336 | return sourceFileLink(decl); |
| | 3337 | |
| | 3338 | } |
| | 3339 | |
| | 3340 | } |
| | 3341 | |
| 3285 | function getCanonDeclPath(index) { | 3342 | function getCanonDeclPath(index) { |
| 3286 | if (canonDeclPaths == null) { | 3343 | if (canonDeclPaths == null) { |
| 3287 | canonDeclPaths = computeCanonDeclPaths(); | 3344 | canonDeclPaths = computeCanonDeclPaths(); |
| 3288 | } | 3345 | } |
| 3289 | //let cd = (canonDeclPaths); | 3346 | |
| 3290 | return canonDeclPaths[index]; | 3347 | return canonDeclPaths[index]; |
| | 3348 | |
| | 3349 | |
| 3291 | } | 3350 | } |
| 3292 | | 3351 | |
| 3293 | function getCanonTypeDecl(index) { | 3352 | function getCanonTypeDecl(index) { |
| ... | @@ -3395,6 +3454,8 @@ Happy writing! | ... | @@ -3395,6 +3454,8 @@ Happy writing! |
| 3395 | | 3454 | |
| 3396 | } | 3455 | } |
| 3397 | | 3456 | |
| | 3457 | |
| | 3458 | |
| 3398 | function detectDeclPath(text, context) { | 3459 | function detectDeclPath(text, context) { |
| 3399 | let result = ""; | 3460 | let result = ""; |
| 3400 | let separator = ":"; | 3461 | let separator = ":"; |
| ... | @@ -3888,109 +3949,7 @@ Happy writing! | ... | @@ -3888,109 +3949,7 @@ Happy writing! |
| 3888 | domSectSearchResults.classList.remove("hidden"); | 3949 | domSectSearchResults.classList.remove("hidden"); |
| 3889 | } | 3950 | } |
| 3890 | | 3951 | |
| 3891 | function renderSearchAPIOld() { | 3952 | |
| 3892 | let matchedItems = []; | | |
| 3893 | let ignoreCase = curNavSearch.toLowerCase() === curNavSearch; | | |
| 3894 | let terms = getSearchTerms(); | | |
| 3895 | | | |
| 3896 | decl_loop: for ( | | |
| 3897 | let declIndex = 0; | | |
| 3898 | declIndex < zigAnalysis.decls.length; | | |
| 3899 | declIndex += 1 | | |
| 3900 | ) { | | |
| 3901 | let canonPath = getCanonDeclPath(declIndex); | | |
| 3902 | if (canonPath == null) continue; | | |
| 3903 | | | |
| 3904 | let decl = getDecl(declIndex); | | |
| 3905 | let lastModName = canonPath.modNames[canonPath.modNames.length - 1]; | | |
| 3906 | let fullPathSearchText = | | |
| 3907 | lastModName + "." + canonPath.declNames.join("."); | | |
| 3908 | let astNode = getAstNode(decl.src); | | |
| 3909 | let fileAndDocs = ""; //zigAnalysis.files[astNode.file]; | | |
| 3910 | // TODO: understand what this piece of code is trying to achieve | | |
| 3911 | // also right now `files` are expressed as a hashmap. | | |
| 3912 | if (astNode.docs != null) { | | |
| 3913 | fileAndDocs += "\n" + astNode.docs; | | |
| 3914 | } | | |
| 3915 | let fullPathSearchTextLower = fullPathSearchText; | | |
| 3916 | if (ignoreCase) { | | |
| 3917 | fullPathSearchTextLower = fullPathSearchTextLower.toLowerCase(); | | |
| 3918 | fileAndDocs = fileAndDocs.toLowerCase(); | | |
| 3919 | } | | |
| 3920 | | | |
| 3921 | let points = 0; | | |
| 3922 | for (let termIndex = 0; termIndex < terms.length; termIndex += 1) { | | |
| 3923 | let term = terms[termIndex]; | | |
| 3924 | | | |
| 3925 | // exact, case sensitive match of full decl path | | |
| 3926 | if (fullPathSearchText === term) { | | |
| 3927 | points += 4; | | |
| 3928 | continue; | | |
| 3929 | } | | |
| 3930 | // exact, case sensitive match of just decl name | | |
| 3931 | if (decl.name == term) { | | |
| 3932 | points += 3; | | |
| 3933 | continue; | | |
| 3934 | } | | |
| 3935 | // substring, case insensitive match of full decl path | | |
| 3936 | if (fullPathSearchTextLower.indexOf(term) >= 0) { | | |
| 3937 | points += 2; | | |
| 3938 | continue; | | |
| 3939 | } | | |
| 3940 | if (fileAndDocs.indexOf(term) >= 0) { | | |
| 3941 | points += 1; | | |
| 3942 | continue; | | |
| 3943 | } | | |
| 3944 | | | |
| 3945 | continue decl_loop; | | |
| 3946 | } | | |
| 3947 | | | |
| 3948 | matchedItems.push({ | | |
| 3949 | decl: decl, | | |
| 3950 | path: canonPath, | | |
| 3951 | points: points, | | |
| 3952 | }); | | |
| 3953 | } | | |
| 3954 | | | |
| 3955 | if (matchedItems.length !== 0) { | | |
| 3956 | matchedItems.sort(function(a, b) { | | |
| 3957 | let cmp = operatorCompare(b.points, a.points); | | |
| 3958 | if (cmp != 0) return cmp; | | |
| 3959 | return operatorCompare(a.decl.name, b.decl.name); | | |
| 3960 | }); | | |
| 3961 | | | |
| 3962 | let searchTrimmed = false; | | |
| 3963 | const searchTrimResultsMaxItems = 60; | | |
| 3964 | if (searchTrimResults && matchedItems.length > searchTrimResultsMaxItems) { | | |
| 3965 | matchedItems = matchedItems.slice(0, searchTrimResultsMaxItems); | | |
| 3966 | searchTrimmed = true; | | |
| 3967 | } | | |
| 3968 | | | |
| 3969 | // Build up the list of search results | | |
| 3970 | let matchedItemsHTML = ""; | | |
| 3971 | | | |
| 3972 | for (let i = 0; i < matchedItems.length; i += 1) { | | |
| 3973 | const match = matchedItems[i]; | | |
| 3974 | const lastModName = match.path.modNames[match.path.modNames.length - 1]; | | |
| 3975 | | | |
| 3976 | const text = lastModName + "." + match.path.declNames.join("."); | | |
| 3977 | const href = navLink(match.path.modNames, match.path.declNames); | | |
| 3978 | | | |
| 3979 | matchedItemsHTML += "<li><a href=\"" + href + "\">" + text + "</a></li>"; | | |
| 3980 | } | | |
| 3981 | | | |
| 3982 | // Replace the search results using our newly constructed HTML string | | |
| 3983 | domListSearchResults.innerHTML = matchedItemsHTML; | | |
| 3984 | if (searchTrimmed) { | | |
| 3985 | domSectSearchAllResultsLink.classList.remove("hidden"); | | |
| 3986 | } | | |
| 3987 | renderSearchCursor(); | | |
| 3988 | | | |
| 3989 | domSectSearchResults.classList.remove("hidden"); | | |
| 3990 | } else { | | |
| 3991 | domSectSearchNoResults.classList.remove("hidden"); | | |
| 3992 | } | | |
| 3993 | } | | |
| 3994 | | 3953 | |
| 3995 | function renderSearchCursor() { | 3954 | function renderSearchCursor() { |
| 3996 | for (let i = 0; i < domListSearchResults.children.length; i += 1) { | 3955 | for (let i = 0; i < domListSearchResults.children.length; i += 1) { |