Keep search code sync when possible
This commit is contained in:
parent
9ef2f07234
commit
3673539e09
|
@ -290,3 +290,7 @@ export function NotImplementedProxy<T>(name: string): { new(): T } {
|
|||
export function assertNever(value: never, message = 'Unreachable') {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
export function isPromise<T>(obj: unknown): obj is Promise<T> {
|
||||
return !!obj && typeof (obj as Promise<T>).then === 'function' && typeof (obj as Promise<T>).catch === 'function';
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import { Event } from 'vs/base/common/event';
|
|||
import * as paths from 'vs/base/common/path';
|
||||
import { isPromiseCanceledError } from 'vs/base/common/errors';
|
||||
import { TextSearchCompleteMessageType } from 'vs/workbench/services/search/common/searchExtTypes';
|
||||
import { isPromise } from 'vs/base/common/types';
|
||||
|
||||
export { TextSearchCompleteMessageType };
|
||||
|
||||
|
@ -655,22 +656,29 @@ export class QueryGlobTester {
|
|||
}
|
||||
|
||||
/**
|
||||
* Guaranteed async.
|
||||
* Evaluating the exclude expression is only async if it includes sibling clauses. As an optimization, avoid doing anything with Promises
|
||||
* unless the expression is async.
|
||||
*/
|
||||
includedInQuery(testPath: string, basename?: string, hasSibling?: (name: string) => boolean | Promise<boolean>): Promise<boolean> {
|
||||
const excludeP = Promise.resolve(this._parsedExcludeExpression(testPath, basename, hasSibling)).then(result => !!result);
|
||||
|
||||
return excludeP.then(excluded => {
|
||||
if (excluded) {
|
||||
return false;
|
||||
}
|
||||
includedInQuery(testPath: string, basename?: string, hasSibling?: (name: string) => boolean | Promise<boolean>): Promise<boolean> | boolean {
|
||||
const excluded = this._parsedExcludeExpression(testPath, basename, hasSibling);
|
||||
|
||||
const isIncluded = () => {
|
||||
return this._parsedIncludeExpression ?
|
||||
Promise.resolve(this._parsedIncludeExpression(testPath, basename, hasSibling)).then(result => !!result) :
|
||||
Promise.resolve(true);
|
||||
}).then(included => {
|
||||
return included;
|
||||
});
|
||||
!!(this._parsedIncludeExpression(testPath, basename, hasSibling)) :
|
||||
true;
|
||||
};
|
||||
|
||||
if (isPromise(excluded)) {
|
||||
return excluded.then(excluded => {
|
||||
if (excluded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isIncluded();
|
||||
});
|
||||
}
|
||||
|
||||
return isIncluded();
|
||||
}
|
||||
|
||||
hasSiblingExcludeClauses(): boolean {
|
||||
|
|
|
@ -3,17 +3,17 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as path from 'vs/base/common/path';
|
||||
import { flatten, mapArrayOrNot } from 'vs/base/common/arrays';
|
||||
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import { toErrorMessage } from 'vs/base/common/errorMessage';
|
||||
import * as resources from 'vs/base/common/resources';
|
||||
import * as glob from 'vs/base/common/glob';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import * as path from 'vs/base/common/path';
|
||||
import * as resources from 'vs/base/common/resources';
|
||||
import { isArray, isPromise } from 'vs/base/common/types';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IExtendedExtensionSearchOptions, IFileMatch, IFolderQuery, IPatternInfo, ISearchCompleteStats, ITextQuery, ITextSearchContext, ITextSearchMatch, ITextSearchResult, QueryGlobTester, resolvePatternsForProvider } from 'vs/workbench/services/search/common/search';
|
||||
import { TextSearchProvider, TextSearchResult, TextSearchMatch, TextSearchComplete, Range, TextSearchOptions, TextSearchQuery } from 'vs/workbench/services/search/common/searchExtTypes';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { isArray } from 'vs/base/common/types';
|
||||
import { Range, TextSearchComplete, TextSearchMatch, TextSearchOptions, TextSearchProvider, TextSearchQuery, TextSearchResult } from 'vs/workbench/services/search/common/searchExtTypes';
|
||||
|
||||
export interface IFileUtils {
|
||||
readdir: (resource: URI) => Promise<string[]>;
|
||||
|
@ -131,20 +131,28 @@ export class TextSearchManager {
|
|||
|
||||
const relativePath = resources.relativePath(folderQuery.folder, result.uri);
|
||||
if (relativePath) {
|
||||
testingPs.push(
|
||||
queryTester.includedInQuery(relativePath, path.basename(relativePath), hasSibling)
|
||||
.then(included => {
|
||||
if (included) {
|
||||
// This method is only async when the exclude contains sibling clauses
|
||||
const included = queryTester.includedInQuery(relativePath, path.basename(relativePath), hasSibling);
|
||||
if (isPromise(included)) {
|
||||
testingPs.push(
|
||||
included.then(isIncluded => {
|
||||
if (isIncluded) {
|
||||
onResult(result);
|
||||
}
|
||||
}));
|
||||
} else if (included) {
|
||||
onResult(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const searchOptions = this.getSearchOptionsForFolder(folderQuery);
|
||||
const result = await this.provider.provideTextSearchResults(patternInfoToQuery(this.query.contentPattern), searchOptions, progress, token);
|
||||
await Promise.all(testingPs);
|
||||
if (testingPs.length) {
|
||||
await Promise.all(testingPs);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue