@@ -139,6 +139,7 @@ private extension BuildSystemKind {
139
139
private static func createBuiltInBuildSystemAdapter(
140
140
projectRoot: AbsolutePath ,
141
141
messagesToSourceKitLSPHandler: any MessageHandler ,
142
+ buildSystemTestHooks: BuildSystemTestHooks ,
142
143
_ createBuildSystem: @Sendable ( _ connectionToSourceKitLSP: any Connection ) async throws -> BuiltInBuildSystem ?
143
144
) async -> BuildSystemAdapter ? {
144
145
let connectionToSourceKitLSP = LocalConnection (
@@ -156,7 +157,8 @@ private extension BuildSystemKind {
156
157
logger. log ( " Created \( type ( of: buildSystem) , privacy: . public) at \( projectRoot. pathString) " )
157
158
let buildSystemAdapter = BuiltInBuildSystemAdapter (
158
159
underlyingBuildSystem: buildSystem,
159
- connectionToSourceKitLSP: connectionToSourceKitLSP
160
+ connectionToSourceKitLSP: connectionToSourceKitLSP,
161
+ buildSystemTestHooks: buildSystemTestHooks
160
162
)
161
163
let connectionToBuildSystem = LocalConnection (
162
164
receiverName: " \( type ( of: buildSystem) ) for \( projectRoot. asURL. lastPathComponent) "
@@ -190,7 +192,8 @@ private extension BuildSystemKind {
190
192
case . compilationDatabase( projectRoot: let projectRoot) :
191
193
return await Self . createBuiltInBuildSystemAdapter (
192
194
projectRoot: projectRoot,
193
- messagesToSourceKitLSPHandler: messagesToSourceKitLSPHandler
195
+ messagesToSourceKitLSPHandler: messagesToSourceKitLSPHandler,
196
+ buildSystemTestHooks: testHooks
194
197
) { connectionToSourceKitLSP in
195
198
CompilationDatabaseBuildSystem (
196
199
projectRoot: projectRoot,
@@ -203,7 +206,8 @@ private extension BuildSystemKind {
203
206
case . swiftPM( projectRoot: let projectRoot) :
204
207
return await Self . createBuiltInBuildSystemAdapter (
205
208
projectRoot: projectRoot,
206
- messagesToSourceKitLSPHandler: messagesToSourceKitLSPHandler
209
+ messagesToSourceKitLSPHandler: messagesToSourceKitLSPHandler,
210
+ buildSystemTestHooks: testHooks
207
211
) { connectionToSourceKitLSP in
208
212
try await SwiftPMBuildSystem (
209
213
projectRoot: projectRoot,
@@ -216,7 +220,8 @@ private extension BuildSystemKind {
216
220
case . testBuildSystem( projectRoot: let projectRoot) :
217
221
return await Self . createBuiltInBuildSystemAdapter (
218
222
projectRoot: projectRoot,
219
- messagesToSourceKitLSPHandler: messagesToSourceKitLSPHandler
223
+ messagesToSourceKitLSPHandler: messagesToSourceKitLSPHandler,
224
+ buildSystemTestHooks: testHooks
220
225
) { connectionToSourceKitLSP in
221
226
TestBuildSystem ( projectRoot: projectRoot, connectionToSourceKitLSP: connectionToSourceKitLSP)
222
227
}
@@ -411,7 +416,8 @@ package actor BuildSystemManager: QueueBasedMessageHandler {
411
416
)
412
417
let adapter = BuiltInBuildSystemAdapter (
413
418
underlyingBuildSystem: legacyBuildServer,
414
- connectionToSourceKitLSP: legacyBuildServer. connectionToSourceKitLSP
419
+ connectionToSourceKitLSP: legacyBuildServer. connectionToSourceKitLSP,
420
+ buildSystemTestHooks: buildSystemTestHooks
415
421
)
416
422
let connectionToBuildSystem = LocalConnection ( receiverName: " Legacy BSP server " )
417
423
connectionToBuildSystem. start ( handler: adapter)
@@ -672,7 +678,12 @@ package actor BuildSystemManager: QueueBasedMessageHandler {
672
678
/// Returns the target's module name as parsed from the `BuildTargetIdentifier`'s compiler arguments.
673
679
package func moduleName( for document: DocumentURI , in target: BuildTargetIdentifier ) async -> String ? {
674
680
guard let language = await self . defaultLanguage ( for: document, in: target) ,
675
- let buildSettings = await buildSettings ( for: document, in: target, language: language)
681
+ let buildSettings = await buildSettings (
682
+ for: document,
683
+ in: target,
684
+ language: language,
685
+ fallbackAfterTimeout: false
686
+ )
676
687
else {
677
688
return nil
678
689
}
@@ -715,11 +726,6 @@ package actor BuildSystemManager: QueueBasedMessageHandler {
715
726
language: language
716
727
)
717
728
718
- // TODO: We should only wait `fallbackSettingsTimeout` for build settings
719
- // and return fallback afterwards.
720
- // For now, this should be fine because all build systems return
721
- // very quickly from `settings(for:language:)`.
722
- // https://github.com/apple/sourcekit-lsp/issues/1181
723
729
let response = try await cachedSourceKitOptions. get ( request, isolation: self ) { request in
724
730
try await buildSystemAdapter. send ( request)
725
731
}
@@ -740,19 +746,30 @@ package actor BuildSystemManager: QueueBasedMessageHandler {
740
746
/// Only call this method if it is known that `document` is a main file. Prefer `buildSettingsInferredFromMainFile`
741
747
/// otherwise. If `document` is a header file, this will most likely return fallback settings because header files
742
748
/// don't have build settings by themselves.
749
+ ///
750
+ /// If `fallbackAfterTimeout` is true fallback build settings will be returned if no build settings can be found in
751
+ /// `SourceKitLSPOptions.buildSettingsTimeoutOrDefault`.
743
752
package func buildSettings(
744
753
for document: DocumentURI ,
745
754
in target: BuildTargetIdentifier ? ,
746
- language: Language
755
+ language: Language ,
756
+ fallbackAfterTimeout: Bool
747
757
) async -> FileBuildSettings ? {
748
- do {
749
- if let target,
750
- let buildSettings = try await buildSettingsFromBuildSystem ( for: document, in: target, language: language)
751
- {
752
- return buildSettings
758
+ if let target {
759
+ let buildSettingsFromBuildSystem = await orLog ( " Getting build settings " ) {
760
+ if fallbackAfterTimeout {
761
+ try await withTimeout ( options. buildSettingsTimeoutOrDefault) {
762
+ return try await self . buildSettingsFromBuildSystem ( for: document, in: target, language: language)
763
+ } resultReceivedAfterTimeout: {
764
+ await self . delegate? . fileBuildSettingsChanged ( [ document] )
765
+ }
766
+ } else {
767
+ try await self . buildSettingsFromBuildSystem ( for: document, in: target, language: language)
768
+ }
769
+ }
770
+ if let buildSettingsFromBuildSystem {
771
+ return buildSettingsFromBuildSystem
753
772
}
754
- } catch {
755
- logger. error ( " Getting build settings failed: \( error. forLogging) " )
756
773
}
757
774
758
775
guard
@@ -780,14 +797,27 @@ package actor BuildSystemManager: QueueBasedMessageHandler {
780
797
/// by the header file.
781
798
package func buildSettingsInferredFromMainFile(
782
799
for document: DocumentURI ,
783
- language: Language
800
+ language: Language ,
801
+ fallbackAfterTimeout: Bool
784
802
) async -> FileBuildSettings ? {
785
803
func mainFileAndSettings(
786
804
basedOn document: DocumentURI
787
805
) async -> ( mainFile: DocumentURI , settings: FileBuildSettings ) ? {
788
806
let mainFile = await self . mainFile ( for: document, language: language)
789
- let target = await canonicalTarget ( for: mainFile)
790
- guard let settings = await buildSettings ( for: mainFile, in: target, language: language) else {
807
+ let settings = await orLog ( " Getting build settings " ) {
808
+ let target = try await withTimeout ( options. buildSettingsTimeoutOrDefault) {
809
+ await self . canonicalTarget ( for: mainFile)
810
+ } resultReceivedAfterTimeout: {
811
+ await self . delegate? . fileBuildSettingsChanged ( [ document] )
812
+ }
813
+ return await self . buildSettings (
814
+ for: mainFile,
815
+ in: target,
816
+ language: language,
817
+ fallbackAfterTimeout: fallbackAfterTimeout
818
+ )
819
+ }
820
+ guard let settings else {
791
821
return nil
792
822
}
793
823
return ( mainFile, settings)
0 commit comments