Skip to content

Commit cc6b4ab

Browse files
authored
Merge pull request #1090 from ahoppen/ahoppen/remove-logging-dependency-from-sourcekitd
Remove logging dependency from `SourceKitD`
2 parents 7d6555c + d12b258 commit cc6b4ab

File tree

8 files changed

+79
-54
lines changed

8 files changed

+79
-54
lines changed

Sources/Diagnose/SourcekitdRequestCommand.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public struct SourceKitdRequestCommand: AsyncParsableCommand {
4040
public func run() async throws {
4141
let requestString = try String(contentsOf: URL(fileURLWithPath: sourcekitdRequestPath))
4242

43-
let sourcekitd = try SourceKitDImpl.getOrCreate(
43+
let sourcekitd = try DynamicallyLoadedSourceKitD.getOrCreate(
4444
dylibPath: try! AbsolutePath(validating: sourcekitdPath)
4545
)
4646

Sources/SourceKitD/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ add_library(SourceKitD STATIC
66
SKDResponseArray.swift
77
SKDResponseDictionary.swift
88
SourceKitD.swift
9-
SourceKitDImpl.swift
9+
DynamicallyLoadedSourceKitD.swift
1010
SourceKitDRegistry.swift
1111
sourcekitd_functions.swift
1212
sourcekitd_uids.swift)

Sources/SourceKitD/SourceKitDImpl.swift renamed to Sources/SourceKitD/DynamicallyLoadedSourceKitD.swift

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import Foundation
14+
import LSPLogging
1415
import SKSupport
1516

1617
import struct TSCBasic.AbsolutePath
@@ -20,7 +21,7 @@ import struct TSCBasic.AbsolutePath
2021
///
2122
/// Users of this class should not call the api functions `initialize`, `shutdown`, or
2223
/// `set_notification_handler`, which are global state managed internally by this class.
23-
public final class SourceKitDImpl: SourceKitD {
24+
public final class DynamicallyLoadedSourceKitD: SourceKitD {
2425

2526
/// The path to the sourcekitd dylib.
2627
public let path: AbsolutePath
@@ -48,7 +49,7 @@ public final class SourceKitDImpl: SourceKitD {
4849

4950
public static func getOrCreate(dylibPath: AbsolutePath) throws -> SourceKitD {
5051
try SourceKitDRegistry.shared
51-
.getOrAdd(dylibPath, create: { try SourceKitDImpl(dylib: dylibPath) })
52+
.getOrAdd(dylibPath, create: { try DynamicallyLoadedSourceKitD(dylib: dylibPath) })
5253
}
5354

5455
init(dylib path: AbsolutePath) throws {
@@ -96,6 +97,45 @@ public final class SourceKitDImpl: SourceKitD {
9697
_notificationHandlers.removeAll(where: { $0.value == nil || $0.value === handler })
9798
}
9899
}
100+
101+
public func log(request: SKDRequestDictionary) {
102+
logger.info(
103+
"""
104+
Sending sourcekitd request:
105+
\(request.forLogging)
106+
"""
107+
)
108+
}
109+
110+
public func log(response: SKDResponse) {
111+
logger.log(
112+
level: (response.error == nil || response.error == .requestCancelled) ? .debug : .error,
113+
"""
114+
Received sourcekitd response:
115+
\(response.forLogging)
116+
"""
117+
)
118+
}
119+
120+
public func log(crashedRequest req: SKDRequestDictionary, fileContents: String?) {
121+
let log = """
122+
Request:
123+
\(req.description)
124+
125+
File contents:
126+
\(fileContents ?? "<nil>")
127+
"""
128+
let chunks = splitLongMultilineMessage(message: log)
129+
for (index, chunk) in chunks.enumerated() {
130+
logger.fault(
131+
"""
132+
sourcekitd crashed (\(index + 1)/\(chunks.count))
133+
\(chunk)
134+
"""
135+
)
136+
}
137+
}
138+
99139
}
100140

101141
struct WeakSKDNotificationHandler {

Sources/SourceKitD/SourceKitD.swift

Lines changed: 24 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
@_exported import Csourcekitd
1414
import Dispatch
1515
import Foundation
16-
import LSPLogging
1716
import SKSupport
1817

1918
/// Access to sourcekitd API, taking care of initialization, shutdown, and notification handler
@@ -42,6 +41,24 @@ public protocol SourceKitD: AnyObject {
4241

4342
/// Removes a previously registered notification handler.
4443
func removeNotificationHandler(_ handler: SKDNotificationHandler)
44+
45+
/// Log the given request.
46+
///
47+
/// This log call is issued during normal operation. It is acceptable for the logger to truncate the log message
48+
/// to achieve good performance.
49+
func log(request: SKDRequestDictionary)
50+
51+
/// Log the given request and file contents, ensuring they do not get truncated.
52+
///
53+
/// This log call is used when a request has crashed. In this case we want the log to contain the entire request to be
54+
/// able to reproduce it.
55+
func log(crashedRequest: SKDRequestDictionary, fileContents: String?)
56+
57+
/// Log the given response.
58+
///
59+
/// This log call is issued during normal operation. It is acceptable for the logger to truncate the log message
60+
/// to achieve good performance.
61+
func log(response: SKDResponse)
4562
}
4663

4764
public enum SKDError: Error, Equatable {
@@ -70,11 +87,7 @@ extension SourceKitD {
7087
/// - fileContents: The contents of the file that the request operates on. If sourcekitd crashes, the file contents
7188
/// will be logged.
7289
public func send(_ req: SKDRequestDictionary, fileContents: String?) async throws -> SKDResponseDictionary {
73-
logRequest(req)
74-
75-
let signposter = logger.makeSignposter()
76-
let signpostID = signposter.makeSignpostID()
77-
let signposterState = signposter.beginInterval("sourcekitd-request", id: signpostID, "Start")
90+
log(request: req)
7891

7992
let sourcekitdResponse: SKDResponse = try await withCancellableCheckedThrowingContinuation { continuation in
8093
var handle: sourcekitd_api_request_handle_t? = nil
@@ -83,58 +96,24 @@ extension SourceKitD {
8396
}
8497
return handle
8598
} cancel: { handle in
86-
api.cancel_request(handle)
99+
if let handle {
100+
api.cancel_request(handle)
101+
}
87102
}
88103

89-
logResponse(sourcekitdResponse)
104+
log(response: sourcekitdResponse)
90105

91106
guard let dict = sourcekitdResponse.value else {
92-
signposter.endInterval("sourcekitd-request", signposterState, "Error")
93107
if sourcekitdResponse.error == .connectionInterrupted {
94-
let log = """
95-
Request:
96-
\(req.description)
97-
98-
File contents:
99-
\(fileContents ?? "<nil>")
100-
"""
101-
let chunks = splitLongMultilineMessage(message: log)
102-
for (index, chunk) in chunks.enumerated() {
103-
logger.fault(
104-
"""
105-
sourcekitd crashed (\(index + 1)/\(chunks.count))
106-
\(chunk)
107-
"""
108-
)
109-
}
108+
log(crashedRequest: req, fileContents: fileContents)
110109
}
111110
throw sourcekitdResponse.error!
112111
}
113112

114-
signposter.endInterval("sourcekitd-request", signposterState, "Done")
115113
return dict
116114
}
117115
}
118116

119-
private func logRequest(_ request: SKDRequestDictionary) {
120-
logger.info(
121-
"""
122-
Sending sourcekitd request:
123-
\(request.forLogging)
124-
"""
125-
)
126-
}
127-
128-
private func logResponse(_ response: SKDResponse) {
129-
logger.log(
130-
level: (response.error == nil || response.error == .requestCancelled) ? .debug : .error,
131-
"""
132-
Received sourcekitd response:
133-
\(response.forLogging)
134-
"""
135-
)
136-
}
137-
138117
/// A sourcekitd notification handler in a class to allow it to be uniquely referenced.
139118
public protocol SKDNotificationHandler: AnyObject {
140119
func notification(_: SKDResponse) -> Void

Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ public actor SwiftLanguageServer: ToolchainLanguageServer {
159159
guard let sourcekitd = toolchain.sourcekitd else { return nil }
160160
self.sourceKitServer = sourceKitServer
161161
self.swiftFormat = toolchain.swiftFormat
162-
self.sourcekitd = try SourceKitDImpl.getOrCreate(dylibPath: sourcekitd)
162+
self.sourcekitd = try DynamicallyLoadedSourceKitD.getOrCreate(dylibPath: sourcekitd)
163163
self.capabilityRegistry = workspace.capabilityRegistry
164164
self.serverOptions = options
165165
self.documentManager = DocumentManager()

Tests/DiagnoseTests/DiagnoseTests.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,9 @@ private struct InProcessSourceKitRequestExecutor: SourceKitRequestExecutor {
204204
func run(request requestYaml: String) async throws -> SourceKitDRequestResult {
205205
logger.info("Sending request: \(requestYaml)")
206206

207-
let sourcekitd = try SourceKitDImpl.getOrCreate(dylibPath: try! AbsolutePath(validating: sourcekitd.path))
207+
let sourcekitd = try DynamicallyLoadedSourceKitD.getOrCreate(
208+
dylibPath: try! AbsolutePath(validating: sourcekitd.path)
209+
)
208210
let response = try await sourcekitd.run(requestYaml: requestYaml)
209211

210212
logger.info("Received response: \(response.description)")

Tests/SourceKitDTests/SourceKitDRegistryTests.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,8 @@ final class FakeSourceKitD: SourceKitD {
7575
static func getOrCreate(_ path: AbsolutePath, in registry: SourceKitDRegistry) -> SourceKitD {
7676
return registry.getOrAdd(path, create: { Self.init() })
7777
}
78+
79+
public func log(request: SKDRequestDictionary) {}
80+
public func log(response: SKDResponse) {}
81+
public func log(crashedRequest: SKDRequestDictionary, fileContents: String?) {}
7882
}

Tests/SourceKitDTests/SourceKitDTests.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import class TSCBasic.Process
2828
final class SourceKitDTests: XCTestCase {
2929
func testMultipleNotificationHandlers() async throws {
3030
let sourcekitdPath = await ToolchainRegistry.forTesting.default!.sourcekitd!
31-
let sourcekitd = try SourceKitDImpl.getOrCreate(dylibPath: sourcekitdPath)
31+
let sourcekitd = try DynamicallyLoadedSourceKitD.getOrCreate(dylibPath: sourcekitdPath)
3232
let keys = sourcekitd.keys
3333
let path = DocumentURI.for(.swift).pseudoPath
3434

@@ -47,7 +47,7 @@ final class SourceKitDTests: XCTestCase {
4747
expectation1.fulfill()
4848
}
4949
}
50-
// SourceKitDImpl weakly references handlers
50+
// DynamicallyLoadedSourceKitD weakly references handlers
5151
defer {
5252
_fixLifetime(handler1)
5353
}
@@ -59,7 +59,7 @@ final class SourceKitDTests: XCTestCase {
5959
expectation2.fulfill()
6060
}
6161
}
62-
// SourceKitDImpl weakly references handlers
62+
// DynamicallyLoadedSourceKitD weakly references handlers
6363
defer {
6464
_fixLifetime(handler2)
6565
}

0 commit comments

Comments
 (0)