search: always pass a session to file search providers

FileSearchProviderOptions.session is declared as an object, but
searches without a cache key got undefined, so providers that key a
WeakMap on the session threw.

Give those searches their own session and cancel it once the search
is done, like clearCache does for cached sessions.
This commit is contained in:
dualfroz committed 2026-10-17 04:24:09 +02:00
1 parent 6cf5d04662
commit 9bba2ad2af
2 files changed
+22 -4

No files matched your search

@@ -293,6 +293,20 @@ suite('ExtHostSearch', () => {
disposables.forEach(d => d?.dispose());
});
test('session is defined when there is no cache key', async () => {
let session: object | undefined;
disposables.add(extHostSearch.registerFileSearchProvider('file', {
provideFileSearchResults(pattern: string, options: vscode.FileSearchProviderOptions, token: vscode.CancellationToken): Promise<URI[]> {
session = options.session;
return Promise.resolve([]);
}
}));
await rpcProtocol.sync();
await runFileSearch(getSimpleQuery());
assert.strictEqual(typeof session, 'object');
});
test('provider returns null', async () => {
await registerTestFileSearchProvider({
provideFileSearchResults(query: vscode.FileSearchQuery, options: vscode.FileSearchOptions, token: vscode.CancellationToken): Promise<URI[]> {
@@ -347,7 +347,11 @@ export class FileSearchManager {
onBatch(batch.map(m => this.rawMatchToSearchItem(m)));
};
return this.doSearch(engine, FileSearchManager.BATCH_SIZE, onInternalResult, token).then(
return this.doSearch(engine, FileSearchManager.BATCH_SIZE, onInternalResult, token).finally(() => {
if (!config.cacheKey) {
sessionTokenSource.cancel();
}
}).then(
result => {
return {
limitHit: result.limitHit,
@@ -369,16 +373,16 @@ export class FileSearchManager {
this.sessions.delete(cacheKey);
}
private getSessionTokenSource(cacheKey: string | undefined): SessionLifecycle | undefined {
private getSessionTokenSource(cacheKey: string | undefined): SessionLifecycle {
if (!cacheKey) {
return undefined;
return new SessionLifecycle();
}
if (!this.sessions.has(cacheKey)) {
this.sessions.set(cacheKey, new SessionLifecycle());
}
return this.sessions.get(cacheKey);
return this.sessions.get(cacheKey)!;
}
private rawMatchToSearchItem(match: IInternalFileMatch): IFileMatch {