Skip to content
This repository was archived by the owner on Jun 1, 2023. It is now read-only.

Bring back links to other symbols in declarations #277

Merged
merged 7 commits into from
Jun 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- Fixed links to type declarations.
#277 by @Lukas-Stuehrk.
- Fixed bug that caused operator implementations to appear in the documentation
although they should be omitted because of their lower access level.
#264 by @Lukas-Stuehrk
Expand Down
6 changes: 3 additions & 3 deletions Sources/swift-doc/Subcommands/Generate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ extension SwiftDoc {
case is Class, is Enumeration, is Structure, is Protocol:
pages[route(for: symbol)] = TypePage(module: module, symbol: symbol, baseURL: baseURL, includingChildren: symbolFilter)
case let `typealias` as Typealias:
pages[route(for: `typealias`.name)] = TypealiasPage(module: module, symbol: symbol, baseURL: baseURL)
pages[route(for: `typealias`.name)] = TypealiasPage(module: module, symbol: symbol, baseURL: baseURL, includingOtherSymbols: symbolFilter)
case is Operator:
let operatorPage = OperatorPage(module: module, symbol: symbol, baseURL: baseURL, includingImplementations: symbolFilter)
if !operatorPage.implementations.isEmpty {
Expand All @@ -97,11 +97,11 @@ extension SwiftDoc {
symbolsByExternalType[extensionDeclaration.extendedType, default: []] += [symbol]
}
for (typeName, symbols) in symbolsByExternalType {
pages[route(for: typeName)] = ExternalTypePage(module: module, externalType: typeName, symbols: symbols, baseURL: baseURL)
pages[route(for: typeName)] = ExternalTypePage(module: module, externalType: typeName, symbols: symbols, baseURL: baseURL, includingOtherSymbols: symbolFilter)
}

for (name, symbols) in globals {
pages[route(for: name)] = GlobalPage(module: module, name: name, symbols: symbols, baseURL: baseURL)
pages[route(for: name)] = GlobalPage(module: module, name: name, symbols: symbols, baseURL: baseURL, includingOtherSymbols: symbolFilter)
}

guard !pages.isEmpty else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ struct Declaration: Component {
var symbol: Symbol
var module: Module
let baseURL: String
let symbolFilter: (Symbol) -> Bool

init(of symbol: Symbol, in module: Module, baseURL: String) {
init(of symbol: Symbol, in module: Module, baseURL: String, includingOtherSymbols symbolFilter: @escaping (Symbol) -> Bool) {
self.symbol = symbol
self.module = module
self.baseURL = baseURL
self.symbolFilter = symbolFilter
}

// MARK: - Component
Expand All @@ -30,9 +32,11 @@ struct Declaration: Component {
var html: HypertextLiteral.HTML {
let code = symbol.declaration.map { $0.html }.joined()

let html = linkTypes(of: code, for: symbol, in: module, with: baseURL, includingSymbols: symbolFilter)

return #"""
<div class="declaration">
<pre class="highlight"><code>\#(unsafeUnescaped: code)</code></pre>
<pre class="highlight"><code>\#(unsafeUnescaped: html)</code></pre>
</div>
"""#
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ struct Documentation: Component {
var symbol: Symbol
var module: Module
let baseURL: String
let symbolFilter: (Symbol) -> Bool

init(for symbol: Symbol, in module: Module, baseURL: String) {
init(for symbol: Symbol, in module: Module, baseURL: String, includingOtherSymbols symbolFilter: @escaping (Symbol) -> Bool) {
self.symbol = symbol
self.module = module
self.baseURL = baseURL
self.symbolFilter = symbolFilter
}

// MARK: - Component
Expand All @@ -39,7 +41,7 @@ struct Documentation: Component {
Fragment { "\(documentation.summary!.description.escapingEmojiShortcodes)" }
}

Declaration(of: symbol, in: module, baseURL: baseURL)
Declaration(of: symbol, in: module, baseURL: baseURL, includingOtherSymbols: symbolFilter)

ForEach(in: documentation.discussionParts) { part in
DiscussionPart(part, for: symbol, in: module, baseURL: baseURL)
Expand Down Expand Up @@ -85,7 +87,7 @@ struct Documentation: Component {

var fragments: [HypertextLiteralConvertible] = []

fragments.append(Declaration(of: symbol, in: module, baseURL: baseURL))
fragments.append(Declaration(of: symbol, in: module, baseURL: baseURL, includingOtherSymbols: symbolFilter))

if let summary = documentation.summary {
fragments.append(#"""
Expand Down
14 changes: 9 additions & 5 deletions Sources/swift-doc/Supporting Types/Components/Members.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ struct Members: Component {
var module: Module
let baseURL: String

let symbolFilter: (Symbol) -> Bool

var members: [Symbol]

var typealiases: [Symbol]
Expand All @@ -20,11 +22,13 @@ struct Members: Component {
var genericallyConstrainedMembers: [[GenericRequirement] : [Symbol]]
let defaultImplementations: [Symbol]

init(of symbol: Symbol, in module: Module, baseURL: String, symbolFilter: (Symbol) -> Bool) {
init(of symbol: Symbol, in module: Module, baseURL: String, symbolFilter: @escaping (Symbol) -> Bool) {
self.symbol = symbol
self.module = module
self.baseURL = baseURL

self.symbolFilter = symbolFilter

self.members = module.interface.members(of: symbol)
.filter { $0.extension?.genericRequirements.isEmpty != false }
.filter(symbolFilter)
Expand Down Expand Up @@ -66,7 +70,7 @@ struct Members: Component {
Heading {
Code { member.name }
}
Documentation(for: member, in: module, baseURL: baseURL)
Documentation(for: member, in: module, baseURL: baseURL, includingOtherSymbols: symbolFilter)
}
}
}
Expand All @@ -83,7 +87,7 @@ struct Members: Component {
Section {
ForEach(in: members) { member in
Heading { member.name }
Documentation(for: member, in: module, baseURL: baseURL)
Documentation(for: member, in: module, baseURL: baseURL, includingOtherSymbols: symbolFilter)
}
}
}
Expand All @@ -109,7 +113,7 @@ struct Members: Component {
<h3>
<code><a href=\#("#\(id)")>\#(softbreak(member.name))</a></code>
</h3>
\#(Documentation(for: member, in: module, baseURL: baseURL).html)
\#(Documentation(for: member, in: module, baseURL: baseURL, includingOtherSymbols: symbolFilter).html)
</div>
"""#
})
Expand All @@ -129,7 +133,7 @@ struct Members: Component {
\#(members.map { member -> HypertextLiteral.HTML in
#"""
<h4>\#(softbreak(member.name))</h4>
\#(Documentation(for: member, in: module, baseURL: baseURL).html)
\#(Documentation(for: member, in: module, baseURL: baseURL, includingOtherSymbols: symbolFilter).html)
"""#
})
</section>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ struct OperatorImplementations: Component {
var module: Module
let baseURL: String

let symbolFilter: (Symbol) -> Bool

var implementations: [Symbol]

init(of symbol: Symbol, in module: Module, baseURL: String, implementations: [Symbol]) {
init(of symbol: Symbol, in module: Module, baseURL: String, implementations: [Symbol], includingOtherSymbols symbolFilter: @escaping (Symbol) -> Bool) {
self.symbol = symbol
self.module = module
self.baseURL = baseURL
self.implementations = implementations
self.symbolFilter = symbolFilter
}


Expand All @@ -29,7 +32,7 @@ struct OperatorImplementations: Component {
Section {
Heading { implementation.name }

Documentation(for: implementation, in: module, baseURL: baseURL)
Documentation(for: implementation, in: module, baseURL: baseURL, includingOtherSymbols: symbolFilter)
}
}
}
Expand Down Expand Up @@ -77,7 +80,7 @@ struct OperatorImplementations: Component {
<a href=\#("#\(id)")>\#(heading)
\#(unsafeUnescaped: function.genericWhereClause.map({ #"<small>\#($0.escaped)</small>"# }) ?? "")</a>
</h3>
\#(Documentation(for: implementation, in: module, baseURL: baseURL).html)
\#(Documentation(for: implementation, in: module, baseURL: baseURL, includingOtherSymbols: symbolFilter).html)
</div>
"""#
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ struct Requirements: Component {
var symbol: Symbol
var module: Module
let baseURL: String
let symbolFilter: (Symbol) -> Bool

init(of symbol: Symbol, in module: Module, baseURL: String) {
init(of symbol: Symbol, in module: Module, baseURL: String, includingOtherSymbols symbolFilter: @escaping (Symbol) -> Bool) {
self.symbol = symbol
self.module = module
self.baseURL = baseURL
self.symbolFilter = symbolFilter
}

var sections: [(title: String, requirements: [Symbol])] {
Expand All @@ -34,7 +36,7 @@ struct Requirements: Component {
Section {
ForEach(in: section.requirements) { requirement in
Heading { requirement.name.escapingEmojiShortcodes }
Documentation(for: requirement, in: module, baseURL: baseURL)
Documentation(for: requirement, in: module, baseURL: baseURL, includingOtherSymbols: symbolFilter)
}
}
}
Expand All @@ -57,7 +59,7 @@ struct Requirements: Component {
<h3>
<code>\#(softbreak(member.name))</code>
</h3>
\#(Documentation(for: member, in: module, baseURL: baseURL).html)
\#(Documentation(for: member, in: module, baseURL: baseURL, includingOtherSymbols: symbolFilter).html)
</div>
"""#
})
Expand Down
23 changes: 23 additions & 0 deletions Sources/swift-doc/Supporting Types/Helpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,23 @@ public func linkCodeElements(of html: String, for symbol: Symbol, in module: Mod
return document.root?.description ?? html
}

public func linkTypes(of html: String, for symbol: Symbol, in module: Module, with baseURL: String, includingSymbols symbolFilter: (Symbol) -> Bool) -> String {
let document = try! Document(string: html.description)!
for element in document.search(xpath: "//span[contains(@class,'type')]") {
guard let name = element.content else { continue }

let candidates = module.interface.symbols(named: "\(symbol.name).\(name)", resolvingTypealiases: true).nonEmpty ?? module.interface.symbols(named: name, resolvingTypealiases: true)
if let candidate = candidates.filter(symbolFilter).filter({ $0 != symbol }).first
{
let a = Element(name: "a")
a["href"] = path(for: candidate, with: baseURL)
element.wrap(inside: a)
}
}

return document.root?.description ?? html
}

public func sidebar(for html: String) -> String {
let toc = Element(name: "ol")

Expand Down Expand Up @@ -78,3 +95,9 @@ public func softbreak(_ string: String) -> String {

return regex.stringByReplacingMatches(in: string, options: [], range: NSRange(string.startIndex..<string.endIndex, in: string), withTemplate: "$1\u{200B}$2")
}

fileprivate extension Collection {
var nonEmpty: Self? {
return isEmpty ? nil : self
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ struct ExternalTypePage: Page {
let properties: [Symbol]
let methods: [Symbol]

init(module: Module, externalType: String, symbols: [Symbol], baseURL: String) {
let symbolFilter: (Symbol) -> Bool

init(module: Module, externalType: String, symbols: [Symbol], baseURL: String, includingOtherSymbols symbolFilter: @escaping (Symbol) -> Bool) {
self.module = module
self.externalType = externalType
self.baseURL = baseURL
self.symbolFilter = symbolFilter

self.typealiases = symbols.filter { $0.api is Typealias }
self.initializers = symbols.filter { $0.api is Initializer }
Expand Down Expand Up @@ -49,7 +52,7 @@ struct ExternalTypePage: Page {
Heading {
Code { member.name }
}
Documentation(for: member, in: module, baseURL: baseURL)
Documentation(for: member, in: module, baseURL: baseURL, includingOtherSymbols: symbolFilter)
}
}
}
Expand Down Expand Up @@ -77,7 +80,7 @@ struct ExternalTypePage: Page {
<h3>
<code><a href=\#("#\(id)")>\#(softbreak(member.name))</a></code>
</h3>
\#(Documentation(for: member, in: module, baseURL: baseURL).html)
\#(Documentation(for: member, in: module, baseURL: baseURL, includingOtherSymbols: symbolFilter).html)
</div>
"""#
})
Expand Down
8 changes: 5 additions & 3 deletions Sources/swift-doc/Supporting Types/Pages/GlobalPage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ struct GlobalPage: Page {
let name: String
let symbols: [Symbol]
let baseURL: String
let symbolFilter: (Symbol) -> Bool

init(module: Module, name: String, symbols: [Symbol], baseURL: String) {
init(module: Module, name: String, symbols: [Symbol], baseURL: String, includingOtherSymbols symbolFilter: @escaping (Symbol) -> Bool) {
self.module = module
self.name = name
self.symbols = symbols
self.baseURL = baseURL
self.symbolFilter = symbolFilter
}

// MARK: - Page
Expand All @@ -26,7 +28,7 @@ struct GlobalPage: Page {
return Document {
ForEach(in: symbols) { symbol in
Heading { symbol.id.description }
Documentation(for: symbol, in: module, baseURL: baseURL)
Documentation(for: symbol, in: module, baseURL: baseURL, includingOtherSymbols: symbolFilter)
}
}
}
Expand All @@ -48,7 +50,7 @@ struct GlobalPage: Page {
</h1>

\#(symbols.map { symbol in
Documentation(for: symbol, in: module, baseURL: baseURL).html
Documentation(for: symbol, in: module, baseURL: baseURL, includingOtherSymbols: symbolFilter).html
})
"""#
}
Expand Down
10 changes: 6 additions & 4 deletions Sources/swift-doc/Supporting Types/Pages/OperatorPage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ struct OperatorPage: Page {
let symbol: Symbol
let implementations: [Symbol]
let baseURL: String
let symbolFilter: (Symbol) -> Bool

init(module: Module, symbol: Symbol, baseURL: String, includingImplementations symbolFilter: (Symbol) -> Bool) {
init(module: Module, symbol: Symbol, baseURL: String, includingImplementations symbolFilter: @escaping (Symbol) -> Bool) {
precondition(symbol.api is Operator)
self.module = module
self.symbol = symbol
self.implementations = module.interface.functionsByOperator[symbol]?.filter(symbolFilter).sorted() ?? []
self.baseURL = baseURL
self.symbolFilter = symbolFilter
}

// MARK: - Page
Expand All @@ -27,7 +29,7 @@ struct OperatorPage: Page {
return CommonMark.Document {
Heading { symbol.id.description }

Documentation(for: symbol, in: module, baseURL: baseURL)
Documentation(for: symbol, in: module, baseURL: baseURL, includingOtherSymbols: symbolFilter)
}
}

Expand All @@ -38,8 +40,8 @@ struct OperatorPage: Page {
<code class="name">\#(softbreak(symbol.id.description))</code>
</h1>

\#(Documentation(for: symbol, in: module, baseURL: baseURL).html)
\#(OperatorImplementations(of: symbol, in: module, baseURL: baseURL, implementations: implementations).html)
\#(Documentation(for: symbol, in: module, baseURL: baseURL, includingOtherSymbols: symbolFilter).html)
\#(OperatorImplementations(of: symbol, in: module, baseURL: baseURL, implementations: implementations, includingOtherSymbols: symbolFilter).html)
"""#
}
}
Expand Down
8 changes: 4 additions & 4 deletions Sources/swift-doc/Supporting Types/Pages/TypePage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ struct TypePage: Page {
return CommonMark.Document {
Heading { symbol.id.description }

Documentation(for: symbol, in: module, baseURL: baseURL)
Documentation(for: symbol, in: module, baseURL: baseURL, includingOtherSymbols: symbolFilter)
Relationships(of: symbol, in: module, baseURL: baseURL, includingChildren: symbolFilter)
Members(of: symbol, in: module, baseURL: baseURL, symbolFilter: symbolFilter)
Requirements(of: symbol, in: module, baseURL: baseURL)
Requirements(of: symbol, in: module, baseURL: baseURL, includingOtherSymbols: symbolFilter)
}
}

Expand All @@ -41,10 +41,10 @@ struct TypePage: Page {
<code class="name">\#(softbreak(symbol.id.description))</code>
</h1>

\#(Documentation(for: symbol, in: module, baseURL: baseURL).html)
\#(Documentation(for: symbol, in: module, baseURL: baseURL, includingOtherSymbols: symbolFilter).html)
\#(Relationships(of: symbol, in: module, baseURL: baseURL, includingChildren: symbolFilter).html)
\#(Members(of: symbol, in: module, baseURL: baseURL, symbolFilter: symbolFilter).html)
\#(Requirements(of: symbol, in: module, baseURL: baseURL).html)
\#(Requirements(of: symbol, in: module, baseURL: baseURL, includingOtherSymbols: symbolFilter).html)
"""#
}
}
Loading