forked from microsoft/vscode-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlocators.ts
More file actions
103 lines (94 loc) · 3.14 KB
/
locators.ts
File metadata and controls
103 lines (94 loc) · 3.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import { EventEmitter } from 'vscode';
import { chain } from '../../common/utils/async';
import { PythonEnvInfo } from './info';
import {
ILocator,
IPythonEnvsIterator,
NOOP_ITERATOR,
PythonEnvUpdatedEvent,
PythonLocatorQuery
} from './locator';
import { DisableableEnvsWatcher, PythonEnvsWatchers } from './watchers';
/**
* Combine the `onUpdated` event of the given iterators into a single event.
*/
export function combineIterators(iterators: IPythonEnvsIterator[]): IPythonEnvsIterator {
const result: IPythonEnvsIterator = chain(iterators);
const events = iterators.map((it) => it.onUpdated).filter((v) => v);
if (!events || events.length === 0) {
// There are no sub-events, so we leave `onUpdated` undefined.
return result;
}
const emitter = new EventEmitter<PythonEnvUpdatedEvent | null>();
let numActive = events.length;
events.forEach((event) => {
event!((e: PythonEnvUpdatedEvent | null) => {
if (e === null) {
numActive -= 1;
if (numActive === 0) {
// All the sub-events are done so we're done.
emitter.fire(null);
}
} else {
emitter.fire(e);
}
});
});
result.onUpdated = emitter.event;
return result;
}
/**
* A wrapper around a set of locators, exposing them as a single locator.
*
* Events and iterator results are combined.
*/
export class Locators extends PythonEnvsWatchers implements ILocator {
constructor(
// The locators will be watched as well as iterated.
private readonly locators: ReadonlyArray<ILocator>
) {
super(locators);
}
public iterEnvs(query?: PythonLocatorQuery): IPythonEnvsIterator {
const iterators = this.locators.map((loc) => loc.iterEnvs(query));
return combineIterators(iterators);
}
public async resolveEnv(env: string | PythonEnvInfo): Promise<PythonEnvInfo | undefined> {
for (const locator of this.locators) {
const resolved = await locator.resolveEnv(env);
if (resolved !== undefined) {
return resolved;
}
}
return undefined;
}
}
/**
* A locator wrapper that can be disabled.
*
* If disabled, events emitted by the wrapped locator are discarded,
* `iterEnvs()` yields nothing, and `resolveEnv()` already returns
* `undefined`.
*/
export class DisableableLocator extends DisableableEnvsWatcher implements ILocator {
constructor(
// To wrapp more than one use `Locators`.
private readonly locator: ILocator
) {
super(locator);
}
public iterEnvs(query?: PythonLocatorQuery): IPythonEnvsIterator {
if (!this.enabled) {
return NOOP_ITERATOR;
}
return this.locator.iterEnvs(query);
}
public async resolveEnv(env: string | PythonEnvInfo): Promise<PythonEnvInfo | undefined> {
if (!this.enabled) {
return undefined;
}
return this.locator.resolveEnv(env);
}
}