private async statIgnoreError(resource: URI): Promise<IStat | undefined> {
return await this.stat(resource);
} catch (error) {
return undefined;
}
async realpath(resource: URI): Promise<string> {
Frontier kind: Code frontier
unlabeled · c_05068fe448dd
12 tests · 14908 LOC · 65 files · introduces 0 tests · 135 LOC · 2 files
The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.
Introduced files, introduced tests, and structurally relevant concept specialization
In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.
Graph controls are ready.
Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.
Every exact file and test below is linked only from the concept that introduces it.
mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache dir includes sdkTarget so Universal launches stay separate|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache miss → downloads, extracts, writes sentinel|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: concurrent calls in same process share one download|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: reports monotonic download progress ending at totalBytes|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: substitutes {sdkTarget} into urlTemplate|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/state/test/node/state.test|title=StateService Basics (delayed strategy)|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/state/test/node/state.test|title=StateService Basics (immediate strategy)|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/state/test/node/state.test|title=StateService Multiple ops (Immediate Strategy)|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/state/test/node/state.test|title=StateService Multiple ops are buffered and applied|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/lifecycle.test|title=Lifecycle Action bar has broken accessibility #100273|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/lifecycle.test|title=Lifecycle dispose disposable array|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/lifecycle.test|title=Lifecycle dispose disposables|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/lifecycle.test|title=Lifecycle dispose single disposable|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/languageStatus/test/common/languageStatusDedupe.test|title=LanguageStatus - Dedicated Entry Deduplication creates new entry when none exists|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/languageStatus/test/common/languageStatusDedupe.test|title=LanguageStatus - Dedicated Entry Deduplication duplicate IDs with existing entry - fixed version reuses existing|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/languageStatus/test/common/languageStatusDedupe.test|title=LanguageStatus - Dedicated Entry Deduplication duplicate status IDs - buggy version leaks entry|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/languageStatus/test/common/languageStatusDedupe.test|title=LanguageStatus - Dedicated Entry Deduplication duplicate status IDs - fixed version reuses entry from current update|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/languageStatus/test/common/languageStatusDedupe.test|title=LanguageStatus - Dedicated Entry Deduplication mixed unique and duplicate IDs|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/languageStatus/test/common/languageStatusDedupe.test|title=LanguageStatus - Dedicated Entry Deduplication reuses existing entry from previous update|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/charCode.test|title=CharCode has good values|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/path.test|title=Paths (Node Implementation) path|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/uri.test|title=URI File paths containing apostrophes break URI parsing and cannot be opened #276075|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/uri.test|title=URI URI#file, win-speciale|occurrence=1Every collected test enters the hierarchy at exactly one concept.
No tests are introduced at this concept. Its intent tests are introduced by other concepts.
Every collected source range enters the hierarchy at exactly one concept.
2 files ranked by introduced lines: 135 introduced LOC across 30 ranges. Expand a file to inspect source; the > gutter marks introduced lines.
private async statIgnoreError(resource: URI): Promise<IStat | undefined> {
return await this.stat(resource);
} catch (error) {
return undefined;
}
async realpath(resource: URI): Promise<string> {
private async createResourceLock(resource: URI): Promise<IDisposable> {
this.traceLock(`[Disk FileSystemProvider]: createResourceLock() - request to acquire resource lock (${filePath})`);
// Await pending locks for resource. It is possible for a new lock being
// added right after opening, so we have to loop over locks until no lock
// remains.
let existingLock: Barrier | undefined = undefined;
while (existingLock = this.resourceLocks.get(resource)) {
this.traceLock(`[Disk FileSystemProvider]: createResourceLock() - waiting for resource lock to be released (${filePath})`);
await existingLock.wait();
}
// Store new
const newLock = new Barrier();
this.resourceLocks.set(resource, newLock);
this.traceLock(`[Disk FileSystemProvider]: createResourceLock() - new resource lock created (${filePath})`);
return toDisposable(() => {
this.traceLock(`[Disk FileSystemProvider]: createResourceLock() - resource lock dispose() (${filePath})`);
// Delete lock if it is still ours
if (this.resourceLocks.get(resource) === newLock) {
this.traceLock(`[Disk FileSystemProvider]: createResourceLock() - resource lock removed from resource-lock map (${filePath})`);
this.resourceLocks.delete(resource);
}
// Open lock
this.traceLock(`[Disk FileSystemProvider]: createResourceLock() - resource lock barrier open() (${filePath})`);
newLock.open();
});
}
async readFile(resource: URI, options?: IFileAtomicReadOptions): Promise<Uint8Array> {
private traceLock(msg: string): void {
this.logService.trace(msg);
}
readFileStream(resource: URI, opts: IFileReadStreamOptions, token: CancellationToken): ReadableStreamEvents<Uint8Array> {
async writeFile(resource: URI, content: Uint8Array, opts: IFileWriteOptions): Promise<void> {
if (opts?.atomic !== false && opts?.atomic?.postfix && await this.canWriteFileAtomic(resource)) {
diskFileSystemProvider.ts
return this.doWriteFileAtomic(resource, joinPath(resourcesDirname(resource), `${resourcesBasename(resource)}${opts.atomic.postfix}`), content, opts);
return this.doWriteFile(resource, content, opts);
}
private async canWriteFileAtomic(resource: URI): Promise<boolean> {
private async doWriteFile(resource: URI, content: Uint8Array, opts: IFileWriteOptions, disableWriteLock?: boolean): Promise<void> {
try {
const filePath = this.toFilePath(resource);
// Validate target unless { create: true, overwrite: true }
if (!opts.create || !opts.overwrite) {
const fileExists = await Promises.exists(filePath);
if (fileExists) {
}
}
// Open
handle = await this.open(resource, { create: true, append: opts.append, unlock: opts.unlock }, disableWriteLock);
// Write content at once
await this.write(handle, 0, content, 0, content.byteLength);
} catch (error) {
throw await this.toFileSystemProviderWriteError(resource, error);
if (typeof handle === 'number') {
await this.close(handle);
}
}
}
private readonly mapHandleToPos = new Map<number, number>();
if (typeof fd !== 'number') {
fd = await Promises.open(filePath, isFileOpenForWriteOptions(opts) ?
// We take `opts.create` as a hint that the file is opened for writing
diskFileSystemProvider.ts
// as such we use 'w' to truncate an existing or create the
// file otherwise. we do not allow reading.
// If `opts.append` is true, use 'a' to append to the file.
(opts.append ? 'a' : 'w') :
// Otherwise we assume the file is opened for reading
// as such we use 'r' to neither truncate, nor create
// remember that this handle was used for writing
if (isFileOpenForWriteOptions(opts)) {
}
if (lock) {
// to flush the contents to disk if possible.
if (this.writeHandles.delete(fd) && DiskFileSystemProvider.canFlush) {
await Promises.fdatasync(fd); // https://github.com/microsoft/vscode/issues/9589
} catch (error) {
// In some exotic setups it is well possible that node fails to sync
// In that case we disable flushing and log the error to our logger
this.logService.error(error);
}
return await Promises.close(fd);
async write(fd: number, pos: number, data: Uint8Array, offset: number, length: number): Promise<number> {
// We know at this point that the file to write to is truncated and thus empty
// if the write now fails, the file remains empty. as such we really try hard
// to ensure the write succeeds by retrying up to three times.
return retry(() => this.doWrite(fd, pos, data, offset, length), 100 /* ms delay */, 3 /* retries */);
}
private async doWrite(fd: number, pos: number, data: Uint8Array, offset: number, length: number): Promise<number> {
let bytesWritten: number | null = null;
try {
bytesWritten = (await Promises.write(fd, data, offset, length, normalizedPos)).bytesWritten;
} catch (error) {
throw await this.toFileSystemProviderWriteError(this.writeHandles.get(fd), error);
this.updatePos(fd, normalizedPos, bytesWritten);
}
return bytesWritten;
}
//#endregion
async rename(from: URI, to: URI, opts: IFileOverwriteOptions): Promise<void> {
const toFilePath = this.toFilePath(to);
if (fromFilePath === toFilePath) {
return; // simulate node.js behaviour here and do a no-op if paths match
}
try {
// Validate the move operation can perform
await this.validateMoveCopy(from, to, 'move', opts.overwrite);
// Rename
await Promises.rename(fromFilePath, toFilePath);
} catch (error) {
// Rewrite some typical errors that can happen especially around symlinks
throw this.toFileSystemProviderError(error);
}
async copy(from: URI, to: URI, opts: IFileOverwriteOptions): Promise<void> {
private async validateMoveCopy(from: URI, to: URI, mode: 'move' | 'copy', overwrite?: boolean): Promise<void> {
const toFilePath = this.toFilePath(to);
let isSameResourceWithDifferentPathCase = false;
const isPathCaseSensitive = !!(this.capabilities & FileSystemProviderCapabilities.PathCaseSensitive);
if (!isPathCaseSensitive) {
isSameResourceWithDifferentPathCase = isEqual(fromFilePath, toFilePath, true /* ignore case */);
}
if (isSameResourceWithDifferentPathCase) {
// You cannot copy the same file to the same location with different
}
}
// Here we have to see if the target to move/copy to exists or not.
// We need to respect the `overwrite` option to throw in case the
// target exists.
const fromStat = await this.statIgnoreError(from);
if (!fromStat) {
throw createFileSystemProviderError(localize('fileMoveCopyErrorNotFound', "File to move/copy does not exist"), FileSystemProviderErrorCode.FileNotFound);
}
const toStat = await this.statIgnoreError(to);
if (!toStat) {
return; // target does not exist so we are good
}
// Handle existing target for move/copy
if ((fromStat.type & FileType.File) !== 0 && (toStat.type & FileType.File) !== 0) {
diskFileSystemProvider.ts
return; // node.js can move/copy a file over an existing file without having to delete it first
} else {
await this.delete(to, { recursive: true, useTrash: false, atomic: false });
}
//#endregion
get write() {
// Not using `promisify` here for a reason: the return
// type is not an object as indicated by TypeScript but
// just the bytes written, so we create our own wrapper.
return (fd: number, buffer: Uint8Array, offset: number | undefined | null, length: number | undefined | null, position: number | undefined | null) => {
return new Promise<{ bytesWritten: number; buffer: Uint8Array }>((resolve, reject) => {
fs.write(fd, buffer, offset, length, position, (err, bytesWritten, buffer) => {
if (err) {
return reject(err);
}
return resolve({ bytesWritten, buffer });
});
});
};
}
get fdatasync() { return promisify(fs.fdatasync); } // not exposed as API in 22.x yet