Skip to content

Commit 5280182

Browse files
d-ronnqvistPortalPeteanferbui
authored
Hide parameter and return value documentation from properties. (#968)
* Hide parameter and return value documentation from properties rdar://130750134 * Apply suggestions from code review Co-authored-by: Pete Lawrence <[email protected]> Co-authored-by: Andrea Fernandez Buitrago <[email protected]> * Fix misaligned guard conditions --------- Co-authored-by: Pete Lawrence <[email protected]> Co-authored-by: Andrea Fernandez Buitrago <[email protected]>
1 parent e5a9c73 commit 5280182

File tree

4 files changed

+559
-37
lines changed

4 files changed

+559
-37
lines changed

Sources/SwiftDocC/Model/ParametersAndReturnValidator.swift

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -222,12 +222,19 @@ struct ParametersAndReturnValidator {
222222
var variants = DocumentationDataVariants<ReturnsSection>()
223223

224224
var traitsWithNonVoidReturnValues = Set(signatures.keys)
225-
for (trait, signature) in signatures where !signature.returns.isEmpty {
226-
// Don't display any return value documentation for language representations that only return void.
227-
if let language = trait.interfaceLanguage.flatMap(SourceLanguage.init(knownLanguageIdentifier:)),
228-
let voidReturnValues = Self.knownVoidReturnValuesByLanguage[language],
229-
signature.returns.allSatisfy({ voidReturnValues.contains($0) })
230-
{
225+
for (trait, signature) in signatures {
226+
/// A Boolean value that indicates whether the current signature returns a known "void" value.
227+
var returnsKnownVoidValue: Bool {
228+
guard let language = trait.interfaceLanguage.flatMap(SourceLanguage.init(knownLanguageIdentifier:)),
229+
let voidReturnValues = Self.knownVoidReturnValuesByLanguage[language]
230+
else {
231+
return false
232+
}
233+
return signature.returns.allSatisfy { voidReturnValues.contains($0) }
234+
}
235+
236+
// Don't display any return value documentation for language representations that return nothing or that only return void.
237+
if signature.returns.isEmpty || returnsKnownVoidValue {
231238
traitsWithNonVoidReturnValues.remove(trait)
232239
// Add an empty section so that this language doesn't fallback to another language's content.
233240
variants[trait] = ReturnsSection(content: [])
@@ -273,7 +280,19 @@ struct ParametersAndReturnValidator {
273280
}
274281
signatures[DocumentationDataVariantsTrait(for: selector)] = signature
275282
}
276-
return signatures.isEmpty ? nil : signatures
283+
284+
guard !signatures.isEmpty else { return nil }
285+
286+
// If the unified symbol has at least one function signature, fill in empty signatures for the other language representations.
287+
//
288+
// This, for example, makes it so that a functions in C which corresponds to property in Swift, displays its parameters and return value documentation
289+
// for the C function representation, but not the Swift property representation of the documented symbol.
290+
let traitsWithoutSignatures = Set(symbol.mainGraphSelectors.map { DocumentationDataVariantsTrait(for: $0) }).subtracting(signatures.keys)
291+
for trait in traitsWithoutSignatures {
292+
signatures[trait] = .init(parameters: [], returns: [])
293+
}
294+
295+
return signatures
277296
}
278297

279298
/// Checks if the language specific function signatures describe a throwing function in Swift that bridges to an Objective-C method with a trailing error parameter.
@@ -285,7 +304,7 @@ struct ParametersAndReturnValidator {
285304
return false
286305
}
287306
guard let swiftSignature = signatures[.swift],
288-
swiftSignature.parameters.last?.name != "error"
307+
swiftSignature.parameters.last?.name != "error"
289308
else {
290309
return false
291310
}

Tests/SwiftDocCTests/Model/ParametersAndReturnValidatorTests.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,39 @@ class ParametersAndReturnValidatorTests: XCTestCase {
196196
}
197197
}
198198

199+
func testFunctionsThatCorrespondToPropertiesInAnotherLanguage() throws {
200+
let (_, _, context) = try testBundleAndContext(named: "GeometricalShapes")
201+
XCTAssertEqual(context.problems.map(\.diagnostic.summary), [])
202+
203+
// A small test helper to format markup for test assertions in this test.
204+
func _format(_ markup: [any Markup]) -> String {
205+
markup.map { $0.format() }.joined()
206+
}
207+
208+
let reference = try XCTUnwrap(context.knownPages.first(where: { $0.lastPathComponent == "isEmpty" }))
209+
let node = try context.entity(with: reference)
210+
211+
let symbolSemantic = try XCTUnwrap(node.semantic as? Symbol)
212+
let swiftParameterNames = symbolSemantic.parametersSectionVariants.firstValue?.parameters
213+
let objcParameterNames = symbolSemantic.parametersSectionVariants.allValues.mapFirst(where: { (trait, variant) -> [Parameter]? in
214+
guard trait.interfaceLanguage == SourceLanguage.objectiveC.id else { return nil }
215+
return variant.parameters
216+
})
217+
218+
XCTAssertEqual(swiftParameterNames?.map(\.name), [])
219+
XCTAssertEqual(objcParameterNames?.map(\.name), ["circle"])
220+
XCTAssertEqual(objcParameterNames?.map { _format($0.contents) }, ["The circle to examine."])
221+
222+
let swiftReturnsContent = symbolSemantic.returnsSection.map { _format($0.content) }
223+
let objcReturnsContent = symbolSemantic.returnsSectionVariants.allValues.mapFirst(where: { (trait, variant) -> String? in
224+
guard trait.interfaceLanguage == SourceLanguage.objectiveC.id else { return nil }
225+
return variant.content.map { $0.format() }.joined()
226+
})
227+
228+
XCTAssertEqual(swiftReturnsContent, "")
229+
XCTAssertEqual(objcReturnsContent, "`YES` if the specified circle is empty; otherwise, `NO`.")
230+
}
231+
199232
func testNoParameterDiagnosticWithoutFunctionSignature() throws {
200233
var symbolGraph = makeSymbolGraph(docComment: """
201234
Some function description

0 commit comments

Comments
 (0)