Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/build/lib/tsb/utils.ts
4772 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
export const strings = (() => {
7
8
function format(value: string, ...rest: unknown[]): string {
9
return value.replace(/(\{\d+\})/g, function (match) {
10
const index = Number(match.substring(1, match.length - 1));
11
return String(rest[index]) || match;
12
});
13
}
14
15
return { format };
16
})();
17
18
export const graph = (() => {
19
20
class Node<T> {
21
22
readonly incoming = new Map<T, Node<T>>();
23
readonly outgoing = new Map<T, Node<T>>();
24
readonly data: T;
25
26
constructor(data: T) {
27
this.data = data;
28
}
29
}
30
31
class Graph<T> {
32
33
private _nodes = new Map<T, Node<T>>();
34
35
inertEdge(from: T, to: T): void {
36
const fromNode = this.lookupOrInsertNode(from);
37
const toNode = this.lookupOrInsertNode(to);
38
39
fromNode.outgoing.set(toNode.data, toNode);
40
toNode.incoming.set(fromNode.data, fromNode);
41
}
42
43
resetNode(data: T): void {
44
const node = this._nodes.get(data);
45
if (!node) {
46
return;
47
}
48
for (const outDep of node.outgoing.values()) {
49
outDep.incoming.delete(node.data);
50
}
51
node.outgoing.clear();
52
}
53
54
lookupOrInsertNode(data: T): Node<T> {
55
let node = this._nodes.get(data);
56
57
if (!node) {
58
node = new Node(data);
59
this._nodes.set(data, node);
60
}
61
62
return node;
63
}
64
65
lookup(data: T): Node<T> | null {
66
return this._nodes.get(data) ?? null;
67
}
68
69
findCycles(allData: T[]): Map<T, T[] | undefined> {
70
const result = new Map<T, T[] | undefined>();
71
const checked = new Set<T>();
72
for (const data of allData) {
73
const node = this.lookup(data);
74
if (!node) {
75
continue;
76
}
77
const r = this._findCycle(node, checked, new Set());
78
result.set(node.data, r);
79
}
80
return result;
81
}
82
83
private _findCycle(node: Node<T>, checked: Set<T>, seen: Set<T>): T[] | undefined {
84
85
if (checked.has(node.data)) {
86
return undefined;
87
}
88
89
let result: T[] | undefined;
90
for (const child of node.outgoing.values()) {
91
if (seen.has(child.data)) {
92
const seenArr = Array.from(seen);
93
const idx = seenArr.indexOf(child.data);
94
seenArr.push(child.data);
95
return idx > 0 ? seenArr.slice(idx) : seenArr;
96
}
97
seen.add(child.data);
98
result = this._findCycle(child, checked, seen);
99
seen.delete(child.data);
100
if (result) {
101
break;
102
}
103
}
104
checked.add(node.data);
105
return result;
106
}
107
}
108
109
return { Node, Graph };
110
})();
111
112