diff --git a/Sources/SemanticIndex/SemanticIndexManager.swift b/Sources/SemanticIndex/SemanticIndexManager.swift index d719e0d71..00f3f5265 100644 --- a/Sources/SemanticIndex/SemanticIndexManager.swift +++ b/Sources/SemanticIndex/SemanticIndexManager.swift @@ -455,10 +455,19 @@ public final actor SemanticIndexManager { // schedule two indexing jobs for the same file in quick succession, only the first one actually updates the index // store and the second one will be a no-op once it runs. let outOfDateFiles = await filesToIndex(toCover: files).asyncFilter { - return await !indexStoreUpToDateStatus.isUpToDate($0.sourceFile) + if await indexStoreUpToDateStatus.isUpToDate($0.sourceFile) { + return false + } + guard let language = await buildSystemManager.defaultLanguage(for: $0.mainFile), + UpdateIndexStoreTaskDescription.canIndex(language: language) + else { + return false + } + return true } // sort files to get deterministic indexing order .sorted(by: { $0.sourceFile.stringValue < $1.sourceFile.stringValue }) + logger.debug("Scheduling indexing of \(outOfDateFiles.map(\.sourceFile.stringValue).joined(separator: ", "))") // Sort the targets in topological order so that low-level targets get built before high-level targets, allowing us // to index the low-level targets ASAP. diff --git a/Sources/SemanticIndex/UpdateIndexStoreTaskDescription.swift b/Sources/SemanticIndex/UpdateIndexStoreTaskDescription.swift index 3183b84ca..3d856628b 100644 --- a/Sources/SemanticIndex/UpdateIndexStoreTaskDescription.swift +++ b/Sources/SemanticIndex/UpdateIndexStoreTaskDescription.swift @@ -76,6 +76,22 @@ public struct FileAndTarget: Sendable { public let target: ConfiguredTarget } +private enum IndexKind { + case clang + case swift + + init?(language: Language) { + switch language { + case .swift: + self = .swift + case .c, .cpp, .objective_c, .objective_cpp: + self = .clang + default: + return nil + } + } +} + /// Describes a task to index a set of source files. /// /// This task description can be scheduled in a `TaskScheduler`. @@ -114,6 +130,10 @@ public struct UpdateIndexStoreTaskDescription: IndexTaskDescription { return "update-indexstore-\(id)" } + static func canIndex(language: Language) -> Bool { + return IndexKind(language: language) != nil + } + init( filesToIndex: [FileAndTarget], buildSystemManager: BuildSystemManager, @@ -219,7 +239,7 @@ public struct UpdateIndexStoreTaskDescription: IndexTaskDescription { return } let startDate = Date() - switch language { + switch IndexKind(language: language) { case .swift: do { try await updateIndexStore( @@ -231,7 +251,7 @@ public struct UpdateIndexStoreTaskDescription: IndexTaskDescription { logger.error("Updating index store for \(file.forLogging) failed: \(error.forLogging)") BuildSettingsLogger.log(settings: buildSettings, for: file.mainFile) } - case .c, .cpp, .objective_c, .objective_cpp: + case .clang: do { try await updateIndexStore( forClangFile: file.mainFile, @@ -242,7 +262,7 @@ public struct UpdateIndexStoreTaskDescription: IndexTaskDescription { logger.error("Updating index store for \(file) failed: \(error.forLogging)") BuildSettingsLogger.log(settings: buildSettings, for: file.mainFile) } - default: + case nil: logger.error( "Not updating index store for \(file) because it is a language that is not supported by background indexing" ) diff --git a/Tests/SourceKitLSPTests/BackgroundIndexingTests.swift b/Tests/SourceKitLSPTests/BackgroundIndexingTests.swift index 9c306db27..9797bb745 100644 --- a/Tests/SourceKitLSPTests/BackgroundIndexingTests.swift +++ b/Tests/SourceKitLSPTests/BackgroundIndexingTests.swift @@ -740,4 +740,51 @@ final class BackgroundIndexingTests: XCTestCase { cleanUp: { expectedIndexTaskTracker.keepAlive() } ) } + + func testNoIndexingHappensWhenPackageIsReopened() async throws { + let project = try await SwiftPMTestProject( + files: [ + "SwiftLib/NonEmptySwiftFile.swift": """ + func test() {} + """, + "CLib/include/EmptyHeader.h": "", + "CLib/Assembly.S": "", + "CLib/EmptyC.c": "", + "CLib/NonEmptyC.c": """ + void test() {} + """, + ], + manifest: """ + // swift-tools-version: 5.7 + + import PackageDescription + + let package = Package( + name: "MyLibrary", + targets: [ + .target(name: "SwiftLib"), + .target(name: "CLib"), + ] + ) + """, + serverOptions: backgroundIndexingOptions + ) + + var otherClientOptions = backgroundIndexingOptions + otherClientOptions.indexTestHooks = IndexTestHooks( + preparationTaskDidStart: { taskDescription in + XCTFail("Did not expect any target preparation, got \(taskDescription.targetsToPrepare)") + }, + updateIndexStoreTaskDidStart: { taskDescription in + XCTFail("Did not expect any indexing tasks, got \(taskDescription.filesToIndex)") + } + ) + let otherClient = try await TestSourceKitLSPClient( + serverOptions: otherClientOptions, + workspaceFolders: [ + WorkspaceFolder(uri: DocumentURI(project.scratchDirectory)) + ] + ) + _ = try await otherClient.send(PollIndexRequest()) + } }