Skip to content

Commit 2e3e73a

Browse files
Render 'Details' section with property list key information. (#987)
Add 'Details' section to document property list keys. To better support the documentation of property list keys this adds the a new section (Details) that renders the mixin information for the key 'plistDetails'. This is used to better describe property list keys in a human-friendly way. rdar://131373480
1 parent 9a5be7e commit 2e3e73a

File tree

4 files changed

+178
-17
lines changed

4 files changed

+178
-17
lines changed

Package.resolved

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

Sources/SwiftDocC/Model/Rendering/RenderNodeTranslator.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,6 +1363,7 @@ public struct RenderNodeTranslator: SemanticVisitor {
13631363
HTTPParametersSectionTranslator(parameterSource: .header),
13641364
HTTPBodySectionTranslator(),
13651365
HTTPResponsesSectionTranslator(),
1366+
PlistDetailsSectionTranslator(),
13661367
DictionaryKeysSectionTranslator(),
13671368
AttributesSectionTranslator(),
13681369
ReturnsSectionTranslator(),
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright (c) 2024 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See https://swift.org/LICENSE.txt for license information
8+
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
import Foundation
12+
import SymbolKit
13+
14+
/// Translates a symbol's details into a render nodes's details section.
15+
struct PlistDetailsSectionTranslator: RenderSectionTranslator, Decodable {
16+
17+
func generatePlistDetailsRenderSection(_ symbol: Symbol, plistDetails: SymbolGraph.Symbol.PlistDetails) -> PlistDetailsRenderSection {
18+
PlistDetailsRenderSection(
19+
details: PlistDetailsRenderSection.Details(
20+
rawKey: plistDetails.rawKey,
21+
value: [TypeDetails(baseType: plistDetails.baseType, arrayMode: plistDetails.arrayMode)],
22+
platforms: [],
23+
displayName: plistDetails.customTitle,
24+
// If the symbol uses the raw key as its title, display its human-friendly name in the details section.
25+
titleStyle: symbol.title == plistDetails.rawKey ? .useRawKey : .useDisplayName
26+
)
27+
)
28+
}
29+
30+
func translateSection(for symbol: Symbol, renderNode: inout RenderNode, renderNodeTranslator: inout RenderNodeTranslator) -> VariantCollection<CodableContentSection?>? {
31+
guard let mixinVariant = symbol.mixinsVariants.allValues.first(where: { mixin in
32+
mixin.variant.keys.contains(SymbolGraph.Symbol.PlistDetails.mixinKey)
33+
}) else { return nil }
34+
guard let plistDetails = symbol.mixinsVariants.allValues.mapFirst(where: { mixin in
35+
mixin.variant[SymbolGraph.Symbol.PlistDetails.mixinKey] as? SymbolGraph.Symbol.PlistDetails
36+
}) else {
37+
return nil
38+
}
39+
let section = generatePlistDetailsRenderSection(symbol, plistDetails: plistDetails)
40+
return VariantCollection(defaultValue: CodableContentSection(section))
41+
}
42+
43+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright (c) 2024 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See https://swift.org/LICENSE.txt for license information
8+
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
import Foundation
12+
import XCTest
13+
@testable import SwiftDocC
14+
import SymbolKit
15+
import SwiftDocCTestUtilities
16+
17+
class PlistDetailsRenderSectionTests: XCTestCase {
18+
19+
func testDecoding() throws {
20+
21+
func getPlistDetailsSection(arrayMode: CustomStringConvertible, baseType: CustomStringConvertible, rawKey: CustomStringConvertible) throws -> PlistDetailsRenderSection {
22+
let symbolJSON = """
23+
{
24+
"accessLevel" : "public",
25+
"availability" : [],
26+
"identifier" : {
27+
"interfaceLanguage" : "plist",
28+
"precise" : "plist:propertylistkey"
29+
},
30+
"kind" : {
31+
"displayName" : "Property List Key",
32+
"identifier" : "typealias"
33+
},
34+
"names" : {
35+
"navigator" : [
36+
{
37+
"kind" : "identifier",
38+
"spelling" : "propertylistkey"
39+
}
40+
],
41+
"title" : "propertylistkey"
42+
},
43+
"pathComponents" : [
44+
"Information-Property-List",
45+
"propertylistkey"
46+
],
47+
"plistDetails" : {
48+
"arrayMode" : \(arrayMode),
49+
"baseType" : \(baseType),
50+
"rawKey" : \(rawKey)
51+
}
52+
}
53+
"""
54+
let symbolGraphString = makeSymbolGraphString(moduleName: "MyModule", symbols: symbolJSON)
55+
let tempURL = try createTempFolder(content: [
56+
Folder(name: "unit-test.docc", content: [
57+
TextFile(name: "MyModule.symbols.json", utf8Content: symbolGraphString)
58+
])
59+
])
60+
let (_, bundle, context) = try loadBundle(from: tempURL)
61+
let node = try XCTUnwrap(context.documentationCache["plist:propertylistkey"])
62+
let converter = DocumentationNodeConverter(bundle: bundle, context: context)
63+
let renderNode = try converter.convert(node)
64+
return try XCTUnwrap(renderNode.primaryContentSections.mapFirst(where: { $0 as? PlistDetailsRenderSection }))
65+
}
66+
67+
// Assert that the Details section is correctly generated when passing valid values into the plistDetails JSON object.
68+
XCTAssertEqual(
69+
try getPlistDetailsSection(arrayMode: true, baseType: "\"string\"", rawKey: "\"property-list-key\""),
70+
PlistDetailsRenderSection(
71+
kind: .plistDetails,
72+
details: PlistDetailsRenderSection.Details(
73+
rawKey: "property-list-key",
74+
value: [TypeDetails(baseType: "string", arrayMode: true)],
75+
platforms: [],
76+
displayName: nil,
77+
titleStyle: .useDisplayName
78+
)
79+
)
80+
)
81+
82+
XCTAssertEqual(
83+
try getPlistDetailsSection(arrayMode: false, baseType: "\"string\"", rawKey: "\"property-list-key\""),
84+
PlistDetailsRenderSection(
85+
kind: .plistDetails,
86+
details: PlistDetailsRenderSection.Details(
87+
rawKey: "property-list-key",
88+
value: [TypeDetails(baseType: "string", arrayMode: false)],
89+
platforms: [],
90+
displayName: nil,
91+
titleStyle: .useDisplayName
92+
)
93+
)
94+
)
95+
96+
// Assert that the Details section does not decode unsupported values.
97+
do {
98+
_ = try getPlistDetailsSection(arrayMode: true, baseType: true, rawKey: "\"property-list-key\"")
99+
} catch {
100+
XCTAssertTrue(error.localizedDescription.contains("isn’t in the correct format"))
101+
}
102+
do {
103+
_ = try getPlistDetailsSection(arrayMode: true, baseType: "\"string\"", rawKey: 1)
104+
} catch {
105+
XCTAssertTrue(error.localizedDescription.contains("isn’t in the correct format"))
106+
}
107+
}
108+
}

0 commit comments

Comments
 (0)