Skip to content

Commit d14ddcf

Browse files
authored
Merge pull request #1199 from ahoppen/6.0/merge-main-2024-04-23
Merge `main` into `release/6.0`
2 parents 32f3b9d + b6a2008 commit d14ddcf

File tree

58 files changed

+4191
-647
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+4191
-647
lines changed

Sources/Diagnose/DiagnoseCommand.swift

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ private var progressBar: PercentProgressAnimation? = nil
2727

2828
/// A component of the diagnostic bundle that's collected in independent stages.
2929
fileprivate enum BundleComponent: String, CaseIterable, ExpressibleByArgument {
30-
case crashReports
31-
case logs
32-
case swiftVersions
33-
case sourcekitdCrashes
34-
case swiftFrontendCrashes
30+
case crashReports = "crash-reports"
31+
case logs = "logs"
32+
case swiftVersions = "swift-versions"
33+
case sourcekitdCrashes = "sourcekitd-crashes"
34+
case swiftFrontendCrashes = "swift-frontend-crashes"
3535
}
3636

3737
public struct DiagnoseCommand: AsyncParsableCommand {
@@ -134,6 +134,7 @@ public struct DiagnoseCommand: AsyncParsableCommand {
134134

135135
for crashInfo in crashInfos {
136136
let dateFormatter = DateFormatter()
137+
dateFormatter.timeZone = NSTimeZone.local
137138
dateFormatter.dateStyle = .none
138139
dateFormatter.timeStyle = .medium
139140
let progressMessagePrefix = "Reducing Swift compiler crash at \(dateFormatter.string(from: crashInfo.date))"
@@ -304,7 +305,9 @@ public struct DiagnoseCommand: AsyncParsableCommand {
304305

305306
progressBar = PercentProgressAnimation(stream: stderrStream, header: "Diagnosing sourcekit-lsp issues")
306307

307-
let date = ISO8601DateFormatter().string(from: Date()).replacingOccurrences(of: ":", with: "-")
308+
let dateFormatter = ISO8601DateFormatter()
309+
dateFormatter.timeZone = NSTimeZone.local
310+
let date = dateFormatter.string(from: Date()).replacingOccurrences(of: ":", with: "-")
308311
let bundlePath = FileManager.default.temporaryDirectory
309312
.appendingPathComponent("sourcekitd-reproducer-\(date)")
310313
try FileManager.default.createDirectory(at: bundlePath, withIntermediateDirectories: true)
@@ -330,9 +333,9 @@ public struct DiagnoseCommand: AsyncParsableCommand {
330333
print(
331334
"""
332335
333-
Bundle created.
334-
When filing an issue at https://github.com/apple/sourcekit-lsp/issues/new,
335-
please attach the bundle located at
336+
Bundle created.
337+
When filing an issue at https://github.com/apple/sourcekit-lsp/issues/new,
338+
please attach the bundle located at
336339
\(bundlePath.path)
337340
"""
338341
)

Sources/Diagnose/ReproducerBundle.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func makeReproducerBundle(for requestInfo: RequestInfo, toolchain: Toolchain, bu
4141
} else {
4242
let request = try requestInfo.request(for: URL(fileURLWithPath: "/input.swift"))
4343
try request.write(
44-
to: bundlePath.appendingPathComponent("request.json"),
44+
to: bundlePath.appendingPathComponent("request.yml"),
4545
atomically: true,
4646
encoding: .utf8
4747
)

Sources/Diagnose/SwiftFrontendCrashScraper.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ struct SwiftFrontendCrashScraper {
7070
}
7171
let interestingString = fileContents[firstNewline...]
7272
let dateFormatter = DateFormatter()
73+
dateFormatter.timeZone = NSTimeZone.local
7374
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSSS Z"
7475
let decoder = JSONDecoder()
7576
decoder.dateDecodingStrategy = .formatted(dateFormatter)

Sources/LSPLogging/NonDarwinLogging.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,8 @@ public struct NonDarwinLogMessage: ExpressibleByStringInterpolation, Expressible
245245
/// a new `DateFormatter` is rather expensive and its the same for all loggers.
246246
private let dateFormatter = {
247247
let dateFormatter = DateFormatter()
248-
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS"
248+
dateFormatter.timeZone = NSTimeZone.local
249+
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSSS Z"
249250
return dateFormatter
250251
}()
251252

@@ -299,11 +300,20 @@ public struct NonDarwinLogger: Sendable {
299300
guard level >= self.logLevel else { return }
300301
let date = Date()
301302
loggingQueue.async {
303+
// Truncate log message after 10.000 characters to avoid flooding the log with huge log messages (eg. from a
304+
// sourcekitd response). 10.000 characters was chosen because it seems to fit the result of most sourcekitd
305+
// responses that are not generated interface or global completion results (which are a lot bigger).
306+
var message = message().value.string(for: self.privacyLevel)
307+
if message.utf8.count > 10_000 {
308+
// Check for UTF-8 byte length first because that's faster since it doesn't need to count UTF-8 characters.
309+
// Truncate using `.prefix` to avoid cutting of in the middle of a UTF-8 multi-byte character.
310+
message = message.prefix(10_000) + "..."
311+
}
302312
// Start each log message with `[org.swift.sourcekit-lsp` so that it’s easy to split the log to the different messages
303313
logHandler(
304314
"""
305315
[\(subsystem):\(category)] \(level) \(dateFormatter.string(from: date))
306-
\(message().value.string(for: self.privacyLevel))
316+
\(message)
307317
---
308318
"""
309319
)

Sources/LanguageServerProtocol/Requests/OpenInterfaceRequest.swift

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,27 +23,24 @@ public struct OpenInterfaceRequest: TextDocumentRequest, Hashable {
2323
public var moduleName: String
2424

2525
/// The module group name.
26-
public var groupNames: [String]
26+
public var groupName: String?
2727

2828
/// The symbol USR to search for in the generated module interface.
2929
public var symbolUSR: String?
3030

31-
public init(textDocument: TextDocumentIdentifier, name: String, symbolUSR: String?) {
31+
public init(textDocument: TextDocumentIdentifier, name: String, groupName: String?, symbolUSR: String?) {
3232
self.textDocument = textDocument
3333
self.symbolUSR = symbolUSR
34-
// Stdlib Swift modules are all in the "Swift" module, but their symbols return a module name `Swift.***`.
35-
let splitName = name.split(separator: ".")
36-
self.moduleName = String(splitName[0])
37-
self.groupNames = [String.SubSequence](splitName.dropFirst()).map(String.init)
34+
self.moduleName = name
35+
self.groupName = groupName
3836
}
3937

4038
/// Name of interface module name with group names appended
4139
public var name: String {
42-
if groupNames.count > 0 {
43-
return "\(self.moduleName).\(self.groupNames.joined(separator: "."))"
44-
} else {
45-
return self.moduleName
40+
if let groupName {
41+
return "\(self.moduleName).\(groupName.replacing("/", with: "."))"
4642
}
43+
return self.moduleName
4744
}
4845
}
4946

Sources/LanguageServerProtocol/Requests/SymbolInfoRequest.swift

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,18 @@ public struct SymbolInfoRequest: TextDocumentRequest, Hashable {
4848
/// Detailed information about a symbol, such as the response to a `SymbolInfoRequest`
4949
/// **(LSP Extension)**.
5050
public struct SymbolDetails: ResponseType, Hashable {
51+
public struct ModuleInfo: Codable, Hashable, Sendable {
52+
/// The name of the module in which the symbol is defined.
53+
public let moduleName: String
54+
55+
/// If the symbol is defined within a subgroup of a module, the name of the group. Otherwise `nil`.
56+
public let groupName: String?
57+
58+
public init(moduleName: String, groupName: String? = nil) {
59+
self.moduleName = moduleName
60+
self.groupName = groupName
61+
}
62+
}
5163

5264
/// The name of the symbol, if any.
5365
public var name: String?
@@ -87,6 +99,11 @@ public struct SymbolDetails: ResponseType, Hashable {
8799
/// Optional because `clangd` does not return whether a symbol is dynamic.
88100
public var isDynamic: Bool?
89101

102+
/// Whether this symbol is defined in the SDK or standard library.
103+
///
104+
/// This property only applies to Swift symbols.
105+
public var isSystem: Bool?
106+
90107
/// If the symbol is dynamic, the USRs of the types that might be called.
91108
///
92109
/// This is relevant in the following cases
@@ -112,21 +129,31 @@ public struct SymbolDetails: ResponseType, Hashable {
112129
/// `B` may be called dynamically.
113130
public var receiverUsrs: [String]?
114131

132+
/// If the symbol is defined in a module that doesn't have source information associated with it, the name and group
133+
/// and group name that defines this symbol.
134+
///
135+
/// This property only applies to Swift symbols.
136+
public var systemModule: ModuleInfo?
137+
115138
public init(
116139
name: String?,
117140
containerName: String?,
118141
usr: String?,
119142
bestLocalDeclaration: Location?,
120143
kind: SymbolKind?,
121144
isDynamic: Bool?,
122-
receiverUsrs: [String]?
145+
isSystem: Bool?,
146+
receiverUsrs: [String]?,
147+
systemModule: ModuleInfo?
123148
) {
124149
self.name = name
125150
self.containerName = containerName
126151
self.usr = usr
127152
self.bestLocalDeclaration = bestLocalDeclaration
128153
self.kind = kind
129154
self.isDynamic = isDynamic
155+
self.isSystem = isSystem
130156
self.receiverUsrs = receiverUsrs
157+
self.systemModule = systemModule
131158
}
132159
}

Sources/LanguageServerProtocol/SupportTypes/TestItem.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ public struct TestItem: ResponseType, Equatable {
3939
/// When `nil` the `label` is used.
4040
public let sortText: String?
4141

42+
/// Whether the test is disabled.
43+
public let disabled: Bool
44+
45+
/// The type of test, eg. the testing framework that was used to declare the test.
46+
public let style: String
47+
4248
/// The location of the test item in the source code.
4349
public let location: Location
4450

@@ -55,6 +61,8 @@ public struct TestItem: ResponseType, Equatable {
5561
label: String,
5662
description: String? = nil,
5763
sortText: String? = nil,
64+
disabled: Bool,
65+
style: String,
5866
location: Location,
5967
children: [TestItem],
6068
tags: [TestTag]
@@ -63,6 +71,8 @@ public struct TestItem: ResponseType, Equatable {
6371
self.label = label
6472
self.description = description
6573
self.sortText = sortText
74+
self.disabled = disabled
75+
self.style = style
6676
self.location = location
6777
self.children = children
6878
self.tags = tags

Sources/SKCore/BuildServerBuildSystem.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,17 @@ extension BuildServerBuildSystem: BuildSystem {
316316

317317
return .unhandled
318318
}
319+
320+
public func testFiles() async -> [DocumentURI] {
321+
// BuildServerBuildSystem does not support syntactic test discovery
322+
// (https://github.com/apple/sourcekit-lsp/issues/1173).
323+
return []
324+
}
325+
326+
public func addTestFilesDidChangeCallback(_ callback: @escaping () async -> Void) {
327+
// BuildServerBuildSystem does not support syntactic test discovery
328+
// (https://github.com/apple/sourcekit-lsp/issues/1173).
329+
}
319330
}
320331

321332
private func loadBuildServerConfig(path: AbsolutePath, fileSystem: FileSystem) throws -> BuildServerConfig {

Sources/SKCore/BuildSystem.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,18 @@ public protocol BuildSystem: AnyObject, Sendable {
8787
func filesDidChange(_ events: [FileEvent]) async
8888

8989
func fileHandlingCapability(for uri: DocumentURI) async -> FileHandlingCapability
90+
91+
/// Returns the list of files that might contain test cases.
92+
///
93+
/// The returned file list is an over-approximation. It might contain tests from non-test targets or files that don't
94+
/// actually contain any tests. Keeping this list as minimal as possible helps reduce the amount of work that the
95+
/// syntactic test indexer needs to perform.
96+
func testFiles() async -> [DocumentURI]
97+
98+
/// Adds a callback that should be called when the value returned by `testFiles()` changes.
99+
///
100+
/// The callback might also be called without an actual change to `testFiles`.
101+
func addTestFilesDidChangeCallback(_ callback: @Sendable @escaping () async -> Void) async
90102
}
91103

92104
public let buildTargetsNotSupported =

Sources/SKCore/BuildSystemManager.swift

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ public actor BuildSystemManager {
4545
let fallbackBuildSystem: FallbackBuildSystem?
4646

4747
/// Provider of file to main file mappings.
48-
var _mainFilesProvider: MainFilesProvider?
48+
var mainFilesProvider: MainFilesProvider?
4949

5050
/// Build system delegate that will receive notifications about setting changes, etc.
51-
var _delegate: BuildSystemDelegate?
51+
var delegate: BuildSystemDelegate?
5252

5353
/// The root of the project that this build system manages. For example, for SwiftPM packages, this is the folder
5454
/// containing Package.swift. For compilation databases it is the root folder based on which the compilation database
@@ -71,7 +71,7 @@ public actor BuildSystemManager {
7171
precondition(!buildSystemHasDelegate)
7272
self.buildSystem = buildSystem
7373
self.fallbackBuildSystem = fallbackBuildSystem
74-
self._mainFilesProvider = mainFilesProvider
74+
self.mainFilesProvider = mainFilesProvider
7575
self.fallbackSettingsTimeout = fallbackSettingsTimeout
7676
await self.buildSystem?.setDelegate(self)
7777
}
@@ -82,21 +82,11 @@ public actor BuildSystemManager {
8282
}
8383

8484
extension BuildSystemManager {
85-
public var delegate: BuildSystemDelegate? {
86-
get { _delegate }
87-
set { _delegate = newValue }
88-
}
89-
9085
/// - Note: Needed so we can set the delegate from a different isolation context.
9186
public func setDelegate(_ delegate: BuildSystemDelegate?) {
9287
self.delegate = delegate
9388
}
9489

95-
public var mainFilesProvider: MainFilesProvider? {
96-
get { _mainFilesProvider }
97-
set { _mainFilesProvider = newValue }
98-
}
99-
10090
/// - Note: Needed so we can set the delegate from a different isolation context.
10191
public func setMainFilesProvider(_ mainFilesProvider: MainFilesProvider?) {
10292
self.mainFilesProvider = mainFilesProvider
@@ -186,6 +176,10 @@ extension BuildSystemManager {
186176
fallbackBuildSystem != nil ? .fallback : .unhandled
187177
)
188178
}
179+
180+
public func testFiles() async -> [DocumentURI] {
181+
return await buildSystem?.testFiles() ?? []
182+
}
189183
}
190184

191185
extension BuildSystemManager: BuildSystemDelegate {
@@ -204,15 +198,15 @@ extension BuildSystemManager: BuildSystemDelegate {
204198
public func fileBuildSettingsChanged(_ changedFiles: Set<DocumentURI>) async {
205199
let changedWatchedFiles = watchedFilesReferencing(mainFiles: changedFiles)
206200

207-
if !changedWatchedFiles.isEmpty, let delegate = self._delegate {
201+
if !changedWatchedFiles.isEmpty, let delegate = self.delegate {
208202
await delegate.fileBuildSettingsChanged(changedWatchedFiles)
209203
}
210204
}
211205

212206
public func filesDependenciesUpdated(_ changedFiles: Set<DocumentURI>) async {
213207
// Empty changes --> assume everything has changed.
214208
guard !changedFiles.isEmpty else {
215-
if let delegate = self._delegate {
209+
if let delegate = self.delegate {
216210
await delegate.filesDependenciesUpdated(changedFiles)
217211
}
218212
return
@@ -226,13 +220,13 @@ extension BuildSystemManager: BuildSystemDelegate {
226220
}
227221

228222
public func buildTargetsChanged(_ changes: [BuildTargetEvent]) async {
229-
if let delegate = self._delegate {
223+
if let delegate = self.delegate {
230224
await delegate.buildTargetsChanged(changes)
231225
}
232226
}
233227

234228
public func fileHandlingCapabilityChanged() async {
235-
if let delegate = self._delegate {
229+
if let delegate = self.delegate {
236230
await delegate.fileHandlingCapabilityChanged()
237231
}
238232
}

Sources/SKCore/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ add_library(SKCore STATIC
77
BuildSystemManager.swift
88
CompilationDatabase.swift
99
CompilationDatabaseBuildSystem.swift
10+
Debouncer.swift
1011
FallbackBuildSystem.swift
1112
FileBuildSettings.swift
1213
MainFilesProvider.swift

Sources/SKCore/CompilationDatabaseBuildSystem.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ public actor CompilationDatabaseBuildSystem {
3939
/// Delegate to handle any build system events.
4040
public weak var delegate: BuildSystemDelegate? = nil
4141

42+
/// Callbacks that should be called if the list of possible test files has changed.
43+
public var testFilesDidChangeCallbacks: [() async -> Void] = []
44+
4245
public func setDelegate(_ delegate: BuildSystemDelegate?) async {
4346
self.delegate = delegate
4447
}
@@ -167,6 +170,9 @@ extension CompilationDatabaseBuildSystem: BuildSystem {
167170
if let delegate = self.delegate {
168171
await delegate.fileBuildSettingsChanged(self.watchedFiles)
169172
}
173+
for testFilesDidChangeCallback in testFilesDidChangeCallbacks {
174+
await testFilesDidChangeCallback()
175+
}
170176
}
171177

172178
public func filesDidChange(_ events: [FileEvent]) async {
@@ -185,4 +191,12 @@ extension CompilationDatabaseBuildSystem: BuildSystem {
185191
return .unhandled
186192
}
187193
}
194+
195+
public func testFiles() async -> [DocumentURI] {
196+
return compdb?.allCommands.map { DocumentURI($0.url) } ?? []
197+
}
198+
199+
public func addTestFilesDidChangeCallback(_ callback: @escaping () async -> Void) async {
200+
testFilesDidChangeCallbacks.append(callback)
201+
}
188202
}

0 commit comments

Comments
 (0)