Skip to content

Commit f1bba29

Browse files
committed
recover from an ambiguous codelink if there is only one possible overload
1 parent ff06f12 commit f1bba29

File tree

2 files changed

+43
-17
lines changed

2 files changed

+43
-17
lines changed

Sources/SymbolGraphLinker/Resolution/SSGC.OutlineDiagnostic.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import FNV1
12
import SourceDiagnostics
23
import UCF
34

45
extension SSGC
56
{
67
enum OutlineDiagnostic:Equatable, Error
78
{
9+
case annealedIncorrectHash(in:UCF.Selector, to:FNV24)
810
case unresolvedAbsolute(Doclink)
911
case suggestReformat(Doclink, to:UCF.Selector)
1012
}
@@ -17,8 +19,14 @@ extension SSGC.OutlineDiagnostic:Diagnostic
1719
{
1820
switch self
1921
{
22+
case .annealedIncorrectHash(in: let selector, to: _):
23+
output[.warning] = """
24+
codelink '\(selector)' is unambiguous, but the hash does not match the resolved \
25+
declaration
26+
"""
27+
2028
case .unresolvedAbsolute(let doclink):
21-
output[.note] = """
29+
output[.warning] = """
2230
doclink '\(doclink)' does not resolve to any article (or tutorial) in this package
2331
"""
2432

@@ -33,6 +41,11 @@ extension SSGC.OutlineDiagnostic:Diagnostic
3341
{
3442
switch self
3543
{
44+
case .annealedIncorrectHash(in: _, to: let hash):
45+
output[.note] = """
46+
replace the hash with [\(hash)] to suppress this warning
47+
"""
48+
3649
case .unresolvedAbsolute:
3750
output[.note] = """
3851
absolute doclinks may only refer to articles (or tutorials), not to symbol \

Sources/SymbolGraphLinker/Resolution/SSGC.OutlineResolver.swift

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -293,34 +293,47 @@ extension SSGC.OutlineResolver
293293
func target(of codelink:UCF.Selector,
294294
at source:SourceReference<Markdown.Source>) -> (Int32, Int32?)?
295295
{
296+
let chosen:any UCF.ResolvableOverload
297+
296298
switch self.codelinks.resolve(codelink)
297299
{
298-
case .ambiguous(let overloads, rejected: let rejected):
299-
self.diagnostics[source] = UCF.ResolutionError<SSGC.Symbolicator>.init(
300-
overloads: overloads,
301-
rejected: rejected,
302-
selector: codelink)
303-
304-
return nil
300+
case .module(let module):
301+
return (self.tables.intern(module) * .module, nil)
305302

306303
case .overload(let overload as UCF.PackageOverload):
307304
return (overload.decl, overload.heir)
308305

309306
case .overload(let overload):
310-
let decl:Int32 = self.tables.intern(overload.id)
307+
chosen = overload
311308

312-
if case let overload as UCF.CausalOverload = overload,
313-
let heir:Symbol.Decl = overload.heir
314-
{
315-
return (decl, self.tables.intern(heir))
316-
}
309+
case .ambiguous(let overloads, rejected: let rejected):
310+
guard overloads.isEmpty, rejected.count == 1
317311
else
318312
{
319-
return (decl, nil)
313+
self.diagnostics[source] = UCF.ResolutionError<SSGC.Symbolicator>.init(
314+
overloads: overloads,
315+
rejected: rejected,
316+
selector: codelink)
317+
return nil
320318
}
321319

322-
case .module(let module):
323-
return (self.tables.intern(module) * .module, nil)
320+
chosen = rejected[0]
321+
322+
self.diagnostics[source] = SSGC.OutlineDiagnostic.annealedIncorrectHash(
323+
in: codelink,
324+
to: chosen.hash)
325+
}
326+
327+
let decl:Int32 = self.tables.intern(chosen.id)
328+
329+
if case let chosen as UCF.CausalOverload = chosen,
330+
let heir:Symbol.Decl = chosen.heir
331+
{
332+
return (decl, self.tables.intern(heir))
333+
}
334+
else
335+
{
336+
return (decl, nil)
324337
}
325338
}
326339
}

0 commit comments

Comments
 (0)