Skip to content
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
4 changes: 4 additions & 0 deletions Sources/SKTestSupport/CustomBuildServerTestProject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -274,10 +274,12 @@ package final class CustomBuildServerTestProject<BuildServer: CustomBuildServer>
package init(
files: [RelativeFileLocation: String],
buildServer buildServerType: BuildServer.Type,
capabilities: ClientCapabilities = ClientCapabilities(),
options: SourceKitLSPOptions? = nil,
hooks: Hooks = Hooks(),
enableBackgroundIndexing: Bool = false,
pollIndex: Bool = true,
preInitialization: ((TestSourceKitLSPClient) -> Void)? = nil,
testScratchDir: URL? = nil,
testName: String = #function
) async throws {
Expand All @@ -290,9 +292,11 @@ package final class CustomBuildServerTestProject<BuildServer: CustomBuildServer>
}
try await super.init(
files: files,
capabilities: capabilities,
options: options,
hooks: hooks,
enableBackgroundIndexing: enableBackgroundIndexing,
preInitialization: preInitialization,
testScratchDir: testScratchDir,
testName: testName
)
Expand Down
1 change: 1 addition & 0 deletions Sources/SemanticIndex/SemanticIndexManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,7 @@ package final actor SemanticIndexManager {
}

if filesToIndex.isEmpty {
indexProgressStatusDidChange()
// Early exit if there are no files to index.
return Task {}
}
Expand Down
100 changes: 100 additions & 0 deletions Tests/SourceKitLSPTests/BackgroundIndexingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2666,6 +2666,106 @@ final class BackgroundIndexingTests: XCTestCase {
]
)
}

func testIndexingProgressDoesNotGetStuckIfThereAreNoSourceFilesInTarget() async throws {
actor BuildServer: CustomBuildServer {
let inProgressRequestsTracker = CustomBuildServerInProgressRequestTracker()
private let projectRoot: URL

init(projectRoot: URL, connectionToSourceKitLSP: any Connection) {
self.projectRoot = projectRoot
}

func initializeBuildRequest(_ request: InitializeBuildRequest) async throws -> InitializeBuildResponse {
return try initializationResponseSupportingBackgroundIndexing(
projectRoot: projectRoot,
outputPathsProvider: false
)
}

func workspaceBuildTargetsRequest(
_ request: WorkspaceBuildTargetsRequest
) async throws -> WorkspaceBuildTargetsResponse {
return WorkspaceBuildTargetsResponse(targets: [
BuildTarget(
id: .dummy,
capabilities: BuildTargetCapabilities(),
languageIds: [],
dependencies: []
)
])
}

func buildTargetSourcesRequest(_ request: BuildTargetSourcesRequest) throws -> BuildTargetSourcesResponse {
return BuildTargetSourcesResponse(items: [
SourcesItem(
target: .dummy,
sources: []
)
])
}

func textDocumentSourceKitOptionsRequest(
_ request: TextDocumentSourceKitOptionsRequest
) -> TextDocumentSourceKitOptionsResponse? {
var arguments = [request.textDocument.uri.pseudoPath]
if let defaultSDKPath {
arguments += ["-sdk", defaultSDKPath]
}
return TextDocumentSourceKitOptionsResponse(compilerArguments: arguments)
}

func prepareTarget(_ request: BuildTargetPrepareRequest) async throws -> VoidResponse {
return VoidResponse()
}
}

let expectation = self.expectation(description: "Did receive indexing work done progress")
let hooks = Hooks(
indexHooks: IndexHooks(buildGraphGenerationDidStart: {
// Defer build graph generation long enough so the the debouncer has time to start a work done progress for
// indexing.
do {
try await fulfillmentOfOrThrow(expectation)
} catch {
XCTFail("\(error)")
}
})
)
let project = try await CustomBuildServerTestProject(
files: [
"Test.swift": """
func 1️⃣myTestFunc() {}
"""
],
buildServer: BuildServer.self,
capabilities: ClientCapabilities(window: WindowClientCapabilities(workDoneProgress: true)),
hooks: hooks,
enableBackgroundIndexing: true,
pollIndex: false,
preInitialization: { testClient in
testClient.handleMultipleRequests { (request: CreateWorkDoneProgressRequest) in
return VoidResponse()
}
}
)
let startIndexing = try await project.testClient.nextNotification(ofType: WorkDoneProgress.self) { notification in
guard case .begin(let value) = notification.value else {
return false
}
return value.title == "Indexing"
}
expectation.fulfill()
_ = try await project.testClient.nextNotification(ofType: WorkDoneProgress.self) { notification in
guard notification.token == startIndexing.token else {
return false
}
guard case .end = notification.value else {
return false
}
return true
}
}
}

extension HoverResponseContents {
Expand Down