mirror of
https://github.com/microsoft/vscode.git
synced 2026-02-24 03:35:38 +00:00
* Check for cyclic dependencies during compile Changes gulp-tsb to check the emitted JS code for cyclic dependencies. Historically we never cared about cycles between TS files as long as they dissappeared after compile (e.g type-dependencies, not runtime dependencies) https://github.com/microsoft/vscode-internalbacklog/issues/5271 * fix cycling dependencies fyi @aeschli @aiday-mar * remove cyclic dependency with unused `BasedTextEdit` fyi @hediet * remove cycle between chatEditService and chatEditingSession fyi @alexdima * remove cyclic dependency between chatSetup and chatViewPane fyi @roblourens * better cycle detection * don't check cycles when not needed * clear graph when reprocessing file dependencies * remove cycle between with `notebookChatEditController` fyi @DonJayamanne * modernize and cleanup tsb/utils
101 lines
3.5 KiB
JavaScript
101 lines
3.5 KiB
JavaScript
"use strict";
|
|
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.graph = exports.strings = void 0;
|
|
var strings;
|
|
(function (strings) {
|
|
function format(value, ...rest) {
|
|
return value.replace(/({\d+})/g, function (match) {
|
|
const index = Number(match.substring(1, match.length - 1));
|
|
return String(rest[index]) || match;
|
|
});
|
|
}
|
|
strings.format = format;
|
|
})(strings || (exports.strings = strings = {}));
|
|
var graph;
|
|
(function (graph) {
|
|
class Node {
|
|
data;
|
|
incoming = new Map();
|
|
outgoing = new Map();
|
|
constructor(data) {
|
|
this.data = data;
|
|
}
|
|
}
|
|
graph.Node = Node;
|
|
class Graph {
|
|
_nodes = new Map();
|
|
inertEdge(from, to) {
|
|
const fromNode = this.lookupOrInsertNode(from);
|
|
const toNode = this.lookupOrInsertNode(to);
|
|
fromNode.outgoing.set(toNode.data, toNode);
|
|
toNode.incoming.set(fromNode.data, fromNode);
|
|
}
|
|
resetNode(data) {
|
|
const node = this._nodes.get(data);
|
|
if (!node) {
|
|
return;
|
|
}
|
|
for (const outDep of node.outgoing.values()) {
|
|
outDep.incoming.delete(node.data);
|
|
}
|
|
node.outgoing.clear();
|
|
}
|
|
lookupOrInsertNode(data) {
|
|
let node = this._nodes.get(data);
|
|
if (!node) {
|
|
node = new Node(data);
|
|
this._nodes.set(data, node);
|
|
}
|
|
return node;
|
|
}
|
|
lookup(data) {
|
|
return this._nodes.get(data) ?? null;
|
|
}
|
|
findCycle() {
|
|
let result;
|
|
let foundStartNodes = false;
|
|
const checked = new Set();
|
|
for (const [_start, value] of this._nodes) {
|
|
if (Object.values(value.incoming).length > 0) {
|
|
continue;
|
|
}
|
|
foundStartNodes = true;
|
|
const dfs = (node, visited) => {
|
|
if (checked.has(node)) {
|
|
return;
|
|
}
|
|
if (visited.has(node)) {
|
|
result = [...visited, node].map(n => n.data);
|
|
const idx = result.indexOf(node.data);
|
|
result = result.slice(idx);
|
|
return;
|
|
}
|
|
visited.add(node);
|
|
for (const child of Object.values(node.outgoing)) {
|
|
dfs(child, visited);
|
|
if (result) {
|
|
break;
|
|
}
|
|
}
|
|
visited.delete(node);
|
|
checked.add(node);
|
|
};
|
|
dfs(value, new Set());
|
|
if (result) {
|
|
break;
|
|
}
|
|
}
|
|
if (!foundStartNodes) {
|
|
// everything is a cycle
|
|
return Array.from(this._nodes.keys());
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
graph.Graph = Graph;
|
|
})(graph || (exports.graph = graph = {}));
|
|
//# sourceMappingURL=utils.js.map
|