Skip to content

Commit 29810ad

Browse files
authored
Merge pull request #305 from tayloraswift/abi-compatibility-metric
compute and display ABI compatibility metric
2 parents 01fba07 + a30a672 commit 29810ad

19 files changed

+225
-166
lines changed

Assets/css/Main.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/css/Main.css.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.resolved

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Sources/UnidocDB/Unidoc.DB.swift

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -729,13 +729,8 @@ extension Unidoc.DB
729729
let dependencies:[Unidoc.VolumeMetadata.Dependency] = linker.dependencies(
730730
pinned: snapshot.pins)
731731

732-
let mesh:Unidoc.Linker.Mesh = linker.link(around: .init(id: snapshot.id.global,
733-
snapshot: .init(abi: snapshot.metadata.abi,
734-
latestManifest: snapshot.metadata.tools,
735-
extraManifests: snapshot.metadata.manifests,
736-
requirements: snapshot.metadata.requirements,
737-
commit: snapshot.metadata.commit?.sha1),
738-
packages: snapshot.pins.compactMap(\.?.package)))
732+
let mesh:Unidoc.Linker.Mesh = linker.link(primary: snapshot.metadata,
733+
pins: snapshot.pins)
739734

740735
linker.status().emit(colors: .enabled)
741736

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import Symbols
22
import Unidoc
33

4-
/// A combined mapping of symbols to global scalars across all upstream dependencies.
5-
/// Within a build tree, we assume module names are unique, which implies that symbol
6-
/// manglings should never collide.
74
extension Unidoc.Linker
85
{
6+
/// A combined mapping of symbols to global scalars across all upstream dependencies.
7+
/// Within a build tree, we assume module names are unique, which implies that symbol
8+
/// manglings should never collide.
99
struct UpstreamScalars
1010
{
1111
var cultures:[Symbol.Module: Unidoc.Scalar]

Sources/UnidocLinker/Unidoc.Linker.swift

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,11 @@ import Unidoc
88
import SourceDiagnostics
99
import UnidocRecords
1010

11-
@available(*, deprecated, renamed: "Unidoc.Linker")
12-
public
13-
typealias DynamicContext = Unidoc.Linker
14-
15-
@available(*, deprecated, renamed: "Unidoc.Linker")
16-
public
17-
typealias DynamicLinker = Unidoc.Linker
18-
19-
2011
extension Unidoc
2112
{
22-
// https://github.com/apple/swift/issues/72136
13+
/// A dynamic symbol graph linker.
2314
@frozen public
24-
struct Linker//:~Copyable
15+
struct Linker//:~Copyable https://github.com/apple/swift/issues/72136
2516
{
2617
var diagnostics:Diagnostics<Unidoc.Symbolicator>
2718

@@ -60,9 +51,6 @@ extension Unidoc.Linker
6051
linking primary:consuming SymbolGraphObject<Unidoc.Edition>,
6152
against others:borrowing [SymbolGraphObject<Unidoc.Edition>])
6253
{
63-
// Build a combined lookup table mapping upstream symbols to scalars.
64-
// Because module names are unique within a build tree, there should
65-
// be no collisions among mangled symbols.
6654
var upstream:UpstreamScalars = .init()
6755

6856
for other:SymbolGraphObject<Unidoc.Edition> in copy others
@@ -112,8 +100,36 @@ extension Unidoc.Linker
112100
extension Unidoc.Linker
113101
{
114102
public mutating
115-
func link(around landing:consuming Unidoc.LandingVertex) -> Mesh
103+
func link(primary metadata:SymbolGraphMetadata, pins:[Unidoc.Edition?]) -> Mesh
116104
{
105+
let current:Unidoc.Edition = self.current.id
106+
let symbols:(linkable:Int, linked:Int) = self.current.scalars.decls.reduce(into: (0, 0))
107+
{
108+
guard
109+
let id:Unidoc.Scalar = $1
110+
else
111+
{
112+
$0.linkable += 1
113+
return
114+
}
115+
116+
if id.edition != current
117+
{
118+
$0.linkable += 1
119+
$0.linked += 1
120+
}
121+
}
122+
123+
let landingVertex:Unidoc.LandingVertex = .init(id: current.global,
124+
snapshot: .init(abi: metadata.abi,
125+
latestManifest: metadata.tools,
126+
extraManifests: metadata.manifests,
127+
requirements: metadata.requirements,
128+
commit: metadata.commit?.sha1,
129+
symbolsLinkable: symbols.linkable,
130+
symbolsLinked: symbols.linked),
131+
packages: pins.compactMap(\.?.package))
132+
117133
var tables:Tables = .init(context: consume self)
118134

119135
let conformances:Table<Unidoc.Conformers> = tables.linkConformingTypes()
@@ -127,7 +143,7 @@ extension Unidoc.Linker
127143

128144
self = (consume tables).context
129145

130-
return .init(around: landing,
146+
return .init(around: landingVertex,
131147
conformances: conformances,
132148
extensions: extensions,
133149
products: products,

Sources/UnidocRecords/Volumes/Vertices/Unidoc.LandingVertex.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@ import UnidocAPI
44

55
extension Unidoc
66
{
7-
@available(*, deprecated, renamed: "LandingVertex")
8-
public
9-
typealias GlobalVertex = LandingVertex
10-
117
@frozen public
128
struct LandingVertex:Identifiable, Equatable, Sendable
139
{

Sources/UnidocRecords/Volumes/Vertices/Unidoc.SnapshotDetails.swift

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ extension Unidoc
2525
public
2626
var commit:SHA1?
2727

28+
// TODO: deoptionalize
29+
public
30+
var symbolsLinkable:Int?
31+
public
32+
var symbolsLinked:Int?
33+
2834
/// Top-level linker statistics.
2935
public
3036
var census:Unidoc.Census
@@ -37,13 +43,17 @@ extension Unidoc
3743
extraManifests:[MinorVersion],
3844
requirements:[SymbolGraphMetadata.PlatformRequirement],
3945
commit:SHA1?,
46+
symbolsLinkable:Int? = nil,
47+
symbolsLinked:Int? = nil,
4048
census:Unidoc.Census = .init())
4149
{
4250
self.abi = abi
4351
self.latestManifest = latestManifest
4452
self.extraManifests = extraManifests
4553
self.requirements = requirements
4654
self.commit = commit
55+
self.symbolsLinkable = symbolsLinkable
56+
self.symbolsLinked = symbolsLinked
4757
self.census = census
4858
}
4959
}
@@ -58,6 +68,8 @@ extension Unidoc.SnapshotDetails
5868
case extraManifests = "E"
5969
case requirements = "O"
6070
case commit = "H"
71+
case symbolsLinkable = "T"
72+
case symbolsLinked = "L"
6173
case census = "C"
6274
}
6375
}
@@ -71,6 +83,8 @@ extension Unidoc.SnapshotDetails:BSONDocumentEncodable
7183
bson[.extraManifests] = self.extraManifests.isEmpty ? nil : self.extraManifests
7284
bson[.requirements] = self.requirements.isEmpty ? nil : self.requirements
7385
bson[.commit] = self.commit
86+
bson[.symbolsLinkable] = self.symbolsLinkable
87+
bson[.symbolsLinked] = self.symbolsLinked
7488
bson[.census] = self.census
7589
}
7690
}
@@ -84,7 +98,8 @@ extension Unidoc.SnapshotDetails:BSONDocumentDecodable
8498
extraManifests: try bson[.extraManifests]?.decode() ?? [],
8599
requirements: try bson[.requirements]?.decode() ?? [],
86100
commit: try bson[.commit]?.decode(),
87-
// Deprojected when serving a redirect.
88-
census: try bson[.census]?.decode() ?? .init())
101+
symbolsLinkable: try bson[.symbolsLinkable]?.decode(),
102+
symbolsLinked: try bson[.symbolsLinked]?.decode(),
103+
census: try bson[.census].decode())
89104
}
90105
}

Sources/UnidocUI/Endpoints/Docs/Unidoc.DocsEndpoint.PackagePage.Heading.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ extension Unidoc.DocsEndpoint.PackagePage
77
case repository
88
case dependencies
99
case platforms
10-
case snapshot
10+
case linkage
1111
}
1212
}
1313
extension Unidoc.DocsEndpoint.PackagePage.Heading:Identifiable
@@ -19,7 +19,7 @@ extension Unidoc.DocsEndpoint.PackagePage.Heading:Identifiable
1919
case .repository: "ss:package-repository"
2020
case .dependencies: "ss:package-dependencies"
2121
case .platforms: "ss:platform-requirements"
22-
case .snapshot: "ss:snapshot-information"
22+
case .linkage: "ss:snapshot-information"
2323
}
2424
}
2525
}
@@ -32,7 +32,7 @@ extension Unidoc.DocsEndpoint.PackagePage.Heading:HTML.OutputStreamableHeading
3232
case .repository: "Package repository"
3333
case .dependencies: "Package dependencies"
3434
case .platforms: "Platform requirements"
35-
case .snapshot: "Snapshot information"
35+
case .linkage: "Linkage information"
3636
}
3737
}
3838
}

Sources/UnidocUI/Endpoints/Docs/Unidoc.DocsEndpoint.PackagePage.swift

Lines changed: 25 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -116,45 +116,7 @@ extension Unidoc.DocsEndpoint.PackagePage:Unidoc.ApicalPage
116116
if let repo:Unidoc.PackageRepo = self.context.repo
117117
{
118118
$0[.h2] = Heading.repository
119-
120-
$0[.dl]
121-
{
122-
switch repo.origin
123-
{
124-
case .github(let origin):
125-
$0[.dt] = "Registrar"
126-
$0[.dd] = "GitHub"
127-
128-
if let license:Unidoc.PackageLicense = repo.license
129-
{
130-
$0[.dt] = "License"
131-
$0[.dd] = license.name
132-
}
133-
134-
if !repo.topics.isEmpty
135-
{
136-
$0[.dt] = "Keywords"
137-
$0[.dd] = repo.topics.joined(separator: ", ")
138-
}
139-
140-
$0[.dt] = "Owner"
141-
142-
if let account:Unidoc.Account = repo.account
143-
{
144-
$0[.dd]
145-
{
146-
$0[.a]
147-
{
148-
$0.href = "\(Unidoc.UserPropertyEndpoint[account])"
149-
} = origin.owner
150-
}
151-
}
152-
else
153-
{
154-
$0[.dd] = origin.owner
155-
}
156-
}
157-
}
119+
$0[.dl] = Unidoc.PackageRepoDescriptionList.init(repo: repo, mode: .abridged)
158120

159121
$0[.a]
160122
{
@@ -234,16 +196,37 @@ extension Unidoc.DocsEndpoint.PackagePage:Unidoc.ApicalPage
234196
"""
235197
}
236198

237-
$0[.h2] = Heading.snapshot
199+
$0[.h2] = Heading.linkage
238200

239201
$0[.dl]
240202
{
241-
$0[.dt] = "Symbol Graph ABI"
203+
$0[.dt] = "Symbol graph ABI"
242204
$0[.dd] = "\(self.apex.snapshot.abi)"
243205

206+
if let symbolsLinkable:Int = self.apex.snapshot.symbolsLinkable,
207+
let symbolsLinked:Int = self.apex.snapshot.symbolsLinked
208+
{
209+
$0[.dt] = "Symbols linked"
210+
$0[.dd]
211+
{
212+
let percentage:Int = symbolsLinkable != 0
213+
? symbolsLinked * 100 / symbolsLinkable
214+
: 100
215+
216+
$0[.span] = "\(symbolsLinked) / \(symbolsLinkable)"
217+
$0 += " "
218+
$0[.span]
219+
{
220+
$0.class = percentage < 100
221+
? "parenthetical warn"
222+
: "parenthetical"
223+
} = "\(percentage)%"
224+
}
225+
}
226+
244227
if let commit:SHA1 = self.apex.snapshot.commit
245228
{
246-
$0[.dt] = "Git Revision"
229+
$0[.dt] = "Git revision"
247230
$0[.dd]
248231
{
249232
let url:String?

0 commit comments

Comments
 (0)