Skip to content

Commit 784ba58

Browse files
add conformance availability data to overloaded declarations (#1009)
rdar://122589806
1 parent 065a609 commit 784ba58

File tree

5 files changed

+354
-7
lines changed

5 files changed

+354
-7
lines changed

Sources/SwiftDocC/Model/Rendering/RenderSectionTranslator/DeclarationsSectionTranslator.swift

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ import SymbolKit
1313

1414
typealias OverloadDeclaration = (
1515
declaration: [SymbolGraph.Symbol.DeclarationFragments.Fragment],
16-
reference: ResolvedTopicReference
16+
reference: ResolvedTopicReference,
17+
conformance: ConformanceSection?
1718
)
1819

1920
/// Translates a symbol's declaration into a render node's Declarations section.
@@ -141,7 +142,9 @@ struct DeclarationsSectionTranslator: RenderSectionTranslator {
141142
commonFragments: commonFragments)
142143
otherDeclarations.append(.init(
143144
tokens: translatedDeclaration,
144-
identifier: overloadDeclaration.reference.absoluteString))
145+
identifier: overloadDeclaration.reference.absoluteString,
146+
conformance: overloadDeclaration.conformance
147+
))
145148

146149
// Add a topic reference to the overload
147150
renderNodeTranslator.collectedTopicReferences.append(
@@ -160,6 +163,8 @@ struct DeclarationsSectionTranslator: RenderSectionTranslator {
160163
return nil
161164
}
162165

166+
let conformance = renderNodeTranslator.contentRenderer.conformanceSectionFor(overloadReference, collectedConstraints: [:])
167+
163168
let declarationFragments = overload.declarationVariants[trait]?.values
164169
.first?
165170
.declarationFragments
@@ -168,7 +173,7 @@ struct DeclarationsSectionTranslator: RenderSectionTranslator {
168173
"Overloaded symbols must have declaration fragments."
169174
)
170175
return declarationFragments.map({
171-
(declaration: $0, reference: overloadReference)
176+
(declaration: $0, reference: overloadReference, conformance: conformance)
172177
})
173178
}
174179

@@ -204,13 +209,13 @@ struct DeclarationsSectionTranslator: RenderSectionTranslator {
204209
// Pre-process the declarations by splitting text fragments apart to increase legibility
205210
let mainDeclaration = declaration.declarationFragments.flatMap(preProcessFragment(_:))
206211
let processedOverloadDeclarations = overloadDeclarations.map({
207-
OverloadDeclaration($0.declaration.flatMap(preProcessFragment(_:)), $0.reference)
212+
OverloadDeclaration($0.declaration.flatMap(preProcessFragment(_:)), $0.reference, $0.conformance)
208213
})
209214

210215
// Collect the "common fragments" so we can highlight the ones that are different
211216
// in each declaration
212217
let commonFragments = commonFragments(
213-
for: (mainDeclaration, renderNode.identifier),
218+
for: (mainDeclaration, renderNode.identifier, nil),
214219
overloadDeclarations: processedOverloadDeclarations)
215220

216221
renderedTokens = translateDeclaration(

Sources/SwiftDocC/Model/Rendering/Symbol/DeclarationsRenderSection.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,11 +184,14 @@ public struct DeclarationRenderSection: Codable, Equatable {
184184

185185
/// The symbol's identifier.
186186
public let identifier: String
187-
187+
188+
public let conformance: ConformanceSection?
189+
188190
/// Creates a new other declaration for a symbol that is connected to this one, e.g. an overload.
189-
public init(tokens: [Token], identifier: String) {
191+
public init(tokens: [Token], identifier: String, conformance: ConformanceSection? = nil) {
190192
self.tokens = tokens
191193
self.identifier = identifier
194+
self.conformance = conformance
192195
}
193196
}
194197
/// The displayable declarations for this symbol's overloads.

Sources/SwiftDocC/SwiftDocC.docc/Resources/RenderNode.spec.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2591,6 +2591,9 @@
25912591
},
25922592
"identifier": {
25932593
"type": "string"
2594+
},
2595+
"conformance": {
2596+
"$ref" : "#/components/schemas/ConformanceSection"
25942597
}
25952598
}
25962599
},

Tests/SwiftDocCTests/Rendering/DeclarationsRenderSectionTests.swift

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,50 @@ class DeclarationsRenderSectionTests: XCTestCase {
356356
XCTAssert(declarations.tokens.allSatisfy({ $0.highlight == nil }))
357357
}
358358
}
359+
360+
func testOverloadConformanceDataIsSavedWithDeclarations() throws {
361+
enableFeatureFlag(\.isExperimentalOverloadedSymbolPresentationEnabled)
362+
363+
let symbolGraphFile = Bundle.module.url(
364+
forResource: "ConformanceOverloads",
365+
withExtension: "symbols.json",
366+
subdirectory: "Test Resources"
367+
)!
368+
369+
let tempURL = try createTempFolder(content: [
370+
Folder(name: "unit-test.docc", content: [
371+
InfoPlist(displayName: "ConformanceOverloads", identifier: "com.test.example"),
372+
CopyOfFile(original: symbolGraphFile),
373+
])
374+
])
375+
376+
let (_, bundle, context) = try loadBundle(from: tempURL)
377+
378+
// MyClass<T>
379+
// - myFunc() where T: Equatable
380+
// - myFunc() where T: Hashable // <- overload group
381+
let reference = ResolvedTopicReference(
382+
bundleIdentifier: bundle.identifier,
383+
path: "/documentation/ConformanceOverloads/MyClass/myFunc()",
384+
sourceLanguage: .swift
385+
)
386+
let symbol = try XCTUnwrap(context.entity(with: reference).semantic as? Symbol)
387+
var translator = RenderNodeTranslator(context: context, bundle: bundle, identifier: reference)
388+
let renderNode = try XCTUnwrap(translator.visitSymbol(symbol) as? RenderNode)
389+
let declarationsSection = try XCTUnwrap(renderNode.primaryContentSections.compactMap({ $0 as? DeclarationsRenderSection }).first)
390+
XCTAssertEqual(declarationsSection.declarations.count, 1)
391+
let declarations = try XCTUnwrap(declarationsSection.declarations.first)
392+
393+
let otherDeclarations = try XCTUnwrap(declarations.otherDeclarations)
394+
XCTAssertEqual(otherDeclarations.declarations.count, 1)
395+
396+
XCTAssertEqual(otherDeclarations.declarations.first?.conformance?.constraints, [
397+
.codeVoice(code: "T"),
398+
.text(" conforms to "),
399+
.codeVoice(code: "Equatable"),
400+
.text("."),
401+
])
402+
}
359403
}
360404

361405
/// Render a list of declaration tokens as a plain-text decoration and as a plain-text rendering of which characters are highlighted.

0 commit comments

Comments
 (0)