MCPcopy Create free account
hub / github.com/Effect-TS/effect / createJSDocApiSeeLinkResolver

Function createJSDocApiSeeLinkResolver

packages/tools/jsdocs/src/Jsdocs.ts:2252–2327  ·  view source on GitHub ↗
(apis: ReadonlyArray<JSDocApi>)

Source from the content-addressed store, hash-verified

2250}
2251
2252function createJSDocApiSeeLinkResolver(apis: ReadonlyArray<JSDocApi>) {
2253 const byModuleAndName = new Map<string, JSDocApi>()
2254 const byLocalName = new Map<string, Array<JSDocApi>>()
2255 const bySourceRange = new Map<string, JSDocApi>()
2256 const bySourceFile = new Map<string, Array<JSDocApi>>()
2257 for (const api of apis) {
2258 byModuleAndName.set(`${api.moduleName}:${api.apiName}`, api)
2259 bySourceRange.set(sourceRangeKey(api.source.file, api.source.range), api)
2260 const sourceApis = bySourceFile.get(api.source.file) ?? []
2261 sourceApis.push(api)
2262 bySourceFile.set(api.source.file, sourceApis)
2263 for (const name of new Set([api.apiName, api.localName])) {
2264 const existing = byLocalName.get(name) ?? []
2265 existing.push(api)
2266 byLocalName.set(name, existing)
2267 }
2268 }
2269 const resolveSymbol = (link: ParsedInlineLink): JSDocApiSeeLinkResolution | undefined => {
2270 if (link.symbol === undefined) return undefined
2271 const symbol = link.symbol
2272 const exact = bySourceRange.get(sourceRangeKey(symbol.file, symbol.range))
2273 if (exact !== undefined) return { _tag: "Resolved", apiId: exact.id, apiFqn: exact.apiFqn }
2274 const names = seeTargetNames(link)
2275 const candidates = (bySourceFile.get(symbol.file) ?? []).filter((api) =>
2276 apiMatchesSeeTarget(api, names) &&
2277 (rangeContains(symbol.range, api.source.range) ||
2278 rangeContains(api.source.range, symbol.range) ||
2279 rangeOverlaps(symbol.range, api.source.range))
2280 ).sort((self, that) => rangeWidth(self.source.range) - rangeWidth(that.source.range))
2281 const unique = Array.from(new Map(candidates.map((candidate) => [candidate.id, candidate])).values())
2282 if (unique.length === 1) return { _tag: "Resolved", apiId: unique[0].id, apiFqn: unique[0].apiFqn }
2283 if (unique.length > 1) {
2284 return { _tag: "Unresolved", reason: "ambiguous", candidates: unique.map((candidate) => candidate.id) }
2285 }
2286 const sameFileByName = (bySourceFile.get(symbol.file) ?? []).filter((api) => apiMatchesSeeTarget(api, names))
2287 const uniqueByName = Array.from(new Map(sameFileByName.map((candidate) => [candidate.id, candidate])).values())
2288 if (uniqueByName.length === 1) {
2289 return { _tag: "Resolved", apiId: uniqueByName[0].id, apiFqn: uniqueByName[0].apiFqn }
2290 }
2291 if (uniqueByName.length > 1) {
2292 return { _tag: "Unresolved", reason: "ambiguous", candidates: uniqueByName.map((candidate) => candidate.id) }
2293 }
2294 return undefined
2295 }
2296 return (
2297 context: { readonly moduleName: string; readonly namespacePath: ReadonlyArray<string> },
2298 link: ParsedInlineLink
2299 ): JSDocApiSeeLinkResolution => {
2300 const symbolResolution = resolveSymbol(link)
2301 if (symbolResolution !== undefined) return symbolResolution
2302 const targets = new Set<string>()
2303 for (const target of normalizeSeeTarget(link.target)) targets.add(target)
2304 if (link.text !== null) {
2305 for (const target of normalizeSeeTarget(link.text)) targets.add(target)
2306 }
2307 for (const target of targets) {
2308 const sameModule = byModuleAndName.get(`${context.moduleName}:${target}`)
2309 if (sameModule !== undefined) return { _tag: "Resolved", apiId: sameModule.id, apiFqn: sameModule.apiFqn }

Callers 2

resolveJSDocApiSeeLinksFunction · 0.85

Calls 9

sourceRangeKeyFunction · 0.85
resolveSymbolFunction · 0.85
normalizeSeeTargetFunction · 0.85
pushMethod · 0.80
joinMethod · 0.80
setMethod · 0.65
getMethod · 0.65
addMethod · 0.65
mapMethod · 0.45

Tested by

no test coverage detected