Skip to content

Commit b7fa9a9

Browse files
authored
Merge pull request #1413 from ahoppen/prepare-experimental-feature
Make passing `--experimental-prepare-for-indexing` to `swift build` an experimental feature
2 parents f203b3a + f98da77 commit b7fa9a9

File tree

10 files changed

+52
-82
lines changed

10 files changed

+52
-82
lines changed

Sources/Diagnose/IndexCommand.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public struct IndexCommand: AsyncParsableCommand {
7474

7575
public func run() async throws {
7676
var serverOptions = SourceKitLSPServer.Options()
77-
serverOptions.experimentalFeatures.append(.backgroundIndexing)
77+
serverOptions.experimentalFeatures.insert(.backgroundIndexing)
7878

7979
let installPath =
8080
if let toolchainOverride, let toolchain = Toolchain(try AbsolutePath(validating: toolchainOverride)) {

Sources/SKCore/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ add_library(SKCore STATIC
88
CompilationDatabase.swift
99
CompilationDatabaseBuildSystem.swift
1010
Debouncer.swift
11+
ExperimentalFeatures.swift
1112
FallbackBuildSystem.swift
1213
FileBuildSettings.swift
1314
IndexProcessResult.swift

Sources/SourceKitLSP/ExperimentalFeatures.swift renamed to Sources/SKCore/ExperimentalFeatures.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,7 @@
1515
public enum ExperimentalFeature: String, Codable, Sendable, CaseIterable {
1616
/// Enable background indexing.
1717
case backgroundIndexing = "background-indexing"
18+
19+
/// Add `--experimental-prepare-for-indexing` to the `swift build` command run to prepare a target for indexing.
20+
case swiftpmPrepareForIndexing = "swiftpm-prepare-for-indexing"
1821
}

Sources/SKSwiftPMWorkspace/SwiftPMBuildSystem.swift

Lines changed: 24 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -95,71 +95,35 @@ public actor SwiftPMBuildSystem {
9595
}
9696

9797
/// Callbacks that should be called if the list of possible test files has changed.
98-
public var testFilesDidChangeCallbacks: [() async -> Void] = []
98+
private var testFilesDidChangeCallbacks: [() async -> Void] = []
9999

100-
let workspacePath: TSCAbsolutePath
100+
private let workspacePath: TSCAbsolutePath
101101
/// The directory containing `Package.swift`.
102+
@_spi(Testing)
102103
public var projectRoot: TSCAbsolutePath
103-
var modulesGraph: ModulesGraph
104-
let workspace: Workspace
105-
public let toolsBuildParameters: BuildParameters
106-
public let destinationBuildParameters: BuildParameters
107-
let fileSystem: FileSystem
104+
private var modulesGraph: ModulesGraph
105+
private let workspace: Workspace
106+
@_spi(Testing) public let toolsBuildParameters: BuildParameters
107+
@_spi(Testing) public let destinationBuildParameters: BuildParameters
108+
private let fileSystem: FileSystem
108109
private let toolchainRegistry: ToolchainRegistry
109110

110111
private let swiftBuildSupportsPrepareForIndexingTask = SKSupport.ThreadSafeBox<Task<Bool, Never>?>(initialValue: nil)
111112

112-
#if compiler(>=6.1)
113-
#warning(
114-
"Remove swiftBuildSupportsPrepareForIndexing when we no longer need to support SwiftPM versions that don't have support for `--experimental-prepare-for-indexing`"
115-
)
116-
#endif
117-
/// Whether `swift build` supports the `--experimental-prepare-for-indexing` flag.
118-
private var swiftBuildSupportsPrepareForIndexing: Bool {
119-
get async {
120-
let task = swiftBuildSupportsPrepareForIndexingTask.withLock { task in
121-
if let task {
122-
return task
123-
}
124-
let newTask = Task { () -> Bool in
125-
guard let swift = await toolchainRegistry.default?.swift else {
126-
return false
127-
}
128-
129-
do {
130-
let process = Process(args: swift.pathString, "build", "--help-hidden")
131-
try process.launch()
132-
let result = try await process.waitUntilExit()
133-
guard let output = String(bytes: try result.output.get(), encoding: .utf8) else {
134-
return false
135-
}
136-
return output.contains("--experimental-prepare-for-indexing")
137-
} catch {
138-
return false
139-
}
140-
}
141-
task = newTask
142-
return newTask
143-
}
144-
145-
return await task.value
146-
}
147-
}
148-
149-
var fileToTarget: [DocumentURI: SwiftBuildTarget] = [:]
150-
var sourceDirToTarget: [DocumentURI: SwiftBuildTarget] = [:]
113+
private var fileToTarget: [DocumentURI: SwiftBuildTarget] = [:]
114+
private var sourceDirToTarget: [DocumentURI: SwiftBuildTarget] = [:]
151115

152116
/// Maps configured targets ids to their SwiftPM build target as well as an index in their topological sorting.
153117
///
154118
/// Targets with lower index are more low level, ie. targets with higher indices depend on targets with lower indices.
155-
var targets: [ConfiguredTarget: (index: Int, buildTarget: SwiftBuildTarget)] = [:]
119+
private var targets: [ConfiguredTarget: (index: Int, buildTarget: SwiftBuildTarget)] = [:]
156120

157121
/// The URIs for which the delegate has registered for change notifications,
158122
/// mapped to the language the delegate specified when registering for change notifications.
159-
var watchedFiles: Set<DocumentURI> = []
123+
private var watchedFiles: Set<DocumentURI> = []
160124

161125
/// This callback is informed when `reloadPackage` starts and ends executing.
162-
var reloadPackageStatusCallback: (ReloadPackageStatus) async -> Void
126+
private var reloadPackageStatusCallback: (ReloadPackageStatus) async -> Void
163127

164128
/// Debounces calls to `delegate.filesDependenciesUpdated`.
165129
///
@@ -169,16 +133,19 @@ public actor SwiftPMBuildSystem {
169133
/// `fileDependenciesUpdated` call once for every updated file within the target.
170134
///
171135
/// Force-unwrapped optional because initializing it requires access to `self`.
172-
var fileDependenciesUpdatedDebouncer: Debouncer<Set<DocumentURI>>! = nil
136+
private var fileDependenciesUpdatedDebouncer: Debouncer<Set<DocumentURI>>! = nil
173137

174138
/// A `ObservabilitySystem` from `SwiftPM` that logs.
175139
private let observabilitySystem = ObservabilitySystem({ scope, diagnostic in
176140
logger.log(level: diagnostic.severity.asLogLevel, "SwiftPM log: \(diagnostic.description)")
177141
})
178142

143+
/// Whether to pass `--experimental-prepare-for-indexing` to `swift build` as part of preparation.
144+
private let experimentalFeatures: Set<ExperimentalFeature>
145+
179146
/// Whether the `SwiftPMBuildSystem` is pointed at a `.index-build` directory that's independent of the
180147
/// user's build.
181-
private let isForIndexBuild: Bool
148+
private var isForIndexBuild: Bool { experimentalFeatures.contains(.backgroundIndexing) }
182149

183150
/// Creates a build system using the Swift Package Manager, if this workspace is a package.
184151
///
@@ -193,13 +160,13 @@ public actor SwiftPMBuildSystem {
193160
toolchainRegistry: ToolchainRegistry,
194161
fileSystem: FileSystem = localFileSystem,
195162
buildSetup: BuildSetup,
196-
isForIndexBuild: Bool,
163+
experimentalFeatures: Set<ExperimentalFeature>,
197164
reloadPackageStatusCallback: @escaping (ReloadPackageStatus) async -> Void = { _ in }
198165
) async throws {
199166
self.workspacePath = workspacePath
200167
self.fileSystem = fileSystem
201168
self.toolchainRegistry = toolchainRegistry
202-
self.isForIndexBuild = isForIndexBuild
169+
self.experimentalFeatures = experimentalFeatures
203170

204171
guard let packageRoot = findPackageDirectory(containing: workspacePath, fileSystem) else {
205172
throw Error.noManifest(workspacePath: workspacePath)
@@ -218,7 +185,7 @@ public actor SwiftPMBuildSystem {
218185
forRootPackage: AbsolutePath(packageRoot),
219186
fileSystem: fileSystem
220187
)
221-
if isForIndexBuild {
188+
if experimentalFeatures.contains(.backgroundIndexing) {
222189
location.scratchDirectory = AbsolutePath(packageRoot.appending(component: ".index-build"))
223190
} else if let scratchDirectory = buildSetup.path {
224191
location.scratchDirectory = AbsolutePath(scratchDirectory)
@@ -289,7 +256,7 @@ public actor SwiftPMBuildSystem {
289256
uri: DocumentURI,
290257
toolchainRegistry: ToolchainRegistry,
291258
buildSetup: BuildSetup,
292-
isForIndexBuild: Bool,
259+
experimentalFeatures: Set<ExperimentalFeature>,
293260
reloadPackageStatusCallback: @escaping (ReloadPackageStatus) async -> Void
294261
) async {
295262
guard let fileURL = uri.fileURL else {
@@ -301,7 +268,7 @@ public actor SwiftPMBuildSystem {
301268
toolchainRegistry: toolchainRegistry,
302269
fileSystem: localFileSystem,
303270
buildSetup: buildSetup,
304-
isForIndexBuild: isForIndexBuild,
271+
experimentalFeatures: experimentalFeatures,
305272
reloadPackageStatusCallback: reloadPackageStatusCallback
306273
)
307274
} catch Error.noManifest {
@@ -612,7 +579,7 @@ extension SwiftPMBuildSystem: SKCore.BuildSystem {
612579
arguments += self.destinationBuildParameters.flags.swiftCompilerFlags.flatMap { ["-Xswiftc", $0] }
613580
arguments += self.destinationBuildParameters.flags.linkerFlags.flatMap { ["-Xlinker", $0] }
614581
arguments += self.destinationBuildParameters.flags.xcbuildFlags?.flatMap { ["-Xxcbuild", $0] } ?? []
615-
if await swiftBuildSupportsPrepareForIndexing {
582+
if experimentalFeatures.contains(.swiftpmPrepareForIndexing) {
616583
arguments.append("--experimental-prepare-for-indexing")
617584
}
618585
if Task.isCancelled {

Sources/SKTestSupport/TestSourceKitLSPClient.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public final class TestSourceKitLSPClient: MessageHandler {
110110
serverOptions.buildSetup.flags.swiftCompilerFlags += ["-module-cache-path", globalModuleCache.path]
111111
}
112112
if enableBackgroundIndexing {
113-
serverOptions.experimentalFeatures.append(.backgroundIndexing)
113+
serverOptions.experimentalFeatures.insert(.backgroundIndexing)
114114
}
115115

116116
var notificationYielder: AsyncStream<any NotificationType>.Continuation!

Sources/SourceKitLSP/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ add_library(SourceKitLSP STATIC
44
CreateBuildSystem.swift
55
DocumentManager.swift
66
DocumentSnapshot+FromFileContents.swift
7-
ExperimentalFeatures.swift
87
IndexProgressManager.swift
98
IndexStoreDB+MainFilesProvider.swift
109
LanguageServerType.swift

Sources/SourceKitLSP/CreateBuildSystem.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func createBuildSystem(
3838
uri: rootUri,
3939
toolchainRegistry: toolchainRegistry,
4040
buildSetup: options.buildSetup,
41-
isForIndexBuild: options.experimentalFeatures.contains(.backgroundIndexing),
41+
experimentalFeatures: options.experimentalFeatures,
4242
reloadPackageStatusCallback: reloadPackageStatusCallback
4343
)
4444
}

Sources/SourceKitLSP/SourceKitLSPServer+Options.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ extension SourceKitLSPServer {
5050
public var swiftPublishDiagnosticsDebounceDuration: TimeInterval
5151

5252
/// Experimental features that are enabled.
53-
public var experimentalFeatures: [ExperimentalFeature]
53+
public var experimentalFeatures: Set<ExperimentalFeature>
5454

5555
public var indexTestHooks: IndexTestHooks
5656

@@ -62,7 +62,7 @@ extension SourceKitLSPServer {
6262
completionOptions: SKCompletionOptions = .init(),
6363
generatedInterfacesPath: AbsolutePath = defaultDirectoryForGeneratedInterfaces,
6464
swiftPublishDiagnosticsDebounceDuration: TimeInterval = 2, /* 2s */
65-
experimentalFeatures: [ExperimentalFeature] = [],
65+
experimentalFeatures: Set<ExperimentalFeature> = [],
6666
indexTestHooks: IndexTestHooks = IndexTestHooks()
6767
) {
6868
self.buildSetup = buildSetup

Sources/sourcekit-lsp/SourceKitLSP.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ struct SourceKitLSP: AsyncParsableCommand {
224224
serverOptions.indexOptions.indexPrefixMappings = indexPrefixMappings
225225
serverOptions.completionOptions.maxResults = completionMaxResults
226226
serverOptions.generatedInterfacesPath = generatedInterfacesPath
227-
serverOptions.experimentalFeatures = experimentalFeatures
227+
serverOptions.experimentalFeatures = Set(experimentalFeatures)
228228

229229
return serverOptions
230230
}

Tests/SKSwiftPMWorkspaceTests/SwiftPMBuildSystemTests.swift

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import LSPTestSupport
1515
import LanguageServerProtocol
1616
import PackageModel
1717
@_spi(Testing) import SKCore
18-
import SKSwiftPMWorkspace
18+
@_spi(Testing) import SKSwiftPMWorkspace
1919
import SKTestSupport
2020
import SourceKitLSP
2121
import TSCBasic
@@ -54,7 +54,7 @@ final class SwiftPMBuildSystemTests: XCTestCase {
5454
toolchainRegistry: tr,
5555
fileSystem: fs,
5656
buildSetup: SourceKitLSPServer.Options.testDefault.buildSetup,
57-
isForIndexBuild: false
57+
experimentalFeatures: []
5858
)
5959
)
6060
}
@@ -81,7 +81,7 @@ final class SwiftPMBuildSystemTests: XCTestCase {
8181
toolchainRegistry: tr,
8282
fileSystem: fs,
8383
buildSetup: SourceKitLSPServer.Options.testDefault.buildSetup,
84-
isForIndexBuild: false
84+
experimentalFeatures: []
8585
)
8686
await assertThrowsError(try await buildSystem.generateBuildGraph(allowFileSystemWrites: false))
8787
}
@@ -111,7 +111,7 @@ final class SwiftPMBuildSystemTests: XCTestCase {
111111
toolchainRegistry: ToolchainRegistry(toolchains: []),
112112
fileSystem: fs,
113113
buildSetup: SourceKitLSPServer.Options.testDefault.buildSetup,
114-
isForIndexBuild: false
114+
experimentalFeatures: []
115115
)
116116
)
117117
}
@@ -142,7 +142,7 @@ final class SwiftPMBuildSystemTests: XCTestCase {
142142
toolchainRegistry: tr,
143143
fileSystem: fs,
144144
buildSetup: SourceKitLSPServer.Options.testDefault.buildSetup,
145-
isForIndexBuild: false
145+
experimentalFeatures: []
146146
)
147147
try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false)
148148

@@ -207,7 +207,7 @@ final class SwiftPMBuildSystemTests: XCTestCase {
207207
toolchainRegistry: tr,
208208
fileSystem: localFileSystem,
209209
buildSetup: SourceKitLSPServer.Options.testDefault.buildSetup,
210-
isForIndexBuild: false
210+
experimentalFeatures: []
211211
)
212212
try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false)
213213

@@ -270,7 +270,7 @@ final class SwiftPMBuildSystemTests: XCTestCase {
270270
toolchainRegistry: tr,
271271
fileSystem: fs,
272272
buildSetup: config,
273-
isForIndexBuild: false
273+
experimentalFeatures: []
274274
)
275275
try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false)
276276

@@ -312,7 +312,7 @@ final class SwiftPMBuildSystemTests: XCTestCase {
312312
toolchainRegistry: tr,
313313
fileSystem: fs,
314314
buildSetup: SourceKitLSPServer.Options.testDefault.buildSetup,
315-
isForIndexBuild: false
315+
experimentalFeatures: []
316316
)
317317
try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false)
318318

@@ -349,7 +349,7 @@ final class SwiftPMBuildSystemTests: XCTestCase {
349349
toolchainRegistry: tr,
350350
fileSystem: fs,
351351
buildSetup: SourceKitLSPServer.Options.testDefault.buildSetup,
352-
isForIndexBuild: false
352+
experimentalFeatures: []
353353
)
354354
try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false)
355355

@@ -398,7 +398,7 @@ final class SwiftPMBuildSystemTests: XCTestCase {
398398
toolchainRegistry: tr,
399399
fileSystem: fs,
400400
buildSetup: SourceKitLSPServer.Options.testDefault.buildSetup,
401-
isForIndexBuild: false
401+
experimentalFeatures: []
402402
)
403403
try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false)
404404

@@ -463,7 +463,7 @@ final class SwiftPMBuildSystemTests: XCTestCase {
463463
toolchainRegistry: tr,
464464
fileSystem: fs,
465465
buildSetup: SourceKitLSPServer.Options.testDefault.buildSetup,
466-
isForIndexBuild: false
466+
experimentalFeatures: []
467467
)
468468
try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false)
469469

@@ -507,7 +507,7 @@ final class SwiftPMBuildSystemTests: XCTestCase {
507507
toolchainRegistry: tr,
508508
fileSystem: fs,
509509
buildSetup: SourceKitLSPServer.Options.testDefault.buildSetup,
510-
isForIndexBuild: false
510+
experimentalFeatures: []
511511
)
512512
try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false)
513513

@@ -588,7 +588,7 @@ final class SwiftPMBuildSystemTests: XCTestCase {
588588
toolchainRegistry: ToolchainRegistry.forTesting,
589589
fileSystem: fs,
590590
buildSetup: SourceKitLSPServer.Options.testDefault.buildSetup,
591-
isForIndexBuild: false
591+
experimentalFeatures: []
592592
)
593593
try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false)
594594

@@ -640,7 +640,7 @@ final class SwiftPMBuildSystemTests: XCTestCase {
640640
toolchainRegistry: tr,
641641
fileSystem: fs,
642642
buildSetup: SourceKitLSPServer.Options.testDefault.buildSetup,
643-
isForIndexBuild: false
643+
experimentalFeatures: []
644644
)
645645
try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false)
646646

@@ -708,7 +708,7 @@ final class SwiftPMBuildSystemTests: XCTestCase {
708708
toolchainRegistry: ToolchainRegistry.forTesting,
709709
fileSystem: fs,
710710
buildSetup: SourceKitLSPServer.Options.testDefault.buildSetup,
711-
isForIndexBuild: false
711+
experimentalFeatures: []
712712
)
713713
try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false)
714714

@@ -748,7 +748,7 @@ final class SwiftPMBuildSystemTests: XCTestCase {
748748
toolchainRegistry: tr,
749749
fileSystem: fs,
750750
buildSetup: SourceKitLSPServer.Options.testDefault.buildSetup,
751-
isForIndexBuild: false
751+
experimentalFeatures: []
752752
)
753753
try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false)
754754

@@ -789,7 +789,7 @@ final class SwiftPMBuildSystemTests: XCTestCase {
789789
toolchainRegistry: tr,
790790
fileSystem: fs,
791791
buildSetup: SourceKitLSPServer.Options.testDefault.buildSetup,
792-
isForIndexBuild: false
792+
experimentalFeatures: []
793793
)
794794

795795
assertEqual(await swiftpmBuildSystem.projectRoot, try resolveSymlinks(tempDir.appending(component: "pkg")))
@@ -824,7 +824,7 @@ final class SwiftPMBuildSystemTests: XCTestCase {
824824
toolchainRegistry: tr,
825825
fileSystem: fs,
826826
buildSetup: SourceKitLSPServer.Options.testDefault.buildSetup,
827-
isForIndexBuild: false
827+
experimentalFeatures: []
828828
)
829829
try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false)
830830

0 commit comments

Comments
 (0)