Skip to content

Commit 8599c5b

Browse files
committed
write a new, lightweight dynamic linker optimized for newer symbol graphs
1 parent 7730a7f commit 8599c5b

11 files changed

+796
-14
lines changed

Sources/UnidocLinker/Sema/Unidoc.Linker.Table.swift

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ extension Unidoc.Linker.Table:ExpressibleByDictionaryLiteral
2727
self.init(table: [:])
2828
}
2929
}
30+
extension Unidoc.Linker.Table:Sequence
31+
{
32+
func makeIterator() -> Dictionary<Group.Signature, Group>.Iterator
33+
{
34+
self.table.makeIterator()
35+
}
36+
}
3037
extension Unidoc.Linker.Table
3138
{
3239
consuming
@@ -79,6 +86,69 @@ extension Unidoc.Linker.Table<Unidoc.Conformers>
7986
}
8087
}
8188

89+
extension Unidoc.Linker.Table<Unidoc.Extension>
90+
{
91+
mutating
92+
func add(extensions:[SymbolGraph.Extension],
93+
extending extendee:Unidoc.Scalar,
94+
context:inout Unidoc.Linker)
95+
{
96+
for `extension`:SymbolGraph.Extension in extensions
97+
{
98+
let conditions:Unidoc.ExtensionConditions = .init(
99+
constraints: `extension`.conditions.map
100+
{
101+
$0.map { context.current.scalars.decls[$0] }
102+
},
103+
culture: `extension`.culture)
104+
;
105+
// It’s possible for two locally-disjoint extensions to coalesce
106+
// into a single global extension due to failure to link scalars.
107+
{
108+
for local:Int32 in `extension`.conformances
109+
{
110+
if let id:Unidoc.Scalar = context.current.scalars.decls[local]
111+
{
112+
$0.conformances.append(id)
113+
}
114+
}
115+
// The feature might have been declared in a different package!
116+
// This started happening when SSGC stopped emitting unqualified features
117+
// as this was previously handled in ``linkCultures``.
118+
for local:Int32 in `extension`.features
119+
{
120+
if let id:Unidoc.Scalar = context.current.scalars.decls[local]
121+
{
122+
$0.features.append(id)
123+
}
124+
}
125+
for local:Int32 in `extension`.nested
126+
{
127+
if let id:Unidoc.Scalar = context.current.scalars.decls[local]
128+
{
129+
$0.nested.append(id)
130+
}
131+
}
132+
133+
guard
134+
let article:SymbolGraph.Article = `extension`.article
135+
else
136+
{
137+
return
138+
}
139+
guard case (nil, nil) = ($0.overview, $0.details)
140+
else
141+
{
142+
context.diagnostics[nil] = DroppedPassagesError.fromExtension($0.id,
143+
of: extendee)
144+
return
145+
}
146+
147+
($0.overview, $0.details) = context.link(article: article)
148+
} (&self[.extends(extendee, where: conditions)])
149+
}
150+
}
151+
}
82152
extension Unidoc.Linker.Table<Unidoc.Extension>
83153
{
84154
/// Creates extension records from the given symbol graph extensions, performing any

Sources/UnidocLinker/Sema/Unidoc.Linker.Tables.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ extension Unidoc.Linker
3232
var peers:[Int32: Unidoc.Group]
3333

3434
private
35-
var next:Next
35+
var next:Unidoc.LinkerTables.Next
3636

3737
private(set)
3838
var extensions:Unidoc.Linker.Table<Unidoc.Extension>

Sources/UnidocLinker/Sema/Unidoc.Linker.Tables.Counter.swift renamed to Sources/UnidocLinker/Sema/Unidoc.LinkerTables.Counter.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
extension Unidoc.Linker.Tables
1+
extension Unidoc.LinkerTables
22
{
33
struct Counter
44
{
@@ -11,7 +11,7 @@ extension Unidoc.Linker.Tables
1111
}
1212
}
1313
}
14-
extension Unidoc.Linker.Tables.Counter
14+
extension Unidoc.LinkerTables.Counter
1515
{
1616
mutating
1717
func callAsFunction() -> Int
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import SymbolGraphs
2+
import Symbols
3+
import Unidoc
4+
5+
extension Unidoc.LinkerTables
6+
{
7+
struct ModuleContext
8+
{
9+
let culture:SymbolGraph.Culture
10+
let symbol:Symbol.Module
11+
let id:Unidoc.Scalar
12+
}
13+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import Symbols
2+
import Unidoc
3+
4+
extension Unidoc.LinkerTables
5+
{
6+
struct ModuleNamespace
7+
{
8+
let culture:Unidoc.Scalar
9+
let colony:Unidoc.Scalar
10+
let symbol:Symbol.Module
11+
}
12+
}
13+
extension Unidoc.LinkerTables.ModuleNamespace
14+
{
15+
var cultureOffset:Int { .init(self.culture.citizen) }
16+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import SymbolGraphs
2+
import Symbols
3+
import Unidoc
4+
import UnidocRecords
5+
6+
extension Unidoc.LinkerTables
7+
{
8+
struct ModuleView
9+
{
10+
let namespaces:[Symbol.Module]
11+
let cultures:[SymbolGraph.Culture]
12+
let edition:Unidoc.Edition
13+
14+
init(namespaces:[Symbol.Module],
15+
cultures:[SymbolGraph.Culture],
16+
edition:Unidoc.Edition)
17+
{
18+
self.namespaces = namespaces
19+
self.cultures = cultures
20+
self.edition = edition
21+
}
22+
}
23+
}
24+
extension Unidoc.LinkerTables.ModuleView:RandomAccessCollection
25+
{
26+
var startIndex:Int { self.cultures.startIndex }
27+
var endIndex:Int { self.cultures.endIndex }
28+
29+
subscript(culture:Int) -> Unidoc.LinkerTables.ModuleContext
30+
{
31+
.init(culture: self.cultures[culture],
32+
symbol: self.namespaces[culture],
33+
id: self.edition + culture)
34+
}
35+
}

Sources/UnidocLinker/Sema/Unidoc.Linker.Tables.Next.swift renamed to Sources/UnidocLinker/Sema/Unidoc.LinkerTables.Next.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import UnidocRecords
22

3-
extension Unidoc.Linker.Tables
3+
extension Unidoc.LinkerTables
44
{
55
/// A type that can generate ``Unidoc.Group`` identifiers.
66
struct Next
@@ -17,7 +17,7 @@ extension Unidoc.Linker.Tables
1717
}
1818
}
1919
}
20-
extension Unidoc.Linker.Tables.Next
20+
extension Unidoc.LinkerTables.Next
2121
{
2222
mutating
2323
func callAsFunction(_ type:Unidoc.GroupType) -> Unidoc.Group

0 commit comments

Comments
 (0)