Merge from vscode 93309f060778f6480a7d2a13913e6e7c624e9bc7

This commit is contained in:
ADS Merger
2020-03-26 07:08:23 +00:00
parent 685e0ccf7e
commit f5134198e2
87 changed files with 942 additions and 631 deletions

View File

@@ -63,12 +63,22 @@ export interface IPickerQuickAccessProviderOptions {
canAcceptInBackground?: boolean;
}
export type FastAndSlowPicksType<T> = { picks: Array<T | IQuickPickSeparator>, additionalPicks: Promise<Array<T | IQuickPickSeparator>> };
export type Pick<T> = T | IQuickPickSeparator;
export type PicksWithActive<T> = { items: ReadonlyArray<Pick<T>>, active?: T };
export type Picks<T> = ReadonlyArray<Pick<T>> | PicksWithActive<T>;
export type FastAndSlowPicks<T> = { picks: Picks<T>, additionalPicks: Promise<Picks<T>> };
export type FastAndSlowPicksWithActive<T> = { picks: PicksWithActive<T>, additionalPicks: PicksWithActive<Picks<T>> };
function isFastAndSlowPicksType<T>(obj: unknown): obj is FastAndSlowPicksType<T> {
const candidate = obj as FastAndSlowPicksType<T>;
function isPicksWithActive<T>(obj: unknown): obj is PicksWithActive<T> {
const candidate = obj as PicksWithActive<T>;
return Array.isArray(candidate.picks) && candidate.additionalPicks instanceof Promise;
return Array.isArray(candidate.items);
}
function isFastAndSlowPicks<T>(obj: unknown): obj is FastAndSlowPicks<T> {
const candidate = obj as FastAndSlowPicks<T>;
return !!candidate.picks && candidate.additionalPicks instanceof Promise;
}
export abstract class PickerQuickAccessProvider<T extends IPickerQuickAccessItem> extends Disposable implements IQuickAccessProvider {
@@ -103,15 +113,26 @@ export abstract class PickerQuickAccessProvider<T extends IPickerQuickAccessItem
// Collect picks and support both long running and short or combined
const picksToken = picksCts.token;
const res = this.getPicks(picker.value.substr(this.prefix.length).trim(), picksDisposables, picksToken);
const providedPicks = this.getPicks(picker.value.substr(this.prefix.length).trim(), picksDisposables, picksToken);
function applyPicks(picks: Picks<T>): void {
if (isPicksWithActive(picks)) {
picker.items = picks.items;
if (picks.active) {
picker.activeItems = [picks.active];
}
} else {
picker.items = picks;
}
}
// No Picks
if (res === null) {
if (providedPicks === null) {
// Ignore
}
// Fast and Slow Picks
else if (isFastAndSlowPicksType(res)) {
else if (isFastAndSlowPicks(providedPicks)) {
let fastPicksHandlerDone = false;
let slowPicksHandlerDone = false;
@@ -129,7 +150,7 @@ export abstract class PickerQuickAccessProvider<T extends IPickerQuickAccessItem
}
if (!slowPicksHandlerDone) {
picker.items = res.picks;
applyPicks(providedPicks.picks);
}
} finally {
fastPicksHandlerDone = true;
@@ -142,13 +163,34 @@ export abstract class PickerQuickAccessProvider<T extends IPickerQuickAccessItem
(async () => {
picker.busy = true;
try {
const additionalPicks = await res.additionalPicks;
const awaitedAdditionalPicks = await providedPicks.additionalPicks;
if (picksToken.isCancellationRequested) {
return;
}
let picks: ReadonlyArray<Pick<T>>;
let activePick: Pick<T> | undefined = undefined;
if (isPicksWithActive(providedPicks.picks)) {
picks = providedPicks.picks.items;
activePick = providedPicks.picks.active;
} else {
picks = providedPicks.picks;
}
let additionalPicks: ReadonlyArray<Pick<T>>;
let additionalActivePick: Pick<T> | undefined = undefined;
if (isPicksWithActive(awaitedAdditionalPicks)) {
additionalPicks = awaitedAdditionalPicks.items;
additionalActivePick = awaitedAdditionalPicks.active;
} else {
additionalPicks = awaitedAdditionalPicks;
}
if (additionalPicks.length > 0 || !fastPicksHandlerDone) {
picker.items = [...res.picks, ...additionalPicks];
applyPicks({
items: [...picks, ...additionalPicks],
active: activePick as T || additionalActivePick as T // {{SQL CARBON EDIT}} strict-null-checks
});
}
} finally {
if (!picksToken.isCancellationRequested) {
@@ -162,20 +204,20 @@ export abstract class PickerQuickAccessProvider<T extends IPickerQuickAccessItem
}
// Fast Picks
else if (Array.isArray(res)) {
picker.items = res;
else if (!(providedPicks instanceof Promise)) {
applyPicks(providedPicks);
}
// Slow Picks
else {
picker.busy = true;
try {
const items = await res;
const awaitedPicks = await providedPicks;
if (picksToken.isCancellationRequested) {
return;
}
picker.items = items;
applyPicks(awaitedPicks);
} finally {
if (!picksToken.isCancellationRequested) {
picker.busy = false;
@@ -251,5 +293,5 @@ export abstract class PickerQuickAccessProvider<T extends IPickerQuickAccessItem
* @returns the picks either directly, as promise or combined fast and slow results.
* Pickers can return `null` to signal that no change in picks is needed.
*/
protected abstract getPicks(filter: string, disposables: DisposableStore, token: CancellationToken): Array<T | IQuickPickSeparator> | Promise<Array<T | IQuickPickSeparator>> | FastAndSlowPicksType<T> | null;
protected abstract getPicks(filter: string, disposables: DisposableStore, token: CancellationToken): Picks<T> | Promise<Picks<T>> | FastAndSlowPicks<T> | null;
}