Use a plain Set intead of custom FilePathSet
This commit is contained in:
@@ -1,42 +0,0 @@
|
|||||||
import { containsPath } from "../pure/files";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A set of file paths.
|
|
||||||
*
|
|
||||||
* All paths in the set will not overlap. If a path is added to the set
|
|
||||||
* that is a parent or child of an existing path in the set, only the
|
|
||||||
* parent path will be kept.
|
|
||||||
*/
|
|
||||||
export class FilePathSet {
|
|
||||||
private paths: string[] = [];
|
|
||||||
|
|
||||||
/** Is the set currently empty */
|
|
||||||
public isEmpty(): boolean {
|
|
||||||
return this.paths.length === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds the path to the set.
|
|
||||||
*
|
|
||||||
* The set will not contain overlapping paths. This means that if the
|
|
||||||
* new path is a child of an existing path in the set then it will not
|
|
||||||
* be added. And if the new path is a parent of any existing paths, then
|
|
||||||
* those existing paths will be removed. This can cause the "size" of
|
|
||||||
* the set of decrease, but it won't go from non-zero to zero.
|
|
||||||
*/
|
|
||||||
public addPath(path: string): void {
|
|
||||||
if (this.paths.some((p) => containsPath(p, path))) {
|
|
||||||
// The new path is a child of an existing path, so don't add it.
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
// Remove any existing paths that are children of the new path.
|
|
||||||
this.paths = this.paths.filter((p) => !containsPath(path, p));
|
|
||||||
this.paths.push(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Removes and returns a path from the set, if the set is non-empty. */
|
|
||||||
public popPath(): string | undefined {
|
|
||||||
return this.paths.shift();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,7 +9,6 @@ import {
|
|||||||
import { MultiFileSystemWatcher } from "./multi-file-system-watcher";
|
import { MultiFileSystemWatcher } from "./multi-file-system-watcher";
|
||||||
import { AppEventEmitter } from "../events";
|
import { AppEventEmitter } from "../events";
|
||||||
import { extLogger } from "..";
|
import { extLogger } from "..";
|
||||||
import { FilePathSet } from "../file-path-set";
|
|
||||||
import { exists, lstat } from "fs-extra";
|
import { exists, lstat } from "fs-extra";
|
||||||
import { containsPath } from "../../pure/files";
|
import { containsPath } from "../../pure/files";
|
||||||
import { getOnDiskWorkspaceFoldersObjects } from "./workspace-folders";
|
import { getOnDiskWorkspaceFoldersObjects } from "./workspace-folders";
|
||||||
@@ -30,9 +29,23 @@ interface PathData {
|
|||||||
export abstract class FilePathDiscovery<T extends PathData> extends Discovery {
|
export abstract class FilePathDiscovery<T extends PathData> extends Discovery {
|
||||||
/** The set of known paths we are tracking */
|
/** The set of known paths we are tracking */
|
||||||
protected paths: T[] = [];
|
protected paths: T[] = [];
|
||||||
|
|
||||||
|
/** Event that fires whenever the set of known paths changes */
|
||||||
protected readonly onDidChangePathsEmitter: AppEventEmitter<void>;
|
protected readonly onDidChangePathsEmitter: AppEventEmitter<void>;
|
||||||
|
|
||||||
private readonly changedFilePaths = new FilePathSet();
|
/**
|
||||||
|
* The set of file paths that may have changed on disk since the last time
|
||||||
|
* refresh was run. Whenever a watcher reports some change to a file we add
|
||||||
|
* it to this set, and then during the next refresh we will process all
|
||||||
|
* file paths from this set and update our internal state to match whatever
|
||||||
|
* we find on disk (i.e. the file exists, doesn't exist, computed data has
|
||||||
|
* changed).
|
||||||
|
*/
|
||||||
|
private readonly changedFilePaths = new Set<string>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Watches for changes to files and directories in all workspace folders.
|
||||||
|
*/
|
||||||
private readonly watcher: MultiFileSystemWatcher = this.push(
|
private readonly watcher: MultiFileSystemWatcher = this.push(
|
||||||
new MultiFileSystemWatcher(),
|
new MultiFileSystemWatcher(),
|
||||||
);
|
);
|
||||||
@@ -76,7 +89,7 @@ export abstract class FilePathDiscovery<T extends PathData> extends Discovery {
|
|||||||
*/
|
*/
|
||||||
public async initialRefresh() {
|
public async initialRefresh() {
|
||||||
getOnDiskWorkspaceFoldersObjects().forEach((workspaceFolder) => {
|
getOnDiskWorkspaceFoldersObjects().forEach((workspaceFolder) => {
|
||||||
this.changedFilePaths.addPath(workspaceFolder.uri.fsPath);
|
this.changedFilePaths.add(workspaceFolder.uri.fsPath);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.updateWatchers();
|
this.updateWatchers();
|
||||||
@@ -85,10 +98,10 @@ export abstract class FilePathDiscovery<T extends PathData> extends Discovery {
|
|||||||
|
|
||||||
private workspaceFoldersChanged(event: WorkspaceFoldersChangeEvent) {
|
private workspaceFoldersChanged(event: WorkspaceFoldersChangeEvent) {
|
||||||
event.added.forEach((workspaceFolder) => {
|
event.added.forEach((workspaceFolder) => {
|
||||||
this.changedFilePaths.addPath(workspaceFolder.uri.fsPath);
|
this.changedFilePaths.add(workspaceFolder.uri.fsPath);
|
||||||
});
|
});
|
||||||
event.removed.forEach((workspaceFolder) => {
|
event.removed.forEach((workspaceFolder) => {
|
||||||
this.changedFilePaths.addPath(workspaceFolder.uri.fsPath);
|
this.changedFilePaths.add(workspaceFolder.uri.fsPath);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.updateWatchers();
|
this.updateWatchers();
|
||||||
@@ -108,14 +121,14 @@ export abstract class FilePathDiscovery<T extends PathData> extends Discovery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fileChanged(uri: Uri) {
|
private fileChanged(uri: Uri) {
|
||||||
this.changedFilePaths.addPath(uri.fsPath);
|
this.changedFilePaths.add(uri.fsPath);
|
||||||
void this.refresh();
|
void this.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async discover() {
|
protected async discover() {
|
||||||
let pathsUpdated = false;
|
let pathsUpdated = false;
|
||||||
let path: string | undefined;
|
for (const path of this.changedFilePaths) {
|
||||||
while ((path = this.changedFilePaths.popPath()) !== undefined) {
|
this.changedFilePaths.delete(path);
|
||||||
if (await this.handledChangedPath(path)) {
|
if (await this.handledChangedPath(path)) {
|
||||||
pathsUpdated = true;
|
pathsUpdated = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,58 +0,0 @@
|
|||||||
import { FilePathSet } from "../../../src/common/file-path-set";
|
|
||||||
|
|
||||||
describe("FilePathSet", () => {
|
|
||||||
describe("isEmpty", () => {
|
|
||||||
it("should return true only when set is empty", () => {
|
|
||||||
const v = new FilePathSet();
|
|
||||||
expect(v.isEmpty()).toBe(true);
|
|
||||||
|
|
||||||
v.addPath("/foo");
|
|
||||||
expect(v.isEmpty()).toBe(false);
|
|
||||||
|
|
||||||
v.popPath();
|
|
||||||
expect(v.isEmpty()).toBe(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("addPath / popPath", () => {
|
|
||||||
it("should keep all paths when they don't overlap", () => {
|
|
||||||
const v = new FilePathSet();
|
|
||||||
v.addPath("/foo");
|
|
||||||
v.addPath("/bar");
|
|
||||||
v.addPath("/baz");
|
|
||||||
expect(v.popPath()).toBe("/foo");
|
|
||||||
expect(v.popPath()).toBe("/bar");
|
|
||||||
expect(v.popPath()).toBe("/baz");
|
|
||||||
expect(v.popPath()).toBe(undefined);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should only keep one copy of repeated paths", () => {
|
|
||||||
const v = new FilePathSet();
|
|
||||||
v.addPath("/foo");
|
|
||||||
v.addPath("/foo");
|
|
||||||
v.addPath("/foo");
|
|
||||||
expect(v.popPath()).toBe("/foo");
|
|
||||||
expect(v.popPath()).toBe(undefined);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should adding adding paths that are children of existing paths", () => {
|
|
||||||
const v = new FilePathSet();
|
|
||||||
v.addPath("/foo");
|
|
||||||
v.addPath("/foo/bar");
|
|
||||||
v.addPath("/foo/baz");
|
|
||||||
expect(v.popPath()).toBe("/foo");
|
|
||||||
expect(v.popPath()).toBe(undefined);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should remove existing paths that are children of new paths", () => {
|
|
||||||
const v = new FilePathSet();
|
|
||||||
v.addPath("/foo");
|
|
||||||
v.addPath("/bar/baz");
|
|
||||||
v.addPath("/bar/qux");
|
|
||||||
v.addPath("/bar");
|
|
||||||
expect(v.popPath()).toBe("/foo");
|
|
||||||
expect(v.popPath()).toBe("/bar");
|
|
||||||
expect(v.popPath()).toBe(undefined);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Reference in New Issue
Block a user