Skip to content

Commit 5caa44e

Browse files
authored
Add optionalRequirementOf builder (#280)
* Add optionalRequirementOf builder * Update doc and refactor code to fix review comment
1 parent 321dbcc commit 5caa44e

File tree

3 files changed

+56
-26
lines changed

3 files changed

+56
-26
lines changed

Sources/SwiftDocC/Infrastructure/DocumentationContext.swift

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1568,28 +1568,24 @@ public class DocumentationContext: DocumentationContextDataProviderDelegate {
15681568
/// - ``SymbolGraphRelationshipsBuilder``
15691569
func buildRelationships(_ relationships: Set<SymbolGraph.Relationship>, bundle: DocumentationBundle, engine: DiagnosticEngine) {
15701570
for edge in relationships {
1571-
// Build conformant type <-> protocol relationships
1572-
if case .conformsTo = edge.kind {
1571+
switch edge.kind {
1572+
case .conformsTo:
1573+
// Build conformant type <-> protocol relationships
15731574
SymbolGraphRelationshipsBuilder.addConformanceRelationship(edge: edge, in: bundle, symbolIndex: &symbolIndex, engine: diagnosticEngine)
1574-
continue
1575-
}
1576-
1577-
// Build implementation <-> protocol requirement relationships.
1578-
if case .defaultImplementationOf = edge.kind {
1575+
case .defaultImplementationOf:
1576+
// Build implementation <-> protocol requirement relationships.
15791577
SymbolGraphRelationshipsBuilder.addImplementationRelationship(edge: edge, in: bundle, context: self, symbolIndex: &symbolIndex, engine: diagnosticEngine)
1580-
continue
1581-
}
1582-
1583-
// Build ancestor <-> offspring relationships.
1584-
if case .inheritsFrom = edge.kind {
1578+
case .inheritsFrom:
1579+
// Build ancestor <-> offspring relationships.
15851580
SymbolGraphRelationshipsBuilder.addInheritanceRelationship(edge: edge, in: bundle, symbolIndex: &symbolIndex, engine: diagnosticEngine)
1586-
continue
1587-
}
1588-
1589-
// Build required member -> protocol relationships.
1590-
if case .requirementOf = edge.kind {
1581+
case .requirementOf:
1582+
// Build required member -> protocol relationships.
15911583
SymbolGraphRelationshipsBuilder.addRequirementRelationship(edge: edge, in: bundle, symbolIndex: &symbolIndex, engine: diagnosticEngine)
1592-
continue
1584+
case .optionalRequirementOf:
1585+
// Build optional required member -> protocol relationships.
1586+
SymbolGraphRelationshipsBuilder.addOptionalRequirementRelationship(edge: edge, in: bundle, symbolIndex: &symbolIndex, engine: diagnosticEngine)
1587+
default:
1588+
break
15931589
}
15941590
}
15951591
}

Sources/SwiftDocC/Infrastructure/Symbol Graph/SymbolGraphRelationshipsBuilder.swift

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift.org open source project
33

4-
Copyright (c) 2021 Apple Inc. and the Swift project authors
4+
Copyright (c) 2021-2022 Apple Inc. and the Swift project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See https://swift.org/LICENSE.txt for license information
@@ -232,22 +232,42 @@ struct SymbolGraphRelationshipsBuilder {
232232
}
233233
}
234234

235-
/// Adds a relationship from a type member to a protocol requirement.
235+
/// Adds a required relationship from a type member to a protocol requirement.
236236
/// - Parameters:
237237
/// - edge: A symbol graph relationship with a source and a target.
238238
/// - bundle: A documentation bundle.
239239
/// - symbolIndex: A symbol lookup map by precise identifier.
240240
/// - engine: A diagnostic collecting engine.
241241
static func addRequirementRelationship(edge: SymbolGraph.Relationship, in bundle: DocumentationBundle, symbolIndex: inout [String: DocumentationNode], engine: DiagnosticEngine) {
242+
addProtocolRelationship(edge: edge, in: bundle, symbolIndex: &symbolIndex, engine: engine, required: true)
243+
}
244+
245+
/// Adds an optional relationship from a type member to a protocol requirement.
246+
/// - Parameters:
247+
/// - edge: A symbol graph relationship with a source and a target.
248+
/// - bundle: A documentation bundle.
249+
/// - symbolIndex: A symbol lookup map by precise identifier.
250+
/// - engine: A diagnostic collecting engine.
251+
static func addOptionalRequirementRelationship(edge: SymbolGraph.Relationship, in bundle: DocumentationBundle, symbolIndex: inout [String: DocumentationNode], engine: DiagnosticEngine) {
252+
addProtocolRelationship(edge: edge, in: bundle, symbolIndex: &symbolIndex, engine: engine, required: false)
253+
}
254+
255+
/// Adds a relationship from a type member to a protocol requirement.
256+
/// - Parameters:
257+
/// - edge: A symbol graph relationship with a source and a target.
258+
/// - bundle: A documentation bundle.
259+
/// - symbolIndex: A symbol lookup map by precise identifier.
260+
/// - engine: A diagnostic collecting engine.
261+
/// - required: A bool value indicating whether the protocol requirement is required or optional
262+
private static func addProtocolRelationship(edge: SymbolGraph.Relationship, in bundle: DocumentationBundle, symbolIndex: inout [String: DocumentationNode], engine: DiagnosticEngine, required: Bool) {
242263
// Resolve source symbol
243264
guard let requiredNode = symbolIndex[edge.source],
244265
let requiredSymbol = requiredNode.semantic as? Symbol else {
245266
// The source node for requirement relationship not found.
246267
engine.emit(NodeProblem.notFound(edge.source))
247268
return
248269
}
249-
250-
requiredSymbol.isRequired = true
270+
requiredSymbol.isRequired = required
251271
}
252272

253273
/// Sets a node in the context as an inherited symbol if the origin symbol is provided in the given relationship.

Tests/SwiftDocCTests/Infrastructure/SymbolGraph/SymbolGraphRelationshipsBuilderTests.swift

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift.org open source project
33

4-
Copyright (c) 2021 Apple Inc. and the Swift project authors
4+
Copyright (c) 2021-2022 Apple Inc. and the Swift project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See https://swift.org/LICENSE.txt for license information
@@ -24,8 +24,8 @@ class SymbolGraphRelationshipsBuilderTests: XCTestCase {
2424

2525
let moduleRef = ResolvedTopicReference(bundleIdentifier: bundle.identifier, path: "/documentation/MyKit", sourceLanguage: .swift)
2626

27-
let sourceSymbol = SymbolGraph.Symbol(identifier: sourceIdentifier, names: SymbolGraph.Symbol.Names(title: "A", navigator: nil, subHeading: nil, prose: nil), pathComponents: ["MyKit", "A"], docComment: nil, accessLevel: .init(rawValue: "public"), kind: SymbolGraph.Symbol.Kind(parsedIdentifier: .class, displayName: "Class"), mixins: [:])
28-
let targetSymbol = SymbolGraph.Symbol(identifier: targetIdentifier, names: SymbolGraph.Symbol.Names(title: "B", navigator: nil, subHeading: nil, prose: nil), pathComponents: ["MyKit", "B"], docComment: nil, accessLevel: .init(rawValue: "public"), kind: SymbolGraph.Symbol.Kind(parsedIdentifier: .class, displayName: "Protocol"), mixins: [:])
27+
let sourceSymbol = SymbolGraph.Symbol(identifier: sourceIdentifier, names: SymbolGraph.Symbol.Names(title: "A", navigator: nil, subHeading: nil, prose: nil), pathComponents: ["MyKit", "A"], docComment: nil, accessLevel: .init(rawValue: "public"), kind: sourceType, mixins: [:])
28+
let targetSymbol = SymbolGraph.Symbol(identifier: targetIdentifier, names: SymbolGraph.Symbol.Names(title: "B", navigator: nil, subHeading: nil, prose: nil), pathComponents: ["MyKit", "B"], docComment: nil, accessLevel: .init(rawValue: "public"), kind: targetType, mixins: [:])
2929

3030
let engine = DiagnosticEngine()
3131
symbolIndex["A"] = DocumentationNode(reference: sourceRef, symbol: sourceSymbol, platformName: "macOS", moduleReference: moduleRef, article: nil, engine: engine)
@@ -145,12 +145,26 @@ class SymbolGraphRelationshipsBuilderTests: XCTestCase {
145145
var symbolIndex = [String: DocumentationNode]()
146146
let engine = DiagnosticEngine()
147147

148-
let edge = createSymbols(in: &symbolIndex, bundle: bundle, sourceType: .init(parsedIdentifier: .class, displayName: "Class"), targetType: .init(parsedIdentifier: .protocol, displayName: "Protocol"))
148+
let edge = createSymbols(in: &symbolIndex, bundle: bundle, sourceType: .init(parsedIdentifier: .method, displayName: "Method"), targetType: .init(parsedIdentifier: .protocol, displayName: "Protocol"))
149149

150150
// Adding the relationship
151151
SymbolGraphRelationshipsBuilder.addRequirementRelationship(edge: edge, in: bundle, symbolIndex: &symbolIndex, engine: engine)
152152

153153
// Test default implementation was added
154154
XCTAssertTrue((symbolIndex["A"]!.semantic as! Symbol).isRequired)
155155
}
156+
157+
func testOptionalRequirementRelationship() throws {
158+
let bundle = try testBundle(named: "TestBundle")
159+
var symbolIndex = [String: DocumentationNode]()
160+
let engine = DiagnosticEngine()
161+
162+
let edge = createSymbols(in: &symbolIndex, bundle: bundle, sourceType: .init(parsedIdentifier: .method, displayName: "Method"), targetType: .init(parsedIdentifier: .protocol, displayName: "Protocol"))
163+
164+
// Adding the relationship
165+
SymbolGraphRelationshipsBuilder.addOptionalRequirementRelationship(edge: edge, in: bundle, symbolIndex: &symbolIndex, engine: engine)
166+
167+
// Test default implementation was added
168+
XCTAssertFalse((symbolIndex["A"]!.semantic as! Symbol).isRequired)
169+
}
156170
}

0 commit comments

Comments
 (0)