Skip to content

Commit 1ccafcc

Browse files
authored
Merge pull request #1589 from ahoppen/log-options
Log the options with which SourceKit-LSP is launched
2 parents 0493221 + 7790706 commit 1ccafcc

File tree

4 files changed

+126
-5
lines changed

4 files changed

+126
-5
lines changed

Sources/SKLogging/CustomLogStringConvertible.swift

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,55 @@ extension Optional where Wrapped: CustomLogStringConvertible {
8585
return CustomLogStringConvertibleWrapper(OptionalWrapper(optional: self))
8686
}
8787
}
88+
89+
/// A JSON-like description of the object.
90+
public func recursiveDescription(of subject: Any) -> String {
91+
return "{"
92+
+ Mirror(reflecting: subject).children.map { (key, value) in
93+
"\(key ?? "<nil>"): \(String(describing: value))"
94+
}.joined(separator: ", ")
95+
+ "}"
96+
}
97+
98+
fileprivate protocol OptionalProtocol {
99+
associatedtype Wrapped
100+
var asOptional: Wrapped? { get }
101+
}
102+
extension Optional: OptionalProtocol {
103+
var asOptional: Wrapped? { self }
104+
}
105+
106+
/// A JSON-like description of the object that shows trivial values but redacts values that might contain sensitive
107+
/// information.
108+
public func recursiveRedactedDescription(of value: Any) -> String {
109+
switch value {
110+
case let value as Bool:
111+
return value.description
112+
case let value as Int:
113+
return value.description
114+
case let value as Double:
115+
return value.description
116+
case let value as String:
117+
return value.hashForLogging
118+
case let value as any CustomLogStringConvertible:
119+
return value.redactedDescription
120+
case let value as any OptionalProtocol:
121+
if let value = value.asOptional {
122+
return recursiveRedactedDescription(of: value)
123+
} else {
124+
return "nil"
125+
}
126+
default:
127+
break
128+
}
129+
130+
let children = Mirror(reflecting: value).children.sorted { $0.label ?? "" < $1.label ?? "" }
131+
if !children.isEmpty {
132+
return "{"
133+
+ children.map { (label, value) -> String in
134+
"\(label ?? "<nil>"): \(recursiveRedactedDescription(of: value))"
135+
}.joined(separator: ", ")
136+
+ "}"
137+
}
138+
return "<private>"
139+
}

Sources/SKOptions/SourceKitLSPOptions.swift

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ import struct TSCBasic.AbsolutePath
2020
/// Options that can be used to modify SourceKit-LSP's behavior.
2121
///
2222
/// See `ConfigurationFile.md` for a description of the configuration file's behavior.
23-
public struct SourceKitLSPOptions: Sendable, Codable {
24-
public struct SwiftPMOptions: Sendable, Codable {
23+
public struct SourceKitLSPOptions: Sendable, Codable, CustomLogStringConvertible {
24+
public struct SwiftPMOptions: Sendable, Codable, CustomLogStringConvertible {
2525
/// Build configuration (debug|release).
2626
///
2727
/// Equivalent to SwiftPM's `--configuration` option.
@@ -88,9 +88,17 @@ public struct SourceKitLSPOptions: Sendable, Codable {
8888
linkerFlags: override?.linkerFlags ?? base.linkerFlags
8989
)
9090
}
91+
92+
public var description: String {
93+
recursiveDescription(of: self)
94+
}
95+
96+
public var redactedDescription: String {
97+
recursiveRedactedDescription(of: self)
98+
}
9199
}
92100

93-
public struct CompilationDatabaseOptions: Sendable, Codable {
101+
public struct CompilationDatabaseOptions: Sendable, Codable, CustomLogStringConvertible {
94102
/// Additional paths to search for a compilation database, relative to a workspace root.
95103
public var searchPaths: [String]?
96104

@@ -104,9 +112,17 @@ public struct SourceKitLSPOptions: Sendable, Codable {
104112
) -> CompilationDatabaseOptions {
105113
return CompilationDatabaseOptions(searchPaths: override?.searchPaths ?? base.searchPaths)
106114
}
115+
116+
public var description: String {
117+
recursiveDescription(of: self)
118+
}
119+
120+
public var redactedDescription: String {
121+
recursiveRedactedDescription(of: self)
122+
}
107123
}
108124

109-
public struct FallbackBuildSystemOptions: Sendable, Codable {
125+
public struct FallbackBuildSystemOptions: Sendable, Codable, CustomLogStringConvertible {
110126
public var cCompilerFlags: [String]?
111127
public var cxxCompilerFlags: [String]?
112128
public var swiftCompilerFlags: [String]?
@@ -131,9 +147,17 @@ public struct SourceKitLSPOptions: Sendable, Codable {
131147
swiftCompilerFlags: override?.swiftCompilerFlags ?? base.swiftCompilerFlags
132148
)
133149
}
150+
151+
public var description: String {
152+
recursiveDescription(of: self)
153+
}
154+
155+
public var redactedDescription: String {
156+
recursiveRedactedDescription(of: self)
157+
}
134158
}
135159

136-
public struct IndexOptions: Sendable, Codable {
160+
public struct IndexOptions: Sendable, Codable, CustomLogStringConvertible {
137161
public var indexStorePath: String?
138162
public var indexDatabasePath: String?
139163
public var indexPrefixMap: [String: String]?
@@ -176,6 +200,14 @@ public struct SourceKitLSPOptions: Sendable, Codable {
176200
updateIndexStoreTimeout: override?.updateIndexStoreTimeout ?? base.updateIndexStoreTimeout
177201
)
178202
}
203+
204+
public var description: String {
205+
recursiveDescription(of: self)
206+
}
207+
208+
public var redactedDescription: String {
209+
recursiveRedactedDescription(of: self)
210+
}
179211
}
180212

181213
public enum BackgroundPreparationMode: String {
@@ -392,4 +424,12 @@ public struct SourceKitLSPOptions: Sendable, Codable {
392424
forKey: CodingKeys.workDoneProgressDebounceDuration
393425
)
394426
}
427+
428+
public var description: String {
429+
recursiveDescription(of: self)
430+
}
431+
432+
public var redactedDescription: String {
433+
recursiveRedactedDescription(of: self)
434+
}
395435
}

Sources/SourceKitLSP/SourceKitLSPServer.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,7 @@ extension SourceKitLSPServer {
897897
.appendingPathComponent("config.json")
898898
)
899899
)
900+
logger.log("Creating workspace at \(workspaceFolder.uri.forLogging) with options: \(options.forLogging)")
900901
let buildSystem = await createBuildSystem(
901902
rootUri: workspaceFolder.uri,
902903
options: options,
@@ -998,6 +999,8 @@ extension SourceKitLSPServer {
998999
override: orLog("Parsing SourceKitLSPOptions", { try SourceKitLSPOptions(fromLSPAny: req.initializationOptions) })
9991000
)
10001001

1002+
logger.log("Initialized SourceKit-LSP with options: \(self.options.forLogging)")
1003+
10011004
await workspaceQueue.async { [testHooks] in
10021005
if let workspaceFolders = req.workspaceFolders {
10031006
self.workspacesAndIsImplicit += await workspaceFolders.asyncCompactMap {

Tests/SKLoggingTests/LoggingTests.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,4 +212,30 @@ final class LoggingTests: XCTestCase {
212212
$0.log("got \(LogStringConvertible().forLogging)")
213213
}
214214
}
215+
216+
func testRecursiveRedactedDescription() {
217+
struct Outer {
218+
struct Inner {
219+
var publicValue: Int
220+
var redactedValue: String
221+
}
222+
var inner: Inner
223+
}
224+
225+
XCTAssertEqual(
226+
recursiveRedactedDescription(of: Outer(inner: Outer.Inner(publicValue: 42, redactedValue: "password"))),
227+
"""
228+
{inner: {publicValue: 42, redactedValue: MD5 digest: 5f4dcc3b5aa765d61d8327deb882cf99}}
229+
"""
230+
)
231+
232+
XCTAssertEqual(recursiveRedactedDescription(of: (nil as Int?) as Any), "nil")
233+
234+
XCTAssertEqual(recursiveRedactedDescription(of: (42 as Int?) as Any), "42")
235+
236+
XCTAssertEqual(
237+
recursiveRedactedDescription(of: ("abc" as String?) as Any),
238+
"MD5 digest: 900150983cd24fb0d6963f7d28e17f72"
239+
)
240+
}
215241
}

0 commit comments

Comments
 (0)