Skip to content

Commit 805b7cb

Browse files
committed
Merge branch 'main' into phase-out-legacy-fixture-in-symbol-tests
2 parents 072c504 + 9cd9bc3 commit 805b7cb

File tree

2 files changed

+62
-13
lines changed

2 files changed

+62
-13
lines changed

Sources/SwiftDocC/Semantics/Metadata/Metadata.swift

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -224,18 +224,25 @@ public final class Metadata: Semantic, AutomaticDirectiveConvertible {
224224

225225
problems.append(
226226
contentsOf: namesAndRanges.map { (name, range) in
227-
Problem(
228-
diagnostic: Diagnostic(
229-
source: symbolSource,
230-
severity: .warning,
231-
range: range,
232-
identifier: "org.swift.docc.\(Metadata.directiveName).Invalid\(name)InDocumentationComment",
233-
summary: "Invalid use of \(name.singleQuoted) directive in documentation comment; configuration will be ignored",
234-
explanation: "Specify this configuration in a documentation extension file"
235-
236-
// TODO: It would be nice to offer a solution here that removes the directive for you (#1111, rdar://140846407)
237-
)
227+
let diagnostic = Diagnostic(
228+
source: symbolSource,
229+
severity: .warning,
230+
range: range,
231+
identifier: "org.swift.docc.\(Metadata.directiveName).Invalid\(name)InDocumentationComment",
232+
summary: "Invalid use of \(name.singleQuoted) directive in documentation comment; configuration will be ignored",
233+
explanation: "Specify this configuration in a documentation extension file"
238234
)
235+
236+
let solutions: [Solution] = range.map { range in
237+
[Solution(
238+
summary: "Remove invalid \(name.singleQuoted) directive",
239+
replacements: [
240+
Replacement(range: range, replacement: "")
241+
]
242+
)]
243+
} ?? []
244+
245+
return Problem(diagnostic: diagnostic, possibleSolutions: solutions)
239246
}
240247
)
241248

Tests/SwiftDocCTests/Semantics/SymbolTests.swift

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,6 +1319,19 @@ class SymbolTests: XCTestCase {
13191319
"org.swift.docc.unresolvedResource", // For the "test" asset that doesn't exist.
13201320
]
13211321
)
1322+
1323+
// Verify that each problem has exactly one solution to remove the directive
1324+
for problem in problems where problem.diagnostic.identifier.hasPrefix("org.swift.docc.Metadata.") {
1325+
XCTAssertEqual(problem.possibleSolutions.count, 1, "Each invalid metadata directive should have exactly one solution")
1326+
1327+
let solution = try XCTUnwrap(problem.possibleSolutions.first)
1328+
XCTAssertTrue(solution.summary.hasPrefix("Remove invalid"), "Solution summary should start with 'Remove invalid'")
1329+
XCTAssertEqual(solution.replacements.count, 1, "Solution should have exactly one replacement")
1330+
1331+
let replacement = try XCTUnwrap(solution.replacements.first)
1332+
XCTAssertEqual(replacement.replacement, "", "Replacement should be empty string to remove the directive")
1333+
XCTAssertNotNil(replacement.range, "Replacement should have a valid range")
1334+
}
13221335
}
13231336

13241337
func testParsesDeprecationSummaryDirectiveFromDocComment() async throws {
@@ -1360,6 +1373,36 @@ class SymbolTests: XCTestCase {
13601373
XCTAssertEqual(problems.count, 0, "Unexpected problems: \(problems.map(\.diagnostic.summary).sorted())")
13611374
}
13621375

1376+
func testSolutionForInvalidMetadataDirectiveRemovesDirective() async throws {
1377+
let (_, problems) = try await makeDocumentationNodeForSymbol(
1378+
docComment: """
1379+
The symbol's abstract.
1380+
1381+
@Metadata {
1382+
@DisplayName("Invalid Display Name")
1383+
}
1384+
""",
1385+
extensionFileContent: nil
1386+
)
1387+
1388+
XCTAssertEqual(problems.count, 1)
1389+
let problem = try XCTUnwrap(problems.first)
1390+
1391+
XCTAssertEqual(problem.diagnostic.identifier, "org.swift.docc.Metadata.InvalidDisplayNameInDocumentationComment")
1392+
XCTAssertEqual(problem.possibleSolutions.count, 1)
1393+
1394+
let solution = try XCTUnwrap(problem.possibleSolutions.first)
1395+
XCTAssertEqual(solution.summary, "Remove invalid 'DisplayName' directive")
1396+
XCTAssertEqual(solution.replacements.count, 1)
1397+
1398+
let replacement = try XCTUnwrap(solution.replacements.first)
1399+
XCTAssertEqual(replacement.replacement, "", "Replacement should be empty string to remove the directive")
1400+
XCTAssertNotNil(replacement.range, "Replacement should have a valid range")
1401+
1402+
// Verify that the replacement range covers the expected content
1403+
XCTAssertEqual(replacement.range, problem.diagnostic.range, "Replacement range should match the problem's diagnostic range to ensure it removes the entire @DisplayName directive")
1404+
}
1405+
13631406
// MARK: - Leading Whitespace in Doc Comments
13641407

13651408
func testWithoutLeadingWhitespace() {
@@ -1550,8 +1593,7 @@ class SymbolTests: XCTestCase {
15501593
returns: [
15511594
.init(kind: .typeIdentifier, spelling: "ReturnValue", preciseIdentifier: "return-value-id")
15521595
]
1553-
),
1554-
1596+
)
15551597
)
15561598
],
15571599
relationships: [

0 commit comments

Comments
 (0)