diff --git a/Sources/SourceKitLSP/Swift/Diagnostic.swift b/Sources/SourceKitLSP/Swift/Diagnostic.swift index 7495407de..b3e32aaf0 100644 --- a/Sources/SourceKitLSP/Swift/Diagnostic.swift +++ b/Sources/SourceKitLSP/Swift/Diagnostic.swift @@ -125,6 +125,19 @@ extension TextEdit { } } +fileprivate extension String { + /// Returns this string with the first letter uppercased. + /// + /// If the string does not start with a letter, no change is made to it. + func withFirstLetterUppercased() -> String { + if let firstLetter = self.first { + return firstLetter.uppercased() + self.dropFirst() + } else { + return self + } + } +} + extension Diagnostic { /// Creates a diagnostic from a sourcekitd response dictionary. @@ -138,7 +151,7 @@ extension Diagnostic { let keys = diag.sourcekitd.keys let values = diag.sourcekitd.values - guard let message: String = diag[keys.description] else { return nil } + guard let message: String = diag[keys.description]?.withFirstLetterUppercased() else { return nil } var range: Range? = nil if let line: Int = diag[keys.line], @@ -309,7 +322,7 @@ extension DiagnosticRelatedInformation { return nil } - guard let message: String = diag[keys.description] else { return nil } + guard let message: String = diag[keys.description]?.withFirstLetterUppercased() else { return nil } var actions: [CodeAction]? = nil if let skfixits: SKDResponseArray = diag[keys.fixits], diff --git a/Tests/SourceKitLSPTests/LocalSwiftTests.swift b/Tests/SourceKitLSPTests/LocalSwiftTests.swift index eabdbf7ca..d039cf969 100644 --- a/Tests/SourceKitLSPTests/LocalSwiftTests.swift +++ b/Tests/SourceKitLSPTests/LocalSwiftTests.swift @@ -447,7 +447,7 @@ final class LocalSwiftTests: XCTestCase { XCTAssertEqual( fixit, CodeAction( - title: "chain the optional using '?' to access member 'bigEndian' only for non-'nil' base values", + title: "Chain the optional using '?' to access member 'bigEndian' only for non-'nil' base values", kind: .quickFix, diagnostics: nil, edit: WorkspaceEdit(changes: [uri: [expectedTextEdit]], documentChanges: nil), @@ -469,7 +469,7 @@ final class LocalSwiftTests: XCTestCase { XCTAssertEqual( fixit, CodeAction( - title: "force-unwrap using '!' to abort execution if the optional value contains 'nil'", + title: "Force-unwrap using '!' to abort execution if the optional value contains 'nil'", kind: .quickFix, diagnostics: nil, edit: WorkspaceEdit(changes: [uri: [expectedTextEdit]], documentChanges: nil), @@ -627,11 +627,11 @@ final class LocalSwiftTests: XCTestCase { for fixit in quickFixes { if fixit.title.contains("!") { - XCTAssert(fixit.title.starts(with: "force-unwrap using '!'")) + XCTAssert(fixit.title.starts(with: "Force-unwrap using '!'")) expectedTextEdit.newText = "!" XCTAssertEqual(fixit.edit, WorkspaceEdit(changes: [uri: [expectedTextEdit]], documentChanges: nil)) } else { - XCTAssert(fixit.title.starts(with: "chain the optional using '?'")) + XCTAssert(fixit.title.starts(with: "Chain the optional using '?'")) expectedTextEdit.newText = "?" XCTAssertEqual(fixit.edit, WorkspaceEdit(changes: [uri: [expectedTextEdit]], documentChanges: nil)) } @@ -639,7 +639,7 @@ final class LocalSwiftTests: XCTestCase { XCTAssertEqual(fixit.diagnostics?.count, 1) XCTAssertEqual(fixit.diagnostics?.first?.severity, .error) XCTAssertEqual(fixit.diagnostics?.first?.range, Range(Position(line: 1, utf16index: 6))) - XCTAssert(fixit.diagnostics?.first?.message.starts(with: "value of optional type") == true) + XCTAssert(fixit.diagnostics?.first?.message.starts(with: "Value of optional type") == true) } } @@ -729,7 +729,7 @@ final class LocalSwiftTests: XCTestCase { XCTAssertEqual(quickFixes.count, 1) guard let fixit = quickFixes.first else { return } - XCTAssertEqual(fixit.title, "use 'new(_:hotness:)' instead") + XCTAssertEqual(fixit.title, "Use 'new(_:hotness:)' instead") XCTAssertEqual(fixit.diagnostics?.count, 1) XCTAssert(fixit.diagnostics?.first?.message.contains("is deprecated") == true) XCTAssertEqual( @@ -1627,7 +1627,7 @@ final class LocalSwiftTests: XCTestCase { let diagnostic = try await testClient.nextDiagnosticsNotification() let diag = try XCTUnwrap(diagnostic.diagnostics.first) - XCTAssertEqual(diag.message, "cannot find 'bar' in scope") + XCTAssertEqual(diag.message, "Cannot find 'bar' in scope") // Ensure that we don't get a second `PublishDiagnosticsNotification` await assertThrowsError(try await testClient.nextDiagnosticsNotification(timeout: 2)) diff --git a/Tests/SourceKitLSPTests/PullDiagnosticsTests.swift b/Tests/SourceKitLSPTests/PullDiagnosticsTests.swift index 4eb62c25e..76620e395 100644 --- a/Tests/SourceKitLSPTests/PullDiagnosticsTests.swift +++ b/Tests/SourceKitLSPTests/PullDiagnosticsTests.swift @@ -101,8 +101,8 @@ final class PullDiagnosticsTests: XCTestCase { // toolchains that don't contain the change yet. XCTAssert( [ - "add stubs for conformance", - "do you want to add protocol stubs?", + "Add stubs for conformance", + "Do you want to add protocol stubs?", ].contains(action.title) ) } diff --git a/Tests/SourceKitLSPTests/SourceKitTests.swift b/Tests/SourceKitLSPTests/SourceKitTests.swift index 6be73a700..d68440805 100644 --- a/Tests/SourceKitLSPTests/SourceKitTests.swift +++ b/Tests/SourceKitLSPTests/SourceKitTests.swift @@ -287,8 +287,8 @@ final class SKTests: XCTestCase { // FIXME: The error message for the missing module is misleading on Darwin // https://github.com/apple/swift-package-manager/issues/5925 XCTAssert( - diagnostic.message.contains("could not build Objective-C module") - || diagnostic.message.contains("no such module"), + diagnostic.message.contains("Could not build Objective-C module") + || diagnostic.message.contains("No such module"), "expected module import error but found \"\(diagnostic.message)\"" ) }