diff --git a/Sources/Diagnose/IndexCommand.swift b/Sources/Diagnose/IndexCommand.swift index 8e556581c..8fd7fba59 100644 --- a/Sources/Diagnose/IndexCommand.swift +++ b/Sources/Diagnose/IndexCommand.swift @@ -82,7 +82,10 @@ public struct IndexCommand: AsyncParsableCommand { public init() {} public func run() async throws { - let options = SourceKitLSPOptions(experimentalFeatures: Set(experimentalFeatures).union([.backgroundIndexing])) + let options = SourceKitLSPOptions( + backgroundIndexing: true, + experimentalFeatures: Set(experimentalFeatures) + ) let installPath = if let toolchainOverride, let toolchain = Toolchain(try AbsolutePath(validating: toolchainOverride)) { diff --git a/Sources/SKCore/SourceKitLSPOptions.swift b/Sources/SKCore/SourceKitLSPOptions.swift index 0a9ad011a..85efe653d 100644 --- a/Sources/SKCore/SourceKitLSPOptions.swift +++ b/Sources/SKCore/SourceKitLSPOptions.swift @@ -111,6 +111,18 @@ public struct SourceKitLSPOptions: Sendable, Codable { public var maxCoresPercentageToUseForBackgroundIndexing: Double? public var updateIndexStoreTimeout: Int? + public var maxCoresPercentageToUseForBackgroundIndexingOrDefault: Double { + return maxCoresPercentageToUseForBackgroundIndexing ?? 1 + } + + public var updateIndexStoreTimeoutOrDefault: Duration { + if let updateIndexStoreTimeout { + .seconds(updateIndexStoreTimeout) + } else { + .seconds(120) + } + } + public init( indexStorePath: String? = nil, indexDatabasePath: String? = nil, @@ -137,16 +149,19 @@ public struct SourceKitLSPOptions: Sendable, Codable { } } - public var swiftPM: SwiftPMOptions? - public var compilationDatabase: CompilationDatabaseOptions? - public var fallbackBuildSystem: FallbackBuildSystemOptions? + public var swiftPM: SwiftPMOptions + public var compilationDatabase: CompilationDatabaseOptions + public var fallbackBuildSystem: FallbackBuildSystemOptions public var clangdOptions: [String]? - public var index: IndexOptions? + public var index: IndexOptions /// Default workspace type (buildserver|compdb|swiftpm). Overrides workspace type selection logic. public var defaultWorkspaceType: WorkspaceType? public var generatedFilesPath: String? + /// Whether background indexing is enabled. + public var backgroundIndexing: Bool? + /// Experimental features that are enabled. public var experimentalFeatures: Set? = nil @@ -155,25 +170,29 @@ public struct SourceKitLSPOptions: Sendable, Codable { /// /// This is mostly intended for testing purposes so we don't need to wait the debouncing time to get a diagnostics /// notification when running unit tests. - public var swiftPublishDiagnosticsDebounce: Double? = nil + public var swiftPublishDiagnosticsDebounceDuration: Double? = nil - public var swiftPublishDiagnosticsDebounceDuration: TimeInterval { - if let workDoneProgressDebounce { - return workDoneProgressDebounce + public var swiftPublishDiagnosticsDebounceDurationOrDefault: Duration { + if let swiftPublishDiagnosticsDebounceDuration { + return .seconds(swiftPublishDiagnosticsDebounceDuration) } - return 2 /* seconds */ + return .seconds(2) } /// When a task is started that should be displayed to the client as a work done progress, how many milliseconds to /// wait before actually starting the work done progress. This prevents flickering of the work done progress in the /// client for short-lived index tasks which end within this duration. - public var workDoneProgressDebounce: Double? = nil + public var workDoneProgressDebounceDuration: Double? = nil - public var workDoneProgressDebounceDuration: Duration { - if let workDoneProgressDebounce { - return .seconds(workDoneProgressDebounce) + public var workDoneProgressDebounceDurationOrDefault: Duration { + if let workDoneProgressDebounceDuration { + return .seconds(workDoneProgressDebounceDuration) } - return .seconds(0) + return .seconds(1) + } + + public var backgroundIndexingOrDefault: Bool { + return backgroundIndexing ?? false } public init( @@ -184,9 +203,10 @@ public struct SourceKitLSPOptions: Sendable, Codable { index: IndexOptions = .init(), defaultWorkspaceType: WorkspaceType? = nil, generatedFilesPath: String? = nil, + backgroundIndexing: Bool? = nil, experimentalFeatures: Set? = nil, - swiftPublishDiagnosticsDebounce: Double? = nil, - workDoneProgressDebounce: Double? = nil + swiftPublishDiagnosticsDebounceDuration: Double? = nil, + workDoneProgressDebounceDuration: Double? = nil ) { self.swiftPM = swiftPM self.fallbackBuildSystem = fallbackBuildSystem @@ -195,9 +215,10 @@ public struct SourceKitLSPOptions: Sendable, Codable { self.index = index self.generatedFilesPath = generatedFilesPath self.defaultWorkspaceType = defaultWorkspaceType + self.backgroundIndexing = backgroundIndexing self.experimentalFeatures = experimentalFeatures - self.swiftPublishDiagnosticsDebounce = swiftPublishDiagnosticsDebounce - self.workDoneProgressDebounce = workDoneProgressDebounce + self.swiftPublishDiagnosticsDebounceDuration = swiftPublishDiagnosticsDebounceDuration + self.workDoneProgressDebounceDuration = workDoneProgressDebounceDuration } public init?(path: URL?) { @@ -207,7 +228,7 @@ public struct SourceKitLSPOptions: Sendable, Codable { guard let decoded = orLog( "Parsing config.json", - { try JSONDecoder().decode(SourceKitLSPOptions.self, from: contents) } + { try JSONDecoder().decode(Self.self, from: contents) } ) else { return nil @@ -217,23 +238,25 @@ public struct SourceKitLSPOptions: Sendable, Codable { public static func merging(base: SourceKitLSPOptions, override: SourceKitLSPOptions?) -> SourceKitLSPOptions { return SourceKitLSPOptions( - swiftPM: SwiftPMOptions.merging(base: base.swiftPM ?? .init(), override: override?.swiftPM), + swiftPM: SwiftPMOptions.merging(base: base.swiftPM, override: override?.swiftPM), fallbackBuildSystem: FallbackBuildSystemOptions.merging( - base: base.fallbackBuildSystem ?? .init(), + base: base.fallbackBuildSystem, override: override?.fallbackBuildSystem ), compilationDatabase: CompilationDatabaseOptions.merging( - base: base.compilationDatabase ?? .init(), + base: base.compilationDatabase, override: override?.compilationDatabase ), clangdOptions: override?.clangdOptions ?? base.clangdOptions, - index: IndexOptions.merging(base: base.index ?? .init(), override: override?.index), + index: IndexOptions.merging(base: base.index, override: override?.index), defaultWorkspaceType: override?.defaultWorkspaceType ?? base.defaultWorkspaceType, generatedFilesPath: override?.generatedFilesPath ?? base.generatedFilesPath, + backgroundIndexing: override?.backgroundIndexing ?? base.backgroundIndexing, experimentalFeatures: override?.experimentalFeatures ?? base.experimentalFeatures, - swiftPublishDiagnosticsDebounce: override?.swiftPublishDiagnosticsDebounce - ?? base.swiftPublishDiagnosticsDebounce, - workDoneProgressDebounce: override?.workDoneProgressDebounce ?? base.workDoneProgressDebounce + swiftPublishDiagnosticsDebounceDuration: override?.swiftPublishDiagnosticsDebounceDuration + ?? base.swiftPublishDiagnosticsDebounceDuration, + workDoneProgressDebounceDuration: override?.workDoneProgressDebounceDuration + ?? base.workDoneProgressDebounceDuration ) } @@ -250,4 +273,34 @@ public struct SourceKitLSPOptions: Sendable, Codable { } return experimentalFeatures.contains(feature) } + + public init(from decoder: any Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + + self.swiftPM = try container.decodeIfPresent(SwiftPMOptions.self, forKey: CodingKeys.swiftPM) ?? .init() + self.compilationDatabase = + try container.decodeIfPresent(CompilationDatabaseOptions.self, forKey: CodingKeys.compilationDatabase) ?? .init() + self.fallbackBuildSystem = + try container.decodeIfPresent(FallbackBuildSystemOptions.self, forKey: CodingKeys.fallbackBuildSystem) ?? .init() + self.clangdOptions = try container.decodeIfPresent([String].self, forKey: CodingKeys.clangdOptions) + self.index = try container.decodeIfPresent(IndexOptions.self, forKey: CodingKeys.index) ?? .init() + self.defaultWorkspaceType = try container.decodeIfPresent( + WorkspaceType.self, + forKey: CodingKeys.defaultWorkspaceType + ) + self.generatedFilesPath = try container.decodeIfPresent(String.self, forKey: CodingKeys.generatedFilesPath) + self.backgroundIndexing = try container.decodeIfPresent(Bool.self, forKey: CodingKeys.backgroundIndexing) + self.experimentalFeatures = try container.decodeIfPresent( + Set.self, + forKey: CodingKeys.experimentalFeatures + ) + self.swiftPublishDiagnosticsDebounceDuration = try container.decodeIfPresent( + Double.self, + forKey: CodingKeys.swiftPublishDiagnosticsDebounceDuration + ) + self.workDoneProgressDebounceDuration = try container.decodeIfPresent( + Double.self, + forKey: CodingKeys.workDoneProgressDebounceDuration + ) + } } diff --git a/Sources/SKSupport/ExperimentalFeatures.swift b/Sources/SKSupport/ExperimentalFeatures.swift index 3bb670563..5c7b4a4b8 100644 --- a/Sources/SKSupport/ExperimentalFeatures.swift +++ b/Sources/SKSupport/ExperimentalFeatures.swift @@ -13,9 +13,6 @@ /// An experimental feature that can be enabled by passing `--experimental-feature` to `sourcekit-lsp` on the command /// line. The raw value of this feature is how it is named on the command line. public enum ExperimentalFeature: String, Codable, Sendable, CaseIterable { - /// Enable background indexing. - case backgroundIndexing = "background-indexing" - /// Add `--experimental-prepare-for-indexing` to the `swift build` command run to prepare a target for indexing. case swiftpmPrepareForIndexing = "swiftpm-prepare-for-indexing" diff --git a/Sources/SKSwiftPMWorkspace/SwiftPMBuildSystem.swift b/Sources/SKSwiftPMWorkspace/SwiftPMBuildSystem.swift index 0f47fa071..7b372b56c 100644 --- a/Sources/SKSwiftPMWorkspace/SwiftPMBuildSystem.swift +++ b/Sources/SKSwiftPMWorkspace/SwiftPMBuildSystem.swift @@ -131,7 +131,7 @@ public actor SwiftPMBuildSystem { private let workspacePath: TSCAbsolutePath /// Options that allow the user to pass extra compiler flags. - private let options: SourceKitLSPOptions.SwiftPMOptions + private let options: SourceKitLSPOptions /// The directory containing `Package.swift`. @_spi(Testing) @@ -175,12 +175,9 @@ public actor SwiftPMBuildSystem { logger.log(level: diagnostic.severity.asLogLevel, "SwiftPM log: \(diagnostic.description)") }) - /// Whether to pass `--experimental-prepare-for-indexing` to `swift build` as part of preparation. - private let experimentalFeatures: Set - /// Whether the `SwiftPMBuildSystem` is pointed at a `.index-build` directory that's independent of the /// user's build. - private var isForIndexBuild: Bool { experimentalFeatures.contains(.backgroundIndexing) } + private var isForIndexBuild: Bool { options.backgroundIndexingOrDefault } private let testHooks: SwiftPMTestHooks @@ -196,8 +193,7 @@ public actor SwiftPMBuildSystem { workspacePath: TSCAbsolutePath, toolchainRegistry: ToolchainRegistry, fileSystem: FileSystem = localFileSystem, - options: SourceKitLSPOptions.SwiftPMOptions, - experimentalFeatures: Set, + options: SourceKitLSPOptions, reloadPackageStatusCallback: @escaping (ReloadPackageStatus) async -> Void = { _ in }, testHooks: SwiftPMTestHooks ) async throws { @@ -209,7 +205,6 @@ public actor SwiftPMBuildSystem { } self.toolchain = toolchain - self.experimentalFeatures = experimentalFeatures self.testHooks = testHooks guard let packageRoot = findPackageDirectory(containing: workspacePath, fileSystem) else { @@ -229,9 +224,9 @@ public actor SwiftPMBuildSystem { forRootPackage: AbsolutePath(packageRoot), fileSystem: fileSystem ) - if experimentalFeatures.contains(.backgroundIndexing) { + if options.backgroundIndexingOrDefault { location.scratchDirectory = AbsolutePath(packageRoot.appending(component: ".index-build")) - } else if let scratchDirectory = options.scratchPath, + } else if let scratchDirectory = options.swiftPM.scratchPath, let scratchDirectoryPath = try? AbsolutePath(validating: scratchDirectory) { location.scratchDirectory = scratchDirectoryPath @@ -248,7 +243,7 @@ public actor SwiftPMBuildSystem { ) let buildConfiguration: PackageModel.BuildConfiguration - switch options.configuration { + switch options.swiftPM.configuration { case .debug, nil: buildConfiguration = .debug case .release: @@ -256,10 +251,10 @@ public actor SwiftPMBuildSystem { } let buildFlags = BuildFlags( - cCompilerFlags: options.cCompilerFlags ?? [], - cxxCompilerFlags: options.cxxCompilerFlags ?? [], - swiftCompilerFlags: options.swiftCompilerFlags ?? [], - linkerFlags: options.linkerFlags ?? [] + cCompilerFlags: options.swiftPM.cCompilerFlags ?? [], + cxxCompilerFlags: options.swiftPM.cxxCompilerFlags ?? [], + swiftCompilerFlags: options.swiftPM.swiftCompilerFlags ?? [], + linkerFlags: options.swiftPM.linkerFlags ?? [] ) self.toolsBuildParameters = try BuildParameters( @@ -312,8 +307,7 @@ public actor SwiftPMBuildSystem { public init?( uri: DocumentURI, toolchainRegistry: ToolchainRegistry, - options: SourceKitLSPOptions.SwiftPMOptions, - experimentalFeatures: Set, + options: SourceKitLSPOptions, reloadPackageStatusCallback: @escaping (ReloadPackageStatus) async -> Void, testHooks: SwiftPMTestHooks ) async { @@ -326,7 +320,6 @@ public actor SwiftPMBuildSystem { toolchainRegistry: toolchainRegistry, fileSystem: localFileSystem, options: options, - experimentalFeatures: experimentalFeatures, reloadPackageStatusCallback: reloadPackageStatusCallback, testHooks: testHooks ) @@ -613,14 +606,14 @@ extension SwiftPMBuildSystem: SKCore.BuildSystem { "--disable-index-store", "--target", target.targetID, ] - if let configuration = options.configuration { + if let configuration = options.swiftPM.configuration { arguments += ["-c", configuration.rawValue] } - arguments += options.cCompilerFlags?.flatMap { ["-Xcc", $0] } ?? [] - arguments += options.cxxCompilerFlags?.flatMap { ["-Xcxx", $0] } ?? [] - arguments += options.swiftCompilerFlags?.flatMap { ["-Xswiftc", $0] } ?? [] - arguments += options.linkerFlags?.flatMap { ["-Xlinker", $0] } ?? [] - if experimentalFeatures.contains(.swiftpmPrepareForIndexing) { + arguments += options.swiftPM.cCompilerFlags?.flatMap { ["-Xcc", $0] } ?? [] + arguments += options.swiftPM.cxxCompilerFlags?.flatMap { ["-Xcxx", $0] } ?? [] + arguments += options.swiftPM.swiftCompilerFlags?.flatMap { ["-Xswiftc", $0] } ?? [] + arguments += options.swiftPM.linkerFlags?.flatMap { ["-Xlinker", $0] } ?? [] + if options.hasExperimentalFeature(.swiftpmPrepareForIndexing) { arguments.append("--experimental-prepare-for-indexing") } if Task.isCancelled { diff --git a/Sources/SKTestSupport/TestSourceKitLSPClient.swift b/Sources/SKTestSupport/TestSourceKitLSPClient.swift index 92924acd0..1ac41d9d4 100644 --- a/Sources/SKTestSupport/TestSourceKitLSPClient.swift +++ b/Sources/SKTestSupport/TestSourceKitLSPClient.swift @@ -24,7 +24,7 @@ import XCTest extension SourceKitLSPOptions { public static func testDefault(experimentalFeatures: Set? = nil) -> SourceKitLSPOptions { - return SourceKitLSPOptions(experimentalFeatures: experimentalFeatures, swiftPublishDiagnosticsDebounce: 0) + return SourceKitLSPOptions(experimentalFeatures: experimentalFeatures, swiftPublishDiagnosticsDebounceDuration: 0) } } @@ -108,13 +108,10 @@ public final class TestSourceKitLSPClient: MessageHandler, Sendable { ) async throws { var options = options if let globalModuleCache { - options.swiftPM = options.swiftPM ?? SourceKitLSPOptions.SwiftPMOptions() - options.swiftPM!.swiftCompilerFlags = - (options.swiftPM!.swiftCompilerFlags ?? []) + ["-module-cache-path", globalModuleCache.path] - } - if enableBackgroundIndexing { - options.experimentalFeatures = (options.experimentalFeatures ?? []).union([.backgroundIndexing]) + options.swiftPM.swiftCompilerFlags = + (options.swiftPM.swiftCompilerFlags ?? []) + ["-module-cache-path", globalModuleCache.path] } + options.backgroundIndexing = enableBackgroundIndexing var notificationYielder: AsyncStream.Continuation! self.notifications = AsyncStream { continuation in diff --git a/Sources/SourceKitLSP/CreateBuildSystem.swift b/Sources/SourceKitLSP/CreateBuildSystem.swift index 6798e51f7..c1c8ca19c 100644 --- a/Sources/SourceKitLSP/CreateBuildSystem.swift +++ b/Sources/SourceKitLSP/CreateBuildSystem.swift @@ -38,8 +38,7 @@ func createBuildSystem( return await SwiftPMBuildSystem( uri: rootUri, toolchainRegistry: toolchainRegistry, - options: options.swiftPM ?? .init(), - experimentalFeatures: options.experimentalFeatures ?? [], + options: options, reloadPackageStatusCallback: reloadPackageStatusCallback, testHooks: testHooks.swiftpmTestHooks ) @@ -48,7 +47,7 @@ func createBuildSystem( func createCompilationDatabaseBuildSystem(rootPath: AbsolutePath) -> CompilationDatabaseBuildSystem? { return CompilationDatabaseBuildSystem( projectRoot: rootPath, - searchPaths: (options.compilationDatabase?.searchPaths ?? []).compactMap { try? RelativePath(validating: $0) } + searchPaths: (options.compilationDatabase.searchPaths ?? []).compactMap { try? RelativePath(validating: $0) } ) } diff --git a/Sources/SourceKitLSP/IndexProgressManager.swift b/Sources/SourceKitLSP/IndexProgressManager.swift index f3bcb1531..591ba6ce3 100644 --- a/Sources/SourceKitLSP/IndexProgressManager.swift +++ b/Sources/SourceKitLSP/IndexProgressManager.swift @@ -128,7 +128,7 @@ actor IndexProgressManager { workDoneProgress = await WorkDoneProgressManager( server: sourceKitLSPServer, tokenPrefix: "indexing", - initialDebounce: sourceKitLSPServer.options.workDoneProgressDebounceDuration, + initialDebounce: sourceKitLSPServer.options.workDoneProgressDebounceDurationOrDefault, title: "Indexing", message: message, percentage: percentage diff --git a/Sources/SourceKitLSP/SourceKitLSPServer.swift b/Sources/SourceKitLSP/SourceKitLSPServer.swift index fe41305f2..8ca15e358 100644 --- a/Sources/SourceKitLSP/SourceKitLSPServer.swift +++ b/Sources/SourceKitLSP/SourceKitLSPServer.swift @@ -214,7 +214,7 @@ public actor SourceKitLSPServer { self.client = client let processorCount = ProcessInfo.processInfo.processorCount - let lowPriorityCores = (options.index?.maxCoresPercentageToUseForBackgroundIndexing ?? 1) * Double(processorCount) + let lowPriorityCores = options.index.maxCoresPercentageToUseForBackgroundIndexingOrDefault * Double(processorCount) self.indexTaskScheduler = TaskScheduler(maxConcurrentTasksByPriority: [ (TaskPriority.medium, processorCount), (TaskPriority.low, max(Int(lowPriorityCores), 1)), @@ -940,7 +940,7 @@ extension SourceKitLSPServer { self?.indexProgressManager.indexProgressStatusDidChange() } ) - if let workspace, options.hasExperimentalFeature(.backgroundIndexing), workspace.semanticIndexManager == nil, + if let workspace, options.backgroundIndexingOrDefault, workspace.semanticIndexManager == nil, !self.didSendBackgroundIndexingNotSupportedNotification { self.sendNotificationToClient( diff --git a/Sources/SourceKitLSP/Swift/SwiftLanguageService.swift b/Sources/SourceKitLSP/Swift/SwiftLanguageService.swift index 1f8414b1f..ff31ecbf3 100644 --- a/Sources/SourceKitLSP/Swift/SwiftLanguageService.swift +++ b/Sources/SourceKitLSP/Swift/SwiftLanguageService.swift @@ -484,9 +484,7 @@ extension SwiftLanguageService { // Sleep for a little bit until triggering the diagnostic generation. This effectively de-bounces diagnostic // generation since any later edit will cancel the previous in-flight task, which will thus never go on to send // the `DocumentDiagnosticsRequest`. - try await Task.sleep( - nanoseconds: UInt64(sourceKitLSPServer.options.swiftPublishDiagnosticsDebounceDuration * 1_000_000_000) - ) + try await Task.sleep(for: sourceKitLSPServer.options.swiftPublishDiagnosticsDebounceDurationOrDefault) } catch { return } diff --git a/Sources/SourceKitLSP/WorkDoneProgressManager.swift b/Sources/SourceKitLSP/WorkDoneProgressManager.swift index 3cb3b30e4..f82280f4d 100644 --- a/Sources/SourceKitLSP/WorkDoneProgressManager.swift +++ b/Sources/SourceKitLSP/WorkDoneProgressManager.swift @@ -225,7 +225,7 @@ actor SharedWorkDoneProgressManager { } // Do all asynchronous operations up-front so that incrementing `inProgressOperations` and setting `workDoneProgress` // cannot be interrupted by an `await` call - let initialDebounce = await sourceKitLSPServer.options.workDoneProgressDebounceDuration + let initialDebounceDuration = await sourceKitLSPServer.options.workDoneProgressDebounceDurationOrDefault let capabilityRegistry = await sourceKitLSPServer.capabilityRegistry inProgressOperations += 1 @@ -234,7 +234,7 @@ actor SharedWorkDoneProgressManager { server: sourceKitLSPServer, capabilityRegistry: capabilityRegistry, tokenPrefix: tokenPrefix, - initialDebounce: initialDebounce, + initialDebounce: initialDebounceDuration, title: title, message: message ) diff --git a/Sources/SourceKitLSP/Workspace.swift b/Sources/SourceKitLSP/Workspace.swift index e4fcbe76f..26a847c1c 100644 --- a/Sources/SourceKitLSP/Workspace.swift +++ b/Sources/SourceKitLSP/Workspace.swift @@ -105,24 +105,15 @@ public final class Workspace: Sendable { self._uncheckedIndex = ThreadSafeBox(initialValue: uncheckedIndex) self.buildSystemManager = await BuildSystemManager( buildSystem: underlyingBuildSystem, - fallbackBuildSystem: FallbackBuildSystem(options: options.fallbackBuildSystem ?? .init()), + fallbackBuildSystem: FallbackBuildSystem(options: options.fallbackBuildSystem), mainFilesProvider: uncheckedIndex, toolchainRegistry: toolchainRegistry ) - if options.hasExperimentalFeature(.backgroundIndexing), - let uncheckedIndex, - await buildSystemManager.supportsPreparation - { - let updateIndexStoreTimeoutDuration: Duration = - if let timeout = options.index?.updateIndexStoreTimeout { - .seconds(timeout) - } else { - .seconds(120) - } + if options.backgroundIndexingOrDefault, let uncheckedIndex, await buildSystemManager.supportsPreparation { self.semanticIndexManager = SemanticIndexManager( index: uncheckedIndex, buildSystemManager: buildSystemManager, - updateIndexStoreTimeout: updateIndexStoreTimeoutDuration, + updateIndexStoreTimeout: options.index.updateIndexStoreTimeoutOrDefault, testHooks: testHooks.indexTestHooks, indexTaskScheduler: indexTaskScheduler, logMessageToIndexLog: logMessageToIndexLog, @@ -172,11 +163,11 @@ public final class Workspace: Sendable { let indexOptions = options.index if let storePath = await firstNonNil( - AbsolutePath(validatingOrNil: indexOptions?.indexStorePath), + AbsolutePath(validatingOrNil: indexOptions.indexStorePath), await buildSystem?.indexStorePath ), let dbPath = await firstNonNil( - AbsolutePath(validatingOrNil: indexOptions?.indexDatabasePath), + AbsolutePath(validatingOrNil: indexOptions.indexDatabasePath), await buildSystem?.indexDatabasePath ), let libPath = await toolchainRegistry.default?.libIndexStore @@ -186,7 +177,7 @@ public final class Workspace: Sendable { indexDelegate = SourceKitIndexDelegate() let prefixMappings = await firstNonNil( - indexOptions?.indexPrefixMap?.map { PathPrefixMapping(original: $0.key, replacement: $0.value) }, + indexOptions.indexPrefixMap?.map { PathPrefixMapping(original: $0.key, replacement: $0.value) }, await buildSystem?.indexPrefixMappings ) ?? [] index = try IndexStoreDB( diff --git a/Sources/sourcekit-lsp/SourceKitLSP.swift b/Sources/sourcekit-lsp/SourceKitLSP.swift index 8b3c2f26a..937e67146 100644 --- a/Sources/sourcekit-lsp/SourceKitLSP.swift +++ b/Sources/sourcekit-lsp/SourceKitLSP.swift @@ -201,7 +201,7 @@ struct SourceKitLSP: AsyncParsableCommand { Available features are: \(ExperimentalFeature.allCases.map(\.rawValue).joined(separator: ", ")) """ ) - var experimentalFeatures: [ExperimentalFeature] = [] + var experimentalFeatures: [String] = [] /// Maps The options passed on the command line to a `SourceKitLSPOptions` struct. func commandLineOptions() -> SourceKitLSPOptions { @@ -233,7 +233,8 @@ struct SourceKitLSP: AsyncParsableCommand { ), defaultWorkspaceType: defaultWorkspaceType, generatedFilesPath: generatedFilesPath, - experimentalFeatures: Set(experimentalFeatures) + backgroundIndexing: experimentalFeatures.contains("background-indexing"), + experimentalFeatures: Set(experimentalFeatures.compactMap(ExperimentalFeature.init)) ) } diff --git a/Tests/SKSwiftPMWorkspaceTests/SwiftPMBuildSystemTests.swift b/Tests/SKSwiftPMWorkspaceTests/SwiftPMBuildSystemTests.swift index 92a1a38ac..54bcc5caf 100644 --- a/Tests/SKSwiftPMWorkspaceTests/SwiftPMBuildSystemTests.swift +++ b/Tests/SKSwiftPMWorkspaceTests/SwiftPMBuildSystemTests.swift @@ -53,8 +53,7 @@ final class SwiftPMBuildSystemTests: XCTestCase { workspacePath: packageRoot, toolchainRegistry: tr, fileSystem: fs, - options: SourceKitLSPOptions.SwiftPMOptions(), - experimentalFeatures: [], + options: SourceKitLSPOptions(), testHooks: SwiftPMTestHooks() ) ) @@ -81,8 +80,7 @@ final class SwiftPMBuildSystemTests: XCTestCase { workspacePath: packageRoot, toolchainRegistry: tr, fileSystem: fs, - options: SourceKitLSPOptions.SwiftPMOptions(), - experimentalFeatures: [], + options: SourceKitLSPOptions(), testHooks: SwiftPMTestHooks() ) await assertThrowsError(try await buildSystem.generateBuildGraph(allowFileSystemWrites: false)) @@ -112,8 +110,7 @@ final class SwiftPMBuildSystemTests: XCTestCase { workspacePath: packageRoot, toolchainRegistry: ToolchainRegistry(toolchains: []), fileSystem: fs, - options: SourceKitLSPOptions.SwiftPMOptions(), - experimentalFeatures: [], + options: SourceKitLSPOptions(), testHooks: SwiftPMTestHooks() ) ) @@ -144,8 +141,7 @@ final class SwiftPMBuildSystemTests: XCTestCase { workspacePath: packageRoot, toolchainRegistry: tr, fileSystem: fs, - options: SourceKitLSPOptions.SwiftPMOptions(), - experimentalFeatures: [], + options: SourceKitLSPOptions(), testHooks: SwiftPMTestHooks() ) try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false) @@ -210,8 +206,7 @@ final class SwiftPMBuildSystemTests: XCTestCase { workspacePath: packageRoot, toolchainRegistry: tr, fileSystem: localFileSystem, - options: SourceKitLSPOptions.SwiftPMOptions(), - experimentalFeatures: [], + options: SourceKitLSPOptions(), testHooks: SwiftPMTestHooks() ) try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false) @@ -274,8 +269,7 @@ final class SwiftPMBuildSystemTests: XCTestCase { workspacePath: packageRoot, toolchainRegistry: tr, fileSystem: fs, - options: options, - experimentalFeatures: [], + options: SourceKitLSPOptions(swiftPM: options), testHooks: SwiftPMTestHooks() ) try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false) @@ -317,8 +311,7 @@ final class SwiftPMBuildSystemTests: XCTestCase { workspacePath: packageRoot, toolchainRegistry: tr, fileSystem: fs, - options: SourceKitLSPOptions.SwiftPMOptions(), - experimentalFeatures: [], + options: SourceKitLSPOptions(), testHooks: SwiftPMTestHooks() ) try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false) @@ -355,8 +348,7 @@ final class SwiftPMBuildSystemTests: XCTestCase { workspacePath: packageRoot, toolchainRegistry: tr, fileSystem: fs, - options: SourceKitLSPOptions.SwiftPMOptions(), - experimentalFeatures: [], + options: SourceKitLSPOptions(), testHooks: SwiftPMTestHooks() ) try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false) @@ -405,8 +397,7 @@ final class SwiftPMBuildSystemTests: XCTestCase { workspacePath: packageRoot, toolchainRegistry: tr, fileSystem: fs, - options: SourceKitLSPOptions.SwiftPMOptions(), - experimentalFeatures: [], + options: SourceKitLSPOptions(), testHooks: SwiftPMTestHooks() ) try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false) @@ -471,8 +462,7 @@ final class SwiftPMBuildSystemTests: XCTestCase { workspacePath: packageRoot, toolchainRegistry: tr, fileSystem: fs, - options: SourceKitLSPOptions.SwiftPMOptions(), - experimentalFeatures: [], + options: SourceKitLSPOptions(), testHooks: SwiftPMTestHooks() ) try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false) @@ -516,8 +506,7 @@ final class SwiftPMBuildSystemTests: XCTestCase { workspacePath: packageRoot, toolchainRegistry: tr, fileSystem: fs, - options: SourceKitLSPOptions.SwiftPMOptions(), - experimentalFeatures: [], + options: SourceKitLSPOptions(), testHooks: SwiftPMTestHooks() ) try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false) @@ -598,8 +587,7 @@ final class SwiftPMBuildSystemTests: XCTestCase { workspacePath: packageRoot, toolchainRegistry: ToolchainRegistry.forTesting, fileSystem: fs, - options: SourceKitLSPOptions.SwiftPMOptions(), - experimentalFeatures: [], + options: SourceKitLSPOptions(), testHooks: SwiftPMTestHooks() ) try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false) @@ -651,8 +639,7 @@ final class SwiftPMBuildSystemTests: XCTestCase { workspacePath: packageRoot, toolchainRegistry: tr, fileSystem: fs, - options: SourceKitLSPOptions.SwiftPMOptions(), - experimentalFeatures: [], + options: SourceKitLSPOptions(), testHooks: SwiftPMTestHooks() ) try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false) @@ -720,8 +707,7 @@ final class SwiftPMBuildSystemTests: XCTestCase { workspacePath: symlinkRoot, toolchainRegistry: ToolchainRegistry.forTesting, fileSystem: fs, - options: SourceKitLSPOptions.SwiftPMOptions(), - experimentalFeatures: [], + options: SourceKitLSPOptions(), testHooks: SwiftPMTestHooks() ) try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false) @@ -761,8 +747,7 @@ final class SwiftPMBuildSystemTests: XCTestCase { workspacePath: packageRoot, toolchainRegistry: tr, fileSystem: fs, - options: SourceKitLSPOptions.SwiftPMOptions(), - experimentalFeatures: [], + options: SourceKitLSPOptions(), testHooks: SwiftPMTestHooks() ) try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false) @@ -803,8 +788,7 @@ final class SwiftPMBuildSystemTests: XCTestCase { workspacePath: packageRoot, toolchainRegistry: tr, fileSystem: fs, - options: SourceKitLSPOptions.SwiftPMOptions(), - experimentalFeatures: [], + options: SourceKitLSPOptions(), testHooks: SwiftPMTestHooks() ) @@ -839,8 +823,7 @@ final class SwiftPMBuildSystemTests: XCTestCase { workspacePath: packageRoot, toolchainRegistry: tr, fileSystem: fs, - options: SourceKitLSPOptions.SwiftPMOptions(), - experimentalFeatures: [], + options: SourceKitLSPOptions(), testHooks: SwiftPMTestHooks() ) try await swiftpmBuildSystem.generateBuildGraph(allowFileSystemWrites: false) diff --git a/Tests/SourceKitLSPTests/BackgroundIndexingTests.swift b/Tests/SourceKitLSPTests/BackgroundIndexingTests.swift index 5cbc7edfb..2bbe4b24e 100644 --- a/Tests/SourceKitLSPTests/BackgroundIndexingTests.swift +++ b/Tests/SourceKitLSPTests/BackgroundIndexingTests.swift @@ -969,8 +969,7 @@ final class BackgroundIndexingTests: XCTestCase { func testUseBuildFlagsDuringPreparation() async throws { var options = SourceKitLSPOptions.testDefault() - options.swiftPM = options.swiftPM ?? SourceKitLSPOptions.SwiftPMOptions() - options.swiftPM!.swiftCompilerFlags = ["-D", "MY_FLAG"] + options.swiftPM.swiftCompilerFlags = ["-D", "MY_FLAG"] let project = try await SwiftPMTestProject( files: [ "Lib/Lib.swift": """ @@ -1350,8 +1349,7 @@ final class BackgroundIndexingTests: XCTestCase { try SkipUnless.longTestsEnabled() var options = SourceKitLSPOptions.testDefault(experimentalFeatures: [.swiftpmPrepareForIndexing]) - options.index = options.index ?? .init() - options.index!.updateIndexStoreTimeout = 1 /* second */ + options.index.updateIndexStoreTimeout = 1 /* second */ let dateStarted = Date() _ = try await SwiftPMTestProject( diff --git a/Tests/SourceKitLSPTests/LocalSwiftTests.swift b/Tests/SourceKitLSPTests/LocalSwiftTests.swift index 1f0be02cb..9de72a9e7 100644 --- a/Tests/SourceKitLSPTests/LocalSwiftTests.swift +++ b/Tests/SourceKitLSPTests/LocalSwiftTests.swift @@ -1400,7 +1400,7 @@ final class LocalSwiftTests: XCTestCase { func testDebouncePublishDiagnosticsNotification() async throws { try SkipUnless.longTestsEnabled() - let options = SourceKitLSPOptions(swiftPublishDiagnosticsDebounce: 1 /* second */) + let options = SourceKitLSPOptions(swiftPublishDiagnosticsDebounceDuration: 1 /* second */) // Construct our own `TestSourceKitLSPClient` instead of the one from set up because we want a higher debounce interval. let testClient = try await TestSourceKitLSPClient(options: options, usePullDiagnostics: false)