Skip to content

Don’t re-index files in languages that cannot be indexed #1352

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion Sources/SemanticIndex/SemanticIndexManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
26 changes: 23 additions & 3 deletions Sources/SemanticIndex/UpdateIndexStoreTaskDescription.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -219,7 +239,7 @@ public struct UpdateIndexStoreTaskDescription: IndexTaskDescription {
return
}
let startDate = Date()
switch language {
switch IndexKind(language: language) {
case .swift:
do {
try await updateIndexStore(
Expand All @@ -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,
Expand All @@ -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"
)
Expand Down
47 changes: 47 additions & 0 deletions Tests/SourceKitLSPTests/BackgroundIndexingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
}