Skip to content

Commit 9e2b1c9

Browse files
authored
Merge pull request #1723 from ahoppen/revert-build-settings-timeout
2 parents 9b4a9b0 + 794d493 commit 9e2b1c9

File tree

9 files changed

+19
-157
lines changed

9 files changed

+19
-157
lines changed

Documentation/Configuration File.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ The structure of the file is currently not guaranteed to be stable. Options may
3131
- `cxxCompilerFlags: string[]`: Extra arguments passed to the compiler for C++ files
3232
- `swiftCompilerFlags: string[]`: Extra arguments passed to the compiler for Swift files
3333
- `sdk: string`: The SDK to use for fallback arguments. Default is to infer the SDK using `xcrun`.
34-
- `buildSettingsTimeout: int`: Number of milliseconds to wait for build settings from the build system before using fallback build settings.
3534
- `clangdOptions: string[]`: Extra command line arguments passed to `clangd` when launching it
3635
- `index`: Dictionary with the following keys, defining options related to indexing
3736
- `indexStorePath: string`: Directory in which a separate compilation stores the index store. By default, inferred from the build system.

Sources/BuildSystemIntegration/BuildSystemManager.swift

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,6 @@ private extension BuildSystemKind {
137137
private static func createBuiltInBuildSystemAdapter(
138138
projectRoot: AbsolutePath,
139139
messagesToSourceKitLSPHandler: any MessageHandler,
140-
buildSystemTestHooks: BuildSystemTestHooks,
141140
_ createBuildSystem: @Sendable (_ connectionToSourceKitLSP: any Connection) async throws -> BuiltInBuildSystem?
142141
) async -> BuildSystemAdapter? {
143142
let connectionToSourceKitLSP = LocalConnection(receiverName: "BuildSystemManager")
@@ -153,8 +152,7 @@ private extension BuildSystemKind {
153152
logger.log("Created \(type(of: buildSystem), privacy: .public) at \(projectRoot.pathString)")
154153
let buildSystemAdapter = BuiltInBuildSystemAdapter(
155154
underlyingBuildSystem: buildSystem,
156-
connectionToSourceKitLSP: connectionToSourceKitLSP,
157-
buildSystemTestHooks: buildSystemTestHooks
155+
connectionToSourceKitLSP: connectionToSourceKitLSP
158156
)
159157
let connectionToBuildSystem = LocalConnection(receiverName: "Build system")
160158
connectionToBuildSystem.start(handler: buildSystemAdapter)
@@ -186,8 +184,7 @@ private extension BuildSystemKind {
186184
case .compilationDatabase(projectRoot: let projectRoot):
187185
return await Self.createBuiltInBuildSystemAdapter(
188186
projectRoot: projectRoot,
189-
messagesToSourceKitLSPHandler: messagesToSourceKitLSPHandler,
190-
buildSystemTestHooks: testHooks
187+
messagesToSourceKitLSPHandler: messagesToSourceKitLSPHandler
191188
) { connectionToSourceKitLSP in
192189
CompilationDatabaseBuildSystem(
193190
projectRoot: projectRoot,
@@ -200,8 +197,7 @@ private extension BuildSystemKind {
200197
case .swiftPM(projectRoot: let projectRoot):
201198
return await Self.createBuiltInBuildSystemAdapter(
202199
projectRoot: projectRoot,
203-
messagesToSourceKitLSPHandler: messagesToSourceKitLSPHandler,
204-
buildSystemTestHooks: testHooks
200+
messagesToSourceKitLSPHandler: messagesToSourceKitLSPHandler
205201
) { connectionToSourceKitLSP in
206202
try await SwiftPMBuildSystem(
207203
projectRoot: projectRoot,
@@ -214,8 +210,7 @@ private extension BuildSystemKind {
214210
case .testBuildSystem(projectRoot: let projectRoot):
215211
return await Self.createBuiltInBuildSystemAdapter(
216212
projectRoot: projectRoot,
217-
messagesToSourceKitLSPHandler: messagesToSourceKitLSPHandler,
218-
buildSystemTestHooks: testHooks
213+
messagesToSourceKitLSPHandler: messagesToSourceKitLSPHandler
219214
) { connectionToSourceKitLSP in
220215
TestBuildSystem(projectRoot: projectRoot, connectionToSourceKitLSP: connectionToSourceKitLSP)
221216
}
@@ -404,8 +399,7 @@ package actor BuildSystemManager: QueueBasedMessageHandler {
404399
)
405400
let adapter = BuiltInBuildSystemAdapter(
406401
underlyingBuildSystem: legacyBuildServer,
407-
connectionToSourceKitLSP: legacyBuildServer.connectionToSourceKitLSP,
408-
buildSystemTestHooks: buildSystemTestHooks
402+
connectionToSourceKitLSP: legacyBuildServer.connectionToSourceKitLSP
409403
)
410404
let connectionToBuildSystem = LocalConnection(receiverName: "Legacy BSP server")
411405
connectionToBuildSystem.start(handler: adapter)
@@ -711,17 +705,14 @@ package actor BuildSystemManager: QueueBasedMessageHandler {
711705
in target: BuildTargetIdentifier?,
712706
language: Language
713707
) async -> FileBuildSettings? {
714-
if let target {
715-
let buildSettingsFromBuildSystem = await orLog("Getting build settings") {
716-
try await withTimeout(options.buildSettingsTimeoutOrDefault) {
717-
try await self.buildSettingsFromBuildSystem(for: document, in: target, language: language)
718-
} resultReceivedAfterTimeout: {
719-
await self.delegate?.fileBuildSettingsChanged([document])
720-
}
721-
}
722-
if let buildSettingsFromBuildSystem {
723-
return buildSettingsFromBuildSystem
708+
do {
709+
if let target,
710+
let buildSettings = try await buildSettingsFromBuildSystem(for: document, in: target, language: language)
711+
{
712+
return buildSettings
724713
}
714+
} catch {
715+
logger.error("Getting build settings failed: \(error.forLogging)")
725716
}
726717

727718
guard
@@ -755,15 +746,8 @@ package actor BuildSystemManager: QueueBasedMessageHandler {
755746
basedOn document: DocumentURI
756747
) async -> (mainFile: DocumentURI, settings: FileBuildSettings)? {
757748
let mainFile = await self.mainFile(for: document, language: language)
758-
let settings = await orLog("Getting build settings") {
759-
let target = try await withTimeout(options.buildSettingsTimeoutOrDefault) {
760-
await self.canonicalTarget(for: mainFile)
761-
} resultReceivedAfterTimeout: {
762-
await self.delegate?.fileBuildSettingsChanged([document])
763-
}
764-
return await self.buildSettings(for: mainFile, in: target, language: language)
765-
}
766-
guard let settings else {
749+
let target = await canonicalTarget(for: mainFile)
750+
guard let settings = await buildSettings(for: mainFile, in: target, language: language) else {
767751
return nil
768752
}
769753
return (mainFile, settings)

Sources/BuildSystemIntegration/BuildSystemTestHooks.swift

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,10 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
import LanguageServerProtocol
14-
1513
package struct BuildSystemTestHooks: Sendable {
1614
package var swiftPMTestHooks: SwiftPMTestHooks
1715

18-
/// A hook that will be executed before a request is handled by a `BuiltInBuildSystem`.
19-
///
20-
/// This allows requests to be artificially delayed.
21-
package var handleRequest: (@Sendable (any RequestType) async -> Void)?
22-
23-
package init(
24-
swiftPMTestHooks: SwiftPMTestHooks = SwiftPMTestHooks(),
25-
handleRequest: (@Sendable (any RequestType) async -> Void)? = nil
26-
) {
16+
package init(swiftPMTestHooks: SwiftPMTestHooks = SwiftPMTestHooks()) {
2717
self.swiftPMTestHooks = swiftPMTestHooks
28-
self.handleRequest = handleRequest
2918
}
3019
}

Sources/BuildSystemIntegration/BuiltInBuildSystemAdapter.swift

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ actor BuiltInBuildSystemAdapter: QueueBasedMessageHandler {
5151
/// The connection with which messages are sent to `BuildSystemManager`.
5252
private let connectionToSourceKitLSP: LocalConnection
5353

54-
private let buildSystemTestHooks: BuildSystemTestHooks
55-
5654
/// If the underlying build system is a `TestBuildSystem`, return it. Otherwise, `nil`
5755
///
5856
/// - Important: For testing purposes only.
@@ -64,12 +62,10 @@ actor BuiltInBuildSystemAdapter: QueueBasedMessageHandler {
6462
/// from the build system to SourceKit-LSP.
6563
init(
6664
underlyingBuildSystem: BuiltInBuildSystem,
67-
connectionToSourceKitLSP: LocalConnection,
68-
buildSystemTestHooks: BuildSystemTestHooks
65+
connectionToSourceKitLSP: LocalConnection
6966
) {
7067
self.underlyingBuildSystem = underlyingBuildSystem
7168
self.connectionToSourceKitLSP = connectionToSourceKitLSP
72-
self.buildSystemTestHooks = buildSystemTestHooks
7369
}
7470

7571
deinit {
@@ -106,7 +102,6 @@ actor BuiltInBuildSystemAdapter: QueueBasedMessageHandler {
106102
}
107103

108104
package func handleImpl<Request: RequestType>(_ request: RequestAndReply<Request>) async {
109-
await buildSystemTestHooks.handleRequest?(request.params)
110105
switch request {
111106
case let request as RequestAndReply<BuildShutdownRequest>:
112107
await request.reply { VoidResponse() }

Sources/SKOptions/SourceKitLSPOptions.swift

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -241,13 +241,6 @@ public struct SourceKitLSPOptions: Sendable, Codable, Equatable, CustomLogString
241241
set { fallbackBuildSystem = newValue }
242242
}
243243

244-
/// Number of milliseconds to wait for build settings from the build system before using fallback build settings.
245-
public var buildSettingsTimeout: Int?
246-
public var buildSettingsTimeoutOrDefault: Duration {
247-
// The default timeout of 500ms was chosen arbitrarily without any measurements.
248-
get { .milliseconds(buildSettingsTimeout ?? 500) }
249-
}
250-
251244
public var clangdOptions: [String]?
252245

253246
private var index: IndexOptions?

Sources/SKTestSupport/WrappedSemaphore.swift

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,12 @@ package struct WrappedSemaphore: Sendable {
5151
}
5252

5353
/// Wait for a signal and emit an XCTFail if the semaphore is not signaled within `timeout`.
54-
package func waitOrXCTFail(
55-
timeout: DispatchTime = DispatchTime.now() + .seconds(Int(defaultTimeout)),
56-
file: StaticString = #filePath,
57-
line: UInt = #line
58-
) {
54+
package func waitOrXCTFail(timeout: DispatchTime = DispatchTime.now() + .seconds(Int(defaultTimeout))) {
5955
switch self.wait(timeout: timeout) {
6056
case .success:
6157
break
6258
case .timedOut:
63-
XCTFail("\(name) timed out", file: file, line: line)
59+
XCTFail("\(name) timed out")
6460
}
6561
}
6662
}

Sources/SourceKitLSP/Swift/SwiftLanguageService.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -989,7 +989,6 @@ extension SwiftLanguageService {
989989
)
990990
let snapshot = try await self.latestSnapshot(for: req.textDocument.uri)
991991
let buildSettings = await self.buildSettings(for: req.textDocument.uri)
992-
try Task.checkCancellation()
993992
let diagnosticReport = try await self.diagnosticReportManager.diagnosticReport(
994993
for: snapshot,
995994
buildSettings: buildSettings

Sources/SwiftExtensions/AsyncUtils.swift

Lines changed: 1 addition & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,6 @@ extension Collection where Element: Sendable {
169169

170170
package struct TimeoutError: Error, CustomStringConvertible {
171171
package var description: String { "Timed out" }
172-
173-
package init() {}
174172
}
175173

176174
/// Executes `body`. If it doesn't finish after `duration`, throws a `TimeoutError`.
@@ -186,56 +184,10 @@ package func withTimeout<T: Sendable>(
186184
taskGroup.addTask {
187185
return try await body()
188186
}
189-
defer {
190-
taskGroup.cancelAll()
191-
}
192187
for try await value in taskGroup {
188+
taskGroup.cancelAll()
193189
return value
194190
}
195191
throw CancellationError()
196192
}
197193
}
198-
199-
/// Executes `body`. If it doesn't finish after `duration`, return `nil` and continue running body. When `body` returns
200-
/// a value after the timeout, `resultReceivedAfterTimeout` is called.
201-
///
202-
/// - Important: `body` will not be cancelled when the timeout is received. Use the other overload of `withTimeout` if
203-
/// `body` should be cancelled after `timeout`.
204-
package func withTimeout<T: Sendable>(
205-
_ timeout: Duration,
206-
body: @escaping @Sendable () async throws -> T?,
207-
resultReceivedAfterTimeout: @escaping @Sendable () async -> Void
208-
) async throws -> T? {
209-
let didHitTimeout = AtomicBool(initialValue: false)
210-
211-
let stream = AsyncThrowingStream<T?, Error> { continuation in
212-
Task {
213-
try await Task.sleep(for: timeout)
214-
didHitTimeout.value = true
215-
continuation.yield(nil)
216-
}
217-
218-
Task {
219-
do {
220-
let result = try await body()
221-
if didHitTimeout.value {
222-
await resultReceivedAfterTimeout()
223-
}
224-
continuation.yield(result)
225-
} catch {
226-
continuation.yield(with: .failure(error))
227-
}
228-
}
229-
}
230-
231-
for try await value in stream {
232-
return value
233-
}
234-
// The only reason for the loop above to terminate is if the Task got cancelled or if the continuation finishes
235-
// (which it never does).
236-
if Task.isCancelled {
237-
throw CancellationError()
238-
} else {
239-
preconditionFailure("Continuation never finishes")
240-
}
241-
}

Tests/BuildSystemIntegrationTests/FallbackBuildSettingsTests.swift

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,10 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
import BuildServerProtocol
1413
@_spi(Testing) import BuildSystemIntegration
1514
import LanguageServerProtocol
1615
import SKOptions
1716
import SKTestSupport
18-
import SourceKitLSP
1917
import TSCBasic
2018
import XCTest
2119

@@ -162,47 +160,4 @@ final class FallbackBuildSystemTests: XCTestCase {
162160

163161
XCTAssertNil(fallbackBuildSettings(for: source, language: Language(rawValue: "unknown"), options: .init()))
164162
}
165-
166-
func testFallbackBuildSettingsWhileBuildSystemIsComputingBuildSettings() async throws {
167-
let fallbackResultsReceived = WrappedSemaphore(name: "Fallback results received")
168-
let project = try await SwiftPMTestProject(
169-
files: [
170-
"Test.swift": """
171-
let x: 1️⃣String = 1
172-
"""
173-
],
174-
testHooks: TestHooks(
175-
buildSystemTestHooks: BuildSystemTestHooks(
176-
handleRequest: { request in
177-
if request is TextDocumentSourceKitOptionsRequest {
178-
fallbackResultsReceived.waitOrXCTFail()
179-
}
180-
}
181-
)
182-
)
183-
)
184-
185-
let (uri, positions) = try project.openDocument("Test.swift")
186-
187-
let diagsBeforeBuildSettings = try await project.testClient.send(
188-
DocumentDiagnosticsRequest(textDocument: TextDocumentIdentifier(uri))
189-
)
190-
XCTAssertEqual(diagsBeforeBuildSettings.fullReport?.items, [])
191-
192-
let hoverBeforeBuildSettings = try await project.testClient.send(
193-
HoverRequest(textDocument: TextDocumentIdentifier(uri), position: positions["1️⃣"])
194-
)
195-
XCTAssertNotNil(hoverBeforeBuildSettings?.contents)
196-
197-
fallbackResultsReceived.signal()
198-
199-
try await repeatUntilExpectedResult {
200-
let diagsAfterBuildSettings = try await project.testClient.send(
201-
DocumentDiagnosticsRequest(textDocument: TextDocumentIdentifier(uri))
202-
)
203-
return diagsAfterBuildSettings.fullReport?.items.map(\.message) == [
204-
"Cannot convert value of type 'Int' to specified type 'String'"
205-
]
206-
}
207-
}
208163
}

0 commit comments

Comments
 (0)