Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve detection of inherited documentation comments for parameter and return validation #1130

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
15 changes: 9 additions & 6 deletions Sources/SwiftDocC/Model/ParametersAndReturnValidator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -278,13 +278,16 @@ struct ParametersAndReturnValidator {

/// Checks if the symbol's documentation is inherited from another source location.
private func hasInheritedDocumentationComment(symbol: UnifiedSymbolGraph.Symbol) -> Bool {
let symbolLocationURI = symbol.documentedSymbol?.mixins.getValueIfPresent(for: SymbolGraph.Symbol.Location.self)?.uri
for case .sourceCode(let location, _) in docChunkSources {
// Check if the symbol has documentation from another source location
return location?.uri != symbolLocationURI
guard let documentedSymbol = symbol.documentedSymbol else {
// If there's no doc comment, any documentation comes from an extension file and isn't inherited from another symbol.
return false
}
// If the symbol didn't have any in-source documentation, check if there's a extension file override.
return docChunkSources.isEmpty

// A symbol has inherited documentation if the doc comment doesn't come from the current module.
let moduleNames: Set<String> = symbol.modules.values.reduce(into: []) { $0.insert($1.name) }
return !moduleNames.contains(where: { moduleName in
documentedSymbol.isDocCommentFromSameModule(symbolModuleName: moduleName) == true
})
}

private typealias Signatures = [DocumentationDataVariantsTrait: SymbolGraph.Symbol.FunctionSignature]
Expand Down
6 changes: 5 additions & 1 deletion Sources/SwiftDocCTestUtilities/SymbolGraphCreation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ extension XCTestCase {

package func makeLineList(
docComment: String,
moduleName: String?,
startOffset: SymbolGraph.LineList.SourceRange.Position = defaultSymbolPosition,
url: URL = defaultSymbolURL
) -> SymbolGraph.LineList {
Expand All @@ -64,7 +65,8 @@ extension XCTestCase {
)
},
// We want to include the file:// scheme here
uri: url.absoluteString
uri: url.absoluteString,
moduleName: moduleName
)
}

Expand All @@ -83,6 +85,7 @@ extension XCTestCase {
kind kindID: SymbolGraph.Symbol.KindIdentifier,
pathComponents: [String],
docComment: String? = nil,
moduleName: String? = nil,
accessLevel: SymbolGraph.Symbol.AccessControl = .init(rawValue: "public"), // Defined internally in SwiftDocC
location: (position: SymbolGraph.LineList.SourceRange.Position, url: URL)? = (defaultSymbolPosition, defaultSymbolURL),
signature: SymbolGraph.Symbol.FunctionSignature? = nil,
Expand All @@ -109,6 +112,7 @@ extension XCTestCase {
docComment: docComment.map {
makeLineList(
docComment: $0,
moduleName: moduleName,
startOffset: location?.position ?? defaultSymbolPosition,
url: location?.url ?? defaultSymbolURL
)
Expand Down
31 changes: 28 additions & 3 deletions Tests/SwiftDocCTests/Model/ParametersAndReturnValidatorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ class ParametersAndReturnValidatorTests: XCTestCase {
Folder(name: "swift", content: [
JSONFile(name: "ModuleName.symbols.json", content: makeSymbolGraph(
docComment: nil,
docCommentModuleName: "ModuleName",
sourceLanguage: .swift,
parameters: [],
returnValue: .init(kind: .typeIdentifier, spelling: "Void", preciseIdentifier: "s:s4Voida")
Expand All @@ -416,6 +417,7 @@ class ParametersAndReturnValidatorTests: XCTestCase {
- Returns: Some return value description.
""",
docCommentModuleName: "ModuleName",
sourceLanguage: .objectiveC,
parameters: [(name: "error", externalName: nil)],
returnValue: .init(kind: .typeIdentifier, spelling: "BOOL", preciseIdentifier: "c:@T@BOOL")
Expand Down Expand Up @@ -447,6 +449,7 @@ class ParametersAndReturnValidatorTests: XCTestCase {
JSONFile(name: "Platform1-ModuleName.symbols.json", content: makeSymbolGraph(
platform: .init(operatingSystem: .init(name: "Platform1")),
docComment: nil,
docCommentModuleName: "ModuleName",
sourceLanguage: .objectiveC,
parameters: [(name: "first", externalName: nil)],
returnValue: .init(kind: .typeIdentifier, spelling: "void", preciseIdentifier: "c:v")
Expand All @@ -455,6 +458,7 @@ class ParametersAndReturnValidatorTests: XCTestCase {
JSONFile(name: "Platform2-ModuleName.symbols.json", content: makeSymbolGraph(
platform: .init(operatingSystem: .init(name: "Platform2")),
docComment: nil,
docCommentModuleName: "ModuleName",
sourceLanguage: .objectiveC,
parameters: [(name: "first", externalName: nil), (name: "second", externalName: nil)],
returnValue: .init(kind: .typeIdentifier, spelling: "void", preciseIdentifier: "c:v")
Expand All @@ -463,6 +467,7 @@ class ParametersAndReturnValidatorTests: XCTestCase {
JSONFile(name: "Platform3-ModuleName.symbols.json", content: makeSymbolGraph(
platform: .init(operatingSystem: .init(name: "Platform3")),
docComment: nil,
docCommentModuleName: "ModuleName",
sourceLanguage: .objectiveC,
parameters: [(name: "first", externalName: nil),],
returnValue: .init(kind: .typeIdentifier, spelling: "BOOL", preciseIdentifier: "c:@T@BOOL")
Expand Down Expand Up @@ -502,6 +507,7 @@ class ParametersAndReturnValidatorTests: XCTestCase {
Folder(name: "swift", content: [
JSONFile(name: "ModuleName.symbols.json", content: makeSymbolGraph(
docComment: nil,
docCommentModuleName: "ModuleName",
sourceLanguage: .swift,
parameters: [(name: "error", externalName: nil)],
returnValue: .init(kind: .typeIdentifier, spelling: "Void", preciseIdentifier: "s:s4Voida")
Expand All @@ -514,6 +520,7 @@ class ParametersAndReturnValidatorTests: XCTestCase {
- Parameter error: Some parameter description.
""",
docCommentModuleName: "ModuleName",
sourceLanguage: .objectiveC,
parameters: [(name: "error", externalName: nil)],
returnValue: .init(kind: .typeIdentifier, spelling: "void", preciseIdentifier: "c:v")
Expand Down Expand Up @@ -661,14 +668,28 @@ class ParametersAndReturnValidatorTests: XCTestCase {
10 + /// - Parameter first: Some parameter description
| ╰─suggestion: Document 'second' parameter
""")


}

func testDoesNotWarnAboutInheritedDocumentation() throws {
let warningOutput = try warningOutputRaisedFrom(
docComment: """
Some function description
- Parameter second: Some parameter description
- Returns: Nothing.
""",
docCommentModuleName: "SomeOtherModule",
parameters: [(name: "first", externalName: "with"), (name: "second", externalName: "and")],
returnValue: .init(kind: .typeIdentifier, spelling: "Void", preciseIdentifier: "s:s4Voida")
)
XCTAssertEqual(warningOutput, "")
}

// MARK: Test helpers

private func warningOutputRaisedFrom(
docComment: String,
docCommentModuleName: String? = "ModuleName",
parameters: [(name: String, externalName: String?)],
returnValue: SymbolGraph.Symbol.DeclarationFragments.Fragment,
file: StaticString = #file,
Expand All @@ -685,6 +706,7 @@ class ParametersAndReturnValidatorTests: XCTestCase {
Folder(name: "unit-test.docc", content: [
JSONFile(name: "ModuleName.symbols.json", content: makeSymbolGraph(
docComment: docComment,
docCommentModuleName: docCommentModuleName,
sourceLanguage: .swift,
parameters: parameters,
returnValue: returnValue
Expand Down Expand Up @@ -712,6 +734,7 @@ class ParametersAndReturnValidatorTests: XCTestCase {
private func makeSymbolGraph(docComment: String) -> SymbolGraph {
makeSymbolGraph(
docComment: docComment,
docCommentModuleName: "ModuleName",
sourceLanguage: .swift,
parameters: [
("firstParameter", nil),
Expand All @@ -726,12 +749,13 @@ class ParametersAndReturnValidatorTests: XCTestCase {
private func makeSymbolGraph(
platform: SymbolGraph.Platform = .init(),
docComment: String?,
docCommentModuleName: String?,
sourceLanguage: SourceLanguage,
parameters: [(name: String, externalName: String?)],
returnValue: SymbolGraph.Symbol.DeclarationFragments.Fragment
) -> SymbolGraph {
return makeSymbolGraph(
moduleName: "ModuleName",
moduleName: "ModuleName", // Don't use `docCommentModuleName` here.
platform: platform,
symbols: [
makeSymbol(
Expand All @@ -740,6 +764,7 @@ class ParametersAndReturnValidatorTests: XCTestCase {
kind: .func,
pathComponents: ["functionName(...)"],
docComment: docComment,
moduleName: docCommentModuleName,
location: (start, symbolURL),
signature: .init(
parameters: parameters.map {
Expand Down
1 change: 1 addition & 0 deletions Tests/SwiftDocCTests/Semantics/SymbolTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1368,6 +1368,7 @@ class SymbolTests: XCTestCase {

let newDocComment = self.makeLineList(
docComment: docComment,
moduleName: nil,
startOffset: .init(
line: docCommentLineOffset,
character: 0
Expand Down