Skip to content

Commit 193ab77

Browse files
committed
Don’t re-index files in languages that cannot be indexed
Swift packages can have source files that we can’t index (like assembly files). When re-opening, we schedule indexing for those files, which requires the targets to be re-prepared. We skip them earlier. rdar://128711633
1 parent ea6a585 commit 193ab77

File tree

3 files changed

+80
-4
lines changed

3 files changed

+80
-4
lines changed

Sources/SemanticIndex/SemanticIndexManager.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,10 +455,19 @@ public final actor SemanticIndexManager {
455455
// schedule two indexing jobs for the same file in quick succession, only the first one actually updates the index
456456
// store and the second one will be a no-op once it runs.
457457
let outOfDateFiles = await filesToIndex(toCover: files).asyncFilter {
458-
return await !indexStoreUpToDateStatus.isUpToDate($0.sourceFile)
458+
if await indexStoreUpToDateStatus.isUpToDate($0.sourceFile) {
459+
return false
460+
}
461+
guard let language = await buildSystemManager.defaultLanguage(for: $0.mainFile),
462+
UpdateIndexStoreTaskDescription.canIndex(language: language)
463+
else {
464+
return false
465+
}
466+
return true
459467
}
460468
// sort files to get deterministic indexing order
461469
.sorted(by: { $0.sourceFile.stringValue < $1.sourceFile.stringValue })
470+
logger.debug("Scheduling indexing of \(outOfDateFiles.map(\.sourceFile.stringValue).joined(separator: ", "))")
462471

463472
// Sort the targets in topological order so that low-level targets get built before high-level targets, allowing us
464473
// to index the low-level targets ASAP.

Sources/SemanticIndex/UpdateIndexStoreTaskDescription.swift

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,22 @@ public struct FileAndTarget: Sendable {
7676
public let target: ConfiguredTarget
7777
}
7878

79+
private enum IndexKind {
80+
case clang
81+
case swift
82+
83+
init?(language: Language) {
84+
switch language {
85+
case .swift:
86+
self = .swift
87+
case .c, .cpp, .objective_c, .objective_cpp:
88+
self = .clang
89+
default:
90+
return nil
91+
}
92+
}
93+
}
94+
7995
/// Describes a task to index a set of source files.
8096
///
8197
/// This task description can be scheduled in a `TaskScheduler`.
@@ -114,6 +130,10 @@ public struct UpdateIndexStoreTaskDescription: IndexTaskDescription {
114130
return "update-indexstore-\(id)"
115131
}
116132

133+
static func canIndex(language: Language) -> Bool {
134+
return IndexKind(language: language) != nil
135+
}
136+
117137
init(
118138
filesToIndex: [FileAndTarget],
119139
buildSystemManager: BuildSystemManager,
@@ -219,7 +239,7 @@ public struct UpdateIndexStoreTaskDescription: IndexTaskDescription {
219239
return
220240
}
221241
let startDate = Date()
222-
switch language {
242+
switch IndexKind(language: language) {
223243
case .swift:
224244
do {
225245
try await updateIndexStore(
@@ -231,7 +251,7 @@ public struct UpdateIndexStoreTaskDescription: IndexTaskDescription {
231251
logger.error("Updating index store for \(file.forLogging) failed: \(error.forLogging)")
232252
BuildSettingsLogger.log(settings: buildSettings, for: file.mainFile)
233253
}
234-
case .c, .cpp, .objective_c, .objective_cpp:
254+
case .clang:
235255
do {
236256
try await updateIndexStore(
237257
forClangFile: file.mainFile,
@@ -242,7 +262,7 @@ public struct UpdateIndexStoreTaskDescription: IndexTaskDescription {
242262
logger.error("Updating index store for \(file) failed: \(error.forLogging)")
243263
BuildSettingsLogger.log(settings: buildSettings, for: file.mainFile)
244264
}
245-
default:
265+
case nil:
246266
logger.error(
247267
"Not updating index store for \(file) because it is a language that is not supported by background indexing"
248268
)

Tests/SourceKitLSPTests/BackgroundIndexingTests.swift

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,4 +740,51 @@ final class BackgroundIndexingTests: XCTestCase {
740740
cleanUp: { expectedIndexTaskTracker.keepAlive() }
741741
)
742742
}
743+
744+
func testNoIndexingHappensWhenPackageIsReopened() async throws {
745+
let project = try await SwiftPMTestProject(
746+
files: [
747+
"SwiftLib/NonEmptySwiftFile.swift": """
748+
func test() {}
749+
""",
750+
"CLib/include/EmptyHeader.h": "",
751+
"CLib/Assembly.S": "",
752+
"CLib/EmptyC.c": "",
753+
"CLib/NonEmptyC.c": """
754+
void test() {}
755+
""",
756+
],
757+
manifest: """
758+
// swift-tools-version: 5.7
759+
760+
import PackageDescription
761+
762+
let package = Package(
763+
name: "MyLibrary",
764+
targets: [
765+
.target(name: "SwiftLib"),
766+
.target(name: "CLib"),
767+
]
768+
)
769+
""",
770+
serverOptions: backgroundIndexingOptions
771+
)
772+
773+
var otherClientOptions = backgroundIndexingOptions
774+
otherClientOptions.indexTestHooks = IndexTestHooks(
775+
preparationTaskDidStart: { taskDescription in
776+
XCTFail("Did not expect any target preparation, got \(taskDescription.targetsToPrepare)")
777+
},
778+
updateIndexStoreTaskDidStart: { taskDescription in
779+
XCTFail("Did not expect any indexing tasks, got \(taskDescription.filesToIndex)")
780+
}
781+
)
782+
let otherClient = try await TestSourceKitLSPClient(
783+
serverOptions: otherClientOptions,
784+
workspaceFolders: [
785+
WorkspaceFolder(uri: DocumentURI(project.scratchDirectory))
786+
]
787+
)
788+
_ = try await otherClient.send(PollIndexRequest())
789+
}
743790
}

0 commit comments

Comments
 (0)