@@ -234,11 +234,20 @@ public actor SourceKitLSPServer {
234234 // The latter might happen if there is an existing SwiftPM workspace that hasn't been reloaded after a new file
235235 // was added to it and thus currently doesn't know that it can handle that file. In that case, we shouldn't open
236236 // a new workspace for the same root. Instead, the existing workspace's build system needs to be reloaded.
237- if let workspace = await self . createWorkspace ( WorkspaceFolder ( uri: DocumentURI ( url) ) ) ,
238- await workspace. buildSystemManager. fileHandlingCapability ( for: uri) == . handled,
239- let projectRoot = await workspace. buildSystemManager. projectRoot,
240- !projectRoots. contains ( projectRoot)
241- {
237+ let workspace = await self . createWorkspace ( WorkspaceFolder ( uri: DocumentURI ( url) ) ) { buildSystem in
238+ guard let buildSystem, !projectRoots. contains ( await buildSystem. projectRoot) else {
239+ // If we didn't create a build system, `url` is not capable of handling the document.
240+ // If we already have a workspace at the same project root, don't create another one.
241+ return false
242+ }
243+ do {
244+ try await buildSystem. generateBuildGraph ( allowFileSystemWrites: false )
245+ } catch {
246+ return false
247+ }
248+ return await buildSystem. fileHandlingCapability ( for: uri) == . handled
249+ }
250+ if let workspace {
242251 return workspace
243252 }
244253 url. deleteLastPathComponent ( )
@@ -866,25 +875,22 @@ extension SourceKitLSPServer {
866875 }
867876
868877 /// Creates a workspace at the given `uri`.
869- private func createWorkspace( _ workspaceFolder: WorkspaceFolder ) async -> Workspace ? {
878+ ///
879+ /// If the build system that was determined for the workspace does not satisfy `condition`, `nil` is returned.
880+ private func createWorkspace(
881+ _ workspaceFolder: WorkspaceFolder ,
882+ condition: ( BuildSystem ? ) async -> Bool = { _ in true }
883+ ) async -> Workspace ? {
870884 guard let capabilityRegistry = capabilityRegistry else {
871885 logger. log ( " Cannot open workspace before server is initialized " )
872886 return nil
873887 }
874888 var options = self . options
875889 options. buildSetup = self . options. buildSetup. merging ( buildSetup ( for: workspaceFolder) )
876- return try ? await Workspace (
877- documentManager: self . documentManager,
890+ let buildSystem = await createBuildSystem (
878891 rootUri: workspaceFolder. uri,
879- capabilityRegistry: capabilityRegistry,
880- toolchainRegistry: self . toolchainRegistry,
881892 options: options,
882- compilationDatabaseSearchPaths: self . options. compilationDatabaseSearchPaths,
883- indexOptions: self . options. indexOptions,
884- indexTaskScheduler: indexTaskScheduler,
885- indexProcessDidProduceResult: { [ weak self] in
886- self ? . indexTaskDidProduceResult ( $0)
887- } ,
893+ toolchainRegistry: toolchainRegistry,
888894 reloadPackageStatusCallback: { [ weak self] status in
889895 guard let self else { return }
890896 switch status {
@@ -893,6 +899,34 @@ extension SourceKitLSPServer {
893899 case . end:
894900 await self . packageLoadingWorkDoneProgress. endProgress ( server: self )
895901 }
902+ }
903+ )
904+ guard await condition ( buildSystem) else {
905+ return nil
906+ }
907+ do {
908+ try await buildSystem? . generateBuildGraph ( allowFileSystemWrites: true )
909+ } catch {
910+ logger. error ( " failed to generate build graph at \( workspaceFolder. uri. forLogging) : \( error. forLogging) " )
911+ return nil
912+ }
913+
914+ let projectRoot = await buildSystem? . projectRoot. pathString
915+ logger. log (
916+ " Created workspace at \( workspaceFolder. uri. forLogging) as \( type ( of: buildSystem) ) with project root \( projectRoot ?? " <nil> " ) "
917+ )
918+
919+ return try ? await Workspace (
920+ documentManager: self . documentManager,
921+ rootUri: workspaceFolder. uri,
922+ capabilityRegistry: capabilityRegistry,
923+ buildSystem: buildSystem,
924+ toolchainRegistry: self . toolchainRegistry,
925+ options: options,
926+ indexOptions: self . options. indexOptions,
927+ indexTaskScheduler: indexTaskScheduler,
928+ indexProcessDidProduceResult: { [ weak self] in
929+ self ? . indexTaskDidProduceResult ( $0)
896930 } ,
897931 indexTasksWereScheduled: { [ weak self] count in
898932 self ? . indexProgressManager. indexTasksWereScheduled ( count: count)
0 commit comments